diff --git a/src/backend/utils/adt/encode.c b/src/backend/utils/adt/encode.c index b8d9ec7e00..e56ebd707d 100644 --- a/src/backend/utils/adt/encode.c +++ b/src/backend/utils/adt/encode.c @@ -20,7 +20,7 @@ struct pg_encoding { - unsigned (*encode_len) (const char *data, unsigned dlen); + int64 (*encode_len) (const char *data, unsigned dlen); unsigned (*decode_len) (const char *data, unsigned dlen); unsigned (*encode) (const char *data, unsigned dlen, char *res); unsigned (*decode) (const char *data, unsigned dlen, char *res); @@ -40,8 +40,8 @@ binary_encode(PG_FUNCTION_ARGS) text *result; char *namebuf; int datalen, - resultlen, res; + int64 resultlen; const struct pg_encoding *enc; datalen = VARSIZE_ANY_EXHDR(data); @@ -60,7 +60,7 @@ binary_encode(PG_FUNCTION_ARGS) res = enc->encode(VARDATA_ANY(data), datalen, VARDATA(result)); /* Make this FATAL 'cause we've trodden on memory ... */ - if (res > resultlen) + if ((int64)res > resultlen) elog(FATAL, "overflow - encode estimate too small"); SET_VARSIZE(result, VARHDRSZ + res); @@ -76,8 +76,8 @@ binary_decode(PG_FUNCTION_ARGS) bytea *result; char *namebuf; int datalen, - resultlen, res; + unsigned resultlen; const struct pg_encoding *enc; datalen = VARSIZE_ANY_EXHDR(data); @@ -184,10 +184,10 @@ hex_decode(const char *src, unsigned len, char *dst) return p - dst; } -static unsigned +static int64 hex_enc_len(const char *src, unsigned srclen) { - return srclen << 1; + return (int64)(srclen << 1); } static unsigned @@ -331,11 +331,11 @@ pg_base64_decode(const char *src, unsigned len, char *dst) } -static unsigned +static int64 pg_base64_enc_len(const char *src, unsigned srclen) { /* 3 bytes will be converted to 4, linefeed after 76 chars */ - return (srclen + 2) * 4 / 3 + srclen / (76 * 3 / 4); + return (int64)((srclen + 2) * 4 / 3 + srclen / (76 * 3 / 4)); } static unsigned @@ -448,11 +448,11 @@ esc_decode(const char *src, unsigned srclen, char *dst) return len; } -static unsigned +static int64 esc_enc_len(const char *src, unsigned srclen) { const char *end = src + srclen; - int len = 0; + int64 len = 0; while (src < end) { diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index 907b5ab7b0..b8b06d5e32 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -388,7 +388,7 @@ byteaout(PG_FUNCTION_ARGS) { /* Print traditional escaped format */ char *vp; - int len; + int64 len; int i; len = 1; /* empty string has 1 char */ @@ -3463,11 +3463,11 @@ byteaGetBit(PG_FUNCTION_ARGS) len = VARSIZE_ANY_EXHDR(v); - if (n < 0 || n >= len * 8) + if (n < 0 || (int64)n >= (int64)len * 8) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), - errmsg("index %d out of valid range, 0..%d", - n, len * 8 - 1))); + errmsg("index %d out of valid range, 0.."INT64_FORMAT, + n, (int64)len * 8 - 1))); byteNo = n / 8; bitNo = n % 8; @@ -3534,11 +3534,11 @@ byteaSetBit(PG_FUNCTION_ARGS) len = VARSIZE(res) - VARHDRSZ; - if (n < 0 || n >= len * 8) + if (n < 0 || (int64)n >= (int64)len * 8) ereport(ERROR, (errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), - errmsg("index %d out of valid range, 0..%d", - n, len * 8 - 1))); + errmsg("index %d out of valid range, 0.."INT64_FORMAT, + n, (int64)len * 8 - 1))); byteNo = n / 8; bitNo = n % 8; diff --git a/src/test/regress/expected/bit.out b/src/test/regress/expected/bit.out index a1fab7ebcb..f7fda19b97 100644 --- a/src/test/regress/expected/bit.out +++ b/src/test/regress/expected/bit.out @@ -656,6 +656,22 @@ SELECT set_bit(B'0101011000100100', 15, 1); SELECT set_bit(B'0101011000100100', 16, 1); -- fail ERROR: bit index 16 out of valid range (0..15) +SELECT get_bit( + set_bit((repeat('Postgres', 512 * 1024 * 1024 / 8))::bytea, 0, 0) + ,0); + get_bit +--------- + 0 +(1 row) + +SELECT get_bit( + set_bit((repeat('Postgres', 512 * 1024 * 1024 / 8))::bytea, 0, 1) + ,0); + get_bit +--------- + 1 +(1 row) + -- Overlay SELECT overlay(B'0101011100' placing '001' from 2 for 3); overlay diff --git a/src/test/regress/sql/bit.sql b/src/test/regress/sql/bit.sql index 7681d4ab4d..89323d98e8 100644 --- a/src/test/regress/sql/bit.sql +++ b/src/test/regress/sql/bit.sql @@ -200,6 +200,13 @@ DROP TABLE VARBIT_SHIFT_TABLE; SELECT get_bit(B'0101011000100', 10); SELECT set_bit(B'0101011000100100', 15, 1); SELECT set_bit(B'0101011000100100', 16, 1); -- fail +SELECT get_bit( + set_bit((repeat('Postgres', 512 * 1024 * 1024 / 8))::bytea, 0, 0) + ,0); +SELECT get_bit( + set_bit((repeat('Postgres', 512 * 1024 * 1024 / 8))::bytea, 0, 1) + ,0); + -- Overlay SELECT overlay(B'0101011100' placing '001' from 2 for 3);