Skip to content

Commit f5ef00a

Browse files
committed
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.
1 parent 62a4a1a commit f5ef00a

File tree

3 files changed

+24
-10
lines changed

3 files changed

+24
-10
lines changed

src/pl/plpgsql/src/pl_exec.c

+3-9
Original file line numberDiff line numberDiff line change
@@ -1243,8 +1243,9 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
12431243
{
12441244
/*
12451245
* Initialize the magic SQLSTATE and SQLERRM variables for
1246-
* the exception block. We needn't do this until we have
1247-
* found a matching exception.
1246+
* the exception block; this also frees values from any
1247+
* prior use of the same exception. We needn't do this
1248+
* until we have found a matching exception.
12481249
*/
12491250
PLpgSQL_var *state_var;
12501251
PLpgSQL_var *errm_var;
@@ -1268,13 +1269,6 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
12681269

12691270
rc = exec_stmts(estate, exception->action);
12701271

1271-
free_var(state_var);
1272-
state_var->value = (Datum) 0;
1273-
state_var->isnull = true;
1274-
free_var(errm_var);
1275-
errm_var->value = (Datum) 0;
1276-
errm_var->isnull = true;
1277-
12781272
break;
12791273
}
12801274
}

src/test/regress/expected/plpgsql.out

+12
Original file line numberDiff line numberDiff line change
@@ -2655,9 +2655,21 @@ NOTICE: P0001 user exception
26552655

26562656
(1 row)
26572657

2658+
create function excpt_test4() returns text as $$
2659+
begin
2660+
begin perform 1/0;
2661+
exception when others then return sqlerrm; end;
2662+
end; $$ language plpgsql;
2663+
select excpt_test4();
2664+
excpt_test4
2665+
------------------
2666+
division by zero
2667+
(1 row)
2668+
26582669
drop function excpt_test1();
26592670
drop function excpt_test2();
26602671
drop function excpt_test3();
2672+
drop function excpt_test4();
26612673
-- parameters of raise stmt can be expressions
26622674
create function raise_exprs() returns void as $$
26632675
declare

src/test/regress/sql/plpgsql.sql

+9-1
Original file line numberDiff line numberDiff line change
@@ -2246,11 +2246,19 @@ begin
22462246
raise notice '% %', sqlstate, sqlerrm;
22472247
end;
22482248
end; $$ language plpgsql;
2249-
22502249
select excpt_test3();
2250+
2251+
create function excpt_test4() returns text as $$
2252+
begin
2253+
begin perform 1/0;
2254+
exception when others then return sqlerrm; end;
2255+
end; $$ language plpgsql;
2256+
select excpt_test4();
2257+
22512258
drop function excpt_test1();
22522259
drop function excpt_test2();
22532260
drop function excpt_test3();
2261+
drop function excpt_test4();
22542262

22552263
-- parameters of raise stmt can be expressions
22562264
create function raise_exprs() returns void as $$

0 commit comments

Comments
 (0)