Catch invalid typlens in a couple of places
authorPeter Eisentraut
Mon, 4 Nov 2019 07:30:00 +0000 (08:30 +0100)
committerPeter Eisentraut
Mon, 4 Nov 2019 08:14:44 +0000 (09:14 +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
src/backend/utils/adt/datum.c
src/backend/utils/adt/rowtypes.c

index 81ea5a48e597bc64520488c5054b956585681fb1..76bd7ee1aa0582839ffbf28b4085c64621491dc2 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 aa7ec8735c4a104249f659b5b66b5521a9c5b4b0..4d6cfc68b862928eca15de43d266c3d29e78ea63 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)
            {