Skip to content

Commit 40a9a16

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 7a501bc commit 40a9a16

File tree

3 files changed

+24
-10
lines changed

3 files changed

+24
-10
lines changed

src/pl/plpgsql/src/pl_exec.c

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,8 +1125,9 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
11251125
{
11261126
/*
11271127
* Initialize the magic SQLSTATE and SQLERRM variables for
1128-
* the exception block. We needn't do this until we have
1129-
* found a matching exception.
1128+
* the exception block; this also frees values from any
1129+
* prior use of the same exception. We needn't do this
1130+
* until we have found a matching exception.
11301131
*/
11311132
PLpgSQL_var *state_var;
11321133
PLpgSQL_var *errm_var;
@@ -1144,13 +1145,6 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
11441145

11451146
rc = exec_stmts(estate, exception->action);
11461147

1147-
free_var(state_var);
1148-
state_var->value = (Datum) 0;
1149-
state_var->isnull = true;
1150-
free_var(errm_var);
1151-
errm_var->value = (Datum) 0;
1152-
errm_var->isnull = true;
1153-
11541148
/* re-throw error if requested by handler */
11551149
if (rc == PLPGSQL_RC_RERAISE)
11561150
ReThrowError(edata);

src/test/regress/expected/plpgsql.out

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2469,9 +2469,21 @@ NOTICE: P0001 user exception
24692469

24702470
(1 row)
24712471

2472+
create function excpt_test4() returns text as $$
2473+
begin
2474+
begin perform 1/0;
2475+
exception when others then return sqlerrm; end;
2476+
end; $$ language plpgsql;
2477+
select excpt_test4();
2478+
excpt_test4
2479+
------------------
2480+
division by zero
2481+
(1 row)
2482+
24722483
drop function excpt_test1();
24732484
drop function excpt_test2();
24742485
drop function excpt_test3();
2486+
drop function excpt_test4();
24752487
-- parameters of raise stmt can be expressions
24762488
create function raise_exprs() returns void as $$
24772489
declare

src/test/regress/sql/plpgsql.sql

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2093,11 +2093,19 @@ begin
20932093
raise notice '% %', sqlstate, sqlerrm;
20942094
end;
20952095
end; $$ language plpgsql;
2096-
20972096
select excpt_test3();
2097+
2098+
create function excpt_test4() returns text as $$
2099+
begin
2100+
begin perform 1/0;
2101+
exception when others then return sqlerrm; end;
2102+
end; $$ language plpgsql;
2103+
select excpt_test4();
2104+
20982105
drop function excpt_test1();
20992106
drop function excpt_test2();
21002107
drop function excpt_test3();
2108+
drop function excpt_test4();
21012109

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

0 commit comments

Comments
 (0)