Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 9b6fb9f

Browse files
committed
Fix ExecuteCallStmt to not scribble on the passed-in parse tree.
Modifying the parse tree at execution time is, or at least ought to be, verboten. It seems quite difficult to actually cause a crash this way in v11 (although you can exhibit it pretty easily in HEAD by messing with plan_cache_mode). Nonetheless, it's risky, so fix and back-patch. Discussion: https://postgr.es/m/13789.1541359611@sss.pgh.pa.us
1 parent 15c7293 commit 9b6fb9f

File tree

1 file changed

+18
-5
lines changed

1 file changed

+18
-5
lines changed

src/backend/commands/functioncmds.c

+18-5
Original file line numberDiff line numberDiff line change
@@ -2225,6 +2225,7 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver
22252225

22262226
fexpr = stmt->funcexpr;
22272227
Assert(fexpr);
2228+
Assert(IsA(fexpr, FuncExpr));
22282229

22292230
aclresult = pg_proc_aclcheck(fexpr->funcid, GetUserId(), ACL_EXECUTE);
22302231
if (aclresult != ACLCHECK_OK)
@@ -2253,13 +2254,25 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver
22532254
* and AbortTransaction() resets the security context. This could be
22542255
* reorganized, but right now it doesn't work.
22552256
*/
2256-
if (((Form_pg_proc )GETSTRUCT(tp))->prosecdef)
2257+
if (((Form_pg_proc) GETSTRUCT(tp))->prosecdef)
22572258
callcontext->atomic = true;
22582259

22592260
/*
2260-
* Expand named arguments, defaults, etc.
2261+
* Expand named arguments, defaults, etc. We do not want to scribble on
2262+
* the passed-in CallStmt parse tree, so first flat-copy fexpr, allowing
2263+
* us to replace its args field. (Note that expand_function_arguments
2264+
* will not modify any of the passed-in data structure.)
22612265
*/
2262-
fexpr->args = expand_function_arguments(fexpr->args, fexpr->funcresulttype, tp);
2266+
{
2267+
FuncExpr *nexpr = makeNode(FuncExpr);
2268+
2269+
memcpy(nexpr, fexpr, sizeof(FuncExpr));
2270+
fexpr = nexpr;
2271+
}
2272+
2273+
fexpr->args = expand_function_arguments(fexpr->args,
2274+
fexpr->funcresulttype,
2275+
tp);
22632276
nargs = list_length(fexpr->args);
22642277

22652278
ReleaseSysCache(tp);
@@ -2362,8 +2375,8 @@ TupleDesc
23622375
CallStmtResultDesc(CallStmt *stmt)
23632376
{
23642377
FuncExpr *fexpr;
2365-
HeapTuple tuple;
2366-
TupleDesc tupdesc;
2378+
HeapTuple tuple;
2379+
TupleDesc tupdesc;
23672380

23682381
fexpr = stmt->funcexpr;
23692382

0 commit comments

Comments
 (0)