Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit889786e

Browse files
committed
Adjust bytea get_bit/set_bit to cope with bytea strings > 256MB.
Since the existing bit number argument can't exceed INT32_MAX, it'snot possible for these functions to manipulate bits beyond the first256MB of a bytea value. However, it'd be good if they could do atleast 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 coverageof these functions.Apply patch to back branches only; HEAD has a better solutionas of commit26a944c.Extracted from a much larger patch by Movead LiDiscussion:https://postgr.es/m/20200312115135445367128@highgo.ca
1 parentcef2b8d commit889786e

File tree

3 files changed

+110
-4
lines changed

3 files changed

+110
-4
lines changed

‎src/backend/utils/adt/varlena.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3055,11 +3055,12 @@ byteaGetBit(PG_FUNCTION_ARGS)
30553055

30563056
len=VARSIZE_ANY_EXHDR(v);
30573057

3058-
if (n<0||n >=len*8)
3058+
/* Do comparison arithmetic in int64 in case len exceeds INT_MAX/8 */
3059+
if (n<0||n >= (int64)len*8)
30593060
ereport(ERROR,
30603061
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
30613062
errmsg("index %d out of valid range, 0..%d",
3062-
n,len*8-1)));
3063+
n,(int)Min((int64)len*8-1,INT_MAX))));
30633064

30643065
byteNo=n /8;
30653066
bitNo=n %8;
@@ -3126,11 +3127,12 @@ byteaSetBit(PG_FUNCTION_ARGS)
31263127

31273128
len=VARSIZE(res)-VARHDRSZ;
31283129

3129-
if (n<0||n >=len*8)
3130+
/* Do comparison arithmetic in int64 in case len exceeds INT_MAX/8 */
3131+
if (n<0||n >= (int64)len*8)
31303132
ereport(ERROR,
31313133
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
31323134
errmsg("index %d out of valid range, 0..%d",
3133-
n,len*8-1)));
3135+
n,(int)Min((int64)len*8-1,INT_MAX))));
31343136

31353137
byteNo=n /8;
31363138
bitNo=n %8;

