diff options
author | Noah Misch <noah@leadboat.com> | 2015-02-25 23:48:28 -0500 |
---|---|---|
committer | Noah Misch <noah@leadboat.com> | 2015-02-25 23:48:49 -0500 |
commit | 38930e473a799c1ba2b33b2964dd2b9f8862a268 (patch) | |
tree | 1d945435c28d38957f9cac6395a8a52392a50e3c /src | |
parent | f16270aded0af5f3b19719bee3f67c8cc19b20aa (diff) |
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.
Diffstat (limited to 'src')
-rw-r--r-- | src/pl/plpgsql/src/pl_exec.c | 12 | ||||
-rw-r--r-- | src/test/regress/expected/plpgsql.out | 12 | ||||
-rw-r--r-- | src/test/regress/sql/plpgsql.sql | 10 |
3 files changed, 24 insertions, 10 deletions
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index 69d1965253d..b7f44ca1d1a 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -1243,8 +1243,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; @@ -1268,13 +1269,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; } } diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out index 8892bb417d3..46f139e41ea 100644 --- a/src/test/regress/expected/plpgsql.out +++ b/src/test/regress/expected/plpgsql.out @@ -2644,9 +2644,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 diff --git a/src/test/regress/sql/plpgsql.sql b/src/test/regress/sql/plpgsql.sql index c5616ee8fc6..0de8000b941 100644 --- a/src/test/regress/sql/plpgsql.sql +++ b/src/test/regress/sql/plpgsql.sql @@ -2241,11 +2241,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 $$ |