Skip to content

Commit 6c40838

Browse files
authored
Fix substring() crash when start-offset is NULL and length is supplied (#2401)
age_substring() reads the null map produced by extract_variadic_args() and rejects null offset/length with this guard: if ((nargs == 2 && nulls[1]) || (nargs == 3 && nulls[2])) { ereport(ERROR, ..., errmsg("substring() offset or length cannot be null")); } The condition only checks nulls[1] in the 2-argument form. When the caller passes `substring(str, null, len)` the function takes nargs = 3, nulls[1] = true, but the guard above does not fire. Execution reaches the numeric-parameter loop below, which reads args[1] through DatumGetInt32 / DATUM_GET_AGTYPE_P without ever re-checking nulls[i]. The Datum in that slot is undefined, the dereference segfaults, and the PostgreSQL backend terminates - not a query error but a connection-level crash (#2386). Widen the guard to nargs >= 2 && nulls[1] so it catches start-is-null in both the 2-arg and 3-arg forms. nulls[2] is still only checked when nargs == 3. No behaviour change on any non-null path; the connection-crash case is now reported as a normal query error, matching the intent the existing error message already implies.
1 parent bdc8b6d commit 6c40838

1 file changed

Lines changed: 9 additions & 2 deletions

File tree

src/backend/utils/adt/agtype.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8639,8 +8639,15 @@ Datum age_substring(PG_FUNCTION_ARGS)
86398639
PG_RETURN_NULL();
86408640
}
86418641

8642-
/* neither offset or length can be null if there is a valid string */
8643-
if ((nargs == 2 && nulls[1]) ||
8642+
/*
8643+
* neither offset nor length may be null when there is a valid string.
8644+
* Both arg positions must be checked whenever they are supplied; the
8645+
* previous condition missed the `start is null, length is provided`
8646+
* case (nargs == 3 && nulls[1]), which fell through to the numeric
8647+
* parser below and dereferenced an undefined Datum - crashing the
8648+
* backend (#2386).
8649+
*/
8650+
if ((nargs >= 2 && nulls[1]) ||
86448651
(nargs == 3 && nulls[2]))
86458652
{
86468653
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),

0 commit comments

Comments
 (0)