mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
Fix all known instances of signed-integer overflow. Within SQL expressions,
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
This commit is contained in:
32
manifest
32
manifest
@ -1,8 +1,8 @@
|
|||||||
-----BEGIN PGP SIGNED MESSAGE-----
|
-----BEGIN PGP SIGNED MESSAGE-----
|
||||||
Hash: SHA1
|
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.
|
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-05T13:54:15.956
|
D 2011-03-05T20:59:46.394
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f
|
F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@ -133,10 +133,10 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
|
|||||||
F src/ctime.c 7deec4534f3b5a0c3b4a4cbadf809d321f64f9c4
|
F src/ctime.c 7deec4534f3b5a0c3b4a4cbadf809d321f64f9c4
|
||||||
F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b
|
F src/date.c 1548fdac51377e4e7833251de878b4058c148e1b
|
||||||
F src/delete.c 7ed8a8c8b5f748ece92df173d7e0f7810c899ebd
|
F src/delete.c 7ed8a8c8b5f748ece92df173d7e0f7810c899ebd
|
||||||
F src/expr.c 0afd6a93d95614e57b29d1c6da5f74be5a4d4fbd
|
F src/expr.c 66c9383e5e1f5259c43ef3aa7883da66cfc0f492
|
||||||
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
|
||||||
F src/fkey.c 17950a28f28b23e8ad3feaac5fc88c324d2f600a
|
F src/fkey.c 17950a28f28b23e8ad3feaac5fc88c324d2f600a
|
||||||
F src/func.c 9b88e09d238eecdb6242bd387901e6d9f7f64531
|
F src/func.c 3a8cb2fb2de3e3aed7f39106daf4878d9d17fcce
|
||||||
F src/global.c 02335177cf6946fe5525c6f0755cf181140debf3
|
F src/global.c 02335177cf6946fe5525c6f0755cf181140debf3
|
||||||
F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af
|
F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af
|
||||||
F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
|
F src/hash.h 2894c932d84d9f892d4b4023a75e501f83050970
|
||||||
@ -175,7 +175,7 @@ F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
|
|||||||
F src/pcache1.c d548e31beafa792d1994b663a29a5303569efc4e
|
F src/pcache1.c d548e31beafa792d1994b663a29a5303569efc4e
|
||||||
F src/pragma.c a83f320497aee18eda60fc8d854df5897906c2b1
|
F src/pragma.c a83f320497aee18eda60fc8d854df5897906c2b1
|
||||||
F src/prepare.c 395b3fab1b93f45b6aa194b23ebc201221c47b99
|
F src/prepare.c 395b3fab1b93f45b6aa194b23ebc201221c47b99
|
||||||
F src/printf.c 6eb5c70b531464cca4254e70aaafdf2e7da3a743
|
F src/printf.c 585a36b6a963df832cfb69505afa3a34ed5ef8a1
|
||||||
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
F src/random.c cd4a67b3953b88019f8cd4ccd81394a8ddfaba50
|
||||||
F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706
|
F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706
|
||||||
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
||||||
@ -183,7 +183,7 @@ F src/select.c d24406c45dd2442eb2eeaac413439066b149c944
|
|||||||
F src/shell.c 649c51979812f77f97507024a4cea480c6862b8b
|
F src/shell.c 649c51979812f77f97507024a4cea480c6862b8b
|
||||||
F src/sqlite.h.in ccb23cc9378874c7c72682b739f311474a80848d
|
F src/sqlite.h.in ccb23cc9378874c7c72682b739f311474a80848d
|
||||||
F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754
|
F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754
|
||||||
F src/sqliteInt.h 4290fff17fabc6e07fc4338233df0e39e6350ca1
|
F src/sqliteInt.h 118481da7db00c4ae2709ed8af6498be900e6ae0
|
||||||
F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44
|
F src/sqliteLimit.h a17dcd3fb775d63b64a43a55c54cb282f9726f44
|
||||||
F src/status.c 4997380fbb915426fef9e500b4872e79c99267fc
|
F src/status.c 4997380fbb915426fef9e500b4872e79c99267fc
|
||||||
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
|
||||||
@ -231,15 +231,15 @@ F src/tokenize.c 604607d6813e9551cf5189d899e0a25c12681080
|
|||||||
F src/trigger.c b8bedb9c0084ceb51a40f54fcca2ce048c8de852
|
F src/trigger.c b8bedb9c0084ceb51a40f54fcca2ce048c8de852
|
||||||
F src/update.c c40aedd40baf460806f1c9f2cbe4a1dac445ee91
|
F src/update.c c40aedd40baf460806f1c9f2cbe4a1dac445ee91
|
||||||
F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685
|
F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685
|
||||||
F src/util.c 77572d1f37c5b319d9e735c745349304791f7ba5
|
F src/util.c c849a1e77d00a8a28429a22818155dbf9c311fee
|
||||||
F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f
|
F src/vacuum.c 924bd1bcee2dfb05376f79845bd3b4cec7b54b2f
|
||||||
F src/vdbe.c 953d44f0fbd72bf73a278c10e7bdd9164235260d
|
F src/vdbe.c 038e5689e48cd6597158c5dc34f8d40a03a87ad7
|
||||||
F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2
|
F src/vdbe.h 4de0efb4b0fdaaa900cf419b35c458933ef1c6d2
|
||||||
F src/vdbeInt.h 6e6f28e9bccc6c703dca1372fd661c57b5c15fb0
|
F src/vdbeInt.h 6e6f28e9bccc6c703dca1372fd661c57b5c15fb0
|
||||||
F src/vdbeapi.c 8e9324fd35eb70d0b5904bd1af40f2598744dc4d
|
F src/vdbeapi.c 8e9324fd35eb70d0b5904bd1af40f2598744dc4d
|
||||||
F src/vdbeaux.c 3ce2588ffe921e457d00baee7dd409afabe8c8af
|
F src/vdbeaux.c 3ce2588ffe921e457d00baee7dd409afabe8c8af
|
||||||
F src/vdbeblob.c 18955f0ee6b133cd08e1592010cb9a6b11e9984c
|
F src/vdbeblob.c 18955f0ee6b133cd08e1592010cb9a6b11e9984c
|
||||||
F src/vdbemem.c 0fa2ed786cd207d5b988afef3562a8e663a75b50
|
F src/vdbemem.c d8f713bcc3e176040d3e2bb4fbffc3b31faa4252
|
||||||
F src/vdbetrace.c 3ba13bc32bdf16d2bdea523245fd16736bed67b5
|
F src/vdbetrace.c 3ba13bc32bdf16d2bdea523245fd16736bed67b5
|
||||||
F src/vtab.c b297e8fa656ab5e66244ab15680d68db0adbec30
|
F src/vtab.c b297e8fa656ab5e66244ab15680d68db0adbec30
|
||||||
F src/wal.c 5386fb5e13c2daa8ab9062597fdc17bd849da371
|
F src/wal.c 5386fb5e13c2daa8ab9062597fdc17bd849da371
|
||||||
@ -383,7 +383,7 @@ F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3
|
|||||||
F test/exclusive.test 53e1841b422e554cecf0160f937c473d6d0e3062
|
F test/exclusive.test 53e1841b422e554cecf0160f937c473d6d0e3062
|
||||||
F test/exclusive2.test 343d55130c12c67b8bf10407acec043a6c26c86b
|
F test/exclusive2.test 343d55130c12c67b8bf10407acec043a6c26c86b
|
||||||
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
|
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
|
||||||
F test/expr.test 620a636cf7b7d4e5834a0b9d83a4da372e24a7b7
|
F test/expr.test 19e8ac40313e2282a47b586d11c4892040990d3a
|
||||||
F test/fallocate.test 43dc34b8c24be6baffadc3b4401ee15710ce83c6
|
F test/fallocate.test 43dc34b8c24be6baffadc3b4401ee15710ce83c6
|
||||||
F test/filectrl.test 97003734290887566e01dded09dc9e99cb937e9e
|
F test/filectrl.test 97003734290887566e01dded09dc9e99cb937e9e
|
||||||
F test/filefmt.test f178cfc29501a14565954c961b226e61877dd32c
|
F test/filefmt.test f178cfc29501a14565954c961b226e61877dd32c
|
||||||
@ -914,14 +914,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
|||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||||
P 952f5e8c69904c48f2decfabf8ea60a2e9f3e134
|
P 04abab71ecd52f6070b9f84781a3df3d6dba7722
|
||||||
R c0946fb5d31ae3d41275b61febc12359
|
R dffbfc883d2df8713fd0ba30b453b561
|
||||||
U drh
|
U drh
|
||||||
Z 4b81d66afc295ddd153d99c651678bf2
|
Z e566f37c8f9e6003556e493773a7db62
|
||||||
-----BEGIN PGP SIGNATURE-----
|
-----BEGIN PGP SIGNATURE-----
|
||||||
Version: GnuPG v1.4.6 (GNU/Linux)
|
Version: GnuPG v1.4.6 (GNU/Linux)
|
||||||
|
|
||||||
iD8DBQFNckCLoxKgR168RlERAq5MAJwIkQItYpj2jIMbedpVkYZIN7SirACePysg
|
iD8DBQFNcqRGoxKgR168RlERAlK6AJ9gnf6EDR2ZKhaKkoiA1Nkl5MKeDgCeOJxY
|
||||||
Jf8UO88YpxqtY86joGQ7FqQ=
|
dz92w6QJZQImuyiplDh238s=
|
||||||
=f5iN
|
=sTB2
|
||||||
-----END PGP SIGNATURE-----
|
-----END PGP SIGNATURE-----
|
||||||
|
@ -1 +1 @@
|
|||||||
04abab71ecd52f6070b9f84781a3df3d6dba7722
|
abf21394124a0af46f072793718964cee2ce55d0
|
@ -1964,7 +1964,7 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){
|
|||||||
c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8);
|
c = sqlite3Atoi64(z, &value, sqlite3Strlen30(z), SQLITE_UTF8);
|
||||||
if( c==0 || (c==2 && negFlag) ){
|
if( c==0 || (c==2 && negFlag) ){
|
||||||
char *zV;
|
char *zV;
|
||||||
if( negFlag ){ value = -value; } /* CLANG */
|
if( negFlag ){ value = c==2 ? SMALLEST_INT64 : -value; }
|
||||||
zV = dup8bytes(v, (char*)&value);
|
zV = dup8bytes(v, (char*)&value);
|
||||||
sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64);
|
sqlite3VdbeAddOp4(v, OP_Int64, 0, iMem, 0, zV, P4_INT64);
|
||||||
}else{
|
}else{
|
||||||
|
@ -1239,13 +1239,8 @@ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
|
|||||||
if( type==SQLITE_INTEGER ){
|
if( type==SQLITE_INTEGER ){
|
||||||
i64 v = sqlite3_value_int64(argv[0]);
|
i64 v = sqlite3_value_int64(argv[0]);
|
||||||
p->rSum += v;
|
p->rSum += v;
|
||||||
if( (p->approx|p->overflow)==0 ){
|
if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){
|
||||||
i64 iNewSum = p->iSum + v; /* CLANG */
|
p->overflow = 1;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
p->rSum += sqlite3_value_double(argv[0]);
|
p->rSum += sqlite3_value_double(argv[0]);
|
||||||
|
@ -400,7 +400,11 @@ void sqlite3VXPrintf(
|
|||||||
v = va_arg(ap,int);
|
v = va_arg(ap,int);
|
||||||
}
|
}
|
||||||
if( v<0 ){
|
if( v<0 ){
|
||||||
longvalue = -v; /* CLANG */
|
if( v==SMALLEST_INT64 ){
|
||||||
|
longvalue = ((u64)1)<<63;
|
||||||
|
}else{
|
||||||
|
longvalue = -v;
|
||||||
|
}
|
||||||
prefix = '-';
|
prefix = '-';
|
||||||
}else{
|
}else{
|
||||||
longvalue = v;
|
longvalue = v;
|
||||||
|
@ -2903,6 +2903,9 @@ Expr *sqlite3ExprSetCollByToken(Parse *pParse, Expr*, Token*);
|
|||||||
int sqlite3CheckCollSeq(Parse *, CollSeq *);
|
int sqlite3CheckCollSeq(Parse *, CollSeq *);
|
||||||
int sqlite3CheckObjectName(Parse *, const char *);
|
int sqlite3CheckObjectName(Parse *, const char *);
|
||||||
void sqlite3VdbeSetChanges(sqlite3 *, int);
|
void sqlite3VdbeSetChanges(sqlite3 *, int);
|
||||||
|
int sqlite3AddInt64(i64*,i64);
|
||||||
|
int sqlite3SubInt64(i64*,i64);
|
||||||
|
int sqlite3MulInt64(i64*,i64);
|
||||||
|
|
||||||
const void *sqlite3ValueText(sqlite3_value*, u8);
|
const void *sqlite3ValueText(sqlite3_value*, u8);
|
||||||
int sqlite3ValueBytes(sqlite3_value*, u8);
|
int sqlite3ValueBytes(sqlite3_value*, u8);
|
||||||
|
128
src/util.c
128
src/util.c
@ -441,14 +441,17 @@ static int compare2pow63(const char *zNum, int incr){
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Convert zNum to a 64-bit signed integer and write
|
** Convert zNum to a 64-bit signed integer.
|
||||||
** the value of the integer into *pNum.
|
**
|
||||||
** If zNum is exactly 9223372036854665808, return 2.
|
** If the zNum value is representable as a 64-bit twos-complement
|
||||||
** This is a special case as the context will determine
|
** integer, then write that value into *pNum and return 0.
|
||||||
** if it is too big (used as a negative).
|
**
|
||||||
** If zNum is not an integer or is an integer that
|
** If zNum is exactly 9223372036854665808, return 2. This special
|
||||||
** is too large to be expressed with 64 bits,
|
** case is broken out because while 9223372036854665808 cannot be a
|
||||||
** then return 1. Otherwise return 0.
|
** 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).
|
** length is the number of bytes in the string (bytes, not characters).
|
||||||
** The string is not necessarily zero-terminated. The encoding is
|
** 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 sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
|
||||||
int incr = (enc==SQLITE_UTF8?1:2);
|
int incr = (enc==SQLITE_UTF8?1:2);
|
||||||
i64 v = 0;
|
u64 u = 0;
|
||||||
int neg = 0; /* assume positive */
|
int neg = 0; /* assume positive */
|
||||||
int i;
|
int i;
|
||||||
int c = 0;
|
int c = 0;
|
||||||
@ -464,20 +467,26 @@ int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){
|
|||||||
const char *zEnd = zNum + length;
|
const char *zEnd = zNum + length;
|
||||||
if( enc==SQLITE_UTF16BE ) zNum++;
|
if( enc==SQLITE_UTF16BE ) zNum++;
|
||||||
while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
|
while( zNum<zEnd && sqlite3Isspace(*zNum) ) zNum+=incr;
|
||||||
if( zNum>=zEnd ) goto do_atoi_calc;
|
if( zNum<zEnd ){
|
||||||
if( *zNum=='-' ){
|
if( *zNum=='-' ){
|
||||||
neg = 1;
|
neg = 1;
|
||||||
zNum+=incr;
|
zNum+=incr;
|
||||||
}else if( *zNum=='+' ){
|
}else if( *zNum=='+' ){
|
||||||
zNum+=incr;
|
zNum+=incr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
do_atoi_calc:
|
|
||||||
zStart = zNum;
|
zStart = zNum;
|
||||||
while( zNum<zEnd && zNum[0]=='0' ){ zNum+=incr; } /* Skip leading zeros. */
|
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){
|
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==18 );
|
||||||
testcase( i==19 );
|
testcase( i==19 );
|
||||||
testcase( i==20 );
|
testcase( i==20 );
|
||||||
@ -487,14 +496,25 @@ do_atoi_calc:
|
|||||||
return 1;
|
return 1;
|
||||||
}else if( i<19*incr ){
|
}else if( i<19*incr ){
|
||||||
/* Less than 19 digits, so we know that it fits in 64 bits */
|
/* Less than 19 digits, so we know that it fits in 64 bits */
|
||||||
|
assert( u<=LARGEST_INT64 );
|
||||||
return 0;
|
return 0;
|
||||||
}else{
|
}else{
|
||||||
/* 19-digit numbers must be no larger than 9223372036854775807 if positive
|
/* zNum is a 19-digit numbers. Compare it against 9223372036854775808. */
|
||||||
** or 9223372036854775808 if negative. Note that 9223372036854665808
|
c = compare2pow63(zNum, incr);
|
||||||
** is 2^63. Return 1 if to large */
|
if( c<0 ){
|
||||||
c=compare2pow63(zNum, incr);
|
/* zNum is less than 9223372036854775808 so it fits */
|
||||||
if( c==0 && neg==0 ) return 2; /* too big, exactly 9223372036854665808 */
|
assert( u<=LARGEST_INT64 );
|
||||||
return c<neg ? 0 : 1;
|
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;
|
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;
|
||||||
|
}
|
||||||
|
62
src/vdbe.c
62
src/vdbe.c
@ -1246,19 +1246,12 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
|
|||||||
iA = pIn1->u.i;
|
iA = pIn1->u.i;
|
||||||
iB = pIn2->u.i;
|
iB = pIn2->u.i;
|
||||||
switch( pOp->opcode ){
|
switch( pOp->opcode ){
|
||||||
case OP_Add: iB += iA; break; /* CLANG */
|
case OP_Add: if( sqlite3AddInt64(&iB,iA) ) goto fp_math; break;
|
||||||
case OP_Subtract: iB -= iA; break;
|
case OP_Subtract: if( sqlite3SubInt64(&iB,iA) ) goto fp_math; break;
|
||||||
case OP_Multiply: iB *= iA; break;
|
case OP_Multiply: if( sqlite3MulInt64(&iB,iA) ) goto fp_math; break;
|
||||||
case OP_Divide: {
|
case OP_Divide: {
|
||||||
if( iA==0 ) goto arithmetic_result_is_null;
|
if( iA==0 ) goto arithmetic_result_is_null;
|
||||||
/* Dividing the largest possible negative 64-bit integer (1<<63) by
|
if( iA==-1 && iB==SMALLEST_INT64 ) goto fp_math;
|
||||||
** -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;
|
|
||||||
iB /= iA;
|
iB /= iA;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1272,6 +1265,7 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */
|
|||||||
pOut->u.i = iB;
|
pOut->u.i = iB;
|
||||||
MemSetTypeFlag(pOut, MEM_Int);
|
MemSetTypeFlag(pOut, MEM_Int);
|
||||||
}else{
|
}else{
|
||||||
|
fp_math:
|
||||||
rA = sqlite3VdbeRealValue(pIn1);
|
rA = sqlite3VdbeRealValue(pIn1);
|
||||||
rB = sqlite3VdbeRealValue(pIn2);
|
rB = sqlite3VdbeRealValue(pIn2);
|
||||||
switch( pOp->opcode ){
|
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_BitOr: /* same as TK_BITOR, in1, in2, out3 */
|
||||||
case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, out3 */
|
case OP_ShiftLeft: /* same as TK_LSHIFT, in1, in2, out3 */
|
||||||
case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
|
case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
|
||||||
i64 a;
|
i64 iA;
|
||||||
i64 b;
|
u64 uA;
|
||||||
|
i64 iB;
|
||||||
|
u8 op;
|
||||||
|
|
||||||
pIn1 = &aMem[pOp->p1];
|
pIn1 = &aMem[pOp->p1];
|
||||||
pIn2 = &aMem[pOp->p2];
|
pIn2 = &aMem[pOp->p2];
|
||||||
@ -1476,16 +1472,38 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */
|
|||||||
sqlite3VdbeMemSetNull(pOut);
|
sqlite3VdbeMemSetNull(pOut);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
a = sqlite3VdbeIntValue(pIn2);
|
iA = sqlite3VdbeIntValue(pIn2);
|
||||||
b = sqlite3VdbeIntValue(pIn1);
|
iB = sqlite3VdbeIntValue(pIn1);
|
||||||
switch( pOp->opcode ){
|
op = pOp->opcode;
|
||||||
case OP_BitAnd: a &= b; break;
|
if( op==OP_BitAnd ){
|
||||||
case OP_BitOr: a |= b; break;
|
iA &= iB;
|
||||||
case OP_ShiftLeft: a <<= b; break;
|
}else if( op==OP_BitOr ){
|
||||||
default: assert( pOp->opcode==OP_ShiftRight );
|
iA |= iB;
|
||||||
a >>= b; break;
|
}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);
|
MemSetTypeFlag(pOut, MEM_Int);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -367,7 +367,7 @@ i64 sqlite3VdbeIntValue(Mem *pMem){
|
|||||||
}else if( flags & MEM_Real ){
|
}else if( flags & MEM_Real ){
|
||||||
return doubleToInt64(pMem->r);
|
return doubleToInt64(pMem->r);
|
||||||
}else if( flags & (MEM_Str|MEM_Blob) ){
|
}else if( flags & (MEM_Str|MEM_Blob) ){
|
||||||
i64 value;
|
i64 value = 0;
|
||||||
assert( pMem->z || pMem->n==0 );
|
assert( pMem->z || pMem->n==0 );
|
||||||
testcase( pMem->z==0 );
|
testcase( pMem->z==0 );
|
||||||
sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
|
sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
|
||||||
|
119
test/expr.test
119
test/expr.test
@ -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.43b {i1=1, i2=2} {4&5} {4}
|
||||||
test_expr expr-1.44 {i1=1} {~i1} {-2}
|
test_expr expr-1.44 {i1=1} {~i1} {-2}
|
||||||
test_expr expr-1.44b {i1=NULL} {~i1} {{}}
|
test_expr expr-1.44b {i1=NULL} {~i1} {{}}
|
||||||
test_expr expr-1.45 {i1=1, i2=3} {i1<<i2} {8}
|
test_expr expr-1.45a {i1=1, i2=3} {i1<<i2} {8}
|
||||||
test_expr expr-1.46 {i1=32, i2=3} {i1>>i2} {4}
|
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.47 {i1=9999999999, i2=8888888888} {i1<i2} 0
|
||||||
test_expr expr-1.48 {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
|
test_expr expr-1.49 {i1=9999999999, i2=8888888888} {i1>i2} 1
|
||||||
@ -154,10 +164,10 @@ ifcapable floatingpoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if {[working_64bit_int]} {
|
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.108 {i1=0} {1%0} {{}}
|
||||||
test_expr expr-1.109 {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} \
|
test_expr expr-1.126 {i1=8, i2=8} \
|
||||||
{CASE WHEN i1 IS NOT i2 THEN 'yes' ELSE 'no' END} no
|
{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 {
|
ifcapable floatingpoint {
|
||||||
test_expr expr-2.1 {r1=1.23, r2=2.34} {r1+r2} 3.57
|
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
|
test_expr expr-2.2 {r1=1.23, r2=2.34} {r1-r2} -1.11
|
||||||
|
Reference in New Issue
Block a user