From daeb6018f5719f351bde91623f106c4568c63ff4 Mon Sep 17 00:00:00 2001 From: Marko Grujic Date: Sat, 17 Oct 2026 21:50:29 +0200 Subject: [PATCH v2] intarray: Parse query_int integers as decimals Previously the base was 0, so when zero-padded integers were supplied the parser interpreted the value as octal, and produced a wrong value. Instead, set the base as decimal, and add regression test too. Also reject a lone minus sign consistently, since strtol() sets errno for it only on some platforms. --- contrib/intarray/_int_bool.c | 5 +++-- contrib/intarray/expected/_int.out | 22 ++++++++++++++++++++++ contrib/intarray/sql/_int.sql | 8 ++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/contrib/intarray/_int_bool.c b/contrib/intarray/_int_bool.c index 4382f882939..abac3ced433 100644 --- a/contrib/intarray/_int_bool.c +++ b/contrib/intarray/_int_bool.c @@ -90,12 +90,13 @@ gettoken(WORKSTATE *state, int32 *val) else { long lval; + char *endptr; nnn[innn] = '\0'; errno = 0; - lval = strtol(nnn, NULL, 0); + lval = strtol(nnn, &endptr, 10); *val = (int32) lval; - if (errno != 0 || (long) *val != lval) + if (errno != 0 || *endptr != '\0' || (long) *val != lval) return ERR; state->state = WAITOPERATOR; return (state->count && *(state->buf) == '\0') diff --git a/contrib/intarray/expected/_int.out b/contrib/intarray/expected/_int.out index fb4086a95ca..e1919bfb87b 100644 --- a/contrib/intarray/expected/_int.out +++ b/contrib/intarray/expected/_int.out @@ -398,6 +398,28 @@ SELECT '1&(2&(4&(5|!6)))'::query_int; 1 & 2 & 4 & ( 5 | !6 ) (1 row) +-- Leading zeros do not make an octal number. +SELECT '010'::query_int; + query_int +----------- + 10 +(1 row) + +SELECT '{10}'::int[] @@ '010'::query_int; + ?column? +---------- + t +(1 row) + +-- A lone minus sign is not a number. +SELECT '-'::query_int; +ERROR: syntax error +LINE 1: SELECT '-'::query_int; + ^ +SELECT '1&-'::query_int; +ERROR: syntax error +LINE 1: SELECT '1&-'::query_int; + ^ -- Test for overflow of the int16 "left" field in findoprnd(). -- This query uses a balanced binary tree to avoid using too much stack. DO $$ diff --git a/contrib/intarray/sql/_int.sql b/contrib/intarray/sql/_int.sql index 0d30914725e..284842e42ff 100644 --- a/contrib/intarray/sql/_int.sql +++ b/contrib/intarray/sql/_int.sql @@ -75,6 +75,14 @@ SELECT '1&2&4&5&6'::query_int; SELECT '1&(2&(4&(5|6)))'::query_int; SELECT '1&(2&(4&(5|!6)))'::query_int; +-- Leading zeros do not make an octal number. +SELECT '010'::query_int; +SELECT '{10}'::int[] @@ '010'::query_int; + +-- A lone minus sign is not a number. +SELECT '-'::query_int; +SELECT '1&-'::query_int; + -- Test for overflow of the int16 "left" field in findoprnd(). -- This query uses a balanced binary tree to avoid using too much stack. DO $$ -- 2.54.0 (Apple Git-157)