mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-27 08:39:28 +08:00
Fix plpgsql to avoid reference to already-freed memory when returning a
pass-by-reference data type and the RETURN statement is within an EXCEPTION block. Bug introduced by my fix of 2007-01-28 to use per-subtransaction ExprContexts/EStates; since that wasn't back-patched into older branches, only 8.2 and HEAD are affected. Per report from Gary Winslow.
This commit is contained in:
parent
9de4b61388
commit
266a0ffe45
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.180.2.4 2007/02/08 18:37:43 tgl Exp $
|
* $PostgreSQL: pgsql/src/pl/plpgsql/src/pl_exec.c,v 1.180.2.5 2007/04/19 16:33:32 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -951,6 +951,25 @@ exec_stmt_block(PLpgSQL_execstate *estate, PLpgSQL_stmt_block *block)
|
|||||||
/* Run the block's statements */
|
/* Run the block's statements */
|
||||||
rc = exec_stmts(estate, block->body);
|
rc = exec_stmts(estate, block->body);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the block ended with RETURN, we may need to copy the return
|
||||||
|
* value out of the subtransaction eval_context. This is currently
|
||||||
|
* only needed for scalar result types --- rowtype values will
|
||||||
|
* always exist in the function's own memory context.
|
||||||
|
*/
|
||||||
|
if (rc == PLPGSQL_RC_RETURN &&
|
||||||
|
!estate->retisset &&
|
||||||
|
!estate->retisnull &&
|
||||||
|
estate->rettupdesc == NULL)
|
||||||
|
{
|
||||||
|
int16 resTypLen;
|
||||||
|
bool resTypByVal;
|
||||||
|
|
||||||
|
get_typlenbyval(estate->rettype, &resTypLen, &resTypByVal);
|
||||||
|
estate->retval = datumCopy(estate->retval,
|
||||||
|
resTypByVal, resTypLen);
|
||||||
|
}
|
||||||
|
|
||||||
/* Commit the inner transaction, return to outer xact context */
|
/* Commit the inner transaction, return to outer xact context */
|
||||||
ReleaseCurrentSubTransaction();
|
ReleaseCurrentSubTransaction();
|
||||||
MemoryContextSwitchTo(oldcontext);
|
MemoryContextSwitchTo(oldcontext);
|
||||||
|
Loading…
Reference in New Issue
Block a user