/ Check-in [6a049c65]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Make sure the OP_ForceInt vdbe opcode does not cause a rowid overflow. Ticket #3536. Tests to verify this change will be checked in separately. (CVS 6022)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:6a049c6595550c123e77199cf7f3898bfcf40c86
User & Date: drh 2008-12-11 19:50:19
Context
2008-12-11
20:03
Previous change to the OP_ForceInt opcode did not work correctly when the input is a negative floating point value. This change is the fix. Ticket #3536. (CVS 6023) check-in: f6c50f35 user: drh tags: trunk
19:50
Make sure the OP_ForceInt vdbe opcode does not cause a rowid overflow. Ticket #3536. Tests to verify this change will be checked in separately. (CVS 6022) check-in: 6a049c65 user: drh tags: trunk
16:17
Guard against attacks from deliberately corrupted database files. (CVS 6021) check-in: da2ec964 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

    39     39   **
    40     40   ** Various scripts scan this source file in order to generate HTML
    41     41   ** documentation, headers files, or other derived files.  The formatting
    42     42   ** of the code in this file is, therefore, important.  See other comments
    43     43   ** in this file for details.  If in doubt, do not deviate from existing
    44     44   ** commenting and indentation practices when changing or adding code.
    45     45   **
    46         -** $Id: vdbe.c,v 1.799 2008/12/11 16:17:04 drh Exp $
           46  +** $Id: vdbe.c,v 1.800 2008/12/11 19:50:19 drh Exp $
    47     47   */
    48     48   #include "sqliteInt.h"
    49     49   #include <ctype.h>
    50     50   #include "vdbeInt.h"
    51     51   
    52     52   /*
    53     53   ** The following global variable is incremented every time a cursor
................................................................................
  1437   1437     break;
  1438   1438   }
  1439   1439   
  1440   1440   /* Opcode: ForceInt P1 P2 P3 * *
  1441   1441   **
  1442   1442   ** Convert value in register P1 into an integer.  If the value 
  1443   1443   ** in P1 is not numeric (meaning that is is a NULL or a string that
  1444         -** does not look like an integer or floating point number) then
  1445         -** jump to P2.  If the value in P1 is numeric then
  1446         -** convert it into the least integer that is greater than or equal to its
  1447         -** current value if P3==0, or to the least integer that is strictly
  1448         -** greater than its current value if P3==1.
         1444  +** does not look like an integer) then jump to P2.
         1445  +**
         1446  +** If the value in P1 is numeric then convert it into the smallest
         1447  +** integer that is greater than or equal to its current value if P3==0, 
         1448  +** or to the smallest integer that is strictly greater than its current
         1449  +** value if P3==1.
         1450  +**
         1451  +** If the conversion described in the previous paragraph causes the
         1452  +** value to exceed the largest possible integer value 
         1453  +** (9223372036854775807), then jump to P2.
  1449   1454   */
  1450   1455   case OP_ForceInt: {            /* jump, in1 */
  1451         -  i64 v;
         1456  +  i64 v;                       /* The value to store in P1 */
         1457  +  int incrV = 0;               /* True to cause v to increment */
  1452   1458     applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
  1453   1459     if( (pIn1->flags & (MEM_Int|MEM_Real))==0 ){
  1454   1460       pc = pOp->p2 - 1;
  1455   1461       break;
  1456   1462     }
         1463  +  incrV = pOp->p3 ?1:0;
  1457   1464     if( pIn1->flags & MEM_Int ){
  1458         -    v = pIn1->u.i + (pOp->p3!=0);
         1465  +    v = pIn1->u.i;
  1459   1466     }else{
  1460   1467       assert( pIn1->flags & MEM_Real );
  1461   1468       v = (sqlite3_int64)pIn1->r;
  1462         -    if( pIn1->r>(double)v ) v++;
  1463         -    if( pOp->p3 && pIn1->r==(double)v ) v++;
         1469  +    if( pIn1->r>(double)v ){
         1470  +      incrV = 1;
         1471  +    }
         1472  +  }
         1473  +  if( incrV ){
         1474  +    if( v==LARGEST_INT64 ){
         1475  +      pc = pOp->p2 - 1;
         1476  +      break;
         1477  +    }
         1478  +    v++;
  1464   1479     }
  1465   1480     pIn1->u.i = v;
  1466   1481     MemSetTypeFlag(pIn1, MEM_Int);
  1467   1482     break;
  1468   1483   }
  1469   1484   
  1470   1485   /* Opcode: MustBeInt P1 P2 * * *