]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix all known instances of signed-integer overflow. Within SQL expressions,
authordrh <drh@noemail.net>
Sat, 5 Mar 2011 20:59:46 +0000 (20:59 +0000)
committerdrh <drh@noemail.net>
Sat, 5 Mar 2011 20:59:46 +0000 (20:59 +0000)
integer overflow now forces coercion to floating point.  The shift operators
work with any integer right-hand operand with negative values reversing
the direction of the shift.

FossilOrigin-Name: abf21394124a0af46f072793718964cee2ce55d0

manifest
manifest.uuid
src/expr.c
src/func.c
src/printf.c
src/sqliteInt.h
src/util.c
src/vdbe.c
src/vdbemem.c
test/expr.test

index e8bdbb82a6940ae0906f845b20fb9dc3af2f7342..c596f893aea121f956ffc2700878c2834b866ba9 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,8 @@
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
-C Fix\san\sinstance\sof\ssigned\sarithmetic\soverflow\sand\san\sone\sbit-shift\soverflow.\nMark\ssix\sother\ssigned\sarithmetic\soverflow\slocations\sthat\sneed\sfixing.
-D 2011-03-05T13:54:15.956
+C Fix\sall\sknown\sinstances\sof\ssigned-integer\soverflow.\s\sWithin\sSQL\sexpressions,\ninteger\soverflow\snow\sforces\scoercion\sto\sfloating\spoint.\s\sThe\sshift\soperators\nwork\swith\sany\sinteger\sright-hand\soperand\swith\snegative\svalues\sreversing\nthe\sdirection\sof\sthe\sshift.
+D 2011-03-05T20:59:46.394
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -133,10 +133,10 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
 F src/ctime.c 7deec4534f3b5a0c3b4a4cbadf809d321f64f9c4
 F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b
 F src/delete.c 7ed8a8c8b5f748ece92df173d7e0f7810c899ebd
-F src/expr.c 0afd6a93d95614e57b29d1c6da5f74be5a4d4fbd
+F src/expr.c 66c9383e5e1f5259c43ef3aa7883da66cfc0f492
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
 F src/fkey.c 17950a28f28b23e8ad3feaac5fc88c324d2f600a
-F src/func.c 9b88e09d238eecdb6242bd387901e6d9f7f64531
+F src/func.c 3a8cb2fb2de3e3aed7f39106daf4878d9d17fcce
 F src/global.c 02335177cf6946fe5525c6f0755cf181140debf3
 F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af
 F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
@@ -175,7 +175,7 @@ F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
 F src/pcache1.c d548e31beafa792d1994b663a29a5303569efc4e
 F src/pragma.c a83f320497aee18eda60fc8d854df5897906c2b1
 F src/prepare.c 395b3fab1b93f45b6aa194b23ebc201221c47b99
-F src/printf.c 6eb5c70b531464cca4254e70aaafdf2e7da3a743
+F src/printf.c 585a36b6a963df832cfb69505afa3a34ed5ef8a1
 F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
 F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706
 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
@@ -183,7 +183,7 @@ F src/select.c d24406c45dd2442eb2eeaac413439066b149c944
 F src/shell.c 649c51979812f77f97507024a4cea480c6862b8b
 F src/sqlite.h.in ccb23cc9378874c7c72682b739f311474a80848d
 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754
-F src/sqliteInt.h 4290fff17fabc6e07fc4338233df0e39e6350ca1
+F src/sqliteInt.h 118481da7db00c4ae2709ed8af6498be900e6ae0
 F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44
 F src/status.c 4997380fbb915426fef9e500b4872e79c99267fc
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -231,15 +231,15 @@ F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080
 F src/trigger.c b8bedb9c0084ceb51a40f54fcca2ce048c8de852
 F src/update.c c40aedd40baf460806f1c9f2cbe4a1dac445ee91
 F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685
-F src/util.c 77572d1f37c5b319d9e735c745349304791f7ba5
+F src/util.c c849a1e77d00a8a28429a22818155dbf9c311fee
 F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f
