agora inbox for pgsql-committers@postgresql.org
help / color / mirror / Atom feedpgsql: Handle PG_INT32_MIN negation overflow in right()
6+ messages / 1 participants
[nested] [flat]
* pgsql: Handle PG_INT32_MIN negation overflow in right()
@ 2026-09-01 08:19 Daniel Gustafsson <dgustafsson@postgresql.org>
0 siblings, 0 replies; 6+ messages in thread
From: Daniel Gustafsson @ 2026-09-01 08:19 UTC (permalink / raw)
To: pgsql-committers@lists.postgresql.org
Handle PG_INT32_MIN negation overflow in right()
A negative n means "return all but the first |n| characters", so
text_right() negates n before clipping. Negating PG_INT32_MIN
overflows; with -fwrapv the result is PG_INT32_MIN again, still
negative, and pg_mbcharcliplen() then returns an offset of zero,
so the whole string is returned where the correct answer is an
empty string:
SELECT right('abcdef', (-2147483648)::int4); -- 'abcdef', want ''
SELECT right('abcdef', -2147483647); -- '', correct
Clamp to PG_INT32_MAX instead. Any n whose absolute value is at
least the string's length skips all of it, and a text value cannot
be longer than PG_INT32_MAX, so this gives the same answer for every
other input. Erroring out, as text_format_string_conversion() does
for a width of INT_MIN, would not be correct here: unlike a format
width, an out-of-range skip count has a well-defined result.
Using pg_neg_s32_overflow() would be a slightly more optimal fix but
as it's only available in PostgreSQL 18 and later the decision was
taken to apply the same fix to all backbranches.
Backpatch to all supported versions.
Author: Ewan Young <kdbase.hack@gmail.com>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Reviewed-by: David Rowley <dgrowleyml@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/CAON2xHNnBz-AcPJgDmd5_39+8qR5AUKEZk4X3ZM-0zdsATn8kQ@mail.gmail.com
Backpatch-through: 14
Branch
------
master
Details
-------
https://git.postgresql.org/pg/commitdiff/a63df2664225d06d5bee5dd9195f6d10e7fa1502
Modified Files
--------------
src/backend/utils/adt/varlena.c | 12 +++++++++++-
src/test/regress/expected/text.out | 8 ++++++++
src/test/regress/sql/text.sql | 3 +++
3 files changed, 22 insertions(+), 1 deletion(-)
^ permalink raw reply [nested|flat] 6+ messages in thread
* pgsql: Handle PG_INT32_MIN negation overflow in right()
@ 2026-09-01 08:20 Daniel Gustafsson <dgustafsson@postgresql.org>
0 siblings, 0 replies; 6+ messages in thread
From: Daniel Gustafsson @ 2026-09-01 08:20 UTC (permalink / raw)
To: pgsql-committers@lists.postgresql.org
Handle PG_INT32_MIN negation overflow in right()
A negative n means "return all but the first |n| characters", so
text_right() negates n before clipping. Negating PG_INT32_MIN
overflows; with -fwrapv the result is PG_INT32_MIN again, still
negative, and pg_mbcharcliplen() then returns an offset of zero,
so the whole string is returned where the correct answer is an
empty string:
SELECT right('abcdef', (-2147483648)::int4); -- 'abcdef', want ''
SELECT right('abcdef', -2147483647); -- '', correct
Clamp to PG_INT32_MAX instead. Any n whose absolute value is at
least the string's length skips all of it, and a text value cannot
be longer than PG_INT32_MAX, so this gives the same answer for every
other input. Erroring out, as text_format_string_conversion() does
for a width of INT_MIN, would not be correct here: unlike a format
width, an out-of-range skip count has a well-defined result.
Using pg_neg_s32_overflow() would be a slightly more optimal fix but
as it's only available in PostgreSQL 18 and later the decision was
taken to apply the same fix to all backbranches.
Backpatch to all supported versions.
Author: Ewan Young <kdbase.hack@gmail.com>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Reviewed-by: David Rowley <dgrowleyml@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/CAON2xHNnBz-AcPJgDmd5_39+8qR5AUKEZk4X3ZM-0zdsATn8kQ@mail.gmail.com
Backpatch-through: 14
Branch
------
REL_19_STABLE
Details
-------
https://git.postgresql.org/pg/commitdiff/2291b6ffbe2351deaada0f9bf7967c4db21a86e9
Modified Files
--------------
src/backend/utils/adt/varlena.c | 12 +++++++++++-
src/test/regress/expected/text.out | 8 ++++++++
src/test/regress/sql/text.sql | 3 +++
3 files changed, 22 insertions(+), 1 deletion(-)
^ permalink raw reply [nested|flat] 6+ messages in thread
* pgsql: Handle PG_INT32_MIN negation overflow in right()
@ 2026-09-01 08:20 Daniel Gustafsson <dgustafsson@postgresql.org>
0 siblings, 0 replies; 6+ messages in thread
From: Daniel Gustafsson @ 2026-09-01 08:20 UTC (permalink / raw)
To: pgsql-committers@lists.postgresql.org
Handle PG_INT32_MIN negation overflow in right()
A negative n means "return all but the first |n| characters", so
text_right() negates n before clipping. Negating PG_INT32_MIN
overflows; with -fwrapv the result is PG_INT32_MIN again, still
negative, and pg_mbcharcliplen() then returns an offset of zero,
so the whole string is returned where the correct answer is an
empty string:
SELECT right('abcdef', (-2147483648)::int4); -- 'abcdef', want ''
SELECT right('abcdef', -2147483647); -- '', correct
Clamp to PG_INT32_MAX instead. Any n whose absolute value is at
least the string's length skips all of it, and a text value cannot
be longer than PG_INT32_MAX, so this gives the same answer for every
other input. Erroring out, as text_format_string_conversion() does
for a width of INT_MIN, would not be correct here: unlike a format
width, an out-of-range skip count has a well-defined result.
Using pg_neg_s32_overflow() would be a slightly more optimal fix but
as it's only available in PostgreSQL 18 and later the decision was
taken to apply the same fix to all backbranches.
Backpatch to all supported versions.
Author: Ewan Young <kdbase.hack@gmail.com>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Reviewed-by: David Rowley <dgrowleyml@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/CAON2xHNnBz-AcPJgDmd5_39+8qR5AUKEZk4X3ZM-0zdsATn8kQ@mail.gmail.com
Backpatch-through: 14
Branch
------
REL_18_STABLE
Details
-------
https://git.postgresql.org/pg/commitdiff/bfb08d0946e91cf73d1a3bca8c908d6dccb80735
Modified Files
--------------
src/backend/utils/adt/varlena.c | 12 +++++++++++-
src/test/regress/expected/text.out | 8 ++++++++
src/test/regress/sql/text.sql | 3 +++
3 files changed, 22 insertions(+), 1 deletion(-)
^ permalink raw reply [nested|flat] 6+ messages in thread
* pgsql: Handle PG_INT32_MIN negation overflow in right()
@ 2026-09-01 08:20 Daniel Gustafsson <dgustafsson@postgresql.org>
0 siblings, 0 replies; 6+ messages in thread
From: Daniel Gustafsson @ 2026-09-01 08:20 UTC (permalink / raw)
To: pgsql-committers@lists.postgresql.org
Handle PG_INT32_MIN negation overflow in right()
A negative n means "return all but the first |n| characters", so
text_right() negates n before clipping. Negating PG_INT32_MIN
overflows; with -fwrapv the result is PG_INT32_MIN again, still
negative, and pg_mbcharcliplen() then returns an offset of zero,
so the whole string is returned where the correct answer is an
empty string:
SELECT right('abcdef', (-2147483648)::int4); -- 'abcdef', want ''
SELECT right('abcdef', -2147483647); -- '', correct
Clamp to PG_INT32_MAX instead. Any n whose absolute value is at
least the string's length skips all of it, and a text value cannot
be longer than PG_INT32_MAX, so this gives the same answer for every
other input. Erroring out, as text_format_string_conversion() does
for a width of INT_MIN, would not be correct here: unlike a format
width, an out-of-range skip count has a well-defined result.
Using pg_neg_s32_overflow() would be a slightly more optimal fix but
as it's only available in PostgreSQL 18 and later the decision was
taken to apply the same fix to all backbranches.
Backpatch to all supported versions.
Author: Ewan Young <kdbase.hack@gmail.com>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Reviewed-by: David Rowley <dgrowleyml@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/CAON2xHNnBz-AcPJgDmd5_39+8qR5AUKEZk4X3ZM-0zdsATn8kQ@mail.gmail.com
Backpatch-through: 14
Branch
------
REL_17_STABLE
Details
-------
https://git.postgresql.org/pg/commitdiff/3103bdafde6b0dfa8edbcefb48ac51097c6a9c1e
Modified Files
--------------
src/backend/utils/adt/varlena.c | 12 +++++++++++-
src/test/regress/expected/text.out | 8 ++++++++
src/test/regress/sql/text.sql | 3 +++
3 files changed, 22 insertions(+), 1 deletion(-)
^ permalink raw reply [nested|flat] 6+ messages in thread
* pgsql: Handle PG_INT32_MIN negation overflow in right()
@ 2026-09-01 08:21 Daniel Gustafsson <dgustafsson@postgresql.org>
0 siblings, 0 replies; 6+ messages in thread
From: Daniel Gustafsson @ 2026-09-01 08:21 UTC (permalink / raw)
To: pgsql-committers@lists.postgresql.org
Handle PG_INT32_MIN negation overflow in right()
A negative n means "return all but the first |n| characters", so
text_right() negates n before clipping. Negating PG_INT32_MIN
overflows; with -fwrapv the result is PG_INT32_MIN again, still
negative, and pg_mbcharcliplen() then returns an offset of zero,
so the whole string is returned where the correct answer is an
empty string:
SELECT right('abcdef', (-2147483648)::int4); -- 'abcdef', want ''
SELECT right('abcdef', -2147483647); -- '', correct
Clamp to PG_INT32_MAX instead. Any n whose absolute value is at
least the string's length skips all of it, and a text value cannot
be longer than PG_INT32_MAX, so this gives the same answer for every
other input. Erroring out, as text_format_string_conversion() does
for a width of INT_MIN, would not be correct here: unlike a format
width, an out-of-range skip count has a well-defined result.
Using pg_neg_s32_overflow() would be a slightly more optimal fix but
as it's only available in PostgreSQL 18 and later the decision was
taken to apply the same fix to all backbranches.
Backpatch to all supported versions.
Author: Ewan Young <kdbase.hack@gmail.com>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Reviewed-by: David Rowley <dgrowleyml@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/CAON2xHNnBz-AcPJgDmd5_39+8qR5AUKEZk4X3ZM-0zdsATn8kQ@mail.gmail.com
Backpatch-through: 14
Branch
------
REL_16_STABLE
Details
-------
https://git.postgresql.org/pg/commitdiff/48af47dcdd591d8deb0bd4d14652780d165ca879
Modified Files
--------------
src/backend/utils/adt/varlena.c | 12 +++++++++++-
src/test/regress/expected/text.out | 8 ++++++++
src/test/regress/sql/text.sql | 3 +++
3 files changed, 22 insertions(+), 1 deletion(-)
^ permalink raw reply [nested|flat] 6+ messages in thread
* pgsql: Handle PG_INT32_MIN negation overflow in right()
@ 2026-09-01 08:21 Daniel Gustafsson <dgustafsson@postgresql.org>
0 siblings, 0 replies; 6+ messages in thread
From: Daniel Gustafsson @ 2026-09-01 08:21 UTC (permalink / raw)
To: pgsql-committers@lists.postgresql.org
Handle PG_INT32_MIN negation overflow in right()
A negative n means "return all but the first |n| characters", so
text_right() negates n before clipping. Negating PG_INT32_MIN
overflows; with -fwrapv the result is PG_INT32_MIN again, still
negative, and pg_mbcharcliplen() then returns an offset of zero,
so the whole string is returned where the correct answer is an
empty string:
SELECT right('abcdef', (-2147483648)::int4); -- 'abcdef', want ''
SELECT right('abcdef', -2147483647); -- '', correct
Clamp to PG_INT32_MAX instead. Any n whose absolute value is at
least the string's length skips all of it, and a text value cannot
be longer than PG_INT32_MAX, so this gives the same answer for every
other input. Erroring out, as text_format_string_conversion() does
for a width of INT_MIN, would not be correct here: unlike a format
width, an out-of-range skip count has a well-defined result.
Using pg_neg_s32_overflow() would be a slightly more optimal fix but
as it's only available in PostgreSQL 18 and later the decision was
taken to apply the same fix to all backbranches.
Backpatch to all supported versions.
Author: Ewan Young <kdbase.hack@gmail.com>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Reviewed-by: Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>
Reviewed-by: David Rowley <dgrowleyml@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Discussion: https://postgr.es/m/CAON2xHNnBz-AcPJgDmd5_39+8qR5AUKEZk4X3ZM-0zdsATn8kQ@mail.gmail.com
Backpatch-through: 14
Branch
------
REL_14_STABLE
Details
-------
https://git.postgresql.org/pg/commitdiff/858fb27b69bc81b2ac2dab9e4db4df4056cc2fae
Modified Files
--------------
src/backend/utils/adt/varlena.c | 12 +++++++++++-
src/test/regress/expected/text.out | 8 ++++++++
src/test/regress/sql/text.sql | 3 +++
3 files changed, 22 insertions(+), 1 deletion(-)
^ permalink raw reply [nested|flat] 6+ messages in thread
end of thread, other threads:[~2026-09-01 08:21 UTC | newest]
Thread overview: 6+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2026-09-01 08:19 pgsql: Handle PG_INT32_MIN negation overflow in right() Daniel Gustafsson <dgustafsson@postgresql.org>
2026-09-01 08:20 pgsql: Handle PG_INT32_MIN negation overflow in right() Daniel Gustafsson <dgustafsson@postgresql.org>
2026-09-01 08:20 pgsql: Handle PG_INT32_MIN negation overflow in right() Daniel Gustafsson <dgustafsson@postgresql.org>
2026-09-01 08:20 pgsql: Handle PG_INT32_MIN negation overflow in right() Daniel Gustafsson <dgustafsson@postgresql.org>
2026-09-01 08:21 pgsql: Handle PG_INT32_MIN negation overflow in right() Daniel Gustafsson <dgustafsson@postgresql.org>
2026-09-01 08:21 pgsql: Handle PG_INT32_MIN negation overflow in right() Daniel Gustafsson <dgustafsson@postgresql.org>
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox