]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Avoid signed integer overflow when dealing with a LIMIT and OFFSET whose
authordrh <drh@noemail.net>
Sat, 10 Dec 2016 04:06:49 +0000 (04:06 +0000)
committerdrh <drh@noemail.net>
Sat, 10 Dec 2016 04:06:49 +0000 (04:06 +0000)
sum exceeds the maximum integer value.

FossilOrigin-Name: c9bdf7adb4745cfaf23d9afd496e71fa37793108

manifest
manifest.uuid
src/vdbe.c

index 45507e32cb746703ff5d1a5ef5093eaadf84277f..a09f854f7142ffe9afb41b20488834dca58b441c 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C When\sdoing\sthe\ssqlite3BtreeInsert()\soverwrite\soptimization,\smake\ssure\sthe\nmemcpy()\sdoes\snot\sextend\soff\sthe\send\sof\sthe\spage.
-D 2016-12-09T19:42:18.129
+C Avoid\ssigned\sinteger\soverflow\swhen\sdealing\swith\sa\sLIMIT\sand\sOFFSET\swhose\nsum\sexceeds\sthe\smaximum\sinteger\svalue.
+D 2016-12-10T04:06:49.278
 F Makefile.in 7639c6a09da11a9c7c6f2630fc981ee588d1072d
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc b8ca53350ae545e3562403d5da2a69cec79308da
@@ -455,7 +455,7 @@ F src/update.c 1da7c462110bffed442a42884cb0d528c1db46d8
 F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c
 F src/util.c e68e8ced7328f22d2cf7b4c898c394a0de34cdf1
 F src/vacuum.c 33c174b28886b2faf26e503b5a49a1c01a9b1c16
-F src/vdbe.c 3986f226945b14b98eb26bd589de3705223c95ad
+F src/vdbe.c 74a0b006d478fa2473aba99c7ead716853686bfb
 F src/vdbe.h 0c74f6305fb43b9b282dacaff102272370e327d4
 F src/vdbeInt.h 9b498d3cb52dc2efb53571fb8ae8e14cf298ce84
 F src/vdbeapi.c ea4e2dc2213cc6bd7bee375a29a9b51c31b93ae0
@@ -1536,7 +1536,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P c1f0ae9d2981a19875103750379ad26f2575f878
-R 956ba83a1c02ce8b54106bed68f282ac
+P 684ef4582ed19b2af22dda6fc085c70464f92f1b
+R 385b2371f29bb67ef698b575b58999ac
 U drh
-Z 1db7deef38744b5038e919d70ebcde44
+Z 61eef24c866f9763195673d062edf64e
index ea8d54ff5bbfb0f2b4d8a652a142b148d4b6f9d9..81c1cc2c038ae092f6689faca7e0d1c60f414dd9 100644 (file)
@@ -1 +1 @@
-684ef4582ed19b2af22dda6fc085c70464f92f1b
\ No newline at end of file
+c9bdf7adb4745cfaf23d9afd496e71fa37793108
\ No newline at end of file
index 86088905f45d42fdd87b0f568f12329c1990fee5..6b39ac54a178de585d3f8cd4de49204c3ce04d57 100644 (file)
@@ -5991,12 +5991,25 @@ case OP_IfPos: {        /* jump, in1 */
 ** Otherwise, r[P2] is set to the sum of r[P1] and r[P3].
 */
 case OP_OffsetLimit: {    /* in1, out2, in3 */
+  i64 x;
   pIn1 = &aMem[pOp->p1];
   pIn3 = &aMem[pOp->p3];
   pOut = out2Prerelease(p, pOp);
   assert( pIn1->flags & MEM_Int );
   assert( pIn3->flags & MEM_Int );
-  pOut->u.i = pIn1->u.i<=0 ? -1 : pIn1->u.i+(pIn3->u.i>0?pIn3->u.i:0);
+  x = pIn1->u.i;
+  if( x<=0 || sqlite3AddInt64(&x, pIn3->u.i>0?pIn3->u.i:0) ){
+    /* If the LIMIT is less than or equal to zero, loop forever.  This
+    ** is documented.  But also, if the LIMIT+OFFSET exceeds 2^63 then
+    ** also loop forever.  This is undocumented.  In fact, one could argue
+    ** that the loop should terminate.  But assuming 1 billion iterations
+    ** per second (far exceeding the capabilities of any current hardware)
+    ** it would take nearly 300 years to actually reach the limit.  So
+    ** looping forever is a reasonable approximation. */
+    pOut->u.i = -1;
+  }else{
+    pOut->u.i = x;
+  }
   break;
 }