From 6d493e1a013514a6f0abb5d30d08219c1831cfec Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 23 Feb 2017 22:08:10 -0500 Subject: [PATCH] Add an Assert that enum_cmp_internal() gets passed an FmgrInfo pointer. If someone were to try to call one of the enum comparison functions using DirectFunctionCallN, it would very likely seem to work, because only in unusual cases does enum_cmp_internal() need to access the typcache. But once such a case occurred, code like that would crash with a null pointer dereference. To make an oversight of that sort less likely to escape detection, add a non-bypassable Assert that fcinfo->flinfo isn't NULL. Discussion: https://postgr.es/m/25226.1487900067@sss.pgh.pa.us --- src/backend/utils/adt/enum.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/backend/utils/adt/enum.c b/src/backend/utils/adt/enum.c index 8110ee222c1..b1d2a6f0c3b 100644 --- a/src/backend/utils/adt/enum.c +++ b/src/backend/utils/adt/enum.c @@ -263,6 +263,15 @@ enum_cmp_internal(Oid arg1, Oid arg2, FunctionCallInfo fcinfo) { TypeCacheEntry *tcache; + /* + * We don't need the typcache except in the hopefully-uncommon case that + * one or both Oids are odd. This means that cursory testing of code that + * fails to pass flinfo to an enum comparison function might not disclose + * the oversight. To make such errors more obvious, Assert that we have a + * place to cache even when we take a fast-path exit. + */ + Assert(fcinfo->flinfo != NULL); + /* Equal OIDs are equal no matter what */ if (arg1 == arg2) return 0; @@ -381,12 +390,7 @@ enum_cmp(PG_FUNCTION_ARGS) Oid a = PG_GETARG_OID(0); Oid b = PG_GETARG_OID(1); - if (a == b) - PG_RETURN_INT32(0); - else if (enum_cmp_internal(a, b, fcinfo) > 0) - PG_RETURN_INT32(1); - else - PG_RETURN_INT32(-1); + PG_RETURN_INT32(enum_cmp_internal(a, b, fcinfo)); } /* Enum programming support functions */