Fix integer-overflow corner cases in substring() functions.
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 4 Jan 2021 23:32:40 +0000 (18:32 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 4 Jan 2021 23:32:44 +0000 (18:32 -0500)
commit4bd3fad80e5c3bd107583dd9d32d4a47c045a3ec
treef44a9347a89023fa10972e8f367045147f0a6daa
parent87c23d36a3bc81e57b813f13c403f74a67ff33a9
Fix integer-overflow corner cases in substring() functions.

If the substring start index and length overflow when added together,
substring() misbehaved, either throwing a bogus "negative substring
length" error on a case that should succeed, or failing to complain that
a negative length is negative (and instead returning the whole string,
in most cases).  Unsurprisingly, the text, bytea, and bit variants of
the function all had this issue.  Rearrange the logic to ensure that
negative lengths are always rejected, and add an overflow check to
handle the other case.

Also install similar guards into detoast_attr_slice() (nee
heap_tuple_untoast_attr_slice()), since it's far from clear that
no other code paths leading to that function could pass it values
that would overflow.

Patch by myself and Pavel Stehule, per bug #16804 from Rafi Shamim.

Back-patch to v11.  While these bugs are old, the common/int.h
infrastructure for overflow-detecting arithmetic didn't exist before
commit 4d6ad3125, and it doesn't seem like these misbehaviors are bad
enough to justify developing a standalone fix for the older branches.

Discussion: https://postgr.es/m/16804-f4eeeb6c11ba71d4@postgresql.org
src/backend/access/common/detoast.c
src/backend/utils/adt/varbit.c
src/backend/utils/adt/varlena.c
src/test/regress/expected/bit.out
src/test/regress/expected/strings.out
src/test/regress/sql/bit.sql
src/test/regress/sql/strings.sql