commit 819f40496d1f9dda7428707ef1a6a908875862f6 Author: okbob@github.com Date: Mon Jan 4 20:19:07 2021 +0100 initial diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index ec1fb4d1b9..cf4ba68f5b 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -880,26 +880,31 @@ text_substring(Datum str, int32 start, int32 length, bool length_not_specified) else { /* end position */ - int E = S + length; + int E; - /* - * A negative value for L is the only way for the end position to - * be before the start. SQL99 says to throw an error. - */ - if (E < S) - ereport(ERROR, - (errcode(ERRCODE_SUBSTRING_ERROR), - errmsg("negative substring length not allowed"))); + if (!pg_add_s32_overflow(S, length, &E)) + { + /* + * A negative value for L is the only way for the end position to + * be before the start. SQL99 says to throw an error. + */ + if (E < S) + ereport(ERROR, + (errcode(ERRCODE_SUBSTRING_ERROR), + errmsg("negative substring length not allowed"))); - /* - * A zero or negative value for the end position can happen if the - * start was negative or one. SQL99 says to return a zero-length - * string. - */ - if (E < 1) - return cstring_to_text(""); + /* + * A zero or negative value for the end position can happen if the + * start was negative or one. SQL99 says to return a zero-length + * string. + */ + if (E < 1) + return cstring_to_text(""); - L1 = E - S1; + L1 = E - S1; + } + else + L1 = -1; } /* @@ -944,36 +949,41 @@ text_substring(Datum str, int32 start, int32 length, bool length_not_specified) slice_size = L1 = -1; else { - int E = S + length; + int E; - /* - * A negative value for L is the only way for the end position to - * be before the start. SQL99 says to throw an error. - */ - if (E < S) - ereport(ERROR, - (errcode(ERRCODE_SUBSTRING_ERROR), - errmsg("negative substring length not allowed"))); + if (!pg_add_s32_overflow(S, length, &E)) + { + /* + * A negative value for L is the only way for the end position to + * be before the start. SQL99 says to throw an error. + */ + if (E < S) + ereport(ERROR, + (errcode(ERRCODE_SUBSTRING_ERROR), + errmsg("negative substring length not allowed"))); - /* - * A zero or negative value for the end position can happen if the - * start was negative or one. SQL99 says to return a zero-length - * string. - */ - if (E < 1) - return cstring_to_text(""); + /* + * A zero or negative value for the end position can happen if the + * start was negative or one. SQL99 says to return a zero-length + * string. + */ + if (E < 1) + return cstring_to_text(""); - /* - * if E is past the end of the string, the tuple toaster will - * truncate the length for us - */ - L1 = E - S1; + /* + * if E is past the end of the string, the tuple toaster will + * truncate the length for us + */ + L1 = E - S1; - /* - * Total slice size in bytes can't be any longer than the start - * position plus substring length times the encoding max length. - */ - slice_size = (S1 + L1) * eml; + /* + * Total slice size in bytes can't be any longer than the start + * position plus substring length times the encoding max length. + */ + slice_size = (S1 + L1) * eml; + } + else + slice_size = L1 = -1; } /*