diff options
author | Peter Eisentraut | 2019-11-04 07:30:00 +0000 |
---|---|---|
committer | Peter Eisentraut | 2019-11-04 08:08:15 +0000 |
commit | 8557a6f10ca6f01f4b2f2f25e197292f3f46bb5c (patch) | |
tree | 6c6ee9092623cc14fac391eafdfbb4edd5b6cf48 | |
parent | db27b60f07a039e236738fe90bd4215cafd35cf2 (diff) |
Catch invalid typlens in a couple of places
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 <[email protected]>
-rw-r--r-- | src/backend/utils/adt/datum.c | 22 | ||||
-rw-r--r-- | src/backend/utils/adt/rowtypes.c | 24 |
2 files changed, 25 insertions, 21 deletions
diff --git a/src/backend/utils/adt/datum.c b/src/backend/utils/adt/datum.c index 1568658bc9..73703efe05 100644 --- a/src/backend/utils/adt/datum.c +++ b/src/backend/utils/adt/datum.c @@ -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; } diff --git a/src/backend/utils/adt/rowtypes.c b/src/backend/utils/adt/rowtypes.c index ea3e40a369..18496b94c6 100644 --- a/src/backend/utils/adt/rowtypes.c +++ b/src/backend/utils/adt/rowtypes.c @@ -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) { |