mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Free SQLSTATE and SQLERRM no earlier than other PL/pgSQL variables.
"RETURN SQLERRM" prompted plpgsql_exec_function() to read from freed memory. Back-patch to 9.0 (all supported versions). Little code ran between the premature free and the read, so non-assert builds are unlikely to witness user-visible consequences.
This commit is contained in:
		@@ -1123,8 +1123,9 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
 | 
				
			|||||||
				{
 | 
									{
 | 
				
			||||||
					/*
 | 
										/*
 | 
				
			||||||
					 * Initialize the magic SQLSTATE and SQLERRM variables for
 | 
										 * Initialize the magic SQLSTATE and SQLERRM variables for
 | 
				
			||||||
					 * the exception block. We needn't do this until we have
 | 
										 * the exception block; this also frees values from any
 | 
				
			||||||
					 * found a matching exception.
 | 
										 * prior use of the same exception. We needn't do this
 | 
				
			||||||
 | 
										 * until we have found a matching exception.
 | 
				
			||||||
					 */
 | 
										 */
 | 
				
			||||||
					PLpgSQL_var *state_var;
 | 
										PLpgSQL_var *state_var;
 | 
				
			||||||
					PLpgSQL_var *errm_var;
 | 
										PLpgSQL_var *errm_var;
 | 
				
			||||||
@@ -1148,13 +1149,6 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
					rc = exec_stmts(estate, exception->action);
 | 
										rc = exec_stmts(estate, exception->action);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					free_var(state_var);
 | 
					 | 
				
			||||||
					state_var->value = (Datum) 0;
 | 
					 | 
				
			||||||
					state_var->isnull = true;
 | 
					 | 
				
			||||||
					free_var(errm_var);
 | 
					 | 
				
			||||||
					errm_var->value = (Datum) 0;
 | 
					 | 
				
			||||||
					errm_var->isnull = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2498,9 +2498,21 @@ NOTICE:  P0001 user exception
 | 
				
			|||||||
 
 | 
					 
 | 
				
			||||||
(1 row)
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					create function excpt_test4() returns text as $$
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
						begin perform 1/0;
 | 
				
			||||||
 | 
						exception when others then return sqlerrm; end;
 | 
				
			||||||
 | 
					end; $$ language plpgsql;
 | 
				
			||||||
 | 
					select excpt_test4();
 | 
				
			||||||
 | 
					   excpt_test4    
 | 
				
			||||||
 | 
					------------------
 | 
				
			||||||
 | 
					 division by zero
 | 
				
			||||||
 | 
					(1 row)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
drop function excpt_test1();
 | 
					drop function excpt_test1();
 | 
				
			||||||
drop function excpt_test2();
 | 
					drop function excpt_test2();
 | 
				
			||||||
drop function excpt_test3();
 | 
					drop function excpt_test3();
 | 
				
			||||||
 | 
					drop function excpt_test4();
 | 
				
			||||||
-- parameters of raise stmt can be expressions
 | 
					-- parameters of raise stmt can be expressions
 | 
				
			||||||
create function raise_exprs() returns void as $$
 | 
					create function raise_exprs() returns void as $$
 | 
				
			||||||
declare
 | 
					declare
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2118,11 +2118,19 @@ begin
 | 
				
			|||||||
	    raise notice '% %', sqlstate, sqlerrm;
 | 
						    raise notice '% %', sqlstate, sqlerrm;
 | 
				
			||||||
    end;
 | 
					    end;
 | 
				
			||||||
end; $$ language plpgsql;
 | 
					end; $$ language plpgsql;
 | 
				
			||||||
 | 
					 | 
				
			||||||
select excpt_test3();
 | 
					select excpt_test3();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					create function excpt_test4() returns text as $$
 | 
				
			||||||
 | 
					begin
 | 
				
			||||||
 | 
						begin perform 1/0;
 | 
				
			||||||
 | 
						exception when others then return sqlerrm; end;
 | 
				
			||||||
 | 
					end; $$ language plpgsql;
 | 
				
			||||||
 | 
					select excpt_test4();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
drop function excpt_test1();
 | 
					drop function excpt_test1();
 | 
				
			||||||
drop function excpt_test2();
 | 
					drop function excpt_test2();
 | 
				
			||||||
drop function excpt_test3();
 | 
					drop function excpt_test3();
 | 
				
			||||||
 | 
					drop function excpt_test4();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- parameters of raise stmt can be expressions
 | 
					-- parameters of raise stmt can be expressions
 | 
				
			||||||
create function raise_exprs() returns void as $$
 | 
					create function raise_exprs() returns void as $$
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user