diff --git a/manifest b/manifest index 3e1d3c953a..cc5987b05d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite_current_time\svariable\sfor\stesting\spurposes.\s(CVS\s1156) -D 2004-01-06T00:44:25 +C Fix\sproblem\sin\sthe\scode\sgenerator\swere\sincorrect\scode\swas\sbeing\screated\sif\r\nthe\sSQL\ssource\scontained\sa\snegative\sinteger\sthat\swas\stoo\slarge\sto\sfit\sin\r\na\s32-bit\ssigned\sinteger\svariable.\s\sTicket\s#552.\s(CVS\s1157) +D 2004-01-06T01:13:46 F Makefile.in 0515ff9218ad8d5a8f6220f0494b8ef94c67013b F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd @@ -31,7 +31,7 @@ F src/copy.c 9e47975ea96751c658bcf1a0c4f0bb7c6ee61e73 F src/date.c 13775c2dedfc805ebf3f6507bad676f7c974a241 F src/delete.c 0f81e6799c089487615d38e042a2de4d2d6192bc F src/encode.c 25ea901a9cefb3d93774afa4a06b57cb58acf544 -F src/expr.c a14401a54e5923f3e52b6d04a83813d150f43f33 +F src/expr.c abb40922fa9995aca06f999ed35d2061d44650d6 F src/func.c 62cf8fae8147c0301d1c6a4a94fe0a78f7aa5b33 F src/hash.c 058f077c1f36f266581aa16f907a3903abf64aa3 F src/hash.h cd0433998bc1a3759d244e1637fe5a3c13b53bf8 @@ -50,7 +50,7 @@ F src/select.c d79ac60ba1595ff3c94b12892e87098329776482 F src/shell.c 3b067edc098c45caca164bcad1fa79192c3ec5ae F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e F src/sqlite.h.in e6cfff01fafc8a82ce82cd8c932af421dc9adb54 -F src/sqliteInt.h a70744a84caec6d48017143ea5b9f945867e539e +F src/sqliteInt.h 88ab55200183355e35f8f13a6b4c27b4b48288b2 F src/table.c d845cb101b5afc1f7fea083c99e3d2fa7998d895 F src/tclsqlite.c dcd18d1f0d51ac4863d1f9059f614f903bc1fffe F src/test1.c 1d297ca6c01601ee38d723ff08343dc01f351985 @@ -61,7 +61,7 @@ F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e F src/tokenize.c 5597df1fd76d6947e7da824856ac1910e2055729 F src/trigger.c ce83e017b407d046e909d05373d7f8ee70f9f7f9 F src/update.c 24260b4fda00c9726d27699a0561d53c0dccc397 -F src/util.c 48631b7f7b2f3874fb3aa60396e18619933e9386 +F src/util.c 0e3bf40dafe75805495454ff5283b552f14b5d4d F src/vacuum.c 77485a64a6e4e358170f150fff681c1624a092b0 F src/vdbe.c a16a084ca40edeec3a2e490d6f672fc84f851dd9 F src/vdbe.h 3957844e46fea71fd030e78f6a3bd2f7e320fb43 @@ -106,7 +106,7 @@ F test/memleak.test a18e6810cae96d2f6f5136920267adbefc8e1e90 F test/minmax.test 6d9b6d6ee34f42e2a58dffece1f76d35f446b3af F test/misc1.test 0b98d493b0cf55cb5f53e1f3df8107c166eecb5a F test/misc2.test 10c2ce26407d37411b96273e552d5095393732be -F test/misc3.test cfece884d4e552400bb630efb6deda973a97eda2 +F test/misc3.test 860233be672959b6d7df542adbeb0fc10103857c F test/misuse.test a3aa2b18a97e4c409a1fcaff5151a4dd804a0162 F test/notnull.test 7a08117a71e74b0321aaa937dbeb41a09d6eb1d0 F test/null.test c14d0f4739f21e929b8115b72bf0c765b6bb1721 @@ -179,7 +179,7 @@ F www/speed.tcl 2f6b1155b99d39adb185f900456d1d592c4832b3 F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1 -P 720b565e2d02344e4d38263f4995dfabc60c0860 -R f8de8a215a694e6aa8ad957d7bf6a945 +P 23fa407d50741bc0719259792398f28c1d0f12c2 +R 26f4e6dd4d46b029d5b74bd24795dcf2 U drh -Z 4f7ef24347116d6ebacdd3903fd02b08 +Z 323e2dfe44fbdbec4fff461f02b92003 diff --git a/manifest.uuid b/manifest.uuid index 742ca464f7..89f62c396d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -23fa407d50741bc0719259792398f28c1d0f12c2 \ No newline at end of file +b8381d9fe99273507e8626638110646801afef06 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 41cdaf949b..f706a5c22c 100644 --- a/src/expr.c +++ b/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.102 2003/12/10 03:13:44 drh Exp $ +** $Id: expr.c,v 1.103 2004/01/06 01:13:46 drh Exp $ */ #include "sqliteInt.h" #include @@ -328,22 +328,26 @@ int sqliteExprIsConstant(Expr *p){ } /* -** If the given expression codes a constant integer, return 1 and put -** the value of the integer in *pValue. If the expression is not an -** integer, return 0 and leave *pValue unchanged. +** If the given expression codes a constant integer that is small enough +** to fit in a 32-bit integer, return 1 and put the value of the integer +** in *pValue. If the expression is not an integer or if it is too big +** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged. */ int sqliteExprIsInteger(Expr *p, int *pValue){ switch( p->op ){ case TK_INTEGER: { - *pValue = atoi(p->token.z); - return 1; + if( sqliteFitsIn32Bits(p->token.z) ){ + *pValue = atoi(p->token.z); + return 1; + } + break; } case TK_STRING: { const char *z = p->token.z; int n = p->token.n; if( n>0 && z[0]=='-' ){ z++; n--; } while( n>0 && *z && isdigit(*z) ){ z++; n--; } - if( n==0 ){ + if( n==0 && sqliteFitsIn32Bits(p->token.z) ){ *pValue = atoi(p->token.z); return 1; } @@ -969,6 +973,9 @@ int sqliteExprType(Expr *p){ return SQLITE_SO_NUM; } +/* +** Run + /* ** Generate code into the current Vdbe to evaluate the given ** expression and leave the result on the top of stack. @@ -1014,16 +1021,10 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){ break; } case TK_INTEGER: { - int iVal = atoi(pExpr->token.z); - char zBuf[30]; - sprintf(zBuf,"%d",iVal); - if( strlen(zBuf)!=pExpr->token.n - || strncmp(pExpr->token.z,zBuf,pExpr->token.n)!=0 ){ - /* If the integer value cannot be represented exactly in 32 bits, - ** then code it as a string instead. */ + if( !sqliteFitsIn32Bits(pExpr->token.z) ){ sqliteVdbeAddOp(v, OP_String, 0, 0); }else{ - sqliteVdbeAddOp(v, OP_Integer, iVal, 0); + sqliteVdbeAddOp(v, OP_Integer, atoi(pExpr->token.z), 0); } sqliteVdbeChangeP3(v, -1, pExpr->token.z, pExpr->token.n); break; @@ -1090,7 +1091,11 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){ case TK_UPLUS: { Expr *pLeft = pExpr->pLeft; if( pLeft && pLeft->op==TK_INTEGER ){ - sqliteVdbeAddOp(v, OP_Integer, atoi(pLeft->token.z), 0); + if( sqliteFitsIn32Bits(pLeft->token.z) ){ + sqliteVdbeAddOp(v, OP_Integer, atoi(pLeft->token.z), 0); + }else{ + sqliteVdbeAddOp(v, OP_String, 0, 0); + } sqliteVdbeChangeP3(v, -1, pLeft->token.z, pLeft->token.n); }else if( pLeft && pLeft->op==TK_FLOAT ){ sqliteVdbeAddOp(v, OP_String, 0, 0); @@ -1106,7 +1111,7 @@ void sqliteExprCode(Parse *pParse, Expr *pExpr){ Token *p = &pExpr->pLeft->token; char *z = sqliteMalloc( p->n + 2 ); sprintf(z, "-%.*s", p->n, p->z); - if( pExpr->pLeft->op==TK_INTEGER ){ + if( pExpr->pLeft->op==TK_INTEGER && sqliteFitsIn32Bits(z) ){ sqliteVdbeAddOp(v, OP_Integer, atoi(z), 0); }else{ sqliteVdbeAddOp(v, OP_String, 0, 0); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 7879b11237..0cc8e3f995 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.205 2003/12/23 02:17:35 drh Exp $ +** @(#) $Id: sqliteInt.h,v 1.206 2004/01/06 01:13:47 drh Exp $ */ #include "config.h" #include "sqlite.h" @@ -1205,3 +1205,4 @@ int sqliteFixExprList(DbFixer*, ExprList*); int sqliteFixTriggerStep(DbFixer*, TriggerStep*); double sqliteAtoF(const char *z); int sqlite_snprintf(int,char*,const char*,...); +int sqliteFitsIn32Bits(const char *); diff --git a/src/util.c b/src/util.c index d9d2f90c2c..af0f31cd1a 100644 --- a/src/util.c +++ b/src/util.c @@ -14,7 +14,7 @@ ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** -** $Id: util.c,v 1.69 2003/12/23 02:17:35 drh Exp $ +** $Id: util.c,v 1.70 2004/01/06 01:13:47 drh Exp $ */ #include "sqliteInt.h" #include @@ -713,6 +713,24 @@ double sqliteAtoF(const char *z){ return sign<0 ? -v1 : v1; } +/* +** The string zNum represents an integer. There might be some other +** information following the integer too, but that part is ignored. +** If the integer that the prefix of zNum represents will fit in a +** 32-bit signed integer, return TRUE. Otherwise return FALSE. +** +** This routine returns FALSE for the string -2147483648 even that +** that number will, in theory fit in a 32-bit integer. But positive +** 2147483648 will not fit in 32 bits. So it seems safer to return +** false. +*/ +int sqliteFitsIn32Bits(const char *zNum){ + int i, c; + if( *zNum=='-' || *zNum=='+' ) zNum++; + for(i=0; (c=zNum[i])>='0' && c<='9'; i++){} + return i<10 || (i==10 && memcmp(zNum,"2147483647",10)<=0); +} + /* This comparison routine is what we use for comparison operations ** between numeric values in an SQL expression. "Numeric" is a little ** bit misleading here. What we mean is that the strings have a diff --git a/test/misc3.test b/test/misc3.test index 7e8801eda4..256a72b14b 100644 --- a/test/misc3.test +++ b/test/misc3.test @@ -13,7 +13,7 @@ # This file implements tests for miscellanous features that were # left out of other test files. # -# $Id: misc3.test,v 1.2 2003/12/23 02:17:35 drh Exp $ +# $Id: misc3.test,v 1.3 2004/01/06 01:13:47 drh Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -98,5 +98,29 @@ do_test misc3-2.9 { execsql {SELECT 2.0e-27 * '+0.000005e+132'} } 1e+100 +# Ticket #522. Make sure integer overflow is handled properly in +# indices. +# +do_test misc3-3.1 { + execsql {PRAGMA integrity_check} +} ok +do_test misc3-3.2 { + execsql { + CREATE TABLE t2(a INT UNIQUE); + PRAGMA integrity_check; + } +} ok +do_test misc3-3.3 { + execsql { + INSERT INTO t2 VALUES(2147483648); + PRAGMA integrity_check; + } +} ok +do_test misc3-3.4 { + execsql { + INSERT INTO t2 VALUES(-2147483649); + PRAGMA integrity_check; + } +} ok finish_test