diff options
author | Peter Eisentraut <peter@eisentraut.org> | 2019-11-04 08:30:00 +0100 |
---|---|---|
committer | Peter Eisentraut <peter@eisentraut.org> | 2019-11-04 09:20:33 +0100 |
commit | 0782050bc22d4d428c3cffe0d0a7ecee29d2f5fe (patch) | |
tree | d93bcc00114a7e49b3c6a81586797e1a11428091 /src | |
parent | 88d03d73c22440763dbe85378fdda8389db78b0d (diff) |
Catch invalid typlens in a couple of places
Rearrange the logic in record_image_cmp() and record_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>
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/utils/adt/rowtypes.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/src/backend/utils/adt/rowtypes.c b/src/backend/utils/adt/rowtypes.c index 5f729342f8d..5f3dbc59d5c 100644 --- a/src/backend/utils/adt/rowtypes.c +++ b/src/backend/utils/adt/rowtypes.c @@ -1442,7 +1442,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; @@ -1465,17 +1476,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) { @@ -1671,7 +1673,17 @@ record_image_eq(PG_FUNCTION_ARGS) } /* Compare the pair of elements */ - if (att1->attlen == -1) + if (att1->attbyval) + { + result = (values1[i1] == values2[i2]); + } + else if (att1->attlen > 0) + { + result = (memcmp(DatumGetPointer(values1[i1]), + DatumGetPointer(values2[i2]), + att1->attlen) == 0); + } + else if (att1->attlen == -1) { Size len1, len2; @@ -1700,16 +1712,9 @@ record_image_eq(PG_FUNCTION_ARGS) pfree(arg2val); } } - else if (att1->attbyval) - { - result = (values1[i1] == values2[i2]); - } else - { - result = (memcmp(DatumGetPointer(values1[i1]), - DatumGetPointer(values2[i2]), - att1->attlen) == 0); - } + elog(ERROR, "unexpected attlen: %d", att1->attlen); + if (!result) break; } |