8000 Fix an ancient logic error in plpgsql's exec_stmt_block: it thought i… · danielcode/postgres@675a313 · GitHub
[go: up one dir, main page]

Skip to content

Commit 675a313

Browse files
committed
Fix an ancient logic error in plpgsql's exec_stmt_block: it thought it could
get away with not (re)initializing a local variable if the variable is marked "isconst" and not "isnull". Unfortunately it makes this decision after having already freed the old value, meaning that something like for i in 1..10 loop declare c constant text := 'hi there'; leads to subsequent accesses to freed memory, and hence probably crashes. (In particular, this is why Asif Ali Rehman's bug leads to crash and not just an unexpectedly-NULL value for SQLERRM: SQLERRM is marked CONSTANT and so triggers this error.) The whole thing seems wrong on its face anyway: CONSTANT means that you can't change the variable inside the block, not that the initializer expression is guaranteed not to change value across successive block entries. Hence, remove the "optimization" instead of trying to fix it.
1 parent 6eb61d5 commit 675a313

File tree

1 file changed

+14
-14
lines changed

1 file changed

+14
-14
lines changed

src/pl/plpgsql/src/pl_exec.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* procedural language
44
*
55
* IDENTIFICATION
6-
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.65.2.4 2005/06/20 20:45:06 tgl Exp $
6+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.65.2.5 2007/02/08 18:38:31 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -767,26 +767,26 @@ exec_stmt_block(PLpgSQL_execstate * estate, PLpgSQL_stmt_block * block)
767767
{
768768
PLpgSQL_var *var = (PLpgSQL_var *) (estate->datums[n]);
769769

770+
/* free any old value, in case re-entering block */
770771
if (var->freeval)
771772
{
772773
pfree((void *) (var->value));
773774
var->freeval = false;
774775
}
775776

776-
if (!var->isconst || var->isnull)
777+
/* Initially it contains a NULL */
778+
var->value = (Datum) 0;
779+
var->isnull = true;
780+
781+
if (var->default_val == NULL)
777782
{
778-
if (var->default_val == NULL)
779-
{
780-
var->value = (Datum) 0;
781-
var->isnull = true;
782-
if (var->notnull)
783-
elog(ERROR, "variable '%s' declared NOT NULL cannot default to NULL", var->refname);
784-
}
785-
else
786-
{
787-
exec_assign_expr(estate, (PLpgSQL_datum *) var,
788-
var->default_val);
789-
}
783+
if (var->notnull)
784+
elog(ERROR, "variable '%s' declared NOT NULL cannot default to NULL", var->refname);
785+
}
786+
else
787+
{
788+
exec_assign_expr(estate, (PLpgSQL_datum *) var,
789+
var->default_val);
790790
}
791791
}
792792
break;

0 commit comments

Comments
 (0)
0