SQLite

Check-in [6a049c6595]
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
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 6a049c6595550c123e77199cf7f3898bfcf40c86
User & Date: drh 2008-12-11 19:50:19.000
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: f6c50f357c 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: 6a049c6595 user: drh tags: trunk)
16:17
Guard against attacks from deliberately corrupted database files. (CVS 6021) (check-in: da2ec96422 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/vdbe.c.
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.799 2008/12/11 16:17:04 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
**
** Various scripts scan this source file in order to generate HTML
** documentation, headers files, or other derived files.  The formatting
** of the code in this file is, therefore, important.  See other comments
** in this file for details.  If in doubt, do not deviate from existing
** commenting and indentation practices when changing or adding code.
**
** $Id: vdbe.c,v 1.800 2008/12/11 19:50:19 drh Exp $
*/
#include "sqliteInt.h"
#include <ctype.h>
#include "vdbeInt.h"

/*
** The following global variable is incremented every time a cursor
1437
1438
1439
1440
1441
1442
1443
1444

1445
1446
1447
1448




1449
1450
1451

1452
1453
1454
1455
1456

1457
1458
1459
1460
1461
1462





1463



1464
1465
1466
1467
1468
1469
1470
  break;
}

/* Opcode: ForceInt P1 P2 P3 * *
**
** Convert value in register P1 into an integer.  If the value 
** in P1 is not numeric (meaning that is is a NULL or a string that
** does not look like an integer or floating point number) then

** jump to P2.  If the value in P1 is numeric then
** convert it into the least integer that is greater than or equal to its
** current value if P3==0, or to the least integer that is strictly
** greater than its current value if P3==1.




*/
case OP_ForceInt: {            /* jump, in1 */
  i64 v;

  applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
  if( (pIn1->flags & (MEM_Int|MEM_Real))==0 ){
    pc = pOp->p2 - 1;
    break;
  }

  if( pIn1->flags & MEM_Int ){
    v = pIn1->u.i + (pOp->p3!=0);
  }else{
    assert( pIn1->flags & MEM_Real );
    v = (sqlite3_int64)pIn1->r;
    if( pIn1->r>(double)v ) v++;





    if( pOp->p3 && pIn1->r==(double)v ) v++;



  }
  pIn1->u.i = v;
  MemSetTypeFlag(pIn1, MEM_Int);
  break;
}

/* Opcode: MustBeInt P1 P2 * * *







|
>
|
|
|
|
>
>
>
>


|
>





>

|



|
>
>
>
>
>
|
>
>
>







1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
  break;
}

/* Opcode: ForceInt P1 P2 P3 * *
**
** Convert value in register P1 into an integer.  If the value 
** in P1 is not numeric (meaning that is is a NULL or a string that
** does not look like an integer) then jump to P2.
**
** If the value in P1 is numeric then convert it into the smallest
** integer that is greater than or equal to its current value if P3==0, 
** or to the smallest integer that is strictly greater than its current
** value if P3==1.
**
** If the conversion described in the previous paragraph causes the
** value to exceed the largest possible integer value 
** (9223372036854775807), then jump to P2.
*/
case OP_ForceInt: {            /* jump, in1 */
  i64 v;                       /* The value to store in P1 */
  int incrV = 0;               /* True to cause v to increment */
  applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
  if( (pIn1->flags & (MEM_Int|MEM_Real))==0 ){
    pc = pOp->p2 - 1;
    break;
  }
  incrV = pOp->p3 ?1:0;
  if( pIn1->flags & MEM_Int ){
    v = pIn1->u.i;
  }else{
    assert( pIn1->flags & MEM_Real );
    v = (sqlite3_int64)pIn1->r;
    if( pIn1->r>(double)v ){
      incrV = 1;
    }
  }
  if( incrV ){
    if( v==LARGEST_INT64 ){
      pc = pOp->p2 - 1;
      break;
    }
    v++;
  }
  pIn1->u.i = v;
  MemSetTypeFlag(pIn1, MEM_Int);
  break;
}

/* Opcode: MustBeInt P1 P2 * * *