Catch invalid typlens in a couple of places
authorPeter Eisentraut <peter@eisentraut.org>
Mon, 4 Nov 2019 07:30:00 +0000 (08:30 +0100)
committerPeter Eisentraut <peter@eisentraut.org>
Mon, 4 Nov 2019 08:08:15 +0000 (09:08 +0100)
Rearrange the logic in record_image_cmp() and datum_image_eq() to
error out on unexpected typlens (either not supported there or
completely invalid due to corruption).  Barring corruption, this is
not possible today but it seems more future-proof and robust to fix
this.

Reported-by: Peter Geoghegan <pg@bowt.ie>
src/backend/utils/adt/datum.c
src/backend/utils/adt/rowtypes.c

index 1568658bc9cfc4f936dd03d7c9f57558bfe8fb8f..73703efe05a3aa42ff3f876d78fe719f18a58161 100644 (file)
@@ -265,7 +265,17 @@ datum_image_eq(Datum value1, Datum value2, bool typByVal, int typLen)
 {
    bool        result = true;
 
-   if (typLen == -1)
+   if (typByVal)
+   {
+       result = (value1 == value2);
+   }
+   else if (typLen > 0)
+   {
+       result = (memcmp(DatumGetPointer(value1),
+                        DatumGetPointer(value2),
+                        typLen) == 0);
+   }
+   else if (typLen == -1)
    {
        Size        len1,
                    len2;
@@ -294,16 +304,8 @@ datum_image_eq(Datum value1, Datum value2, bool typByVal, int typLen)
                pfree(arg2val);
        }
    }
-   else if (typByVal)
-   {
-       result = (value1 == value2);
-   }
    else
-   {
-       result = (memcmp(DatumGetPointer(value1),
-                        DatumGetPointer(value2),
-                        typLen) == 0);
-   }
+       elog(ERROR, "unexpected typLen: %d", typLen);
 
    return result;
 }
index ea3e40a369429d7b0f2f04fb0a5c062898b2bd65..18496b94c61670adce32d69534102368bc0efa40 100644 (file)
@@ -1443,7 +1443,18 @@ record_image_cmp(FunctionCallInfo fcinfo)
            }
 
            /* Compare the pair of elements */
-           if (att1->attlen == -1)
+           if (att1->attbyval)
+           {
+               if (values1[i1] != values2[i2])
+                   cmpresult = (values1[i1] < values2[i2]) ? -1 : 1;
+           }
+           else if (att1->attlen > 0)
+           {
+               cmpresult = memcmp(DatumGetPointer(values1[i1]),
+                                  DatumGetPointer(values2[i2]),
+                                  att1->attlen);
+           }
+           else if (att1->attlen == -1)
            {
                Size        len1,
                            len2;
@@ -1466,17 +1477,8 @@ record_image_cmp(FunctionCallInfo fcinfo)
                if ((Pointer) arg2val != (Pointer) values2[i2])
                    pfree(arg2val);
            }
-           else if (att1->attbyval)
-           {
-               if (values1[i1] != values2[i2])
-                   cmpresult = (values1[i1] < values2[i2]) ? -1 : 1;
-           }
            else
-           {
-               cmpresult = memcmp(DatumGetPointer(values1[i1]),
-                                  DatumGetPointer(values2[i2]),
-                                  att1->attlen);
-           }
+               elog(ERROR, "unexpected attlen: %d", att1->attlen);
 
            if (cmpresult < 0)
            {