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
 | 
			
		||||
					 * the exception block. We needn't do this until we have
 | 
			
		||||
					 * found a matching exception.
 | 
			
		||||
					 * the exception block; this also frees values from any
 | 
			
		||||
					 * prior use of the same exception. We needn't do this
 | 
			
		||||
					 * until we have found a matching exception.
 | 
			
		||||
					 */
 | 
			
		||||
					PLpgSQL_var *state_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);
 | 
			
		||||
 | 
			
		||||
					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;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
@@ -2498,9 +2498,21 @@ NOTICE:  P0001 user exception
 | 
			
		||||
 
 | 
			
		||||
(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_test2();
 | 
			
		||||
drop function excpt_test3();
 | 
			
		||||
drop function excpt_test4();
 | 
			
		||||
-- parameters of raise stmt can be expressions
 | 
			
		||||
create function raise_exprs() returns void as $$
 | 
			
		||||
declare
 | 
			
		||||
 
 | 
			
		||||
@@ -2118,11 +2118,19 @@ begin
 | 
			
		||||
	    raise notice '% %', sqlstate, sqlerrm;
 | 
			
		||||
    end;
 | 
			
		||||
end; $$ language plpgsql;
 | 
			
		||||
 | 
			
		||||
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_test2();
 | 
			
		||||
drop function excpt_test3();
 | 
			
		||||
drop function excpt_test4();
 | 
			
		||||
 | 
			
		||||
-- parameters of raise stmt can be expressions
 | 
			
		||||
create function raise_exprs() returns void as $$
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user