mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Take care that a corrupt variable-length integer does not cause 32-bit
integer overflow when parsing a record format, nor cause excessively large memory allocations. (CVS 6719) FossilOrigin-Name: 38b20327a80996c7044b88be32161ac4ac0ec3a9
This commit is contained in:
22
manifest
22
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Earlier\sdetection\sof\sfreelist\scorruption\sin\sthe\spage\sallocation\sroutines.\s(CVS\s6718)
|
C Take\scare\sthat\sa\scorrupt\svariable-length\sinteger\sdoes\snot\scause\s32-bit\ninteger\soverflow\swhen\sparsing\sa\srecord\sformat,\snor\scause\sexcessively\slarge\nmemory\sallocations.\s(CVS\s6719)
|
||||||
D 2009-06-04T19:06:10
|
D 2009-06-05T14:17:22
|
||||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||||
F Makefile.in 8b8fb7823264331210cddf103831816c286ba446
|
F Makefile.in 8b8fb7823264331210cddf103831816c286ba446
|
||||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||||
@@ -106,7 +106,7 @@ F src/auth.c 98db07c2088455797678eb1031f42d4d94d18a71
|
|||||||
F src/backup.c ff50af53184a5fd7bdee4d620b5dabef74717c79
|
F src/backup.c ff50af53184a5fd7bdee4d620b5dabef74717c79
|
||||||
F src/bitvec.c 0ef0651714728055d43de7a4cdd95e703fac0119
|
F src/bitvec.c 0ef0651714728055d43de7a4cdd95e703fac0119
|
||||||
F src/btmutex.c 9b899c0d8df3bd68f527b0afe03088321b696d3c
|
F src/btmutex.c 9b899c0d8df3bd68f527b0afe03088321b696d3c
|
||||||
F src/btree.c 17ab7af7d250ba51d3b76eaf8b3885cbd8d91f47
|
F src/btree.c 3a0e52943bf32aba524e3811f4bea0a2e59b078f
|
||||||
F src/btree.h f70b694e8c163227369a66863b01fbff9009f323
|
F src/btree.h f70b694e8c163227369a66863b01fbff9009f323
|
||||||
F src/btreeInt.h df64030d632f8c8ac217ed52e8b6b3eacacb33a5
|
F src/btreeInt.h df64030d632f8c8ac217ed52e8b6b3eacacb33a5
|
||||||
F src/build.c 20e02fd72249159ff6829009f3029d16d59cdff5
|
F src/build.c 20e02fd72249159ff6829009f3029d16d59cdff5
|
||||||
@@ -162,7 +162,7 @@ F src/select.c 2d97084a176a63eabce2d043eb4fbb13c46d6e9f
|
|||||||
F src/shell.c db2643650b9268df89a4bedca3f1c6d9e786f1bb
|
F src/shell.c db2643650b9268df89a4bedca3f1c6d9e786f1bb
|
||||||
F src/sqlite.h.in 79210c4d8905cfb4b038486dde5f36fabb796a86
|
F src/sqlite.h.in 79210c4d8905cfb4b038486dde5f36fabb796a86
|
||||||
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
|
F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
|
||||||
F src/sqliteInt.h 474e85cc85f78c18b8dbaec5cb786cdba6b45183
|
F src/sqliteInt.h f8d70341d527404c5f162dc7fcc0f005700d0b48
|
||||||
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
|
F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
|
||||||
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
|
F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
|
||||||
F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d
|
F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d
|
||||||
@@ -201,13 +201,13 @@ F src/tokenize.c 75367c7e4d2aee39a3b0496911284b73de5b4363
|
|||||||
F src/trigger.c c07c5157c58fcdb704f65d5f5e4775276e45bb8b
|
F src/trigger.c c07c5157c58fcdb704f65d5f5e4775276e45bb8b
|
||||||
F src/update.c 6ae6c26adff8dc34532d578f66e6cfde04b5d177
|
F src/update.c 6ae6c26adff8dc34532d578f66e6cfde04b5d177
|
||||||
F src/utf.c 9541d28f40441812c0b40f00334372a0542c00ff
|
F src/utf.c 9541d28f40441812c0b40f00334372a0542c00ff
|
||||||
F src/util.c a9719d309f6c65b3b79fa3ca8512fa8e3947a391
|
F src/util.c 8ff385a6b474e840d4fa3621f5f7263028ac892c
|
||||||
F src/vacuum.c 0e14f371ea3326c6b8cfba257286d798cd20db59
|
F src/vacuum.c 0e14f371ea3326c6b8cfba257286d798cd20db59
|
||||||
F src/vdbe.c d105cc58a6a0fa08a3fade86633e90d57a7a8129
|
F src/vdbe.c 7f8639cf36a0bb87a4e31bc31432f8af10c3b252
|
||||||
F src/vdbe.h 35a648bc3279a120da24f34d9a25213ec15daf8a
|
F src/vdbe.h 35a648bc3279a120da24f34d9a25213ec15daf8a
|
||||||
F src/vdbeInt.h 43183a2a18654fa570219ab65e53a608057c48ae
|
F src/vdbeInt.h 3727128255a93d116e454f67d4559700f7ae4d6f
|
||||||
F src/vdbeapi.c 86aa27a5f3493aaffb8ac051782aa3b22670d7ed
|
F src/vdbeapi.c 86aa27a5f3493aaffb8ac051782aa3b22670d7ed
|
||||||
F src/vdbeaux.c 37730f227a5301c04e5bf03fd303b9086ada990c
|
F src/vdbeaux.c 78ff6c355ccc2d211350f507bccfcd95118169e8
|
||||||
F src/vdbeblob.c c25d7e7bc6d5917feeb17270bd275fa771f26e5c
|
F src/vdbeblob.c c25d7e7bc6d5917feeb17270bd275fa771f26e5c
|
||||||
F src/vdbemem.c 05183d46094aa99b8f8350e5761b9369dbef35a8
|
F src/vdbemem.c 05183d46094aa99b8f8350e5761b9369dbef35a8
|
||||||
F src/vtab.c e2f4c92df7d06330b151448718c4724742ff444b
|
F src/vtab.c e2f4c92df7d06330b151448718c4724742ff444b
|
||||||
@@ -733,7 +733,7 @@ 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 672f81d693a03f80f5ae60bfefacd8a349e76746
|
F tool/vdbe-compress.tcl 672f81d693a03f80f5ae60bfefacd8a349e76746
|
||||||
P 1335e4440f5a3d24ce9ce187e0e23fc9b166ca98
|
P e557c8e5846f9c4eaaeb3bd07614ac101bb0b3d0
|
||||||
R 6fa526d3fc2cd5b05a7afb7c2a31b3a3
|
R aadc9c06bb2a87f3514e9a9c55bcfa54
|
||||||
U drh
|
U drh
|
||||||
Z 24570d1925b89f9799c0bf39f48794de
|
Z 216b11c06f5be02fd997159248e30587
|
||||||
|
@@ -1 +1 @@
|
|||||||
e557c8e5846f9c4eaaeb3bd07614ac101bb0b3d0
|
38b20327a80996c7044b88be32161ac4ac0ec3a9
|
@@ -9,7 +9,7 @@
|
|||||||
** May you share freely, never taking more than you give.
|
** May you share freely, never taking more than you give.
|
||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** $Id: btree.c,v 1.617 2009/06/04 19:06:10 drh Exp $
|
** $Id: btree.c,v 1.618 2009/06/05 14:17:22 drh Exp $
|
||||||
**
|
**
|
||||||
** This file implements a external (disk-based) database using BTrees.
|
** This file implements a external (disk-based) database using BTrees.
|
||||||
** See the header comment on "btreeInt.h" for additional information.
|
** See the header comment on "btreeInt.h" for additional information.
|
||||||
@@ -4393,7 +4393,7 @@ static int allocateBtreePage(
|
|||||||
){
|
){
|
||||||
MemPage *pPage1;
|
MemPage *pPage1;
|
||||||
int rc;
|
int rc;
|
||||||
int n; /* Number of pages on the freelist */
|
u32 n; /* Number of pages on the freelist */
|
||||||
int k; /* Number of leaves on the trunk of the freelist */
|
int k; /* Number of leaves on the trunk of the freelist */
|
||||||
MemPage *pTrunk = 0;
|
MemPage *pTrunk = 0;
|
||||||
MemPage *pPrevTrunk = 0;
|
MemPage *pPrevTrunk = 0;
|
||||||
@@ -4458,10 +4458,6 @@ static int allocateBtreePage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
k = get4byte(&pTrunk->aData[4]);
|
k = get4byte(&pTrunk->aData[4]);
|
||||||
if( k>mxPage ){
|
|
||||||
rc = SQLITE_CORRUPT_BKPT;
|
|
||||||
goto end_allocate_page;
|
|
||||||
}
|
|
||||||
if( k==0 && !searchList ){
|
if( k==0 && !searchList ){
|
||||||
/* The trunk has no leaves and the list is not being searched.
|
/* The trunk has no leaves and the list is not being searched.
|
||||||
** So extract the trunk page itself and use it as the newly
|
** So extract the trunk page itself and use it as the newly
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
*************************************************************************
|
*************************************************************************
|
||||||
** Internal interface definitions for SQLite.
|
** Internal interface definitions for SQLite.
|
||||||
**
|
**
|
||||||
** @(#) $Id: sqliteInt.h,v 1.881 2009/06/02 21:31:39 drh Exp $
|
** @(#) $Id: sqliteInt.h,v 1.882 2009/06/05 14:17:23 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _SQLITEINT_H_
|
#ifndef _SQLITEINT_H_
|
||||||
#define _SQLITEINT_H_
|
#define _SQLITEINT_H_
|
||||||
@@ -431,6 +431,14 @@ typedef INT16_TYPE i16; /* 2-byte signed integer */
|
|||||||
typedef UINT8_TYPE u8; /* 1-byte unsigned integer */
|
typedef UINT8_TYPE u8; /* 1-byte unsigned integer */
|
||||||
typedef INT8_TYPE i8; /* 1-byte signed integer */
|
typedef INT8_TYPE i8; /* 1-byte signed integer */
|
||||||
|
|
||||||
|
/*
|
||||||
|
** SQLITE_MAX_U32 is a u64 constant that is the maximum u64 value
|
||||||
|
** that can be stored in a u32 without loss of data. The value
|
||||||
|
** is 0x00000000ffffffff. But because of quirks of some compilers, we
|
||||||
|
** have to specify the value in the less intuitive manner shown:
|
||||||
|
*/
|
||||||
|
#define SQLITE_MAX_U32 ((((u64)1)<<32)-1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Macros to determine whether the machine is big or little endian,
|
** Macros to determine whether the machine is big or little endian,
|
||||||
** evaluated at runtime.
|
** evaluated at runtime.
|
||||||
|
12
src/util.c
12
src/util.c
@@ -14,7 +14,7 @@
|
|||||||
** This file contains functions for allocating memory, comparing
|
** This file contains functions for allocating memory, comparing
|
||||||
** strings, and stuff like that.
|
** strings, and stuff like that.
|
||||||
**
|
**
|
||||||
** $Id: util.c,v 1.257 2009/05/31 21:21:41 drh Exp $
|
** $Id: util.c,v 1.258 2009/06/05 14:17:23 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@@ -766,6 +766,10 @@ u8 sqlite3GetVarint(const unsigned char *p, u64 *v){
|
|||||||
/*
|
/*
|
||||||
** Read a 32-bit variable-length integer from memory starting at p[0].
|
** Read a 32-bit variable-length integer from memory starting at p[0].
|
||||||
** Return the number of bytes read. The value is stored in *v.
|
** Return the number of bytes read. The value is stored in *v.
|
||||||
|
**
|
||||||
|
** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned
|
||||||
|
** integer, then set *v to 0xffffffff.
|
||||||
|
**
|
||||||
** A MACRO version, getVarint32, is provided which inlines the
|
** A MACRO version, getVarint32, is provided which inlines the
|
||||||
** single-byte case. All code should use the MACRO version as
|
** single-byte case. All code should use the MACRO version as
|
||||||
** this function assumes the single-byte case has already been handled.
|
** this function assumes the single-byte case has already been handled.
|
||||||
@@ -831,7 +835,11 @@ u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){
|
|||||||
p -= 2;
|
p -= 2;
|
||||||
n = sqlite3GetVarint(p, &v64);
|
n = sqlite3GetVarint(p, &v64);
|
||||||
assert( n>3 && n<=9 );
|
assert( n>3 && n<=9 );
|
||||||
*v = (u32)v64;
|
if( (v64 & SQLITE_MAX_U32)!=v64 ){
|
||||||
|
*v = 0xffffffff;
|
||||||
|
}else{
|
||||||
|
*v = (u32)v64;
|
||||||
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
81
src/vdbe.c
81
src/vdbe.c
@@ -43,7 +43,7 @@
|
|||||||
** in this file for details. If in doubt, do not deviate from existing
|
** in this file for details. If in doubt, do not deviate from existing
|
||||||
** commenting and indentation practices when changing or adding code.
|
** commenting and indentation practices when changing or adding code.
|
||||||
**
|
**
|
||||||
** $Id: vdbe.c,v 1.846 2009/06/03 11:25:07 danielk1977 Exp $
|
** $Id: vdbe.c,v 1.847 2009/06/05 14:17:24 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "vdbeInt.h"
|
#include "vdbeInt.h"
|
||||||
@@ -2002,7 +2002,7 @@ case OP_SetNumColumns: {
|
|||||||
** the result.
|
** the result.
|
||||||
*/
|
*/
|
||||||
case OP_Column: {
|
case OP_Column: {
|
||||||
int payloadSize; /* Number of bytes in the record */
|
u32 payloadSize; /* Number of bytes in the record */
|
||||||
i64 payloadSize64; /* Number of bytes in the record */
|
i64 payloadSize64; /* Number of bytes in the record */
|
||||||
int p1; /* P1 value of the opcode */
|
int p1; /* P1 value of the opcode */
|
||||||
int p2; /* column number to retrieve */
|
int p2; /* column number to retrieve */
|
||||||
@@ -2017,11 +2017,12 @@ case OP_Column: {
|
|||||||
char *zData; /* Part of the record being decoded */
|
char *zData; /* Part of the record being decoded */
|
||||||
Mem *pDest; /* Where to write the extracted value */
|
Mem *pDest; /* Where to write the extracted value */
|
||||||
Mem sMem; /* For storing the record being decoded */
|
Mem sMem; /* For storing the record being decoded */
|
||||||
u8 *zIdx; /* Index into header */
|
u8 *zIdx; /* Index into header */
|
||||||
u8 *zEndHdr; /* Pointer to first byte after the header */
|
u8 *zEndHdr; /* Pointer to first byte after the header */
|
||||||
int offset; /* Offset into the data */
|
u32 offset; /* Offset into the data */
|
||||||
int szHdrSz; /* Size of the header size field at start of record */
|
u64 offset64; /* 64-bit offset. 64 bits needed to catch overflow */
|
||||||
int avail; /* Number of bytes of available data */
|
int szHdr; /* Size of the header size field at start of record */
|
||||||
|
int avail; /* Number of bytes of available data */
|
||||||
|
|
||||||
|
|
||||||
p1 = pOp->p1;
|
p1 = pOp->p1;
|
||||||
@@ -2063,9 +2064,13 @@ case OP_Column: {
|
|||||||
zRec = (char*)pC->aRow;
|
zRec = (char*)pC->aRow;
|
||||||
}else if( pC->isIndex ){
|
}else if( pC->isIndex ){
|
||||||
sqlite3BtreeKeySize(pCrsr, &payloadSize64);
|
sqlite3BtreeKeySize(pCrsr, &payloadSize64);
|
||||||
payloadSize = (int)payloadSize64;
|
if( (payloadSize64 & SQLITE_MAX_U32)!=(u64)payloadSize64 ){
|
||||||
|
rc = SQLITE_CORRUPT_BKPT;
|
||||||
|
goto abort_due_to_error;
|
||||||
|
}
|
||||||
|
payloadSize = (u32)payloadSize64;
|
||||||
}else{
|
}else{
|
||||||
sqlite3BtreeDataSize(pCrsr, (u32 *)&payloadSize);
|
sqlite3BtreeDataSize(pCrsr, &payloadSize);
|
||||||
}
|
}
|
||||||
nField = pC->nField;
|
nField = pC->nField;
|
||||||
}else{
|
}else{
|
||||||
@@ -2084,7 +2089,8 @@ case OP_Column: {
|
|||||||
assert( pDest->flags&MEM_Null );
|
assert( pDest->flags&MEM_Null );
|
||||||
goto op_column_out;
|
goto op_column_out;
|
||||||
}
|
}
|
||||||
if( payloadSize>db->aLimit[SQLITE_LIMIT_LENGTH] ){
|
assert( db->aLimit[SQLITE_LIMIT_LENGTH]>=0 );
|
||||||
|
if( payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
|
||||||
goto too_big;
|
goto too_big;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2117,7 +2123,8 @@ case OP_Column: {
|
|||||||
** having to make additional calls to fetch the content portion of
|
** having to make additional calls to fetch the content portion of
|
||||||
** the record.
|
** the record.
|
||||||
*/
|
*/
|
||||||
if( avail>=payloadSize ){
|
assert( avail>=0 );
|
||||||
|
if( payloadSize <= (u32)avail ){
|
||||||
zRec = zData;
|
zRec = zData;
|
||||||
pC->aRow = (u8*)zData;
|
pC->aRow = (u8*)zData;
|
||||||
}else{
|
}else{
|
||||||
@@ -2127,7 +2134,37 @@ case OP_Column: {
|
|||||||
/* The following assert is true in all cases accept when
|
/* The following assert is true in all cases accept when
|
||||||
** the database file has been corrupted externally.
|
** the database file has been corrupted externally.
|
||||||
** assert( zRec!=0 || avail>=payloadSize || avail>=9 ); */
|
** assert( zRec!=0 || avail>=payloadSize || avail>=9 ); */
|
||||||
szHdrSz = getVarint32((u8*)zData, offset);
|
szHdr = getVarint32((u8*)zData, offset);
|
||||||
|
|
||||||
|
/* Make sure a corrupt database has not given us an oversize header.
|
||||||
|
** Do this now to avoid an oversize memory allocation.
|
||||||
|
**
|
||||||
|
** Type entries can be between 1 and 5 bytes each. But 4 and 5 byte
|
||||||
|
** types use so much data space that there can only be 4096 and 32 of
|
||||||
|
** them, respectively. So the maximum header length results from a
|
||||||
|
** 3-byte type for each of the maximum of 32768 columns plus three
|
||||||
|
** extra bytes for the header length itself. 32768*3 + 3 = 98307.
|
||||||
|
*/
|
||||||
|
if( offset > 98307 ){
|
||||||
|
rc = SQLITE_CORRUPT_BKPT;
|
||||||
|
goto op_column_out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute in len the number of bytes of data we need to read in order
|
||||||
|
** to get nField type values. offset is an upper bound on this. But
|
||||||
|
** nField might be significantly less than the true number of columns
|
||||||
|
** in the table, and in that case, 5*nField+3 might be smaller than offset.
|
||||||
|
** We want to minimize len in order to limit the size of the memory
|
||||||
|
** allocation, especially if a corrupt database file has caused offset
|
||||||
|
** to be oversized. Offset is limited to 98307 above. But 98307 might
|
||||||
|
** still exceed Robson memory allocation limits on some configurations.
|
||||||
|
** On systems that cannot tolerate large memory allocations, nField*5+3
|
||||||
|
** will likely be much smaller since nField will likely be less than
|
||||||
|
** 20 or so. This insures that Robson memory allocation limits are
|
||||||
|
** not exceeded even for corrupt database files.
|
||||||
|
*/
|
||||||
|
len = nField*5 + 3;
|
||||||
|
if( len > offset ) len = offset;
|
||||||
|
|
||||||
/* The KeyFetch() or DataFetch() above are fast and will get the entire
|
/* The KeyFetch() or DataFetch() above are fast and will get the entire
|
||||||
** record header in most cases. But they will fail to get the complete
|
** record header in most cases. But they will fail to get the complete
|
||||||
@@ -2135,28 +2172,29 @@ case OP_Column: {
|
|||||||
** in the B-Tree. When that happens, use sqlite3VdbeMemFromBtree() to
|
** in the B-Tree. When that happens, use sqlite3VdbeMemFromBtree() to
|
||||||
** acquire the complete header text.
|
** acquire the complete header text.
|
||||||
*/
|
*/
|
||||||
if( !zRec && avail<offset ){
|
if( !zRec && avail<len ){
|
||||||
sMem.flags = 0;
|
sMem.flags = 0;
|
||||||
sMem.db = 0;
|
sMem.db = 0;
|
||||||
rc = sqlite3VdbeMemFromBtree(pCrsr, 0, offset, pC->isIndex, &sMem);
|
rc = sqlite3VdbeMemFromBtree(pCrsr, 0, len, pC->isIndex, &sMem);
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
goto op_column_out;
|
goto op_column_out;
|
||||||
}
|
}
|
||||||
zData = sMem.z;
|
zData = sMem.z;
|
||||||
}
|
}
|
||||||
zEndHdr = (u8 *)&zData[offset];
|
zEndHdr = (u8 *)&zData[len];
|
||||||
zIdx = (u8 *)&zData[szHdrSz];
|
zIdx = (u8 *)&zData[szHdr];
|
||||||
|
|
||||||
/* Scan the header and use it to fill in the aType[] and aOffset[]
|
/* Scan the header and use it to fill in the aType[] and aOffset[]
|
||||||
** arrays. aType[i] will contain the type integer for the i-th
|
** arrays. aType[i] will contain the type integer for the i-th
|
||||||
** column and aOffset[i] will contain the offset from the beginning
|
** column and aOffset[i] will contain the offset from the beginning
|
||||||
** of the record to the start of the data for the i-th column
|
** of the record to the start of the data for the i-th column
|
||||||
*/
|
*/
|
||||||
|
offset64 = offset;
|
||||||
for(i=0; i<nField; i++){
|
for(i=0; i<nField; i++){
|
||||||
if( zIdx<zEndHdr ){
|
if( zIdx<zEndHdr ){
|
||||||
aOffset[i] = offset;
|
aOffset[i] = (u32)offset64;
|
||||||
zIdx += getVarint32(zIdx, aType[i]);
|
zIdx += getVarint32(zIdx, aType[i]);
|
||||||
offset += sqlite3VdbeSerialTypeLen(aType[i]);
|
offset64 += sqlite3VdbeSerialTypeLen(aType[i]);
|
||||||
}else{
|
}else{
|
||||||
/* If i is less that nField, then there are less fields in this
|
/* If i is less that nField, then there are less fields in this
|
||||||
** record than SetNumColumns indicated there are columns in the
|
** record than SetNumColumns indicated there are columns in the
|
||||||
@@ -2176,8 +2214,8 @@ case OP_Column: {
|
|||||||
** of the record (when all fields present), then we must be dealing
|
** of the record (when all fields present), then we must be dealing
|
||||||
** with a corrupt database.
|
** with a corrupt database.
|
||||||
*/
|
*/
|
||||||
if( (zIdx > zEndHdr)|| (offset > payloadSize)
|
if( (zIdx > zEndHdr)|| (offset64 > payloadSize)
|
||||||
|| (zIdx==zEndHdr && offset!=payloadSize) ){
|
|| (zIdx==zEndHdr && offset64!=(u64)payloadSize) ){
|
||||||
rc = SQLITE_CORRUPT_BKPT;
|
rc = SQLITE_CORRUPT_BKPT;
|
||||||
goto op_column_out;
|
goto op_column_out;
|
||||||
}
|
}
|
||||||
@@ -2869,7 +2907,8 @@ case OP_VerifyCookie: {
|
|||||||
** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo
|
** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo
|
||||||
** structure, then said structure defines the content and collating
|
** structure, then said structure defines the content and collating
|
||||||
** sequence of the index being opened. Otherwise, if P4 is an integer
|
** sequence of the index being opened. Otherwise, if P4 is an integer
|
||||||
** value, it is set to the number of columns in the table.
|
** value, it is set to the number of columns in the table, or to the
|
||||||
|
** largest index of any column of the table that is actually used.
|
||||||
**
|
**
|
||||||
** This instruction works just like OpenRead except that it opens the cursor
|
** This instruction works just like OpenRead except that it opens the cursor
|
||||||
** in read/write mode. For a given table, there can be one or more read-only
|
** in read/write mode. For a given table, there can be one or more read-only
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
** 6000 lines long) it was split up into several smaller files and
|
** 6000 lines long) it was split up into several smaller files and
|
||||||
** this header information was factored out.
|
** this header information was factored out.
|
||||||
**
|
**
|
||||||
** $Id: vdbeInt.h,v 1.170 2009/05/04 11:42:30 danielk1977 Exp $
|
** $Id: vdbeInt.h,v 1.171 2009/06/05 14:17:25 drh Exp $
|
||||||
*/
|
*/
|
||||||
#ifndef _VDBEINT_H_
|
#ifndef _VDBEINT_H_
|
||||||
#define _VDBEINT_H_
|
#define _VDBEINT_H_
|
||||||
@@ -338,10 +338,10 @@ int sqlite3VdbeCursorMoveto(VdbeCursor*);
|
|||||||
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
|
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
|
||||||
void sqlite3VdbePrintOp(FILE*, int, Op*);
|
void sqlite3VdbePrintOp(FILE*, int, Op*);
|
||||||
#endif
|
#endif
|
||||||
int sqlite3VdbeSerialTypeLen(u32);
|
u32 sqlite3VdbeSerialTypeLen(u32);
|
||||||
u32 sqlite3VdbeSerialType(Mem*, int);
|
u32 sqlite3VdbeSerialType(Mem*, int);
|
||||||
int sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int);
|
u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int);
|
||||||
int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
|
u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
|
||||||
void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);
|
void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);
|
||||||
|
|
||||||
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
|
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
** to version 2.8.7, all this code was combined into the vdbe.c source file.
|
** to version 2.8.7, all this code was combined into the vdbe.c source file.
|
||||||
** But that file was getting too big so this subroutines were split out.
|
** But that file was getting too big so this subroutines were split out.
|
||||||
**
|
**
|
||||||
** $Id: vdbeaux.c,v 1.458 2009/05/29 19:00:13 drh Exp $
|
** $Id: vdbeaux.c,v 1.459 2009/06/05 14:17:25 drh Exp $
|
||||||
*/
|
*/
|
||||||
#include "sqliteInt.h"
|
#include "sqliteInt.h"
|
||||||
#include "vdbeInt.h"
|
#include "vdbeInt.h"
|
||||||
@@ -2120,7 +2120,7 @@ u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
|
|||||||
/*
|
/*
|
||||||
** Return the length of the data corresponding to the supplied serial-type.
|
** Return the length of the data corresponding to the supplied serial-type.
|
||||||
*/
|
*/
|
||||||
int sqlite3VdbeSerialTypeLen(u32 serial_type){
|
u32 sqlite3VdbeSerialTypeLen(u32 serial_type){
|
||||||
if( serial_type>=12 ){
|
if( serial_type>=12 ){
|
||||||
return (serial_type-12)/2;
|
return (serial_type-12)/2;
|
||||||
}else{
|
}else{
|
||||||
@@ -2200,14 +2200,14 @@ static u64 floatSwap(u64 in){
|
|||||||
** of bytes in the zero-filled tail is included in the return value only
|
** of bytes in the zero-filled tail is included in the return value only
|
||||||
** if those bytes were zeroed in buf[].
|
** if those bytes were zeroed in buf[].
|
||||||
*/
|
*/
|
||||||
int sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){
|
u32 sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){
|
||||||
u32 serial_type = sqlite3VdbeSerialType(pMem, file_format);
|
u32 serial_type = sqlite3VdbeSerialType(pMem, file_format);
|
||||||
int len;
|
u32 len;
|
||||||
|
|
||||||
/* Integer and Real */
|
/* Integer and Real */
|
||||||
if( serial_type<=7 && serial_type>0 ){
|
if( serial_type<=7 && serial_type>0 ){
|
||||||
u64 v;
|
u64 v;
|
||||||
int i;
|
u32 i;
|
||||||
if( serial_type==7 ){
|
if( serial_type==7 ){
|
||||||
assert( sizeof(v)==sizeof(pMem->r) );
|
assert( sizeof(v)==sizeof(pMem->r) );
|
||||||
memcpy(&v, &pMem->r, sizeof(v));
|
memcpy(&v, &pMem->r, sizeof(v));
|
||||||
@@ -2233,8 +2233,9 @@ int sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){
|
|||||||
memcpy(buf, pMem->z, len);
|
memcpy(buf, pMem->z, len);
|
||||||
if( pMem->flags & MEM_Zero ){
|
if( pMem->flags & MEM_Zero ){
|
||||||
len += pMem->u.nZero;
|
len += pMem->u.nZero;
|
||||||
if( len>nBuf ){
|
assert( nBuf>=0 );
|
||||||
len = nBuf;
|
if( len > (u32)nBuf ){
|
||||||
|
len = (u32)nBuf;
|
||||||
}
|
}
|
||||||
memset(&buf[pMem->n], 0, len-pMem->n);
|
memset(&buf[pMem->n], 0, len-pMem->n);
|
||||||
}
|
}
|
||||||
@@ -2249,7 +2250,7 @@ int sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){
|
|||||||
** Deserialize the data blob pointed to by buf as serial type serial_type
|
** Deserialize the data blob pointed to by buf as serial type serial_type
|
||||||
** and store the result in pMem. Return the number of bytes read.
|
** and store the result in pMem. Return the number of bytes read.
|
||||||
*/
|
*/
|
||||||
int sqlite3VdbeSerialGet(
|
u32 sqlite3VdbeSerialGet(
|
||||||
const unsigned char *buf, /* Buffer to deserialize from */
|
const unsigned char *buf, /* Buffer to deserialize from */
|
||||||
u32 serial_type, /* Serial type to deserialize */
|
u32 serial_type, /* Serial type to deserialize */
|
||||||
Mem *pMem /* Memory cell to write value into */
|
Mem *pMem /* Memory cell to write value into */
|
||||||
@@ -2327,7 +2328,7 @@ int sqlite3VdbeSerialGet(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
int len = (serial_type-12)/2;
|
u32 len = (serial_type-12)/2;
|
||||||
pMem->z = (char *)buf;
|
pMem->z = (char *)buf;
|
||||||
pMem->n = len;
|
pMem->n = len;
|
||||||
pMem->xDel = 0;
|
pMem->xDel = 0;
|
||||||
|
Reference in New Issue
Block a user