-F src/vdbe.c 953d44f0fbd72bf73a278c10e7bdd9164235260d
+F src/vdbe.c 038e5689e48cd6597158c5dc34f8d40a03a87ad7
 F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2
 F src/vdbeInt.h 6e6f28e9bccc6c703dca1372fd661c57b5c15fb0
 F src/vdbeapi.c 8e9324fd35eb70d0b5904bd1af40f2598744dc4d
 F src/vdbeaux.c 3ce2588ffe921e457d00baee7dd409afabe8c8af
 F src/vdbeblob.c 18955f0ee6b133cd08e1592010cb9a6b11e9984c
-F src/vdbemem.c 0fa2ed786cd207d5b988afef3562a8e663a75b50
+F src/vdbemem.c d8f713bcc3e176040d3e2bb4fbffc3b31faa4252
 F src/vdbetrace.c 3ba13bc32bdf16d2bdea523245fd16736bed67b5
 F src/vtab.c b297e8fa656ab5e66244ab15680d68db0adbec30
 F src/wal.c 5386fb5e13c2daa8ab9062597fdc17bd849da371
@@ -383,7 +383,7 @@ F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3
 F test/exclusive.test 53e1841b422e554cecf0160f937c473d6d0e3062
 F test/exclusive2.test 343d55130c12c67b8bf10407acec043a6c26c86b
 F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
-F test/expr.test 620a636cf7b7d4e5834a0b9d83a4da372e24a7b7
+F test/expr.test 19e8ac40313e2282a47b586d11c4892040990d3a
 F test/fallocate.test 43dc34b8c24be6baffadc3b4401ee15710ce83c6
 F test/filectrl.test 97003734290887566e01dded09dc9e99cb937e9e
 F test/filefmt.test f178cfc29501a14565954c961b226e61877dd32c
@@ -914,14 +914,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 952f5e8c69904c48f2decfabf8ea60a2e9f3e134
-R c0946fb5d31ae3d41275b61febc12359
+P 04abab71ecd52f6070b9f84781a3df3d6dba7722
+R dffbfc883d2df8713fd0ba30b453b561
 U drh
-Z 4b81d66afc295ddd153d99c651678bf2
+Z e566f37c8f9e6003556e493773a7db62
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.6 (GNU/Linux)
 
-iD8DBQFNckCLoxKgR168RlERAq5MAJwIkQItYpj2jIMbedpVkYZIN7SirACePysg
-Jf8UO88YpxqtY86joGQ7FqQ=
-=f5iN
+iD8DBQFNcqRGoxKgR168RlERAlK6AJ9gnf6EDR2ZKhaKkoiA1Nkl5MKeDgCeOJxY
+dz92w6QJZQImuyiplDh238s=
+=sTB2
 -----END PGP SIGNATURE-----
