1
0
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:
drh
2009-06-05 14:17:21 +00:00
parent 1662b5a6f9
commit 35cd643cc7
8 changed files with 107 additions and 55 deletions

View File

@@ -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

View File

@@ -1 +1 @@
e557c8e5846f9c4eaaeb3bd07614ac101bb0b3d0 38b20327a80996c7044b88be32161ac4ac0ec3a9

View File

@@ -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

View File

@@ -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.

View File

@@ -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;
} }

View File

@@ -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

View File

@@ -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 *);

View File

@@ -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;