Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit224501e

Browse files
committed
plpgsql's exec_assign_value() freed the old value of a variable before
copying/converting the new value, which meant that it failed badly on"var := var" if var is of pass-by-reference type. Fix this and a similarhazard in exec_move_row(); not sure that the latter can manifest before8.0, but patch it all the way back anyway. Per report from Dave Chapeskie.
1 parent2b91c8c commit224501e

File tree

1 file changed

+30
-23
lines changed

1 file changed

+30
-23
lines changed

‎src/pl/plpgsql/src/pl_exec.c

Lines changed: 30 additions & 23 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.52.2.1 2002/03/25 07:41:21 tgl Exp $
6+
* $Header: /cvsroot/pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.52.2.2 2005/06/20 20:45:12 tgl Exp $
77
*
88
* This software is copyrighted by Jan Wieck - Hamburg.
99
*
@@ -2665,12 +2665,6 @@ exec_assign_value(PLpgSQL_execstate * estate,
26652665
*/
26662666
var= (PLpgSQL_var*)target;
26672667

2668-
if (var->freeval)
2669-
{
2670-
pfree((void*) (var->value));
2671-
var->freeval= false;
2672-
}
2673-
26742668
newvalue=exec_cast_value(value,valtype,var->datatype->typoid,
26752669
&(var->datatype->typinput),
26762670
var->datatype->typelem,
@@ -2690,23 +2684,28 @@ exec_assign_value(PLpgSQL_execstate * estate,
26902684
if (!var->datatype->typbyval&& !*isNull)
26912685
{
26922686
if (newvalue==value)
2693-
{
2694-
intlen;
2687+
newvalue=datumCopy(newvalue,
2688+
false,
2689+
var->datatype->typlen);
2690+
}
26952691

2696-
if (var->datatype->typlen<0)
2697-
len=VARSIZE(newvalue);
2698-
else
2699-
len=var->datatype->typlen;
2700-
var->value= (Datum)palloc(len);
2701-
memcpy((void*) (var->value), (void*)newvalue,len);
2702-
}
2703-
else
2704-
var->value=newvalue;
2705-
var->freeval= true;
2692+
/*
2693+
* Now free the old value. (We can't do this any earlier
2694+
* because of the possibility that we are assigning the
2695+
* var's old value to it, eg "foo := foo". We could optimize
2696+
* out the assignment altogether in such cases, but it's too
2697+
* infrequent to be worth testing for.)
2698+
*/
2699+
if (var->freeval)
2700+
{
2701+
pfree(DatumGetPointer(var->value));
2702+
var->freeval= false;
27062703
}
2707-
else
2708-
var->value=newvalue;
2704+
2705+
var->value=newvalue;
27092706
var->isnull=*isNull;
2707+
if (!var->datatype->typbyval&& !*isNull)
2708+
var->freeval= true;
27102709
break;
27112710

27122711
casePLPGSQL_DTYPE_RECFIELD:
@@ -3145,6 +3144,14 @@ exec_move_row(PLpgSQL_execstate * estate,
31453144
*/
31463145
if (rec!=NULL)
31473146
{
3147+
/*
3148+
* copy input first, just in case it is pointing at variable's value
3149+
*/
3150+
if (HeapTupleIsValid(tup))
3151+
tup=heap_copytuple(tup);
3152+
if (tupdesc)
3153+
tupdesc=CreateTupleDescCopy(tupdesc);
3154+
31483155
if (rec->freetup)
31493156
{
31503157
heap_freetuple(rec->tup);
@@ -3158,8 +3165,8 @@ exec_move_row(PLpgSQL_execstate * estate,
31583165

31593166
if (HeapTupleIsValid(tup))
31603167
{
3161-
rec->tup=heap_copytuple(tup);
3162-
rec->tupdesc=CreateTupleDescCopy(tupdesc);
3168+
rec->tup=tup;
3169+
rec->tupdesc=tupdesc;
31633170
rec->freetup= true;
31643171
rec->freetupdesc= true;
31653172
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp