Commit f5ef00ae authored by Noah Misch's avatar Noah Misch

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.
parent 62a4a1af
...@@ -1243,8 +1243,9 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block) ...@@ -1243,8 +1243,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;
...@@ -1268,13 +1269,6 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block) ...@@ -1268,13 +1269,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;
} }
} }
......
...@@ -2655,9 +2655,21 @@ NOTICE: P0001 user exception ...@@ -2655,9 +2655,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
......
...@@ -2246,11 +2246,19 @@ begin ...@@ -2246,11 +2246,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 $$
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment