From daeb6018f5719f351bde91623f106c4568c63ff4 Mon Sep 17 00:00:00 2001
From: Marko Grujic <markoog@gmail.com>
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)

