/ Check-in [38b20327]
Login

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

Overview
Comment: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)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 38b20327a80996c7044b88be32161ac4ac0ec3a9
User & Date: drh 2009-06-05 14:17:22
Context
2009-06-05
16:46
Do not cast an unsigned int into an int for comparison. (CVS 6720) check-in: 302ab855 user: drh tags: trunk
14:17
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) check-in: 38b20327 user: drh tags: trunk
2009-06-04
19:06
Earlier detection of freelist corruption in the page allocation routines. (CVS 6718) check-in: e557c8e5 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

     5      5   ** a legal notice, here is a blessing:
     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12         -** $Id: btree.c,v 1.617 2009/06/04 19:06:10 drh Exp $
           12  +** $Id: btree.c,v 1.618 2009/06/05 14:17:22 drh Exp $
    13     13   **
    14     14   ** This file implements a external (disk-based) database using BTrees.
    15     15   ** See the header comment on "btreeInt.h" for additional information.
    16     16   ** Including a description of file format and an overview of operation.
    17     17   */
    18     18   #include "btreeInt.h"
    19     19   
................................................................................
  4389   4389     MemPage **ppPage, 
  4390   4390     Pgno *pPgno, 
  4391   4391     Pgno nearby,
  4392   4392     u8 exact
  4393   4393   ){
  4394   4394     MemPage *pPage1;
  4395   4395     int rc;
  4396         -  int n;     /* Number of pages on the freelist */
         4396  +  u32 n;     /* Number of pages on the freelist */
  4397   4397     int k;     /* Number of leaves on the trunk of the freelist */
  4398   4398     MemPage *pTrunk = 0;
  4399   4399     MemPage *pPrevTrunk = 0;
  4400   4400     Pgno mxPage;     /* Total size of the database file */
  4401   4401   
  4402   4402     assert( sqlite3_mutex_held(pBt->mutex) );
  4403   4403     pPage1 = pBt->pPage1;
................................................................................
  4454   4454         }
  4455   4455         if( rc ){
  4456   4456           pTrunk = 0;
  4457   4457           goto end_allocate_page;
  4458   4458         }
  4459   4459   
  4460   4460         k = get4byte(&pTrunk->aData[4]);
  4461         -      if( k>mxPage ){
  4462         -        rc = SQLITE_CORRUPT_BKPT;
  4463         -        goto end_allocate_page;
  4464         -      }
  4465   4461         if( k==0 && !searchList ){
  4466   4462           /* The trunk has no leaves and the list is not being searched. 
  4467   4463           ** So extract the trunk page itself and use it as the newly 
  4468   4464           ** allocated page */
  4469   4465           assert( pPrevTrunk==0 );
  4470   4466           rc = sqlite3PagerWrite(pTrunk->pDbPage);
  4471   4467           if( rc ){

Changes to src/sqliteInt.h.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.881 2009/06/02 21:31:39 drh Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.882 2009/06/05 14:17:23 drh Exp $
    15     15   */
    16     16   #ifndef _SQLITEINT_H_
    17     17   #define _SQLITEINT_H_
    18     18   
    19     19   /*
    20     20   ** Include the configuration header output by 'configure' if we're using the
    21     21   ** autoconf-based build
................................................................................
   427    427   typedef sqlite_uint64 u64;         /* 8-byte unsigned integer */
   428    428   typedef UINT32_TYPE u32;           /* 4-byte unsigned integer */
   429    429   typedef UINT16_TYPE u16;           /* 2-byte unsigned integer */
   430    430   typedef INT16_TYPE i16;            /* 2-byte signed integer */
   431    431   typedef UINT8_TYPE u8;             /* 1-byte unsigned integer */
   432    432   typedef INT8_TYPE i8;              /* 1-byte signed integer */
   433    433   
          434  +/*
          435  +** SQLITE_MAX_U32 is a u64 constant that is the maximum u64 value
          436  +** that can be stored in a u32 without loss of data.  The value
          437  +** is 0x00000000ffffffff.  But because of quirks of some compilers, we
          438  +** have to specify the value in the less intuitive manner shown:
          439  +*/
          440  +#define SQLITE_MAX_U32  ((((u64)1)<<32)-1)
          441  +
   434    442   /*
   435    443   ** Macros to determine whether the machine is big or little endian,
   436    444   ** evaluated at runtime.
   437    445   */
   438    446   #ifdef SQLITE_AMALGAMATION
   439    447   const int sqlite3one = 1;
   440    448   #else

Changes to src/util.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** Utility functions used throughout sqlite.
    13     13   **
    14     14   ** This file contains functions for allocating memory, comparing
    15     15   ** strings, and stuff like that.
    16     16   **
    17         -** $Id: util.c,v 1.257 2009/05/31 21:21:41 drh Exp $
           17  +** $Id: util.c,v 1.258 2009/06/05 14:17:23 drh Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include <stdarg.h>
    21     21   #ifdef SQLITE_HAVE_ISNAN
    22     22   # include <math.h>
    23     23   #endif
    24     24   
................................................................................
   762    762   
   763    763     return 9;
   764    764   }
   765    765   
   766    766   /*
   767    767   ** Read a 32-bit variable-length integer from memory starting at p[0].
   768    768   ** Return the number of bytes read.  The value is stored in *v.
          769  +**
          770  +** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned
          771  +** integer, then set *v to 0xffffffff.
          772  +**
   769    773   ** A MACRO version, getVarint32, is provided which inlines the 
   770    774   ** single-byte case.  All code should use the MACRO version as 
   771    775   ** this function assumes the single-byte case has already been handled.
   772    776   */
   773    777   u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){
   774    778     u32 a,b;
   775    779   
................................................................................
   827    831     {
   828    832       u64 v64;
   829    833       u8 n;
   830    834   
   831    835       p -= 2;
   832    836       n = sqlite3GetVarint(p, &v64);
   833    837       assert( n>3 && n<=9 );
   834         -    *v = (u32)v64;
          838  +    if( (v64 & SQLITE_MAX_U32)!=v64 ){
          839  +      *v = 0xffffffff;
          840  +    }else{
          841  +      *v = (u32)v64;
          842  +    }
   835    843       return n;
   836    844     }
   837    845   
   838    846   #else
   839    847     /* For following code (kept for historical record only) shows an
   840    848     ** unrolling for the 3- and 4-byte varint cases.  This code is
   841    849     ** slightly faster, but it is also larger and much harder to test.

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.846 2009/06/03 11:25:07 danielk1977 Exp $
           46  +** $Id: vdbe.c,v 1.847 2009/06/05 14:17:24 drh Exp $
    47     47   */
    48     48   #include "sqliteInt.h"
    49     49   #include "vdbeInt.h"
    50     50   
    51     51   /*
    52     52   ** The following global variable is incremented every time a cursor
    53     53   ** moves, either by the OP_SeekXX, OP_Next, or OP_Prev opcodes.  The test
................................................................................
  1998   1998   ** The value extracted is stored in register P3.
  1999   1999   **
  2000   2000   ** If the column contains fewer than P2 fields, then extract a NULL.  Or,
  2001   2001   ** if the P4 argument is a P4_MEM use the value of the P4 argument as
  2002   2002   ** the result.
  2003   2003   */
  2004   2004   case OP_Column: {
  2005         -  int payloadSize;   /* Number of bytes in the record */
         2005  +  u32 payloadSize;   /* Number of bytes in the record */
  2006   2006     i64 payloadSize64; /* Number of bytes in the record */
  2007   2007     int p1;            /* P1 value of the opcode */
  2008   2008     int p2;            /* column number to retrieve */
  2009   2009     VdbeCursor *pC;    /* The VDBE cursor */
  2010   2010     char *zRec;        /* Pointer to complete record-data */
  2011   2011     BtCursor *pCrsr;   /* The BTree cursor */
  2012   2012     u32 *aType;        /* aType[i] holds the numeric type of the i-th column */
................................................................................
  2013   2013     u32 *aOffset;      /* aOffset[i] is offset to start of data for i-th column */
  2014   2014     int nField;        /* number of fields in the record */
  2015   2015     int len;           /* The length of the serialized data for the column */
  2016   2016     int i;             /* Loop counter */
  2017   2017     char *zData;       /* Part of the record being decoded */
  2018   2018     Mem *pDest;        /* Where to write the extracted value */
  2019   2019     Mem sMem;          /* For storing the record being decoded */
  2020         -  u8 *zIdx;         /* Index into header */
  2021         -  u8 *zEndHdr;      /* Pointer to first byte after the header */
  2022         -  int offset;       /* Offset into the data */
  2023         -  int szHdrSz;      /* Size of the header size field at start of record */
  2024         -  int avail;        /* Number of bytes of available data */
         2020  +  u8 *zIdx;          /* Index into header */
         2021  +  u8 *zEndHdr;       /* Pointer to first byte after the header */
         2022  +  u32 offset;        /* Offset into the data */
         2023  +  u64 offset64;      /* 64-bit offset.  64 bits needed to catch overflow */
         2024  +  int szHdr;         /* Size of the header size field at start of record */
         2025  +  int avail;         /* Number of bytes of available data */
  2025   2026   
  2026   2027   
  2027   2028     p1 = pOp->p1;
  2028   2029     p2 = pOp->p2;
  2029   2030     pC = 0;
  2030   2031     memset(&sMem, 0, sizeof(sMem));
  2031   2032     assert( p1<p->nCursor );
................................................................................
  2059   2060       if( pC->nullRow ){
  2060   2061         payloadSize = 0;
  2061   2062       }else if( pC->cacheStatus==p->cacheCtr ){
  2062   2063         payloadSize = pC->payloadSize;
  2063   2064         zRec = (char*)pC->aRow;
  2064   2065       }else if( pC->isIndex ){
  2065   2066         sqlite3BtreeKeySize(pCrsr, &payloadSize64);
  2066         -      payloadSize = (int)payloadSize64;
         2067  +      if( (payloadSize64 & SQLITE_MAX_U32)!=(u64)payloadSize64 ){
         2068  +        rc = SQLITE_CORRUPT_BKPT;
         2069  +        goto abort_due_to_error;
         2070  +      }
         2071  +      payloadSize = (u32)payloadSize64;
  2067   2072       }else{
  2068         -      sqlite3BtreeDataSize(pCrsr, (u32 *)&payloadSize);
         2073  +      sqlite3BtreeDataSize(pCrsr, &payloadSize);
  2069   2074       }
  2070   2075       nField = pC->nField;
  2071   2076     }else{
  2072   2077       assert( pC->pseudoTable );
  2073   2078       /* The record is the sole entry of a pseudo-table */
  2074   2079       payloadSize = pC->nData;
  2075   2080       zRec = pC->pData;
................................................................................
  2080   2085     }
  2081   2086   
  2082   2087     /* If payloadSize is 0, then just store a NULL */
  2083   2088     if( payloadSize==0 ){
  2084   2089       assert( pDest->flags&MEM_Null );
  2085   2090       goto op_column_out;
  2086   2091     }
  2087         -  if( payloadSize>db->aLimit[SQLITE_LIMIT_LENGTH] ){
         2092  +  assert( db->aLimit[SQLITE_LIMIT_LENGTH]>=0 );
         2093  +  if( payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
  2088   2094       goto too_big;
  2089   2095     }
  2090   2096   
  2091   2097     assert( p2<nField );
  2092   2098   
  2093   2099     /* Read and parse the table header.  Store the results of the parse
  2094   2100     ** into the record header cache fields of the cursor.
................................................................................
  2113   2119           zData = (char*)sqlite3BtreeDataFetch(pCrsr, &avail);
  2114   2120         }
  2115   2121         /* If KeyFetch()/DataFetch() managed to get the entire payload,
  2116   2122         ** save the payload in the pC->aRow cache.  That will save us from
  2117   2123         ** having to make additional calls to fetch the content portion of
  2118   2124         ** the record.
  2119   2125         */
  2120         -      if( avail>=payloadSize ){
         2126  +      assert( avail>=0 );
         2127  +      if( payloadSize <= (u32)avail ){
  2121   2128           zRec = zData;
  2122   2129           pC->aRow = (u8*)zData;
  2123   2130         }else{
  2124   2131           pC->aRow = 0;
  2125   2132         }
  2126   2133       }
  2127   2134       /* The following assert is true in all cases accept when
  2128   2135       ** the database file has been corrupted externally.
  2129   2136       **    assert( zRec!=0 || avail>=payloadSize || avail>=9 ); */
  2130         -    szHdrSz = getVarint32((u8*)zData, offset);
         2137  +    szHdr = getVarint32((u8*)zData, offset);
         2138  +
         2139  +    /* Make sure a corrupt database has not given us an oversize header.
         2140  +    ** Do this now to avoid an oversize memory allocation.
         2141  +    **
         2142  +    ** Type entries can be between 1 and 5 bytes each.  But 4 and 5 byte
         2143  +    ** types use so much data space that there can only be 4096 and 32 of
         2144  +    ** them, respectively.  So the maximum header length results from a
         2145  +    ** 3-byte type for each of the maximum of 32768 columns plus three
         2146  +    ** extra bytes for the header length itself.  32768*3 + 3 = 98307.
         2147  +    */
         2148  +    if( offset > 98307 ){
         2149  +      rc = SQLITE_CORRUPT_BKPT;
         2150  +      goto op_column_out;
         2151  +    }
         2152  +
         2153  +    /* Compute in len the number of bytes of data we need to read in order
         2154  +    ** to get nField type values.  offset is an upper bound on this.  But
         2155  +    ** nField might be significantly less than the true number of columns
         2156  +    ** in the table, and in that case, 5*nField+3 might be smaller than offset.
         2157  +    ** We want to minimize len in order to limit the size of the memory
         2158  +    ** allocation, especially if a corrupt database file has caused offset
         2159  +    ** to be oversized. Offset is limited to 98307 above.  But 98307 might
         2160  +    ** still exceed Robson memory allocation limits on some configurations.
         2161  +    ** On systems that cannot tolerate large memory allocations, nField*5+3
         2162  +    ** will likely be much smaller since nField will likely be less than
         2163  +    ** 20 or so.  This insures that Robson memory allocation limits are
         2164  +    ** not exceeded even for corrupt database files.
         2165  +    */
         2166  +    len = nField*5 + 3;
         2167  +    if( len > offset ) len = offset;
  2131   2168   
  2132   2169       /* The KeyFetch() or DataFetch() above are fast and will get the entire
  2133   2170       ** record header in most cases.  But they will fail to get the complete
  2134   2171       ** record header if the record header does not fit on a single page
  2135   2172       ** in the B-Tree.  When that happens, use sqlite3VdbeMemFromBtree() to
  2136   2173       ** acquire the complete header text.
  2137   2174       */
  2138         -    if( !zRec && avail<offset ){
         2175  +    if( !zRec && avail<len ){
  2139   2176         sMem.flags = 0;
  2140   2177         sMem.db = 0;
  2141         -      rc = sqlite3VdbeMemFromBtree(pCrsr, 0, offset, pC->isIndex, &sMem);
         2178  +      rc = sqlite3VdbeMemFromBtree(pCrsr, 0, len, pC->isIndex, &sMem);
  2142   2179         if( rc!=SQLITE_OK ){
  2143   2180           goto op_column_out;
  2144   2181         }
  2145   2182         zData = sMem.z;
  2146   2183       }
  2147         -    zEndHdr = (u8 *)&zData[offset];
  2148         -    zIdx = (u8 *)&zData[szHdrSz];
         2184  +    zEndHdr = (u8 *)&zData[len];
         2185  +    zIdx = (u8 *)&zData[szHdr];
  2149   2186   
  2150   2187       /* Scan the header and use it to fill in the aType[] and aOffset[]
  2151   2188       ** arrays.  aType[i] will contain the type integer for the i-th
  2152   2189       ** column and aOffset[i] will contain the offset from the beginning
  2153   2190       ** of the record to the start of the data for the i-th column
  2154   2191       */
         2192  +    offset64 = offset;
  2155   2193       for(i=0; i<nField; i++){
  2156   2194         if( zIdx<zEndHdr ){
  2157         -        aOffset[i] = offset;
         2195  +        aOffset[i] = (u32)offset64;
  2158   2196           zIdx += getVarint32(zIdx, aType[i]);
  2159         -        offset += sqlite3VdbeSerialTypeLen(aType[i]);
         2197  +        offset64 += sqlite3VdbeSerialTypeLen(aType[i]);
  2160   2198         }else{
  2161   2199           /* If i is less that nField, then there are less fields in this
  2162   2200           ** record than SetNumColumns indicated there are columns in the
  2163   2201           ** table. Set the offset for any extra columns not present in
  2164   2202           ** the record to 0. This tells code below to store a NULL
  2165   2203           ** instead of deserializing a value from the record.
  2166   2204           */
................................................................................
  2172   2210   
  2173   2211       /* If we have read more header data than was contained in the header,
  2174   2212       ** or if the end of the last field appears to be past the end of the
  2175   2213       ** record, or if the end of the last field appears to be before the end
  2176   2214       ** of the record (when all fields present), then we must be dealing 
  2177   2215       ** with a corrupt database.
  2178   2216       */
  2179         -    if( (zIdx > zEndHdr)|| (offset > payloadSize)
  2180         -     || (zIdx==zEndHdr && offset!=payloadSize) ){
         2217  +    if( (zIdx > zEndHdr)|| (offset64 > payloadSize)
         2218  +     || (zIdx==zEndHdr && offset64!=(u64)payloadSize) ){
  2181   2219         rc = SQLITE_CORRUPT_BKPT;
  2182   2220         goto op_column_out;
  2183   2221       }
  2184   2222     }
  2185   2223   
  2186   2224     /* Get the column information. If aOffset[p2] is non-zero, then 
  2187   2225     ** deserialize the value from the record. If aOffset[p2] is zero,
................................................................................
  2865   2903   ** page is P2.  Or if P5!=0 use the content of register P2 to find the
  2866   2904   ** root page.
  2867   2905   **
  2868   2906   ** The P4 value may be either an integer (P4_INT32) or a pointer to
  2869   2907   ** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo 
  2870   2908   ** structure, then said structure defines the content and collating 
  2871   2909   ** sequence of the index being opened. Otherwise, if P4 is an integer 
  2872         -** value, it is set to the number of columns in the table.
         2910  +** value, it is set to the number of columns in the table, or to the
         2911  +** largest index of any column of the table that is actually used.
  2873   2912   **
  2874   2913   ** This instruction works just like OpenRead except that it opens the cursor
  2875   2914   ** in read/write mode.  For a given table, there can be one or more read-only
  2876   2915   ** cursors or a single read/write cursor but not both.
  2877   2916   **
  2878   2917   ** See also OpenRead.
  2879   2918   */

Changes to src/vdbeInt.h.

    11     11   *************************************************************************
    12     12   ** This is the header file for information that is private to the
    13     13   ** VDBE.  This information used to all be at the top of the single
    14     14   ** source code file "vdbe.c".  When that file became too big (over
    15     15   ** 6000 lines long) it was split up into several smaller files and
    16     16   ** this header information was factored out.
    17     17   **
    18         -** $Id: vdbeInt.h,v 1.170 2009/05/04 11:42:30 danielk1977 Exp $
           18  +** $Id: vdbeInt.h,v 1.171 2009/06/05 14:17:25 drh Exp $
    19     19   */
    20     20   #ifndef _VDBEINT_H_
    21     21   #define _VDBEINT_H_
    22     22   
    23     23   /*
    24     24   ** intToKey() and keyToInt() used to transform the rowid.  But with
    25     25   ** the latest versions of the design they are no-ops.
................................................................................
   334    334   */
   335    335   void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
   336    336   void sqliteVdbePopStack(Vdbe*,int);
   337    337   int sqlite3VdbeCursorMoveto(VdbeCursor*);
   338    338   #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
   339    339   void sqlite3VdbePrintOp(FILE*, int, Op*);
   340    340   #endif
   341         -int sqlite3VdbeSerialTypeLen(u32);
          341  +u32 sqlite3VdbeSerialTypeLen(u32);
   342    342   u32 sqlite3VdbeSerialType(Mem*, int);
   343         -int sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int);
   344         -int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
          343  +u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int);
          344  +u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
   345    345   void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);
   346    346   
   347    347   int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
   348    348   int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*);
   349    349   int sqlite3VdbeIdxRowid(BtCursor *, i64 *);
   350    350   int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
   351    351   int sqlite3VdbeExec(Vdbe*);

Changes to src/vdbeaux.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains code used for creating, destroying, and populating
    13     13   ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.)  Prior
    14     14   ** to version 2.8.7, all this code was combined into the vdbe.c source file.
    15     15   ** But that file was getting too big so this subroutines were split out.
    16     16   **
    17         -** $Id: vdbeaux.c,v 1.458 2009/05/29 19:00:13 drh Exp $
           17  +** $Id: vdbeaux.c,v 1.459 2009/06/05 14:17:25 drh Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include "vdbeInt.h"
    21     21   
    22     22   
    23     23   
    24     24   /*
................................................................................
  2116   2116     assert( n>=0 );
  2117   2117     return ((n*2) + 12 + ((flags&MEM_Str)!=0));
  2118   2118   }
  2119   2119   
  2120   2120   /*
  2121   2121   ** Return the length of the data corresponding to the supplied serial-type.
  2122   2122   */
  2123         -int sqlite3VdbeSerialTypeLen(u32 serial_type){
         2123  +u32 sqlite3VdbeSerialTypeLen(u32 serial_type){
  2124   2124     if( serial_type>=12 ){
  2125   2125       return (serial_type-12)/2;
  2126   2126     }else{
  2127   2127       static const u8 aSize[] = { 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, 0, 0 };
  2128   2128       return aSize[serial_type];
  2129   2129     }
  2130   2130   }
................................................................................
  2196   2196   ** prefix and the tail then write the prefix and set the tail to all
  2197   2197   ** zeros.
  2198   2198   **
  2199   2199   ** Return the number of bytes actually written into buf[].  The number
  2200   2200   ** of bytes in the zero-filled tail is included in the return value only
  2201   2201   ** if those bytes were zeroed in buf[].
  2202   2202   */ 
  2203         -int sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){
         2203  +u32 sqlite3VdbeSerialPut(u8 *buf, int nBuf, Mem *pMem, int file_format){
  2204   2204     u32 serial_type = sqlite3VdbeSerialType(pMem, file_format);
  2205         -  int len;
         2205  +  u32 len;
  2206   2206   
  2207   2207     /* Integer and Real */
  2208   2208     if( serial_type<=7 && serial_type>0 ){
  2209   2209       u64 v;
  2210         -    int i;
         2210  +    u32 i;
  2211   2211       if( serial_type==7 ){
  2212   2212         assert( sizeof(v)==sizeof(pMem->r) );
  2213   2213         memcpy(&v, &pMem->r, sizeof(v));
  2214   2214         swapMixedEndianFloat(v);
  2215   2215       }else{
  2216   2216         v = pMem->u.i;
  2217   2217       }
................................................................................
  2229   2229       assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0)
  2230   2230                == sqlite3VdbeSerialTypeLen(serial_type) );
  2231   2231       assert( pMem->n<=nBuf );
  2232   2232       len = pMem->n;
  2233   2233       memcpy(buf, pMem->z, len);
  2234   2234       if( pMem->flags & MEM_Zero ){
  2235   2235         len += pMem->u.nZero;
  2236         -      if( len>nBuf ){
  2237         -        len = nBuf;
         2236  +      assert( nBuf>=0 );
         2237  +      if( len > (u32)nBuf ){
         2238  +        len = (u32)nBuf;
  2238   2239         }
  2239   2240         memset(&buf[pMem->n], 0, len-pMem->n);
  2240   2241       }
  2241   2242       return len;
  2242   2243     }
  2243   2244   
  2244   2245     /* NULL or constants 0 or 1 */
................................................................................
  2245   2246     return 0;
  2246   2247   }
  2247   2248   
  2248   2249   /*
  2249   2250   ** Deserialize the data blob pointed to by buf as serial type serial_type
  2250   2251   ** and store the result in pMem.  Return the number of bytes read.
  2251   2252   */ 
  2252         -int sqlite3VdbeSerialGet(
         2253  +u32 sqlite3VdbeSerialGet(
  2253   2254     const unsigned char *buf,     /* Buffer to deserialize from */
  2254   2255     u32 serial_type,              /* Serial type to deserialize */
  2255   2256     Mem *pMem                     /* Memory cell to write value into */
  2256   2257   ){
  2257   2258     switch( serial_type ){
  2258   2259       case 10:   /* Reserved for future use */
  2259   2260       case 11:   /* Reserved for future use */
................................................................................
  2323   2324       case 8:    /* Integer 0 */
  2324   2325       case 9: {  /* Integer 1 */
  2325   2326         pMem->u.i = serial_type-8;
  2326   2327         pMem->flags = MEM_Int;
  2327   2328         return 0;
  2328   2329       }
  2329   2330       default: {
  2330         -      int len = (serial_type-12)/2;
         2331  +      u32 len = (serial_type-12)/2;
  2331   2332         pMem->z = (char *)buf;
  2332   2333         pMem->n = len;
  2333   2334         pMem->xDel = 0;
  2334   2335         if( serial_type&0x01 ){
  2335   2336           pMem->flags = MEM_Str | MEM_Ephem;
  2336   2337         }else{
  2337   2338           pMem->flags = MEM_Blob | MEM_Ephem;