/ 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 Unified Diffs Ignore Whitespace Patch

Changes to src/vdbe.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
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
**
** 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
................................................................................
  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 * * *







|







 







|
>
|
|
<
>
|
>
>
>
>


<
>
>





>

|



|
|
>
>
>
>
>
>
>
>







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
....
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
**
** 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
................................................................................
  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 * * *