mirror of
https://github.com/postgres/postgres.git
synced 2025-04-29 13:56:47 +03:00
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
This commit is contained in:
parent
15c7293477
commit
9b6fb9fbb4
@ -2225,6 +2225,7 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver
|
|||||||
|
|
||||||
fexpr = stmt->funcexpr;
|
fexpr = stmt->funcexpr;
|
||||||
Assert(fexpr);
|
Assert(fexpr);
|
||||||
|
Assert(IsA(fexpr, FuncExpr));
|
||||||
|
|
||||||
aclresult = pg_proc_aclcheck(fexpr->funcid, GetUserId(), ACL_EXECUTE);
|
aclresult = pg_proc_aclcheck(fexpr->funcid, GetUserId(), ACL_EXECUTE);
|
||||||
if (aclresult != ACLCHECK_OK)
|
if (aclresult != ACLCHECK_OK)
|
||||||
@ -2253,13 +2254,25 @@ ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver
|
|||||||
* and AbortTransaction() resets the security context. This could be
|
* and AbortTransaction() resets the security context. This could be
|
||||||
* reorganized, but right now it doesn't work.
|
* reorganized, but right now it doesn't work.
|
||||||
*/
|
*/
|
||||||
if (((Form_pg_proc )GETSTRUCT(tp))->prosecdef)
|
if (((Form_pg_proc) GETSTRUCT(tp))->prosecdef)
|
||||||
callcontext->atomic = true;
|
callcontext->atomic = true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Expand named arguments, defaults, etc.
|
* Expand named arguments, defaults, etc. We do not want to scribble on
|
||||||
|
* the passed-in CallStmt parse tree, so first flat-copy fexpr, allowing
|
||||||
|
* us to replace its args field. (Note that expand_function_arguments
|
||||||
|
* will not modify any of the passed-in data structure.)
|
||||||
*/
|
*/
|
||||||
fexpr->args = expand_function_arguments(fexpr->args, fexpr->funcresulttype, tp);
|
{
|
||||||
|
FuncExpr *nexpr = makeNode(FuncExpr);
|
||||||
|
|
||||||
|
memcpy(nexpr, fexpr, sizeof(FuncExpr));
|
||||||
|
fexpr = nexpr;
|
||||||
|
}
|
||||||
|
|
||||||
|
fexpr->args = expand_function_arguments(fexpr->args,
|
||||||
|
fexpr->funcresulttype,
|
||||||
|
tp);
|
||||||
nargs = list_length(fexpr->args);
|
nargs = list_length(fexpr->args);
|
||||||
|
|
||||||
ReleaseSysCache(tp);
|
ReleaseSysCache(tp);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user