From 941b45c3a3cae99075b64be94af5977d0e1a042e Mon Sep 17 00:00:00 2001 From: Dan Kennedy Date: Tue, 23 Jan 2024 11:20:58 +0000 Subject: [PATCH] Add extra checks for the validity of a numeric literal to sqlite3DequoteNumber(). --- src/parse.y | 2 +- src/sqliteInt.h | 2 +- src/tokenize.c | 20 ++++---------------- src/util.c | 13 +++++++++---- test/literal.test | 4 ++-- 5 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/parse.y b/src/parse.y index b0d03a04ee..c26a9bccc2 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1926,7 +1926,7 @@ filter_clause(A) ::= FILTER LP WHERE expr(X) RP. { A = X; } term(A) ::= QNUMBER(X). { A=tokenExpr(pParse,@X,X); - sqlite3DequoteNumber(A); + sqlite3DequoteNumber(pParse, A); } /* There must be no more than 255 tokens defined above. If this grammar diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c4aaf9d203..2db491fc81 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4794,7 +4794,7 @@ int sqlite3ErrorToParser(sqlite3*,int); void sqlite3Dequote(char*); void sqlite3DequoteExpr(Expr*); void sqlite3DequoteToken(Token*); -void sqlite3DequoteNumber(Expr*); +void sqlite3DequoteNumber(Parse*, Expr*); void sqlite3TokenInit(Token*,char*); int sqlite3KeywordCode(const unsigned char*, int); int sqlite3RunParser(Parse*, const char*); diff --git a/src/tokenize.c b/src/tokenize.c index f01548d4cb..65d1fbf350 100644 --- a/src/tokenize.c +++ b/src/tokenize.c @@ -439,10 +439,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){ for(i=3; 1; i++){ if( sqlite3Isxdigit(z[i])==0 ){ - if( z[i]==SQLITE_DIGIT_SEPARATOR - && sqlite3Isxdigit(z[i-1]) - && sqlite3Isxdigit(z[i+1]) - ){ + if( z[i]==SQLITE_DIGIT_SEPARATOR ){ *tokenType = TK_QNUMBER; }else{ break; @@ -454,10 +451,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ { for(i=0; 1; i++){ if( sqlite3Isdigit(z[i])==0 ){ - if( z[i]==SQLITE_DIGIT_SEPARATOR - && sqlite3Isdigit(z[i-1]) - && sqlite3Isdigit(z[i+1]) - ){ + if( z[i]==SQLITE_DIGIT_SEPARATOR ){ *tokenType = TK_QNUMBER; }else{ break; @@ -469,10 +463,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ if( *tokenType==TK_INTEGER ) *tokenType = TK_FLOAT; for(i++; 1; i++){ if( sqlite3Isdigit(z[i])==0 ){ - if( z[i]==SQLITE_DIGIT_SEPARATOR - && sqlite3Isdigit(z[i-1]) - && sqlite3Isdigit(z[i+1]) - ){ + if( z[i]==SQLITE_DIGIT_SEPARATOR ){ *tokenType = TK_QNUMBER; }else{ break; @@ -488,10 +479,7 @@ int sqlite3GetToken(const unsigned char *z, int *tokenType){ if( *tokenType==TK_INTEGER ) *tokenType = TK_FLOAT; for(i+=2; 1; i++){ if( sqlite3Isdigit(z[i])==0 ){ - if( z[i]==SQLITE_DIGIT_SEPARATOR - && sqlite3Isdigit(z[i-1]) - && sqlite3Isdigit(z[i+1]) - ){ + if( z[i]==SQLITE_DIGIT_SEPARATOR ){ *tokenType = TK_QNUMBER; }else{ break; diff --git a/src/util.c b/src/util.c index ed7789591b..5a88979fe4 100644 --- a/src/util.c +++ b/src/util.c @@ -316,21 +316,26 @@ void sqlite3DequoteExpr(Expr *p){ ** and set the type to INTEGER or FLOAT. "Quoted" integers or floats are those ** that contain '_' characters that must be removed before further processing. */ -void sqlite3DequoteNumber(Expr *p){ +void sqlite3DequoteNumber(Parse *pParse, Expr *p){ if( p ){ const char *pIn = p->u.zToken; char *pOut = p->u.zToken; + int bHex = (pIn[0]=='0' && (pIn[1]=='x' || pIn[1]=='X')); assert( p->op==TK_QNUMBER ); p->op = TK_INTEGER; do { if( *pIn!=SQLITE_DIGIT_SEPARATOR ){ *pOut++ = *pIn; if( *pIn=='e' || *pIn=='E' || *pIn=='.' ) p->op = TK_FLOAT; + }else{ + if( (bHex==0 && (!sqlite3Isdigit(pIn[-1]) || !sqlite3Isdigit(pIn[1]))) + || (bHex==1 && (!sqlite3Isxdigit(pIn[-1]) || !sqlite3Isxdigit(pIn[1]))) + ){ + sqlite3ErrorMsg(pParse, "unrecognized token: \"%s\"", p->u.zToken); + } } }while( *pIn++ ); - if( p->u.zToken[0]=='0' && (p->u.zToken[1]=='x' || p->u.zToken[1]=='X') ){ - p->op = TK_INTEGER; - } + if( bHex ) p->op = TK_INTEGER; } } diff --git a/test/literal.test b/test/literal.test index fe6b70acf7..30205692c9 100644 --- a/test/literal.test +++ b/test/literal.test @@ -74,7 +74,7 @@ test_literal 3.8 -9_223_372_036_854_775_808 integer -9223372036854775808 foreach {tn lit unrec} { 0 123a456 123a456 1 1_ 1_ - 2 1_.4 1_ + 2 1_.4 1_.4 3 1e_4 1e_4 4 1_e4 1_e4 5 1.4_e4 1.4_e4 @@ -86,7 +86,7 @@ foreach {tn lit unrec} { 11 12__34 12__34 12 1234_ 1234_ 13 12._34 12._34 - 14 12_.34 12_ + 14 12_.34 12_.34 15 12.34_ 12.34_ 16 1.0e1_______2 1.0e1_______2 } { -- 2.11.4.GIT