index ad8d2b9252c97d199ae52ea54a703f81f25d53d2..6a05b41f73ce4018097bf029b86ff3c859e88351 100644 (file)
@@ -1 +1 @@
-04abab71ecd52f6070b9f84781a3df3d6dba7722
\ No newline at end of file
+abf21394124a0af46f072793718964cee2ce55d0
\ No newline at end of file
index 57243c74e87fa75edce932831c7c90bb725cbf92..b938d9657b9cc9c6d91f129d47b05f728f7a1566 100644 (file)
@@ -1964,7 +1964,7 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
     c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8);
     if( c==0 || (c==2 && negFlag) ){
       char *zV;
-      if( negFlag ){ value = -value; } /* CLANG */
+      if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; }
       zV = dup8bytes(v, (char*)&value);
       sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64);
     }else{
index 2f21ac0e3d349a45f5a0de3d0a48d05879bcac0b..6a4f7c09c3d5b315464c61152c861d1f38fba984 100644 (file)
@@ -1239,13 +1239,8 @@ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
     if( type==SQLITE_INTEGER ){
       i64 v = sqlite3_value_int64(argv[0]);
       p->rSum += v;
-      if( (p->approx|p->overflow)==0 ){
-        i64 iNewSum = p->iSum + v;    /* CLANG */
-        int s1 = (int)(p->iSum >> (sizeof(i64)*8-1));
-        int s2 = (int)(v       >> (sizeof(i64)*8-1));
-        int s3 = (int)(iNewSum >> (sizeof(i64)*8-1));
-        p->overflow = ((s1&s2&~s3) | (~s1&~s2&s3))?1:0;
-        p->iSum = iNewSum;
+      if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){
+        p->overflow = 1;
       }
     }else{
       p->rSum += sqlite3_value_double(argv[0]);
index 21b6c0e11ac8074f6aa256107c7b947dc9c2ab42..2a3dd81d7d2603a072d5074973004ab48123bc7f 100644 (file)
@@ -400,7 +400,11 @@ void sqlite3VXPrintf(
             v = va_arg(ap,int);
           }
           if( v<0 ){
-            longvalue = -v;  /* CLANG */
+            if( v==SMALLEST_INT64 ){
+              longvalue = ((u64)1)<<63;
+            }else{
+              longvalue = -v;
+            }
             prefix = '-';
           }else{
             longvalue = v;
index 2987dcd483727bbba28ef60f1b2757d28d78eb12..bbf1b16883075c6795ed416f076eb729c97f912d 100644 (file)
@@ -2903,6 +2903,9 @@ Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr*, Token*);
 int sqlite3CheckCollSeq(Parse *, CollSeq *);
 int sqlite3CheckObjectName(Parse *, const char *);
 void sqlite3VdbeSetChanges(sqlite3 *, int);
+int sqlite3AddInt64(i64*,i64);
+int sqlite3SubInt64(i64*,i64);
+int sqlite3MulInt64(i64*,i64);
 
 const void *sqlite3ValueText(sqlite3_value*, u8);
 int sqlite3ValueBytes(sqlite3_value*, u8);
index ca22749fa074619d671497b7e5cb36eee89fade4..b2787974c1969ef7549e9faa36eaccc4c1c069a3 100644 (file)
@@ -441,14 +441,17 @@ static int compare2pow63(const char *zNum, int incr){
 
 
 /*
-** Convert zNum to a 64-bit signed integer and write
-** the value of the integer into *pNum.
-** If zNum is exactly 9223372036854665808, return 2.
-** This is a special case as the context will determine
-** if it is too big (used as a negative).
-** If zNum is not an integer or is an integer that 
-** is too large to be expressed with 64 bits,
-** then return 1.  Otherwise return 0.
+** Convert zNum to a 64-bit signed integer.
+**
+** If the zNum value is representable as a 64-bit twos-complement 
+** integer, then write that value into *pNum and return 0.
+**
+** If zNum is exactly 9223372036854665808, return 2.  This special
+** case is broken out because while 9223372036854665808 cannot be a 
+** signed 64-bit integer, its negative -9223372036854665808 can be.
+**
+** If zNum is too big for a 64-bit integer and is not
+** 9223372036854665808 then return 1.
 **
 ** length is the number of bytes in the string (bytes, not characters).
 ** The string is not necessarily zero-terminated.  The encoding is
@@ -456,7 +459,7 @@ static int compare2pow63(const char *zNum, int incr){
 */
 int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
   int incr = (enc==SQLITE_UTF8?1:2);
-  i64 v = 0;
+  u64 u = 0;
   int neg = 0; /* assume positive */
   int i;
   int c = 0;
@@ -464,20 +467,26 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
   const char *zEnd = zNum + length;
   if( enc==SQLITE_UTF16BE ) zNum++;
   while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
-  if( zNum>=zEnd ) goto do_atoi_calc;
-  if( *zNum=='-' ){
-    neg = 1;
-    zNum+=incr;
-  }else if( *zNum=='+' ){
-    zNum+=incr;
+  if( zNum<zEnd ){
+    if( *zNum=='-' ){
+      neg = 1;
+      zNum+=incr;
+    }else if( *zNum=='+' ){
+      zNum+=incr;
+    }
   }
-do_atoi_calc:
   zStart = zNum;
   while( zNum<zEnd && zNum[0]=='0' ){ zNum+=incr; } /* Skip leading zeros. */
   for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i+=incr){
-    v = v*10 + c - '0';  /* CLANG */
+    u = u*10 + c - '0';
+  }
+  if( u>LARGEST_INT64 ){
+    *pNum = SMALLEST_INT64;
+  }else if( neg ){
+    *pNum = -(i64)u;
+  }else{
+    *pNum = (i64)u;
   }
-  *pNum = neg ? -v : v;  /* CLANG */
   testcase( i==18 );
   testcase( i==19 );
   testcase( i==20 );
@@ -487,14 +496,25 @@ do_atoi_calc:
     return 1;
   }else if( i<19*incr ){
     /* Less than 19 digits, so we know that it fits in 64 bits */
+    assert( u<=LARGEST_INT64 );
     return 0;
   }else{
-    /* 19-digit numbers must be no larger than 9223372036854775807 if positive
-    ** or 9223372036854775808 if negative.  Note that 9223372036854665808
-    ** is 2^63. Return 1 if to large */
-    c=compare2pow63(zNum, incr);
-    if( c==0 && neg==0 ) return 2; /* too big, exactly 9223372036854665808 */
-    return c<neg ? 0 : 1;
+    /* zNum is a 19-digit numbers.  Compare it against 9223372036854775808. */
+    c = compare2pow63(zNum, incr);
+    if( c<0 ){
+      /* zNum is less than 9223372036854775808 so it fits */
+      assert( u<=LARGEST_INT64 );
+      return 0;
+    }else if( c>0 ){
+      /* zNum is greater than 9223372036854775808 so it overflows */
+      return 1;
+    }else{
+      /* zNum is exactly 9223372036854775808.  Fits if negative.  The
+      ** special case 2 overflow if positive */
+      assert( u-1==LARGEST_INT64 );
+      assert( (*pNum)==SMALLEST_INT64 );
+      return neg ? 0 : 2;
+    }
   }
 }
 
@@ -1060,3 +1080,63 @@ int sqlite3SafetyCheckSickOrOk(sqlite3 *db){
     return 1;
   }
 }
