Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add extended return code SQLITE_CORRUPT_VTAB. Returned when the tcontents of the sqlite tables used internally by a virtual table module are invalid or inconsistent. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
8844e8bfb87314fb40ecb92705e8fff8 |
User & Date: | dan 2011-05-17 15:56:16.473 |
Context
2011-05-17
| ||
18:53 | Add the sqlite3_uri_parameter() interface function for use in building new VFSes. (check-in: 6b5de95fb5 user: drh tags: trunk) | |
15:56 | Add extended return code SQLITE_CORRUPT_VTAB. Returned when the tcontents of the sqlite tables used internally by a virtual table module are invalid or inconsistent. (check-in: 8844e8bfb8 user: dan tags: trunk) | |
15:21 | Avoid exceeding array bounds when reading a corrupt database file in autovacuum mode. Fixes a problem discovered by John Regehr and Peng Li using a customized clang compiler. (check-in: f7c525f5fc user: drh tags: trunk) | |
Changes
Changes to ext/fts3/fts3.c.
︙ | ︙ | |||
1191 1192 1193 1194 1195 1196 1197 | }else{ int rc = sqlite3_reset(pCsr->pStmt); if( rc==SQLITE_OK ){ /* If no row was found and no error has occured, then the %_content ** table is missing a row that is present in the full-text index. ** The data structures are corrupt. */ | | | 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 | }else{ int rc = sqlite3_reset(pCsr->pStmt); if( rc==SQLITE_OK ){ /* If no row was found and no error has occured, then the %_content ** table is missing a row that is present in the full-text index. ** The data structures are corrupt. */ rc = SQLITE_CORRUPT_VTAB; } pCsr->isEof = 1; if( pContext ){ sqlite3_result_error_code(pContext, rc); } return rc; } |
︙ | ︙ | |||
1251 1252 1253 1254 1255 1256 1257 | ** contents, or two zero bytes. Or, if the node is read from the %_segments ** table, then there are always 20 bytes of zeroed padding following the ** nNode bytes of content (see sqlite3Fts3ReadBlock() for details). */ zCsr += sqlite3Fts3GetVarint(zCsr, &iChild); zCsr += sqlite3Fts3GetVarint(zCsr, &iChild); if( zCsr>zEnd ){ | | | | 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 | ** contents, or two zero bytes. Or, if the node is read from the %_segments ** table, then there are always 20 bytes of zeroed padding following the ** nNode bytes of content (see sqlite3Fts3ReadBlock() for details). */ zCsr += sqlite3Fts3GetVarint(zCsr, &iChild); zCsr += sqlite3Fts3GetVarint(zCsr, &iChild); if( zCsr>zEnd ){ return SQLITE_CORRUPT_VTAB; } while( zCsr<zEnd && (piFirst || piLast) ){ int cmp; /* memcmp() result */ int nSuffix; /* Size of term suffix */ int nPrefix = 0; /* Size of term prefix */ int nBuffer; /* Total term size */ /* Load the next term on the node into zBuffer. Use realloc() to expand ** the size of zBuffer if required. */ if( !isFirstTerm ){ zCsr += sqlite3Fts3GetVarint32(zCsr, &nPrefix); } isFirstTerm = 0; zCsr += sqlite3Fts3GetVarint32(zCsr, &nSuffix); if( nPrefix<0 || nSuffix<0 || &zCsr[nSuffix]>zEnd ){ rc = SQLITE_CORRUPT_VTAB; goto finish_scan; } if( nPrefix+nSuffix>nAlloc ){ char *zNew; nAlloc = (nPrefix+nSuffix) * 2; zNew = (char *)sqlite3_realloc(zBuffer, nAlloc); if( !zNew ){ |
︙ | ︙ |
Changes to ext/fts3/fts3_snippet.c.
︙ | ︙ | |||
956 957 958 959 960 961 962 | if( rc!=SQLITE_OK ) return rc; } pStmt = *ppStmt; assert( sqlite3_data_count(pStmt)==1 ); a = sqlite3_column_blob(pStmt, 0); a += sqlite3Fts3GetVarint(a, &nDoc); | | | 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 | if( rc!=SQLITE_OK ) return rc; } pStmt = *ppStmt; assert( sqlite3_data_count(pStmt)==1 ); a = sqlite3_column_blob(pStmt, 0); a += sqlite3Fts3GetVarint(a, &nDoc); if( nDoc==0 ) return SQLITE_CORRUPT_VTAB; *pnDoc = (u32)nDoc; if( paLen ) *paLen = a; return SQLITE_OK; } /* |
︙ | ︙ | |||
1551 1552 1553 1554 1555 1556 1557 | if( rc==SQLITE_OK ){ char aBuffer[64]; sqlite3_snprintf(sizeof(aBuffer), aBuffer, "%d %d %d %d ", iCol, pTerm-sCtx.aTerm, iStart, iEnd-iStart ); rc = fts3StringAppend(&res, aBuffer, -1); }else if( rc==SQLITE_DONE ){ | | | 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 | if( rc==SQLITE_OK ){ char aBuffer[64]; sqlite3_snprintf(sizeof(aBuffer), aBuffer, "%d %d %d %d ", iCol, pTerm-sCtx.aTerm, iStart, iEnd-iStart ); rc = fts3StringAppend(&res, aBuffer, -1); }else if( rc==SQLITE_DONE ){ rc = SQLITE_CORRUPT_VTAB; } } } if( rc==SQLITE_DONE ){ rc = SQLITE_OK; } |
︙ | ︙ |
Changes to ext/fts3/fts3_write.c.
︙ | ︙ | |||
287 288 289 290 291 292 293 | if( rc==SQLITE_OK ){ if( eStmt==SQL_SELECT_DOCSIZE ){ sqlite3_bind_int64(pStmt, 1, iDocid); } rc = sqlite3_step(pStmt); if( rc!=SQLITE_ROW || sqlite3_column_type(pStmt, 0)!=SQLITE_BLOB ){ rc = sqlite3_reset(pStmt); | | | 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | if( rc==SQLITE_OK ){ if( eStmt==SQL_SELECT_DOCSIZE ){ sqlite3_bind_int64(pStmt, 1, iDocid); } rc = sqlite3_step(pStmt); if( rc!=SQLITE_ROW || sqlite3_column_type(pStmt, 0)!=SQLITE_BLOB ){ rc = sqlite3_reset(pStmt); if( rc==SQLITE_OK ) rc = SQLITE_CORRUPT_VTAB; pStmt = 0; }else{ rc = SQLITE_OK; } } *ppStmt = pStmt; |
︙ | ︙ | |||
968 969 970 971 972 973 974 | ** safe (no risk of overread) even if the node data is corrupted. */ pNext += sqlite3Fts3GetVarint32(pNext, &nPrefix); pNext += sqlite3Fts3GetVarint32(pNext, &nSuffix); if( nPrefix<0 || nSuffix<=0 || &pNext[nSuffix]>&pReader->aNode[pReader->nNode] ){ | | | 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 | ** safe (no risk of overread) even if the node data is corrupted. */ pNext += sqlite3Fts3GetVarint32(pNext, &nPrefix); pNext += sqlite3Fts3GetVarint32(pNext, &nSuffix); if( nPrefix<0 || nSuffix<=0 || &pNext[nSuffix]>&pReader->aNode[pReader->nNode] ){ return SQLITE_CORRUPT_VTAB; } if( nPrefix+nSuffix>pReader->nTermAlloc ){ int nNew = (nPrefix+nSuffix)*2; char *zNew = sqlite3_realloc(pReader->zTerm, nNew); if( !zNew ){ return SQLITE_NOMEM; |
︙ | ︙ | |||
994 995 996 997 998 999 1000 | /* Check that the doclist does not appear to extend past the end of the ** b-tree node. And that the final byte of the doclist is 0x00. If either ** of these statements is untrue, then the data structure is corrupt. */ if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode] || pReader->aDoclist[pReader->nDoclist-1] ){ | | | 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 | /* Check that the doclist does not appear to extend past the end of the ** b-tree node. And that the final byte of the doclist is 0x00. If either ** of these statements is untrue, then the data structure is corrupt. */ if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode] || pReader->aDoclist[pReader->nDoclist-1] ){ return SQLITE_CORRUPT_VTAB; } return SQLITE_OK; } /* ** Set the SegReader to point to the first docid in the doclist associated ** with the current term. |
︙ | ︙ | |||
1119 1120 1121 1122 1123 1124 1125 | pEnd = &a[sqlite3_column_bytes(pStmt, 0)]; a += sqlite3Fts3GetVarint(a, &nDoc); while( a<pEnd ){ a += sqlite3Fts3GetVarint(a, &nByte); } if( nDoc==0 || nByte==0 ){ sqlite3_reset(pStmt); | | | 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 | pEnd = &a[sqlite3_column_bytes(pStmt, 0)]; a += sqlite3Fts3GetVarint(a, &nDoc); while( a<pEnd ){ a += sqlite3Fts3GetVarint(a, &nByte); } if( nDoc==0 || nByte==0 ){ sqlite3_reset(pStmt); return SQLITE_CORRUPT_VTAB; } pCsr->nRowAvg = (int)(((nByte / nDoc) + pgsz) / pgsz); assert( pCsr->nRowAvg>0 ); rc = sqlite3_reset(pStmt); if( rc!=SQLITE_OK ) return rc; } |
︙ | ︙ | |||
2758 2759 2760 2761 2762 2763 2764 | iRemove = sqlite3_value_int64(apVal[0]); } /* If this is an INSERT or UPDATE operation, insert the new record. */ if( nArg>1 && rc==SQLITE_OK ){ if( bInsertDone==0 ){ rc = fts3InsertData(p, apVal, pRowid); | | | 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 | iRemove = sqlite3_value_int64(apVal[0]); } /* If this is an INSERT or UPDATE operation, insert the new record. */ if( nArg>1 && rc==SQLITE_OK ){ if( bInsertDone==0 ){ rc = fts3InsertData(p, apVal, pRowid); if( rc==SQLITE_CONSTRAINT ) rc = SQLITE_CORRUPT_VTAB; } if( rc==SQLITE_OK && (!isRemove || *pRowid!=iRemove) ){ rc = fts3PendingTermsDocid(p, *pRowid); } if( rc==SQLITE_OK ){ rc = fts3InsertTerms(p, apVal, aSzIns); } |
︙ | ︙ |
Changes to ext/rtree/rtree.c.
︙ | ︙ | |||
513 514 515 516 517 518 519 | ** the root node. A height of one means the children of the root node ** are the leaves, and so on. If the depth as specified on the root node ** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt. */ if( pNode && iNode==1 ){ pRtree->iDepth = readInt16(pNode->zData); if( pRtree->iDepth>RTREE_MAX_DEPTH ){ | | | | | | 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 | ** the root node. A height of one means the children of the root node ** are the leaves, and so on. If the depth as specified on the root node ** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt. */ if( pNode && iNode==1 ){ pRtree->iDepth = readInt16(pNode->zData); if( pRtree->iDepth>RTREE_MAX_DEPTH ){ rc = SQLITE_CORRUPT_VTAB; } } /* If no error has occurred so far, check if the "number of entries" ** field on the node is too large. If so, set the return code to ** SQLITE_CORRUPT_VTAB. */ if( pNode && rc==SQLITE_OK ){ if( NCELL(pNode)>((pRtree->iNodeSize-4)/pRtree->nBytesPerCell) ){ rc = SQLITE_CORRUPT_VTAB; } } if( rc==SQLITE_OK ){ if( pNode!=0 ){ nodeHashInsert(pRtree, pNode); }else{ rc = SQLITE_CORRUPT_VTAB; } *ppNode = pNode; }else{ sqlite3_free(pNode); *ppNode = 0; } |
︙ | ︙ | |||
1058 1059 1060 1061 1062 1063 1064 | int nCell = NCELL(pNode); for(ii=0; ii<nCell; ii++){ if( nodeGetRowid(pRtree, pNode, ii)==iRowid ){ *piIndex = ii; return SQLITE_OK; } } | | | 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 | int nCell = NCELL(pNode); for(ii=0; ii<nCell; ii++){ if( nodeGetRowid(pRtree, pNode, ii)==iRowid ){ *piIndex = ii; return SQLITE_OK; } } return SQLITE_CORRUPT_VTAB; } /* ** Return the index of the cell containing a pointer to node pNode ** in its parent. If pNode is the root node, return -1. */ static int nodeParentIndex(Rtree *pRtree, RtreeNode *pNode, int *piIndex){ |
︙ | ︙ | |||
1653 1654 1655 1656 1657 1658 1659 | RtreeNode *p = pNode; while( p->pParent ){ RtreeNode *pParent = p->pParent; RtreeCell cell; int iCell; if( nodeParentIndex(pRtree, p, &iCell) ){ | | | 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 | RtreeNode *p = pNode; while( p->pParent ){ RtreeNode *pParent = p->pParent; RtreeCell cell; int iCell; if( nodeParentIndex(pRtree, p, &iCell) ){ return SQLITE_CORRUPT_VTAB; } nodeGetCell(pRtree, pParent, iCell, &cell); if( !cellContains(pRtree, &cell, pCell) ){ cellUnion(pRtree, &cell, pCell); nodeOverwriteCell(pRtree, pParent, &cell, iCell); } |
︙ | ︙ | |||
2325 2326 2327 2328 2329 2330 2331 | for(pTest=pLeaf; pTest && pTest->iNode!=iNode; pTest=pTest->pParent); if( !pTest ){ rc2 = nodeAcquire(pRtree, iNode, 0, &pChild->pParent); } } rc = sqlite3_reset(pRtree->pReadParent); if( rc==SQLITE_OK ) rc = rc2; | | | 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 | for(pTest=pLeaf; pTest && pTest->iNode!=iNode; pTest=pTest->pParent); if( !pTest ){ rc2 = nodeAcquire(pRtree, iNode, 0, &pChild->pParent); } } rc = sqlite3_reset(pRtree->pReadParent); if( rc==SQLITE_OK ) rc = rc2; if( rc==SQLITE_OK && !pChild->pParent ) rc = SQLITE_CORRUPT_VTAB; pChild = pChild->pParent; } return rc; } static int deleteCell(Rtree *, RtreeNode *, int, int); |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
449 450 451 452 453 454 455 456 457 458 459 460 461 462 | #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) /* ** CAPI3REF: Flags For File Open Operations ** ** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and ** in the 4th parameter to the [sqlite3_vfs.xOpen] method. | > | 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 | #define SQLITE_IOERR_SHMSIZE (SQLITE_IOERR | (19<<8)) #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) /* ** CAPI3REF: Flags For File Open Operations ** ** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and ** in the 4th parameter to the [sqlite3_vfs.xOpen] method. |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
159 160 161 162 163 164 165 166 167 168 169 170 171 172 | case SQLITE_IOERR_DELETE: zName = "SQLITE_IOERR_DELETE"; break; case SQLITE_IOERR_BLOCKED: zName = "SQLITE_IOERR_BLOCKED"; break; case SQLITE_IOERR_NOMEM: zName = "SQLITE_IOERR_NOMEM"; break; case SQLITE_IOERR_ACCESS: zName = "SQLITE_IOERR_ACCESS"; break; case SQLITE_IOERR_CHECKRESERVEDLOCK: zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break; case SQLITE_IOERR_LOCK: zName = "SQLITE_IOERR_LOCK"; break; default: zName = "SQLITE_Unknown"; break; } return zName; } #define t1ErrorName sqlite3TestErrorName /* | > > | 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | case SQLITE_IOERR_DELETE: zName = "SQLITE_IOERR_DELETE"; break; case SQLITE_IOERR_BLOCKED: zName = "SQLITE_IOERR_BLOCKED"; break; case SQLITE_IOERR_NOMEM: zName = "SQLITE_IOERR_NOMEM"; break; case SQLITE_IOERR_ACCESS: zName = "SQLITE_IOERR_ACCESS"; break; case SQLITE_IOERR_CHECKRESERVEDLOCK: zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break; case SQLITE_IOERR_LOCK: zName = "SQLITE_IOERR_LOCK"; break; case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break; zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break; default: zName = "SQLITE_Unknown"; break; } return zName; } #define t1ErrorName sqlite3TestErrorName /* |
︙ | ︙ |
Changes to test/fts3corrupt.test.
︙ | ︙ | |||
36 37 38 39 40 41 42 43 44 45 46 47 48 49 | foreach w {a b c d e f g h i j k l m n o} { execsql { INSERT INTO t1 VALUES($w) } } } {} do_catchsql_test 1.3 { INSERT INTO t1 VALUES('world'); } {1 {database disk image is malformed}} do_execsql_test 1.4 { DROP TABLE t1; } # This block of tests checks that corruption is correctly detected if the # length field of a term on a leaf node indicates that the term extends past # the end of the node on which it resides. There are two cases: | > | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | foreach w {a b c d e f g h i j k l m n o} { execsql { INSERT INTO t1 VALUES($w) } } } {} do_catchsql_test 1.3 { INSERT INTO t1 VALUES('world'); } {1 {database disk image is malformed}} do_test 1.3.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB do_execsql_test 1.4 { DROP TABLE t1; } # This block of tests checks that corruption is correctly detected if the # length field of a term on a leaf node indicates that the term extends past # the end of the node on which it resides. There are two cases: |
︙ | ︙ | |||
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | set blob [db one {SELECT root from t1_segdir}] set blob [binary format a*a* "\x00\x7F" [string range $blob 2 end]] execsql { UPDATE t1_segdir SET root = $blob } } {} do_catchsql_test 2.2 { SELECT rowid FROM t1 WHERE t1 MATCH 'hello' } {1 {database disk image is malformed}} do_execsql_test 3.0 { DROP TABLE t1; CREATE VIRTUAL TABLE t1 USING fts3; BEGIN; INSERT INTO t1 VALUES('hello'); INSERT INTO t1 VALUES('world'); COMMIT; } {} do_test fts3corrupt-3.1 { set blob [db one {SELECT quote(root) from t1_segdir}] set blob [binary format a11a*a* $blob "\x7F" [string range $blob 12 end]] execsql { UPDATE t1_segdir SET root = $blob } } {} do_catchsql_test 3.2 { SELECT rowid FROM t1 WHERE t1 MATCH 'world' } {1 {database disk image is malformed}} do_execsql_test 4.0 { DROP TABLE t1; CREATE VIRTUAL TABLE t1 USING fts3; INSERT INTO t1(t1) VALUES('nodesize=24'); } | > > | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | set blob [db one {SELECT root from t1_segdir}] set blob [binary format a*a* "\x00\x7F" [string range $blob 2 end]] execsql { UPDATE t1_segdir SET root = $blob } } {} do_catchsql_test 2.2 { SELECT rowid FROM t1 WHERE t1 MATCH 'hello' } {1 {database disk image is malformed}} do_test 2.2.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB do_execsql_test 3.0 { DROP TABLE t1; CREATE VIRTUAL TABLE t1 USING fts3; BEGIN; INSERT INTO t1 VALUES('hello'); INSERT INTO t1 VALUES('world'); COMMIT; } {} do_test fts3corrupt-3.1 { set blob [db one {SELECT quote(root) from t1_segdir}] set blob [binary format a11a*a* $blob "\x7F" [string range $blob 12 end]] execsql { UPDATE t1_segdir SET root = $blob } } {} do_catchsql_test 3.2 { SELECT rowid FROM t1 WHERE t1 MATCH 'world' } {1 {database disk image is malformed}} do_test 3.2.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB do_execsql_test 4.0 { DROP TABLE t1; CREATE VIRTUAL TABLE t1 USING fts3; INSERT INTO t1(t1) VALUES('nodesize=24'); } |
︙ | ︙ | |||
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | execsql COMMIT } {} do_catchsql_test 4.2 { UPDATE t1_segdir SET root = X'FFFFFFFFFFFFFFFF'; SELECT rowid FROM t1 WHERE t1 MATCH 'world'; } {1 {database disk image is malformed}} set blob [binary format cca*cca*cca*cca*cca*cca*cca*cca*cca*cca*a* \ 22 120 [string repeat a 120] \ 22 120 [string repeat b 120] \ 22 120 [string repeat c 120] \ 22 120 [string repeat d 120] \ 22 120 [string repeat e 120] \ 22 120 [string repeat f 120] \ 22 120 [string repeat g 120] \ 22 120 [string repeat h 120] \ 22 120 [string repeat i 120] \ 22 120 [string repeat j 120] \ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" ] do_catchsql_test 4.3 { UPDATE t1_segdir SET root = $blob; SELECT rowid FROM t1 WHERE t1 MATCH 'world'; } {1 {database disk image is malformed}} # Test a special kind of corruption, where the %_stat table contains # an invalid entry. At one point this could lead to a division-by-zero # error in fts4. # do_execsql_test 5.0 { DROP TABLE t1; | > > | 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | execsql COMMIT } {} do_catchsql_test 4.2 { UPDATE t1_segdir SET root = X'FFFFFFFFFFFFFFFF'; SELECT rowid FROM t1 WHERE t1 MATCH 'world'; } {1 {database disk image is malformed}} do_test 4.2.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB set blob [binary format cca*cca*cca*cca*cca*cca*cca*cca*cca*cca*a* \ 22 120 [string repeat a 120] \ 22 120 [string repeat b 120] \ 22 120 [string repeat c 120] \ 22 120 [string repeat d 120] \ 22 120 [string repeat e 120] \ 22 120 [string repeat f 120] \ 22 120 [string repeat g 120] \ 22 120 [string repeat h 120] \ 22 120 [string repeat i 120] \ 22 120 [string repeat j 120] \ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" ] do_catchsql_test 4.3 { UPDATE t1_segdir SET root = $blob; SELECT rowid FROM t1 WHERE t1 MATCH 'world'; } {1 {database disk image is malformed}} do_test 4.3.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB # Test a special kind of corruption, where the %_stat table contains # an invalid entry. At one point this could lead to a division-by-zero # error in fts4. # do_execsql_test 5.0 { DROP TABLE t1; |
︙ | ︙ | |||
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | execsql { INSERT INTO t1 VALUES('four') } execsql COMMIT } {} do_catchsql_test 5.2 { UPDATE t1_stat SET value = X'0000'; SELECT matchinfo(t1, 'nxa') FROM t1 WHERE t1 MATCH 't*'; } {1 {database disk image is malformed}} do_catchsql_test 5.3 { UPDATE t1_stat SET value = NULL; SELECT matchinfo(t1, 'nxa') FROM t1 WHERE t1 MATCH 't*'; } {1 {database disk image is malformed}} finish_test | > > | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | execsql { INSERT INTO t1 VALUES('four') } execsql COMMIT } {} do_catchsql_test 5.2 { UPDATE t1_stat SET value = X'0000'; SELECT matchinfo(t1, 'nxa') FROM t1 WHERE t1 MATCH 't*'; } {1 {database disk image is malformed}} do_test 5.2.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB do_catchsql_test 5.3 { UPDATE t1_stat SET value = NULL; SELECT matchinfo(t1, 'nxa') FROM t1 WHERE t1 MATCH 't*'; } {1 {database disk image is malformed}} do_test 5.3.1 { sqlite3_extended_errcode db } SQLITE_CORRUPT_VTAB finish_test |