1
0
mirror of https://github.com/postgres/postgres.git synced 2026-10-23 13:29:09 +03:00

contrib/intarray: always parse query_int integers as decimal.

Previously we called strtol() with base 0, so that a leading zero
digit caused the number to be read as octal.  This is not documented
because it was not the original intent: before commit 7ccb6dc2d, this
code used atoi() which would have read the number as decimal always.
Use base 10 instead to restore the original behavior.

Also reject a bare minus sign consistently.  Per POSIX, strtol()
"may" set errno for that case but doesn't have to, and if it doesn't
then we'd not have noticed the bad syntax but read the value as 0.

Although this change restores old behavior, 7ccb6dc2d was a long
time ago, so it's at least possible that someone out there is
expecting the octal behavior.  So it doesn't seem like a great
idea to put this into stable branches.  But I (tgl) judge it
not too late for v19.

Author: Marko Grujic <marko.grujic@enterprisedb.com>
Reviewed-by: Manu <manuelreyesbravo@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAOvwyF3=brZoxwcwHRQqvLjuqSqxiTN7RXpKMNHXJ1WAS5GQ2Q@mail.gmail.com
Backpatch-through: 19
This commit is contained in:
Tom Lane
2026-10-20 15:13:34 -04:00
parent cdc6c25f97
commit ccfe1db5a8
3 changed files with 15 additions and 2 deletions

View File

@@ -90,12 +90,13 @@ gettoken(WORKSTATE *state, int32 *val)
else else
{ {
long lval; long lval;
char *endptr;
nnn[innn] = '\0'; nnn[innn] = '\0';
errno = 0; errno = 0;
lval = strtol(nnn, NULL, 0); lval = strtol(nnn, &endptr, 10);
*val = (int32) lval; *val = (int32) lval;
if (errno != 0 || (long) *val != lval) if (errno != 0 || *endptr != '\0' || (long) *val != lval)
return ERR; return ERR;
state->state = WAITOPERATOR; state->state = WAITOPERATOR;
return (state->count && *(state->buf) == '\0') return (state->count && *(state->buf) == '\0')

View File

@@ -398,6 +398,16 @@ SELECT '1&(2&(4&(5|!6)))'::query_int;
1 & 2 & 4 & ( 5 | !6 ) 1 & 2 & 4 & ( 5 | !6 )
(1 row) (1 row)
SELECT '010'::query_int; -- decimal, not octal
query_int
-----------
10
(1 row)
SELECT '-'::query_int; -- syntax error
ERROR: syntax error
LINE 1: SELECT '-'::query_int;
^
-- Test for overflow of the int16 "left" field in findoprnd(). -- Test for overflow of the int16 "left" field in findoprnd().
-- This query uses a balanced binary tree to avoid using too much stack. -- This query uses a balanced binary tree to avoid using too much stack.
DO $$ DO $$

View File

@@ -74,6 +74,8 @@ SELECT '1&(2&(4&(5&6)))'::query_int;
SELECT '1&2&4&5&6'::query_int; SELECT '1&2&4&5&6'::query_int;
SELECT '1&(2&(4&(5|6)))'::query_int; SELECT '1&(2&(4&(5|6)))'::query_int;
SELECT '1&(2&(4&(5|!6)))'::query_int; SELECT '1&(2&(4&(5|!6)))'::query_int;
SELECT '010'::query_int; -- decimal, not octal
SELECT '-'::query_int; -- syntax error
-- Test for overflow of the int16 "left" field in findoprnd(). -- Test for overflow of the int16 "left" field in findoprnd().
-- This query uses a balanced binary tree to avoid using too much stack. -- This query uses a balanced binary tree to avoid using too much stack.