From be3aa30da3624995b7cbf67b44314f693c2d15bf Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 9 Jul 2005 01:53:22 +0000 Subject: [PATCH] Fix inadequate error checking: you can't assume that fcinfo->resultinfo is a ReturnSetInfo unless you've tested it with IsA. --- contrib/tablefunc/tablefunc.c | 40 +++++++++++++++--------------- contrib/xml2/xpath.c | 46 ++++++++++++++++++----------------- 2 files changed, 45 insertions(+), 41 deletions(-) diff --git a/contrib/tablefunc/tablefunc.c b/contrib/tablefunc/tablefunc.c index 6ab79ebeff..97163c81a4 100644 --- a/contrib/tablefunc/tablefunc.c +++ b/contrib/tablefunc/tablefunc.c @@ -687,9 +687,13 @@ crosstab_hash(PG_FUNCTION_ARGS) int num_categories; /* check to see if caller supports us returning a tuplestore */ - if (!rsinfo || !(rsinfo->allowedModes & SFRM_Materialize)) + if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("set-valued function called in context that cannot accept a set"))); + if (!(rsinfo->allowedModes & SFRM_Materialize)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("materialize mode required, but it is not " \ "allowed in this context"))); @@ -1049,9 +1053,13 @@ connectby_text(PG_FUNCTION_ARGS) MemoryContext oldcontext; /* check to see if caller supports us returning a tuplestore */ - if (!rsinfo || !(rsinfo->allowedModes & SFRM_Materialize)) + if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("set-valued function called in context that cannot accept a set"))); + if (!(rsinfo->allowedModes & SFRM_Materialize)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("materialize mode required, but it is not " \ "allowed in this context"))); @@ -1076,13 +1084,6 @@ connectby_text(PG_FUNCTION_ARGS) /* OK, use it then */ attinmeta = TupleDescGetAttInMetadata(tupdesc); - /* check to see if caller supports us returning a tuplestore */ - if (!rsinfo || !(rsinfo->allowedModes & SFRM_Materialize)) - ereport(ERROR, - (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("materialize mode required, but it is not " \ - "allowed in this context"))); - /* OK, go to work */ rsinfo->returnMode = SFRM_Materialize; rsinfo->setResult = connectby(relname, @@ -1131,9 +1132,15 @@ connectby_text_serial(PG_FUNCTION_ARGS) MemoryContext oldcontext; /* check to see if caller supports us returning a tuplestore */ - if (!rsinfo || !(rsinfo->allowedModes & SFRM_Materialize)) - elog(ERROR, "connectby: materialize mode required, but it is not " - "allowed in this context"); + if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("set-valued function called in context that cannot accept a set"))); + if (!(rsinfo->allowedModes & SFRM_Materialize)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("materialize mode required, but it is not " \ + "allowed in this context"))); if (fcinfo->nargs == 7) { @@ -1156,11 +1163,6 @@ connectby_text_serial(PG_FUNCTION_ARGS) /* OK, use it then */ attinmeta = TupleDescGetAttInMetadata(tupdesc); - /* check to see if caller supports us returning a tuplestore */ - if (!rsinfo->allowedModes & SFRM_Materialize) - elog(ERROR, "connectby requires Materialize mode, but it is not " - "allowed in this context"); - /* OK, go to work */ rsinfo->returnMode = SFRM_Materialize; rsinfo->setResult = connectby(relname, diff --git a/contrib/xml2/xpath.c b/contrib/xml2/xpath.c index c15a5bb622..98a5e3a0e2 100644 --- a/contrib/xml2/xpath.c +++ b/contrib/xml2/xpath.c @@ -669,23 +669,36 @@ xpath_table(PG_FUNCTION_ARGS) StringInfo querysql; -/* We only have a valid tuple description in table function mode */ + /* We only have a valid tuple description in table function mode */ + if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("set-valued function called in context that cannot accept a set"))); if (rsinfo->expectedDesc == NULL) - { - ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("xpath_table must be called as a table function"))); - } + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("xpath_table must be called as a table function"))); -/* The tuplestore must exist in a higher context than - * this function call (per_query_ctx is used) */ + /* + * We want to materialise because it means that we don't have to carry + * libxml2 parser state between invocations of this function + */ + if (!(rsinfo->allowedModes & SFRM_Materialize)) + ereport(ERROR, + (errcode(ERRCODE_SYNTAX_ERROR), + errmsg("xpath_table requires Materialize mode, but it is not " + "allowed in this context"))); + + /* The tuplestore must exist in a higher context than + * this function call (per_query_ctx is used) + */ per_query_ctx = rsinfo->econtext->ecxt_per_query_memory; oldcontext = MemoryContextSwitchTo(per_query_ctx); -/* Create the tuplestore - work_mem is the max in-memory size before a - * file is created on disk to hold it. - */ - + /* Create the tuplestore - work_mem is the max in-memory size before a + * file is created on disk to hold it. + */ tupstore = tuplestore_begin_heap(true, false, work_mem); MemoryContextSwitchTo(oldcontext); @@ -703,17 +716,6 @@ xpath_table(PG_FUNCTION_ARGS) attinmeta = TupleDescGetAttInMetadata(ret_tupdesc); - /* - * We want to materialise because it means that we don't have to carry - * libxml2 parser state between invocations of this function - */ - - /* check to see if caller supports us returning a tuplestore */ - if (!rsinfo || !(rsinfo->allowedModes & SFRM_Materialize)) - ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), - errmsg("xpath_table requires Materialize mode, but it is not " - "allowed in this context"))); - /* Set return mode and allocate value space. */ rsinfo->returnMode = SFRM_Materialize; rsinfo->setDesc = ret_tupdesc;