From: Jeff Davis Date: Wed, 26 Feb 2014 15:47:09 +0000 (-0800) Subject: Fix crash in json_to_record(). X-Git-Tag: REL9_4_BETA1~416 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=486ea0b19e08c10ff53e36e46209a928df048281;p=postgresql Fix crash in json_to_record(). json_to_record() depends on get_call_result_type() for the tuple descriptor of the record that should be returned, but in some cases that cannot be determined. Add a guard to check if the tuple descriptor has been properly resolved, similar to other callers of get_call_result_type(). Also add guard for two other callers of get_call_result_type() in jsonfuncs.c. Although json_to_record() is the only actual bug, it's a good idea to follow convention. --- diff --git a/src/backend/utils/adt/jsonfuncs.c b/src/backend/utils/adt/jsonfuncs.c index e1d8aaed0c..2320305608 100644 --- a/src/backend/utils/adt/jsonfuncs.c +++ b/src/backend/utils/adt/jsonfuncs.c @@ -941,7 +941,11 @@ each_worker(PG_FUNCTION_ARGS, bool as_text) rsi->returnMode = SFRM_Materialize; - (void) get_call_result_type(fcinfo, NULL, &tupdesc); + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("function returning record called in context " + "that cannot accept type record"))); /* make these in a sufficiently long-lived memory context */ old_cxt = MemoryContextSwitchTo(rsi->econtext->ecxt_per_query_memory); @@ -1349,7 +1353,13 @@ populate_record_worker(PG_FUNCTION_ARGS, bool have_record_arg) json = PG_GETARG_TEXT_P(0); - get_call_result_type(fcinfo, NULL, &tupdesc); + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("function returning record called in context " + "that cannot accept type record"), + errhint("Try calling the function in the FROM clause " + "using a column definition list."))); } json_hash = get_json_object_as_hash(json, "json_populate_record", @@ -1713,7 +1723,11 @@ populate_recordset_worker(PG_FUNCTION_ARGS, bool have_record_arg) * get the tupdesc from the result set info - it must be a record type * because we already checked that arg1 is a record type. */ - (void) get_call_result_type(fcinfo, NULL, &tupdesc); + if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("function returning record called in context " + "that cannot accept type record"))); state = palloc0(sizeof(PopulateRecordsetState)); sem = palloc0(sizeof(JsonSemAction));