+
+/*
+** Attempt to add, substract, or multiply the 64-bit signed value iB against
+** the other 64-bit signed integer at *pA and store the result in *pA.
+** Return 0 on success.  Or if the operation would have resulted in an
+** overflow, leave *pA unchanged and return 1.
+*/
+int sqlite3AddInt64(i64 *pA, i64 iB){
+  i64 iA = *pA;
+  testcase( iA==0 ); testcase( iA==1 );
+  testcase( iB==-1 ); testcase( iB==0 );
+  if( iB>=0 ){
+    testcase( iA>0 && LARGEST_INT64 - iA == iB );
+    testcase( iA>0 && LARGEST_INT64 - iA == iB - 1 );
+    if( iA>0 && LARGEST_INT64 - iA < iB ) return 1;
+    *pA += iB;
+  }else{
+    testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 1 );
+    testcase( iA<0 && -(iA + LARGEST_INT64) == iB + 2 );
+    if( iA<0 && -(iA + LARGEST_INT64) > iB + 1 ) return 1;
+    *pA += iB;
+  }
+  return 0; 
+}
+int sqlite3SubInt64(i64 *pA, i64 iB){
+  testcase( iB==SMALLEST_INT64+1 );
+  if( iB==SMALLEST_INT64 ){
+    testcase( (*pA)==(-1) ); testcase( (*pA)==0 );
+    if( (*pA)>=0 ) return 1;
+    *pA -= iB;
+    return 0;
+  }else{
+    return sqlite3AddInt64(pA, -iB);
+  }
+}
+#define TWOPOWER32 (((i64)1)<<32)
+#define TWOPOWER31 (((i64)1)<<31)
+int sqlite3MulInt64(i64 *pA, i64 iB){
+  i64 iA = *pA;
+  i64 iA1, iA0, iB1, iB0, r;
+
+//  if( iB==1 ){ return 0; }
+//  if( iA==1 ){ *pA = iB; return 0; }
+  iA1 = iA/TWOPOWER32;
+  iA0 = iA % TWOPOWER32;
+  iB1 = iB/TWOPOWER32;
+  iB0 = iB % TWOPOWER32;
+  if( iA1*iB1 != 0 ) return 1;
+  r = iA1*iB0;
+  if( sqlite3AddInt64(&r, iA0*iB1) ) return 1;
+  testcase( r==(-TWOPOWER31)-1 );
+  testcase( r==(-TWOPOWER31) );
+  testcase( r==TWOPOWER31 );
+  testcase( r==TWOPOWER31-1 );
+  if( r<(-TWOPOWER31) || r>=TWOPOWER31 ) return 1;
+  r *= TWOPOWER32;
+  if( sqlite3AddInt64(&r, iA0*iB0) ) return 1;
+  *pA = r;
+  return 0;
+}
index 3a7397687b73c2e04c5b2fe9299948453f626b39..823688e797058365dbbc48afae49c21c251c87c8 100644 (file)
@@ -1246,19 +1246,12 @@ case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
     iA = pIn1->u.i;
     iB = pIn2->u.i;
     switch( pOp->opcode ){
-      case OP_Add:         iB += iA;       break;   /* CLANG */
-      case OP_Subtract:    iB -= iA;       break;
-      case OP_Multiply:    iB *= iA;       break;
+      case OP_Add:       if( sqlite3AddInt64(&iB,iA) ) goto fp_math;  break;
+      case OP_Subtract:  if( sqlite3SubInt64(&iB,iA) ) goto fp_math;  break;
+      case OP_Multiply:  if( sqlite3MulInt64(&iB,iA) ) goto fp_math;  break;
       case OP_Divide: {
         if( iA==0 ) goto arithmetic_result_is_null;
-        /* Dividing the largest possible negative 64-bit integer (1<<63) by 
-        ** -1 returns an integer too large to store in a 64-bit data-type. On
-        ** some architectures, the value overflows to (1<<63). On others,
-        ** a SIGFPE is issued. The following statement normalizes this
-        ** behavior so that all architectures behave as if integer 
-        ** overflow occurred.
-        */
-        if( iA==-1 && iB==SMALLEST_INT64 ) iA = 1;
+        if( iA==-1 && iB==SMALLEST_INT64 ) goto fp_math;
         iB /= iA;
         break;
       }
@@ -1272,6 +1265,7 @@ case OP_Remainder: {           /* same as TK_REM, in1, in2, out3 */
     pOut->u.i = iB;
     MemSetTypeFlag(pOut, MEM_Int);
   }else{
+fp_math:
     rA = sqlite3VdbeRealValue(pIn1);
     rB = sqlite3VdbeRealValue(pIn2);
     switch( pOp->opcode ){
@@ -1466,8 +1460,10 @@ case OP_BitAnd:                 /* same as TK_BITAND, in1, in2, out3 */
 case OP_BitOr:                  /* same as TK_BITOR, in1, in2, out3 */
 case OP_ShiftLeft:              /* same as TK_LSHIFT, in1, in2, out3 */
 case OP_ShiftRight: {           /* same as TK_RSHIFT, in1, in2, out3 */
-  i64 a;
-  i64 b;
+  i64 iA;
+  u64 uA;
+  i64 iB;
+  u8 op;
 
   pIn1 = &aMem[pOp->p1];
   pIn2 = &aMem[pOp->p2];
@@ -1476,16 +1472,38 @@ case OP_ShiftRight: {           /* same as TK_RSHIFT, in1, in2, out3 */
     sqlite3VdbeMemSetNull(pOut);
     break;
   }
-  a = sqlite3VdbeIntValue(pIn2);
-  b = sqlite3VdbeIntValue(pIn1);
-  switch( pOp->opcode ){
-    case OP_BitAnd:      a &= b;     break;
-    case OP_BitOr:       a |= b;     break;
-    case OP_ShiftLeft:   a <<= b;    break;
-    default:  assert( pOp->opcode==OP_ShiftRight );
-                         a >>= b;    break;
+  iA = sqlite3VdbeIntValue(pIn2);
+  iB = sqlite3VdbeIntValue(pIn1);
+  op = pOp->opcode;
+  if( op==OP_BitAnd ){
+    iA &= iB;
+  }else if( op==OP_BitOr ){
+    iA |= iB;
+  }else if( iB!=0 ){
+    assert( op==OP_ShiftRight || op==OP_ShiftLeft );
+
+    /* If shifting by a negative amount, shift in the other direction */
+    if( iB<0 ){
+      assert( OP_ShiftRight==OP_ShiftLeft+1 );
+      op = 2*OP_ShiftLeft + 1 - op;
+      iB = iB>(-64) ? -iB : 64;
+    }
+
+    if( iB>=64 ){
+      iA = (iA>=0 || op==OP_ShiftLeft) ? 0 : -1;
+    }else{
+      memcpy(&uA, &iA, sizeof(uA));
+      if( op==OP_ShiftLeft ){
+        uA <<= iB;
+      }else{
+        uA >>= iB;
+        /* Sign-extend on a right shift of a negative number */
+        if( iA<0 ) uA |= ((((u64)0xffffffff)<<32)|0xffffffff) << (64-iB);
+      }
+      memcpy(&iA, &uA, sizeof(iA));
+    }
   }
-  pOut->u.i = a;
+  pOut->u.i = iA;
   MemSetTypeFlag(pOut, MEM_Int);
   break;
 }
index 104b93fd66e16a608357269153b53a62185e39d7..d2fdeb7ee9c30b32a31bd95b70e09197613324f1 100644 (file)
@@ -367,7 +367,7 @@ i64 sqlite3VdbeIntValue(Mem *pMem){
   }else if( flags & MEM_Real ){
     return doubleToInt64(pMem->r);
   }else if( flags & (MEM_Str|MEM_Blob) ){
-    i64 value;
+    i64 value = 0;
     assert( pMem->z || pMem->n==0 );
     testcase( pMem->z==0 );
     sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
index 140ab8d8b31881bcee3ede72416ab1562bbd767b..5a3d16751767b74b9dd3fac1b85ab81c37193b7f 100644 (file)
@@ -82,8 +82,18 @@ test_expr expr-1.43 {i1=1, i2=2} {i1&i2} {0}
 test_expr expr-1.43b {i1=1, i2=2} {4&5} {4}
 test_expr expr-1.44 {i1=1} {~i1} {-2}
 test_expr expr-1.44b {i1=NULL} {~i1} {{}}
-test_expr expr-1.45 {i1=1, i2=3} {i1<<i2} {8}
-test_expr expr-1.46 {i1=32, i2=3} {i1>>i2} {4}
+test_expr expr-1.45a {i1=1, i2=3} {i1<<i2} {8}
+test_expr expr-1.45b {i1=1, i2=-3} {i1>>i2} {8}
+test_expr expr-1.45c {i1=1, i2=0} {i1<<i2} {1}
+test_expr expr-1.45d {i1=1, i2=62} {i1<<i2} {4611686018427387904}
+test_expr expr-1.45e {i1=1, i2=63} {i1<<i2} {-9223372036854775808}
+test_expr expr-1.45f {i1=1, i2=64} {i1<<i2} {0}
+test_expr expr-1.45g {i1=32, i2=-9223372036854775808} {i1>>i2} {0}
+test_expr expr-1.46a {i1=32, i2=3} {i1>>i2} {4}
+test_expr expr-1.46b {i1=32, i2=6} {i1>>i2} {0}
+test_expr expr-1.46c {i1=-32, i2=3} {i1>>i2} {-4}
+test_expr expr-1.46d {i1=-32, i2=100} {i1>>i2} {-1}
+test_expr expr-1.46e {i1=32, i2=-3} {i1>>i2} {256}
 test_expr expr-1.47 {i1=9999999999, i2=8888888888} {i1<i2} 0
 test_expr expr-1.48 {i1=9999999999, i2=8888888888} {i1=i2} 0
 test_expr expr-1.49 {i1=9999999999, i2=8888888888} {i1>i2} 1
@@ -154,10 +164,10 @@ ifcapable floatingpoint {
 }
 
 if {[working_64bit_int]} {
-  test_expr expr-1.106 {i1=0} {(1<<63)/-1} -9223372036854775808
+  test_expr expr-1.106 {i1=0} {-9223372036854775808/-1} 9.22337203685478e+18
 }
 
-test_expr expr-1.107 {i1=0} {(1<<63)%-1} 0
+test_expr expr-1.107 {i1=0} {-9223372036854775808%-1} 0
 test_expr expr-1.108 {i1=0} {1%0} {{}}
 test_expr expr-1.109 {i1=0} {1/0} {{}}
 
@@ -190,6 +200,107 @@ test_expr expr-1.125 {i1=6, i2=NULL} \
 test_expr expr-1.126 {i1=8, i2=8} \
   {CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} no
 
+ifcapable floatingpoint {if {[working_64bit_int]} {
+  test_expr expr-1.200\
+      {i1=9223372036854775806, i2=1} {i1+i2}      9223372036854775807
+  test_expr expr-1.201\
+      {i1=9223372036854775806, i2=2} {i1+i2}      9.22337203685478e+18
+  test_expr expr-1.202\
+      {i1=9223372036854775806, i2=100000} {i1+i2} 9.22337203685488e+18
+  test_expr expr-1.203\
+      {i1=9223372036854775807, i2=0} {i1+i2}      9223372036854775807
+  test_expr expr-1.204\
+      {i1=9223372036854775807, i2=1} {i1+i2}      9.22337203685478e+18
+  test_expr expr-1.205\
+      {i2=9223372036854775806, i1=1} {i1+i2}      9223372036854775807
+  test_expr expr-1.206\
+      {i2=9223372036854775806, i1=2} {i1+i2}      9.22337203685478e+18
+  test_expr expr-1.207\
+      {i2=9223372036854775806, i1=100000} {i1+i2} 9.22337203685488e+18
+  test_expr expr-1.208\
+      {i2=9223372036854775807, i1=0} {i1+i2}      9223372036854775807
+  test_expr expr-1.209\
+      {i2=9223372036854775807, i1=1} {i1+i2}      9.22337203685478e+18
+  test_expr expr-1.210\
+      {i1=-9223372036854775807, i2=-1} {i1+i2}    -9223372036854775808
+  test_expr expr-1.211\
+      {i1=-9223372036854775807, i2=-2} {i1+i2}    -9.22337203685478e+18
+  test_expr expr-1.212\
+      {i1=-9223372036854775807, i2=-100000} {i1+i2} -9.22337203685488e+18
+  test_expr expr-1.213\
+      {i1=-9223372036854775808, i2=0} {i1+i2}     -9223372036854775808
+  test_expr expr-1.214\
+      {i1=-9223372036854775808, i2=-1} {i1+i2}    -9.22337203685478e+18
+  test_expr expr-1.215\
+      {i2=-9223372036854775807, i1=-1} {i1+i2}    -9223372036854775808
+  test_expr expr-1.216\
+      {i2=-9223372036854775807, i1=-2} {i1+i2}    -9.22337203685478e+18
+  test_expr expr-1.217\
+      {i2=-9223372036854775807, i1=-100000} {i1+i2} -9.22337203685488e+18
+  test_expr expr-1.218\
+      {i2=-9223372036854775808, i1=0} {i1+i2}     -9223372036854775808
+  test_expr expr-1.219\
+      {i2=-9223372036854775808, i1=-1} {i1+i2}    -9.22337203685478e+18
+  test_expr expr-1.220\
+      {i1=9223372036854775806, i2=-1} {i1-i2}     9223372036854775807
+  test_expr expr-1.221\
+      {i1=9223372036854775806, i2=-2} {i1-i2}      9.22337203685478e+18
+  test_expr expr-1.222\
+      {i1=9223372036854775806, i2=-100000} {i1-i2} 9.22337203685488e+18
+  test_expr expr-1.223\
+      {i1=9223372036854775807, i2=0} {i1-i2}      9223372036854775807
+  test_expr expr-1.224\
+      {i1=9223372036854775807, i2=-1} {i1-i2}      9.22337203685478e+18
+  test_expr expr-1.225\
+      {i2=-9223372036854775806, i1=1} {i1-i2}      9223372036854775807
+  test_expr expr-1.226\
+      {i2=-9223372036854775806, i1=2} {i1-i2}      9.22337203685478e+18
+  test_expr expr-1.227\
+      {i2=-9223372036854775806, i1=100000} {i1-i2} 9.22337203685488e+18
+  test_expr expr-1.228\
+      {i2=-9223372036854775807, i1=0} {i1-i2}      9223372036854775807
+  test_expr expr-1.229\
+      {i2=-9223372036854775807, i1=1} {i1-i2}      9.22337203685478e+18
+  test_expr expr-1.230\
+      {i1=-9223372036854775807, i2=1} {i1-i2}    -9223372036854775808
+  test_expr expr-1.231\
+      {i1=-9223372036854775807, i2=2} {i1-i2}    -9.22337203685478e+18
+  test_expr expr-1.232\
+      {i1=-9223372036854775807, i2=100000} {i1-i2} -9.22337203685488e+18
+  test_expr expr-1.233\
+      {i1=-9223372036854775808, i2=0} {i1-i2}     -9223372036854775808
+  test_expr expr-1.234\
+      {i1=-9223372036854775808, i2=1} {i1-i2}    -9.22337203685478e+18
+  test_expr expr-1.235\
+      {i2=9223372036854775807, i1=-1} {i1-i2}    -9223372036854775808
+  test_expr expr-1.236\
+      {i2=9223372036854775807, i1=-2} {i1-i2}    -9.22337203685478e+18
+  test_expr expr-1.237\
+      {i2=9223372036854775807, i1=-100000} {i1-i2} -9.22337203685488e+18
+  test_expr expr-1.238\
+      {i2=9223372036854775807, i1=0} {i1-i2}     -9223372036854775807
+  test_expr expr-1.239\
+      {i2=9223372036854775807, i1=-1} {i1-i2}    -9223372036854775808
+
+  test_expr expr-1.250\
+      {i1=4294967296, i2=2147483648} {i1*i2}      9.22337203685478e+18
+  test_expr expr-1.251\
+      {i1=4294967296, i2=2147483647} {i1*i2}      9223372032559808512
+  test_expr expr-1.252\
+      {i1=-4294967296, i2=2147483648} {i1*i2}     -9223372036854775808
+  test_expr expr-1.253\
+      {i1=-4294967296, i2=2147483647} {i1*i2}     -9223372032559808512
+  test_expr expr-1.254\
+      {i1=4294967296, i2=-2147483648} {i1*i2}     -9223372036854775808
+  test_expr expr-1.255\
+      {i1=4294967296, i2=-2147483647} {i1*i2}     -9223372032559808512
+  test_expr expr-1.256\
+      {i1=-4294967296, i2=-2147483648} {i1*i2}    9.22337203685478e+18
+  test_expr expr-1.257\
+      {i1=-4294967296, i2=-2147483647} {i1*i2}    9223372032559808512
+
+}}
+
 ifcapable floatingpoint {
   test_expr expr-2.1 {r1=1.23, r2=2.34} {r1+r2} 3.57
   test_expr expr-2.2 {r1=1.23, r2=2.34} {r1-r2} -1.11