This is an automated email from the ASF dual-hosted git repository.
MuhammadTahaNaveed pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/age.git
The following commit(s) were added to refs/heads/master by this push:
new 6c408386 Fix substring() crash when start-offset is NULL and length is
supplied (#2401)
6c408386 is described below
commit 6c4083862fbf59309a7735aafa7ab1def1bda13d
Author: Sai Asish Y <[email protected]>
AuthorDate: Mon Apr 20 02:19:01 2026 -0700
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.
---
src/backend/utils/adt/agtype.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/src/backend/utils/adt/agtype.c b/src/backend/utils/adt/agtype.c
index 38621955..b2215d01 100644
--- a/src/backend/utils/adt/agtype.c
+++ b/src/backend/utils/adt/agtype.c
@@ -8639,8 +8639,15 @@ Datum age_substring(PG_FUNCTION_ARGS)
PG_RETURN_NULL();
}
- /* neither offset or length can be null if there is a valid string */
- if ((nargs == 2 && nulls[1]) ||
+ /*
+ * neither offset nor length may be null when there is a valid string.
+ * Both arg positions must be checked whenever they are supplied; the
+ * previous condition missed the `start is null, length is provided`
+ * case (nargs == 3 && nulls[1]), which fell through to the numeric
+ * parser below and dereferenced an undefined Datum - crashing the
+ * backend (#2386).
+ */
+ if ((nargs >= 2 && nulls[1]) ||
(nargs == 3 && nulls[2]))
{
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),