From: drh Date: Wed, 23 Jul 2014 13:40:49 +0000 (+0000) Subject: Change the hex literal processing so that only the SQL parser understands X-Git-Tag: version-3.8.6~64^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9296c18a509e32dac34e0ac9560946cee7f560e0;p=thirdparty%2Fsqlite.git Change the hex literal processing so that only the SQL parser understands hex literals. Casting and coercing string literals into numeric values does not understand hexadecimal integers. This preserves backwards compatibility. Also: Throw an error on any hex literal that is too big to fit into 64 bits. FossilOrigin-Name: 6c6f0de59bf96b79c8ace8c9bfe48c7a6a306a50 --- diff --git a/manifest b/manifest index 656415a599..8a6aa1f099 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Casting\shex\sliterals\sdirectly\sfrom\sstring\sto\sfloat\salways\sresults\sin\sa\npositive\snumber. -D 2014-07-23T02:07:11.054 +C Change\sthe\shex\sliteral\sprocessing\sso\sthat\sonly\sthe\sSQL\sparser\sunderstands\nhex\sliterals.\s\sCasting\sand\scoercing\sstring\sliterals\sinto\snumeric\svalues\sdoes\nnot\sunderstand\shexadecimal\sintegers.\s\sThis\spreserves\sbackwards\scompatibility.\nAlso:\s\sThrow\san\serror\son\sany\shex\sliteral\sthat\sis\stoo\sbig\sto\sfit\sinto\s64\sbits. +D 2014-07-23T13:40:49.410 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -176,7 +176,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a F src/date.c 593c744b2623971e45affd0bde347631bdfa4625 F src/delete.c bcf8f72126cea80fc3d5bc5494cf19b3f8935aaf -F src/expr.c 40d06d1543b1355aa02efa9666178f7642a96ed6 +F src/expr.c b1ffac76b69ae005ca38eba6dcdefa5d65eb5c95 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb F src/fkey.c a549cff9fe8b736cdae21650ea0af6de29b77619 F src/func.c 3bc223ea36cd29a91c481485343d0ee4257ab8dc @@ -189,7 +189,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 -F src/main.c 1a420efa9a34e8603c4807886408cba5546b87f9 +F src/main.c cfdb2aa5d248ff1af60227cc3f6d485ba86f92dc F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b @@ -216,7 +216,7 @@ F src/parse.y 22d6a074e5f5a7258947a1dc55a9bf946b765dd0 F src/pcache.c d8eafac28290d4bb80332005435db44991d07fc2 F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222 F src/pcache1.c 102e6f5a2fbc646154463eb856d1fd716867b64c -F src/pragma.c 810ef31ccfaa233201dcf100637a9777cc24e897 +F src/pragma.c e17c5ea1cb9eb9d93c41bbb7c3a17e747d5e0335 F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337 F src/printf.c af06f66927919730f03479fed6ae9854f73419f4 F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece @@ -227,7 +227,7 @@ F src/shell.c 566aee8213372a2e81ba0eb34e9759f7b2574009 F src/sqlite.h.in fd8e3a36b0aded082dc93a4b89c1e85324b4cf75 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc -F src/sqliteInt.h b72a09326d7cbd8375ec3d9a04ea5e0cf476beb3 +F src/sqliteInt.h 783e77ab498ac05a3fab396dfc1c2d6c2083dced F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e @@ -281,7 +281,7 @@ F src/tokenize.c ae45399d6252b4d736af43bee1576ce7bff86aec F src/trigger.c 66f3470b03b52b395e839155786966e3e037fddb F src/update.c 01564b3c430f6c7b0a35afaf7aba7987206fa3a5 F src/utf.c a0314e637768a030e6e84a957d0c4f6ba910cc05 -F src/util.c eff2c1e5a49a3c64af0fe9f2fb32cada3436a167 +F src/util.c 3076bdd51cdbf60a6e2e57fada745be37133c73e F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 F src/vdbe.c fa74c6563486022920db4d73897bd9b837c7441d F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8 @@ -601,7 +601,7 @@ F test/fuzz_malloc.test 328f70aaca63adf29b4c6f06505ed0cf57ca7c26 F test/fuzzer1.test d4c52aaf3ef923da293a2653cfab33d02f718a36 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 -F test/hexlit.test 58b653845b60da52161b5f451db9a89c569187d1 +F test/hexlit.test 1dc49cfd1c8938a8f028e392775bc3e61623ec46 F test/hook.test 162d7cef7a2d2b04839fe14402934e6a1b79442f F test/icu.test 70df4faca133254c042d02ae342c0a141f2663f4 F test/in.test 047c4671328e9032ab95666a67021adbbd36e98e @@ -1184,7 +1184,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P 7e1bbacb11a4689b69856450125cae3d045307af -R 8a73a1b568b990d7d0a1847902994baf +P 4b86ccdf4f4eb4339a5706e10ad24f01b6c3939e +R a36ec645688e0ae2f526ebda77270f17 U drh -Z d9d4d7765f779882d47568941cd5db2a +Z 32ccd1ec50cb642ea84793b61793e5b3 diff --git a/manifest.uuid b/manifest.uuid index 4442ea274c..f47a66e629 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4b86ccdf4f4eb4339a5706e10ad24f01b6c3939e \ No newline at end of file +6c6f0de59bf96b79c8ace8c9bfe48c7a6a306a50 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 803d93f30d..a60c0cba43 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2075,7 +2075,7 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ i64 value; const char *z = pExpr->u.zToken; assert( z!=0 ); - c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); + c = sqlite3DecOrHexToI64(z, &value); if( c==0 || (c==2 && negFlag) ){ char *zV; if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; } @@ -2085,7 +2085,11 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ #ifdef SQLITE_OMIT_FLOATING_POINT sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z); #else - codeReal(v, z, negFlag, iMem); + if( sqlite3_strnicmp(z,"0x",2)==0 ){ + sqlite3ErrorMsg(pParse, "hex literal too big: %s", z); + }else{ + codeReal(v, z, negFlag, iMem); + } #endif } } diff --git a/src/main.c b/src/main.c index 5e976e3397..904e0a4fc1 100644 --- a/src/main.c +++ b/src/main.c @@ -3409,7 +3409,7 @@ sqlite3_int64 sqlite3_uri_int64( ){ const char *z = sqlite3_uri_parameter(zFilename, zParam); sqlite3_int64 v; - if( z && sqlite3Atoi64(z, &v, sqlite3Strlen30(z), SQLITE_UTF8)==SQLITE_OK ){ + if( z && sqlite3DecOrHexToI64(z, &v)==SQLITE_OK ){ bDflt = v; } return bDflt; diff --git a/src/pragma.c b/src/pragma.c index 4c69ceb4fd..709662c989 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1048,7 +1048,7 @@ void sqlite3Pragma( Pager *pPager = sqlite3BtreePager(pDb->pBt); i64 iLimit = -2; if( zRight ){ - sqlite3Atoi64(zRight, &iLimit, sqlite3Strlen30(zRight), SQLITE_UTF8); + sqlite3DecOrHexToI64(zRight, &iLimit); if( iLimit<-1 ) iLimit = -1; } iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); @@ -1176,7 +1176,7 @@ void sqlite3Pragma( assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( zRight ){ int ii; - sqlite3Atoi64(zRight, &sz, sqlite3Strlen30(zRight), SQLITE_UTF8); + sqlite3DecOrHexToI64(zRight, &sz); if( sz<0 ) sz = sqlite3GlobalConfig.szMmap; if( pId2->n==0 ) db->szMmap = sz; for(ii=db->nDb-1; ii>=0; ii--){ @@ -2219,7 +2219,7 @@ void sqlite3Pragma( */ case PragTyp_SOFT_HEAP_LIMIT: { sqlite3_int64 N; - if( zRight && sqlite3Atoi64(zRight, &N, 1000000, SQLITE_UTF8)==SQLITE_OK ){ + if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){ sqlite3_soft_heap_limit64(N); } returnSingleInt(pParse, "soft_heap_limit", sqlite3_soft_heap_limit64(-1)); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7edc04ca42..0bbf9945ce 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3331,9 +3331,11 @@ char sqlite3CompareAffinity(Expr *pExpr, char aff2); int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); char sqlite3ExprAffinity(Expr *pExpr); int sqlite3Atoi64(const char*, i64*, int, u8); +int sqlite3DecOrHexToI64(const char*, i64*); void sqlite3Error(sqlite3*, int, const char*,...); void *sqlite3HexToBlob(sqlite3*, const char *z, int n); u8 sqlite3HexToInt(int h); +int sqlite3HexToI64(const char*,i64*); int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); #if defined(SQLITE_TEST) diff --git a/src/util.c b/src/util.c index f7f3f58b2b..619af7f758 100644 --- a/src/util.c +++ b/src/util.c @@ -255,22 +255,6 @@ int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ return N<0 ? 0 : UpperToLower[*a] - UpperToLower[*b]; } -/* -** Translate a single byte of Hex into an integer. -** This routine only works if h really is a valid hexadecimal -** character: 0..9a..fA..F -*/ -u8 sqlite3HexToInt(int h){ - assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); -#ifdef SQLITE_ASCII - h += 9*(1&(h>>6)); -#endif -#ifdef SQLITE_EBCDIC - h += 9*(1&~(h>>4)); -#endif - return (u8)(h & 0xf); -} - /* ** The string z[] is an text representation of a real number. ** Convert this string to a double and write it into *pResult. @@ -334,20 +318,6 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ }else if( *z=='+' ){ z+=incr; } -#ifndef SQLITE_OMIT_HEX_INTEGER - else if( *z=='0' - && &z[incr*2]=zEnd && nonNum==0; - } -#endif /* skip leading zeroes */ while( z16*incr || nonNum; - } -#endif } zStart = zNum; while( zNum='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); +#ifdef SQLITE_ASCII + h += 9*(1&(h>>6)); +#endif +#ifdef SQLITE_EBCDIC + h += 9*(1&~(h>>4)); +#endif + return (u8)(h & 0xf); +} + #if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) /* ** Convert a BLOB literal of the form "x'hhhhhh'" into its binary diff --git a/test/hexlit.test b/test/hexlit.test index 39ddf96e0b..41133aba0f 100644 --- a/test/hexlit.test +++ b/test/hexlit.test @@ -107,44 +107,22 @@ hexlit1 218 0x00E 14 hexlit1 219 0x00f 15 hexlit1 220 0x00F 15 -proc hexlit2 {tnum hex ans} { - do_execsql_test hexlit-$tnum "SELECT printf('%7e',CAST('$hex' AS real))" $ans -} +# String literals that look like hex do not get cast or coerced. +# +do_execsql_test hexlit-300 { + CREATE TABLE t1(x INT, y REAL); + INSERT INTO t1 VALUES('1234','4567'),('0x1234','0x4567'); + SELECT typeof(x), x, typeof(y), y, '#' FROM t1 ORDER BY rowid; +} {integer 1234 real 4567.0 # text 0x1234 text 0x4567 #} +do_execsql_test hexlit-301 { + SELECT CAST('0x1234' AS INTEGER); +} {0} -hexlit2 300 0x1 1.000000e+00 -hexlit2 301 0x10 1.600000e+01 -hexlit2 302 0x100 2.560000e+02 -hexlit2 303 0x1000 4.096000e+03 -hexlit2 304 0x10000 6.553600e+04 -hexlit2 305 0x100000 1.048576e+06 -hexlit2 306 0x1000000 1.677722e+07 -hexlit2 307 0x10000000 2.684355e+08 -hexlit2 308 0x100000000 4.294967e+09 -hexlit2 309 0x1000000000 6.871948e+10 -hexlit2 310 0x10000000000 1.099512e+12 -hexlit2 311 0x100000000000 1.759219e+13 -hexlit2 312 0x1000000000000 2.814750e+14 -hexlit2 313 0x10000000000000 4.503600e+15 -hexlit2 314 0x100000000000000 7.205759e+16 -hexlit2 315 0x1000000000000000 1.152922e+18 -hexlit2 316 0x10000000000000000 1.844674e+19 -hexlit2 317 0x100000000000000000 2.951479e+20 -hexlit2 318 0x1000000000000000000 4.722366e+21 -hexlit2 319 0x10000000000000000000 7.555786e+22 -hexlit2 320 0x100000000000000000000 1.208926e+24 -hexlit2 321 0x1000000000000000000000 1.934281e+25 -hexlit2 322 0x10000000000000000000000 3.094850e+26 -hexlit2 323 0x100000000000000000000000 4.951760e+27 -hexlit2 324 0x1000000000000000000000000 7.922816e+28 -hexlit2 325 0x10000000000000000000000000 1.267651e+30 -hexlit2 326 0x100000000000000000000000000 2.028241e+31 -hexlit2 327 0x1000000000000000000000000000 3.245186e+32 -hexlit2 328 0x10000000000000000000000000000 5.192297e+33 -hexlit2 329 0x100000000000000000000000000000 8.307675e+34 +# Oversized hex literals are rejected +# +do_catchsql_test hexlist-400 { + SELECT 0x10000000000000000; +} {1 {hex literal too big: 0x10000000000000000}} -hexlit2 400 0x07fffffffffffffff 9.223372e+18 -hexlit2 401 0x08000000000000000 9.223372e+18 -hexlit2 402 0x0ffffffffffffffff 1.844674e+19 -hexlit2 403 0x10000000000000000 1.844674e+19 finish_test