/ Check-in [97704cb7]
Login

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

Overview
Comment:More robust handling of corrupt database file in the rebalance operation of the btree logic.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 97704cb7d29fa7cc4ea9a6761a7844c1946d637ea2b22d287fc787ae0f63c407
User & Date: drh 2019-01-29 16:41:13
Context
2019-01-29
16:47
Load all the latest dbsqlfuzz finds into test/fuzzdata8.db. check-in: e744d2dd user: drh tags: trunk
16:41
More robust handling of corrupt database file in the rebalance operation of the btree logic. check-in: 97704cb7 user: drh tags: trunk
16:34
Avoid an integer overflow in the fts5 snippet() function triggered by a corrupt database record. check-in: 7c862c46 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

  6810   6810     MemPage *pPg                    /* The page to be reconstructed */
  6811   6811   ){
  6812   6812     const int hdr = pPg->hdrOffset;          /* Offset of header on pPg */
  6813   6813     u8 * const aData = pPg->aData;           /* Pointer to data for pPg */
  6814   6814     const int usableSize = pPg->pBt->usableSize;
  6815   6815     u8 * const pEnd = &aData[usableSize];
  6816   6816     int i = iFirst;                 /* Which cell to copy from pCArray*/
  6817         -  int j;                          /* Start of cell content area */
         6817  +  u32 j;                          /* Start of cell content area */
  6818   6818     int iEnd = i+nCell;             /* Loop terminator */
  6819   6819     u8 *pCellptr = pPg->aCellIdx;
  6820   6820     u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager);
  6821   6821     u8 *pData;
  6822   6822     int k;                          /* Current slot in pCArray->apEnd[] */
  6823   6823     u8 *pSrcEnd;                    /* Current pCArray->apEnd[k] value */
  6824   6824   
  6825   6825     assert( i<iEnd );
  6826   6826     j = get2byte(&aData[hdr+5]);
         6827  +  if( NEVER(j>usableSize) ){ j = 0; }
  6827   6828     memcpy(&pTmp[j], &aData[j], usableSize - j);
  6828   6829   
  6829   6830     for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){}
  6830   6831     pSrcEnd = pCArray->apEnd[k];
  6831   6832   
  6832   6833     pData = pEnd;
  6833   6834     while( 1/*exit by break*/ ){
................................................................................
  6999   7000       assert( pFree>aData && (pFree - aData)<65536 );
  7000   7001       freeSpace(pPg, (u16)(pFree - aData), szFree);
  7001   7002     }
  7002   7003     return nRet;
  7003   7004   }
  7004   7005   
  7005   7006   /*
  7006         -** pCArray contains pointers to and sizes of all cells in the pages being
         7007  +** pCArray contains pointers to and sizes of all cells in the page being
  7007   7008   ** balanced.  The current page, pPg, has pPg->nCell cells starting with
  7008   7009   ** pCArray->apCell[iOld].  After balancing, this page should hold nNew cells
  7009   7010   ** starting at apCell[iNew].
  7010   7011   **
  7011   7012   ** This routine makes the necessary adjustments to pPg so that it contains
  7012   7013   ** the correct cells after being balanced.
  7013   7014   **
................................................................................
  7033   7034   
  7034   7035   #ifdef SQLITE_DEBUG
  7035   7036     u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager);
  7036   7037     memcpy(pTmp, aData, pPg->pBt->usableSize);
  7037   7038   #endif
  7038   7039   
  7039   7040     /* Remove cells from the start and end of the page */
         7041  +  assert( nCell>=0 );
  7040   7042     if( iOld<iNew ){
  7041   7043       int nShift = pageFreeArray(pPg, iOld, iNew-iOld, pCArray);
         7044  +    if( nShift>nCell ) return SQLITE_CORRUPT_BKPT;
  7042   7045       memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
  7043   7046       nCell -= nShift;
  7044   7047     }
  7045   7048     if( iNewEnd < iOldEnd ){
  7046         -    nCell -= pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray);
         7049  +    int nTail = pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray);
         7050  +    assert( nCell>=nTail );
         7051  +    nCell -= nTail;
  7047   7052     }
  7048   7053   
  7049   7054     pData = &aData[get2byteNotZero(&aData[hdr+5])];
  7050   7055     if( pData<pBegin ) goto editpage_fail;
  7051   7056   
  7052   7057     /* Add cells to the start of the page */
  7053   7058     if( iNew<iOld ){
  7054   7059       int nAdd = MIN(nNew,iOld-iNew);
  7055   7060       assert( (iOld-iNew)<nNew || nCell==0 || CORRUPT_DB );
         7061  +    assert( nAdd>=0 );
  7056   7062       pCellptr = pPg->aCellIdx;
  7057   7063       memmove(&pCellptr[nAdd*2], pCellptr, nCell*2);
  7058   7064       if( pageInsertArray(
  7059   7065             pPg, pBegin, &pData, pCellptr,
  7060   7066             iNew, nAdd, pCArray
  7061   7067       ) ) goto editpage_fail;
  7062   7068       nCell += nAdd;
................................................................................
  7063   7069     }
  7064   7070   
  7065   7071     /* Add any overflow cells */
  7066   7072     for(i=0; i<pPg->nOverflow; i++){
  7067   7073       int iCell = (iOld + pPg->aiOvfl[i]) - iNew;
  7068   7074       if( iCell>=0 && iCell<nNew ){
  7069   7075         pCellptr = &pPg->aCellIdx[iCell * 2];
         7076  +      assert( nCell>=iCell );
  7070   7077         memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2);
  7071   7078         nCell++;
  7072   7079         if( pageInsertArray(
  7073   7080               pPg, pBegin, &pData, pCellptr,
  7074   7081               iCell+iNew, 1, pCArray
  7075   7082         ) ) goto editpage_fail;
  7076   7083       }
  7077   7084     }
  7078   7085   
  7079   7086     /* Append cells to the end of the page */
         7087  +  assert( nCell>=0 );
  7080   7088     pCellptr = &pPg->aCellIdx[nCell*2];
  7081   7089     if( pageInsertArray(
  7082   7090           pPg, pBegin, &pData, pCellptr,
  7083   7091           iNew+nCell, nNew-nCell, pCArray
  7084   7092     ) ) goto editpage_fail;
  7085   7093   
  7086   7094     pPg->nCell = nNew;

Changes to test/fuzzdata8.db.

cannot compute difference between binary files