‎src/test/regress/expected/strings.out

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1432,6 +1432,83 @@ select md5('12345678901234567890123456789012345678901234567890123456789012345678
14321432
t
14331433
(1 row)
14341434

1435+
--
1436+
-- encode/decode
1437+
--
1438+
SET bytea_output TO hex;
1439+
SELECT encode('\x1234567890abcdef00', 'hex');
1440+
encode
1441+
--------------------
1442+
1234567890abcdef00
1443+
(1 row)
1444+
1445+
SELECT decode('1234567890abcdef00', 'hex');
1446+
decode
1447+
----------------------
1448+
\x1234567890abcdef00
1449+
(1 row)
1450+
1451+
SELECT encode(('\x' || repeat('1234567890abcdef0001', 7))::bytea, 'base64');
1452+
encode
1453+
------------------------------------------------------------------------------
1454+
EjRWeJCrze8AARI0VniQq83vAAESNFZ4kKvN7wABEjRWeJCrze8AARI0VniQq83vAAESNFZ4kKvN+
1455+
7wABEjRWeJCrze8AAQ==
1456+
(1 row)
1457+
1458+
SELECT decode(encode(('\x' || repeat('1234567890abcdef0001', 7))::bytea,
1459+
'base64'), 'base64');
1460+
decode
1461+
------------------------------------------------------------------------------------------------------------------------------------------------
1462+
\x1234567890abcdef00011234567890abcdef00011234567890abcdef00011234567890abcdef00011234567890abcdef00011234567890abcdef00011234567890abcdef0001
1463+
(1 row)
1464+
1465+
SELECT encode('\x1234567890abcdef00', 'escape');
1466+
encode
1467+
-----------------------------
1468+
\x124Vx\220\253\315\357\000
1469+
(1 row)
1470+
1471+
SELECT decode(encode('\x1234567890abcdef00', 'escape'), 'escape');
1472+
decode
1473+
----------------------
1474+
\x1234567890abcdef00
1475+
(1 row)
1476+
1477+
--
1478+
-- get_bit/set_bit etc
1479+
--
1480+
SELECT get_bit('\x1234567890abcdef00'::bytea, 43);
1481+
get_bit
1482+
---------
1483+
1
1484+
(1 row)
1485+
1486+
SELECT get_bit('\x1234567890abcdef00'::bytea, 99); -- error
1487+
ERROR: index 99 out of valid range, 0..71
1488+
SELECT set_bit('\x1234567890abcdef00'::bytea, 43, 0);
1489+
set_bit
1490+
----------------------
1491+
\x1234567890a3cdef00
1492+
(1 row)
1493+
1494+
SELECT set_bit('\x1234567890abcdef00'::bytea, 99, 0); -- error
1495+
ERROR: index 99 out of valid range, 0..71
1496+
SELECT get_byte('\x1234567890abcdef00'::bytea, 3);
1497+
get_byte
1498+
----------
1499+
120
1500+
(1 row)
1501+
1502+
SELECT get_byte('\x1234567890abcdef00'::bytea, 99); -- error
1503+
ERROR: index 99 out of valid range, 0..8
1504+
SELECT set_byte('\x1234567890abcdef00'::bytea, 7, 11);
1505+
set_byte
1506+
----------------------
1507+
\x1234567890abcd0b00
1508+
(1 row)
1509+
1510+
SELECT set_byte('\x1234567890abcdef00'::bytea, 99, 11); -- error
1511+
ERROR: index 99 out of valid range, 0..8
14351512
--
14361513
-- test behavior of escape_string_warning and standard_conforming_strings options
14371514
--
@@ -1518,6 +1595,7 @@ select 'a\\bcd' as f1, 'a\\b\'cd' as f2, 'a\\b\'''cd' as f3, 'abcd\\' as f4, '
15181595
--
15191596
-- Additional string functions
15201597
--
1598+
SET bytea_output TO escape;
15211599
SELECT initcap('hi THOMAS');
15221600
initcap
15231601
-----------

‎src/test/regress/sql/strings.sql

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,31 @@ select md5('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'::byt
492492

493493
select md5('12345678901234567890123456789012345678901234567890123456789012345678901234567890'::bytea)='57edf4a22be3c955ac49da2e2107b67a'AS"TRUE";
494494

495+
--
496+
-- encode/decode
497+
--
498+
SET bytea_output TO hex;
499+
500+
SELECT encode('\x1234567890abcdef00','hex');
501+
SELECT decode('1234567890abcdef00','hex');
502+
SELECT encode(('\x'|| repeat('1234567890abcdef0001',7))::bytea,'base64');
503+
SELECT decode(encode(('\x'|| repeat('1234567890abcdef0001',7))::bytea,
504+
'base64'),'base64');
505+
SELECT encode('\x1234567890abcdef00','escape');
506+
SELECT decode(encode('\x1234567890abcdef00','escape'),'escape');
507+
508+
--
509+
-- get_bit/set_bit etc
510+
--
511+
SELECT get_bit('\x1234567890abcdef00'::bytea,43);
512+
SELECT get_bit('\x1234567890abcdef00'::bytea,99);-- error
513+
SELECT set_bit('\x1234567890abcdef00'::bytea,43,0);
514+
SELECT set_bit('\x1234567890abcdef00'::bytea,99,0);-- error
515+
SELECT get_byte('\x1234567890abcdef00'::bytea,3);
516+
SELECT get_byte('\x1234567890abcdef00'::bytea,99);-- error
517+
SELECT set_byte('\x1234567890abcdef00'::bytea,7,11);
518+
SELECT set_byte('\x1234567890abcdef00'::bytea,99,11);-- error
519+
495520
--
496521
-- test behavior of escape_string_warning and standard_conforming_strings options
497522
--
@@ -526,6 +551,7 @@ select 'a\\bcd' as f1, 'a\\b\'cd' as f2, 'a\\b\'''cd' as f3, 'abcd\\' as f4, '
526551
--
527552
-- Additional string functions
528553
--
554+
SET bytea_output TO escape;
529555

530556
SELECT initcap('hi THOMAS');
531557

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp