postgres.git / summary / log / commit / refs
commit d7083cc546bba50fe1adea5a05772f857cbff96b
Author: Noah Misch <noah@leadboat.com>
Date: Thu Feb 26 04:48:28 2015 +0000
First released in: 9.5.0, 9.0.20, 9.1.16, 9.2.11, 9.3.7, 9.4.2
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.
src/pl/plpgsql/src/pl_exec.c | 12 +++---------
src/test/regress/expected/plpgsql.out | 12 ++++++++++++
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 dc3bcfe37a9..6f4fe918596 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -1129,8 +1129,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;
@@ -1154,13 +1155,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 0582e6275ed..268626ea0eb 100644
--- a/src/test/regress/expected/plpgsql.out
+++ b/src/test/regress/expected/plpgsql.out
@@ -2646,9 +2646,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 83385090f44..d76004424e5 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 $$
[parent: be8801e9c5f8]