Skip to content

Commit d35cd06

Browse files
committed
Fix overflow in parsing of positional parameter
Replace atol with pg_strtoint32_safe in the backend parser and with strtoint in ECPG to reject overflows when parsing the number of a positional parameter. With atol from glibc, parameters $2147483648 and $4294967297 turn into $-2147483648 and $1, respectively. Author: Erik Wienhold <ewie@ewie.name> Reviewed-by: Michael Paquier <michael@paquier.xyz> Reviewed-by: Peter Eisentraut <peter@eisentraut.org> Reviewed-by: Alexander Lakhin <exclusion@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/5d216d1c-91f6-4cbe-95e2-b4cbd930520c@ewie.name
1 parent 4867f8a commit d35cd06

File tree

4 files changed

+19
-2
lines changed

4 files changed

+19
-2
lines changed

src/backend/parser/scan.l

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -992,8 +992,14 @@ other .
992992
}
993993

994994
{param} {
995+
ErrorSaveContext escontext = {T_ErrorSaveContext};
996+
int32 val;
997+
995998
SET_YYLLOC();
996-
yylval->ival = atol(yytext + 1);
999+
val = pg_strtoint32_safe(yytext + 1, (Node *) &escontext);
1000+
if (escontext.error_occurred)
1001+
yyerror("parameter number too large");
1002+
yylval->ival = val;
9971003
return PARAM;
9981004
}
9991005
{param_junk} {

src/interfaces/ecpg/preproc/pgc.l

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -938,7 +938,13 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
938938
}
939939

940940
{param} {
941-
base_yylval.ival = atol(yytext+1);
941+
int val;
942+
943+
errno = 0;
944+
val = strtoint(yytext + 1, NULL, 10);
945+
if (errno == ERANGE)
946+
mmfatal(PARSE_ERROR, "parameter number too large");
947+
base_yylval.ival = val;
942948
return PARAM;
943949
}
944950
{param_junk} {

src/test/regress/expected/numerology.out

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,10 @@ PREPARE p1 AS SELECT $1a;
206206
ERROR: trailing junk after parameter at or near "$1a"
207207
LINE 1: PREPARE p1 AS SELECT $1a;
208208
^
209+
PREPARE p1 AS SELECT $2147483648;
210+
ERROR: parameter number too large at or near "$2147483648"
211+
LINE 1: PREPARE p1 AS SELECT $2147483648;
212+
^
209213
SELECT 0b;
210214
ERROR: invalid binary integer at or near "0b"
211215
LINE 1: SELECT 0b;

src/test/regress/sql/numerology.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ SELECT 0.0e1a;
5252
SELECT 0.0e;
5353
SELECT 0.0e+a;
5454
PREPARE p1 AS SELECT $1a;
55+
PREPARE p1 AS SELECT $2147483648;
5556

5657
SELECT 0b;
5758
SELECT 1b;

0 commit comments

Comments
 (0)