Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Strengthen the new balance_nonroot() code against various corrupt database problems. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
5ba983432069714afebbb2f0ef22d41b |
User & Date: | drh 2015-06-24 12:07:40.692 |
Context
2015-06-24
| ||
12:24 | Prevent an infinite loop while searching a corrupt freelist. (check-in: 4e5424fe89 user: drh tags: trunk) | |
12:07 | Strengthen the new balance_nonroot() code against various corrupt database problems. (check-in: 5ba9834320 user: drh tags: trunk) | |
10:46 | Adjustment to a malloc test so that it accepts a narrow range of values to account for variations in malloc subsystems. (check-in: e0195070f8 user: drh tags: trunk) | |
Changes
Changes to src/btree.c.
︙ | ︙ | |||
1435 1436 1437 1438 1439 1440 1441 | assert( gap<=65536 ); /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size ** and the reserved space is zero (the usual value for reserved space) ** then the cell content offset of an empty page wants to be 65536. ** However, that integer is too large to be stored in a 2-byte unsigned ** integer, so a value of 0 is used in its place. */ top = get2byteNotZero(&data[hdr+5]); | | < < | 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 | assert( gap<=65536 ); /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size ** and the reserved space is zero (the usual value for reserved space) ** then the cell content offset of an empty page wants to be 65536. ** However, that integer is too large to be stored in a 2-byte unsigned ** integer, so a value of 0 is used in its place. */ top = get2byteNotZero(&data[hdr+5]); if( gap>top || (u32)top>pPage->pBt->usableSize ){ return SQLITE_CORRUPT_BKPT; } /* If there is enough space between gap and top for one more cell pointer ** array entry offset, and if the freelist is not empty, then search the ** freelist looking for a free slot big enough to satisfy the request. */ |
︙ | ︙ | |||
7188 7189 7190 7191 7192 7193 7194 | sz = 0; } } szNew[i+1] -= sz; } if( cntNew[i]>=b.nCell ){ k = i+1; | | | 7186 7187 7188 7189 7190 7191 7192 7193 7194 7195 7196 7197 7198 7199 7200 | sz = 0; } } szNew[i+1] -= sz; } if( cntNew[i]>=b.nCell ){ k = i+1; }else if( cntNew[i] <= (i>0 ? cntNew[i-1] : 0) ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; } } /* ** The packing computed by the previous block is biased toward the siblings |
︙ | ︙ | |||
7214 7215 7216 7217 7218 7219 7220 | int szLeft = szNew[i-1]; /* Size of sibling on the left */ int r; /* Index of right-most cell in left sibling */ int d; /* Index of first cell to the left of right sibling */ r = cntNew[i-1] - 1; d = r + 1 - leafData; (void)cachedCellSize(&b, d); | < > < < < < | > > > > | 7212 7213 7214 7215 7216 7217 7218 7219 7220 7221 7222 7223 7224 7225 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 | int szLeft = szNew[i-1]; /* Size of sibling on the left */ int r; /* Index of right-most cell in left sibling */ int d; /* Index of first cell to the left of right sibling */ r = cntNew[i-1] - 1; d = r + 1 - leafData; (void)cachedCellSize(&b, d); do{ assert( d<nMaxCells ); assert( r<nMaxCells ); (void)cachedCellSize(&b, r); if( szRight!=0 && (bBulk || szRight+b.szCell[d]+2 > szLeft-(b.szCell[r]+2)) ){ break; } szRight += b.szCell[d] + 2; szLeft -= b.szCell[r] + 2; cntNew[i-1] = r; r--; d--; }while( r>=0 ); szNew[i] = szRight; szNew[i-1] = szLeft; if( cntNew[i-1] <= (i>1 ? cntNew[i-2] : 0) ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; } } /* Sanity check: For a non-corrupt database file one of the follwing ** must be true: ** (1) We found one or more cells (cntNew[0])>0), or ** (2) pPage is a virtual root page. A virtual root page is when ** the real root page is page 1 and we are the only child of |
︙ | ︙ |