aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2020-04-07 16:30:55 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2020-04-07 16:30:55 -0400
commit6e6b74a206c3b4ad9f22f4910b2e0ed9d922b312 (patch)
tree8b4e74e1cce6d5225bc3687e01273615d09b5f2d /src/backend/utils/adt
parent3e62dd3a937b7da84e8ae126c7bf8319c1cd5c08 (diff)
downloadpostgresql-6e6b74a206c3b4ad9f22f4910b2e0ed9d922b312.tar.gz
postgresql-6e6b74a206c3b4ad9f22f4910b2e0ed9d922b312.zip
Adjust bytea get_bit/set_bit to cope with bytea strings > 256MB.
Since the existing bit number argument can't exceed INT32_MAX, it's not possible for these functions to manipulate bits beyond the first 256MB of a bytea value. However, it'd be good if they could do at least that much, and not fall over entirely for longer bytea values. Adjust the comparisons to be done in int64 arithmetic so that works. Also tweak the error reports to show sane values in case of overflow. Also add some test cases to improve the miserable code coverage of these functions. Apply patch to back branches only; HEAD has a better solution as of commit 26a944cf2. Extracted from a much larger patch by Movead Li Discussion: https://postgr.es/m/20200312115135445367128@highgo.ca
Diffstat (limited to 'src/backend/utils/adt')
-rw-r--r--src/backend/utils/adt/varlena.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index 1587b4ed02a..989d6986399 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -3443,11 +3443,12 @@ byteaGetBit(PG_FUNCTION_ARGS)
len = VARSIZE_ANY_EXHDR(v);
- if (n < 0 || n >= len * 8)
+ /* Do comparison arithmetic in int64 in case len exceeds INT_MAX/8 */
+ if (n < 0 || n >= (int64) len * 8)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("index %d out of valid range, 0..%d",
- n, len * 8 - 1)));
+ n, (int) Min((int64) len * 8 - 1, INT_MAX))));
byteNo = n / 8;
bitNo = n % 8;
@@ -3514,11 +3515,12 @@ byteaSetBit(PG_FUNCTION_ARGS)
len = VARSIZE(res) - VARHDRSZ;
- if (n < 0 || n >= len * 8)
+ /* Do comparison arithmetic in int64 in case len exceeds INT_MAX/8 */
+ if (n < 0 || n >= (int64) len * 8)
ereport(ERROR,
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
errmsg("index %d out of valid range, 0..%d",
- n, len * 8 - 1)));
+ n, (int) Min((int64) len * 8 - 1, INT_MAX))));
byteNo = n / 8;
bitNo = n % 8;