OLD | NEW |
1 Index: ext/fts3/fts3_tokenizer.c | |
2 =================================================================== | |
3 --- ext/fts3/fts3_tokenizer.c (revision 48758) | |
4 +++ ext/fts3/fts3_tokenizer.c (working copy) | |
5 @@ -33,6 +33,7 @@ | |
6 #include "fts3_hash.h" | |
7 #include "fts3_tokenizer.h" | |
8 #include <assert.h> | |
9 +#include <stddef.h> | |
10 | |
11 /* | |
12 ** Implementation of the SQL scalar function for accessing the underlying | |
13 Index: ext/fts3/fts3.c | 1 Index: ext/fts3/fts3.c |
14 =================================================================== | 2 =================================================================== |
15 --- ext/fts3/fts3.c» (revision 48758) | 3 --- ext/fts3/fts3.c» (revision 48811) |
16 +++ ext/fts3/fts3.c (working copy) | 4 +++ ext/fts3/fts3.c (working copy) |
17 @@ -271,6 +271,7 @@ | 5 @@ -271,6 +271,7 @@ |
18 ** deletions and duplications. This would basically be a forced merge | 6 ** deletions and duplications. This would basically be a forced merge |
19 ** into a single segment. | 7 ** into a single segment. |
20 */ | 8 */ |
21 +#define CHROMIUM_FTS3_CHANGES 1 | 9 +#define CHROMIUM_FTS3_CHANGES 1 |
22 | 10 |
23 #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) | 11 #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) |
24 | 12 |
25 @@ -313,6 +314,16 @@ | 13 @@ -313,6 +314,16 @@ |
(...skipping 1212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1238 | 1226 |
1239 - pReader->pData += n+nSuffix; | 1227 - pReader->pData += n+nSuffix; |
1240 - pReader->nData -= n+nSuffix; | 1228 - pReader->nData -= n+nSuffix; |
1241 + pReader->pData += nSuffix; | 1229 + pReader->pData += nSuffix; |
1242 + pReader->nData -= nSuffix; | 1230 + pReader->nData -= nSuffix; |
1243 } | 1231 } |
1244 + return SQLITE_OK; | 1232 + return SQLITE_OK; |
1245 } | 1233 } |
1246 | 1234 |
1247 /* strcmp-style comparison of pReader's current term against pTerm. | 1235 /* strcmp-style comparison of pReader's current term against pTerm. |
1248 @@ -5222,32 +5423,65 @@ | 1236 @@ -5222,32 +5423,67 @@ |
1249 | 1237 |
1250 dataBufferInit(&pReader->rootData, 0); | 1238 dataBufferInit(&pReader->rootData, 0); |
1251 if( iStartBlockid==0 ){ | 1239 if( iStartBlockid==0 ){ |
1252 + int rc; | 1240 + int rc; |
1253 + /* Corrupt if this can't be a leaf node. */ | 1241 + /* Corrupt if this can't be a leaf node. */ |
1254 + if( pRootData==NULL || nRootData<1 || pRootData[0]!='\0' ){ | 1242 + if( pRootData==NULL || nRootData<1 || pRootData[0]!='\0' ){ |
1255 + return SQLITE_CORRUPT_BKPT; | 1243 + return SQLITE_CORRUPT_BKPT; |
1256 + } | 1244 + } |
1257 /* Entire leaf level fit in root data. */ | 1245 /* Entire leaf level fit in root data. */ |
1258 dataBufferReplace(&pReader->rootData, pRootData, nRootData); | 1246 dataBufferReplace(&pReader->rootData, pRootData, nRootData); |
(...skipping 22 matching lines...) Expand all Loading... |
1281 + | 1269 + |
1282 + /* Corrupt if interior node referenced missing leaf node. */ | 1270 + /* Corrupt if interior node referenced missing leaf node. */ |
1283 if( rc==SQLITE_DONE ){ | 1271 if( rc==SQLITE_DONE ){ |
1284 - pReader->eof = 1; | 1272 - pReader->eof = 1; |
1285 - return SQLITE_OK; | 1273 - return SQLITE_OK; |
1286 + rc = SQLITE_CORRUPT_BKPT; | 1274 + rc = SQLITE_CORRUPT_BKPT; |
1287 + goto err; | 1275 + goto err; |
1288 } | 1276 } |
1289 - if( rc!=SQLITE_ROW ) return rc; | 1277 - if( rc!=SQLITE_ROW ) return rc; |
1290 | 1278 |
1291 - pReader->pStmt = s; | |
1292 - leafReaderInit(sqlite3_column_blob(pReader->pStmt, 0), | |
1293 - sqlite3_column_bytes(pReader->pStmt, 0), | |
1294 - &pReader->leafReader); | |
1295 + if( rc!=SQLITE_ROW ) goto err; | 1279 + if( rc!=SQLITE_ROW ) goto err; |
1296 + rc = SQLITE_OK; | 1280 + rc = SQLITE_OK; |
1297 + | 1281 + |
1298 + /* Corrupt if leaf data isn't a blob. */ | 1282 + /* Corrupt if leaf data isn't a blob. */ |
1299 + if( sqlite3_column_type(s, 0)!=SQLITE_BLOB ){ | 1283 + if( sqlite3_column_type(s, 0)!=SQLITE_BLOB ){ |
1300 + rc = SQLITE_CORRUPT_BKPT; | 1284 + rc = SQLITE_CORRUPT_BKPT; |
1301 + }else{ | 1285 + }else{ |
1302 + const char *pLeafData = sqlite3_column_blob(s, 0); | 1286 + const char *pLeafData = sqlite3_column_blob(s, 0); |
1303 + int nLeafData = sqlite3_column_bytes(s, 0); | 1287 + int nLeafData = sqlite3_column_bytes(s, 0); |
1304 + | 1288 + |
1305 + /* Corrupt if this can't be a leaf node. */ | 1289 + /* Corrupt if this can't be a leaf node. */ |
1306 + if( pLeafData==NULL || nLeafData<1 || pLeafData[0]!='\0' ){ | 1290 + if( pLeafData==NULL || nLeafData<1 || pLeafData[0]!='\0' ){ |
1307 + rc = SQLITE_CORRUPT_BKPT; | 1291 + rc = SQLITE_CORRUPT_BKPT; |
1308 + }else{ | 1292 + }else{ |
1309 + rc = leafReaderInit(pLeafData, nLeafData, &pReader->leafReader); | 1293 + rc = leafReaderInit(pLeafData, nLeafData, &pReader->leafReader); |
1310 + } | 1294 + } |
1311 + } | 1295 + } |
1312 + | 1296 + |
1313 + err: | 1297 + err: |
1314 + if( rc!=SQLITE_OK ){ | 1298 + if( rc!=SQLITE_OK ){ |
1315 + if( idx==-1 ){ | 1299 + if( idx==-1 ){ |
1316 + sqlite3_finalize(s); | 1300 + sqlite3_finalize(s); |
1317 + }else{ | 1301 + }else{ |
1318 + sqlite3_reset(s); | 1302 + sqlite3_reset(s); |
1319 + } | 1303 + } |
1320 + return rc; | 1304 + return rc; |
1321 + } | 1305 + } |
| 1306 + |
| 1307 pReader->pStmt = s; |
| 1308 - leafReaderInit(sqlite3_column_blob(pReader->pStmt, 0), |
| 1309 - sqlite3_column_bytes(pReader->pStmt, 0), |
| 1310 - &pReader->leafReader); |
1322 } | 1311 } |
1323 return SQLITE_OK; | 1312 return SQLITE_OK; |
1324 } | 1313 } |
1325 @@ -5256,11 +5490,12 @@ | 1314 @@ -5256,11 +5492,12 @@ |
1326 ** end of the current leaf, step forward to the next leaf block. | 1315 ** end of the current leaf, step forward to the next leaf block. |
1327 */ | 1316 */ |
1328 static int leavesReaderStep(fulltext_vtab *v, LeavesReader *pReader){ | 1317 static int leavesReaderStep(fulltext_vtab *v, LeavesReader *pReader){ |
1329 + int rc; | 1318 + int rc; |
1330 assert( !leavesReaderAtEnd(pReader) ); | 1319 assert( !leavesReaderAtEnd(pReader) ); |
1331 - leafReaderStep(&pReader->leafReader); | 1320 - leafReaderStep(&pReader->leafReader); |
1332 + rc = leafReaderStep(&pReader->leafReader); | 1321 + rc = leafReaderStep(&pReader->leafReader); |
1333 + if( rc!=SQLITE_OK ) return rc; | 1322 + if( rc!=SQLITE_OK ) return rc; |
1334 | 1323 |
1335 if( leafReaderAtEnd(&pReader->leafReader) ){ | 1324 if( leafReaderAtEnd(&pReader->leafReader) ){ |
1336 - int rc; | 1325 - int rc; |
1337 if( pReader->rootData.pData ){ | 1326 if( pReader->rootData.pData ){ |
1338 pReader->eof = 1; | 1327 pReader->eof = 1; |
1339 return SQLITE_OK; | 1328 return SQLITE_OK; |
1340 @@ -5270,10 +5505,25 @@ | 1329 @@ -5270,10 +5507,25 @@ |
1341 pReader->eof = 1; | 1330 pReader->eof = 1; |
1342 return rc==SQLITE_DONE ? SQLITE_OK : rc; | 1331 return rc==SQLITE_DONE ? SQLITE_OK : rc; |
1343 } | 1332 } |
1344 - leafReaderDestroy(&pReader->leafReader); | 1333 - leafReaderDestroy(&pReader->leafReader); |
1345 - leafReaderInit(sqlite3_column_blob(pReader->pStmt, 0), | 1334 - leafReaderInit(sqlite3_column_blob(pReader->pStmt, 0), |
1346 - sqlite3_column_bytes(pReader->pStmt, 0), | 1335 - sqlite3_column_bytes(pReader->pStmt, 0), |
1347 - &pReader->leafReader); | 1336 - &pReader->leafReader); |
1348 + | 1337 + |
1349 + /* Corrupt if leaf data isn't a blob. */ | 1338 + /* Corrupt if leaf data isn't a blob. */ |
1350 + if( sqlite3_column_type(pReader->pStmt, 0)!=SQLITE_BLOB ){ | 1339 + if( sqlite3_column_type(pReader->pStmt, 0)!=SQLITE_BLOB ){ |
1351 + return SQLITE_CORRUPT_BKPT; | 1340 + return SQLITE_CORRUPT_BKPT; |
1352 + }else{ | 1341 + }else{ |
1353 + LeafReader tmp; | 1342 + LeafReader tmp; |
1354 + const char *pLeafData = sqlite3_column_blob(pReader->pStmt, 0); | 1343 + const char *pLeafData = sqlite3_column_blob(pReader->pStmt, 0); |
1355 + int nLeafData = sqlite3_column_bytes(pReader->pStmt, 0); | 1344 + int nLeafData = sqlite3_column_bytes(pReader->pStmt, 0); |
1356 + | 1345 + |
1357 + /* Corrupt if this can't be a leaf node. */ | 1346 + /* Corrupt if this can't be a leaf node. */ |
1358 + if( pLeafData==NULL || nLeafData<1 || pLeafData[0]!='\0' ){ | 1347 + if( pLeafData==NULL || nLeafData<1 || pLeafData[0]!='\0' ){ |
1359 + return SQLITE_CORRUPT_BKPT; | 1348 + return SQLITE_CORRUPT_BKPT; |
1360 + } | 1349 + } |
1361 + | 1350 + |
1362 + rc = leafReaderInit(pLeafData, nLeafData, &tmp); | 1351 + rc = leafReaderInit(pLeafData, nLeafData, &tmp); |
1363 + if( rc!=SQLITE_OK ) return rc; | 1352 + if( rc!=SQLITE_OK ) return rc; |
1364 + leafReaderDestroy(&pReader->leafReader); | 1353 + leafReaderDestroy(&pReader->leafReader); |
1365 + pReader->leafReader = tmp; | 1354 + pReader->leafReader = tmp; |
1366 + } | 1355 + } |
1367 } | 1356 } |
1368 return SQLITE_OK; | 1357 return SQLITE_OK; |
1369 } | 1358 } |
1370 @@ -5334,8 +5584,19 @@ | 1359 @@ -5334,8 +5586,19 @@ |
1371 sqlite_int64 iEnd = sqlite3_column_int64(s, 1); | 1360 sqlite_int64 iEnd = sqlite3_column_int64(s, 1); |
1372 const char *pRootData = sqlite3_column_blob(s, 2); | 1361 const char *pRootData = sqlite3_column_blob(s, 2); |
1373 int nRootData = sqlite3_column_bytes(s, 2); | 1362 int nRootData = sqlite3_column_bytes(s, 2); |
1374 + sqlite_int64 iIndex = sqlite3_column_int64(s, 3); | 1363 + sqlite_int64 iIndex = sqlite3_column_int64(s, 3); |
1375 | 1364 |
1376 - assert( i<MERGE_COUNT ); | 1365 - assert( i<MERGE_COUNT ); |
1377 + /* Corrupt if we get back different types than we stored. */ | 1366 + /* Corrupt if we get back different types than we stored. */ |
1378 + /* Also corrupt if the index is not sequential starting at 0. */ | 1367 + /* Also corrupt if the index is not sequential starting at 0. */ |
1379 + if( sqlite3_column_type(s, 0)!=SQLITE_INTEGER || | 1368 + if( sqlite3_column_type(s, 0)!=SQLITE_INTEGER || |
1380 + sqlite3_column_type(s, 1)!=SQLITE_INTEGER || | 1369 + sqlite3_column_type(s, 1)!=SQLITE_INTEGER || |
1381 + sqlite3_column_type(s, 2)!=SQLITE_BLOB || | 1370 + sqlite3_column_type(s, 2)!=SQLITE_BLOB || |
1382 + i!=iIndex || | 1371 + i!=iIndex || |
1383 + i>=MERGE_COUNT ){ | 1372 + i>=MERGE_COUNT ){ |
1384 + rc = SQLITE_CORRUPT_BKPT; | 1373 + rc = SQLITE_CORRUPT_BKPT; |
1385 + break; | 1374 + break; |
1386 + } | 1375 + } |
1387 + | 1376 + |
1388 rc = leavesReaderInit(v, i, iStart, iEnd, pRootData, nRootData, | 1377 rc = leavesReaderInit(v, i, iStart, iEnd, pRootData, nRootData, |
1389 &pReaders[i]); | 1378 &pReaders[i]); |
1390 if( rc!=SQLITE_OK ) break; | 1379 if( rc!=SQLITE_OK ) break; |
1391 @@ -5346,6 +5607,7 @@ | 1380 @@ -5346,6 +5609,7 @@ |
1392 while( i-->0 ){ | 1381 while( i-->0 ){ |
1393 leavesReaderDestroy(&pReaders[i]); | 1382 leavesReaderDestroy(&pReaders[i]); |
1394 } | 1383 } |
1395 + sqlite3_reset(s); /* So we don't leave a lock. */ | 1384 + sqlite3_reset(s); /* So we don't leave a lock. */ |
1396 return rc; | 1385 return rc; |
1397 } | 1386 } |
1398 | 1387 |
1399 @@ -5369,14 +5631,27 @@ | 1388 @@ -5369,14 +5633,27 @@ |
1400 DLReader dlReaders[MERGE_COUNT]; | 1389 DLReader dlReaders[MERGE_COUNT]; |
1401 const char *pTerm = leavesReaderTerm(pReaders); | 1390 const char *pTerm = leavesReaderTerm(pReaders); |
1402 int i, nTerm = leavesReaderTermBytes(pReaders); | 1391 int i, nTerm = leavesReaderTermBytes(pReaders); |
1403 + int rc; | 1392 + int rc; |
1404 | 1393 |
1405 assert( nReaders<=MERGE_COUNT ); | 1394 assert( nReaders<=MERGE_COUNT ); |
1406 | 1395 |
1407 for(i=0; i<nReaders; i++){ | 1396 for(i=0; i<nReaders; i++){ |
1408 - dlrInit(&dlReaders[i], DL_DEFAULT, | 1397 - dlrInit(&dlReaders[i], DL_DEFAULT, |
1409 - leavesReaderData(pReaders+i), | 1398 - leavesReaderData(pReaders+i), |
(...skipping 10 matching lines...) Expand all Loading... |
1420 } | 1409 } |
1421 + if( rc!=SQLITE_OK ){ | 1410 + if( rc!=SQLITE_OK ){ |
1422 + while( i-->0 ){ | 1411 + while( i-->0 ){ |
1423 + dlrDestroy(&dlReaders[i]); | 1412 + dlrDestroy(&dlReaders[i]); |
1424 + } | 1413 + } |
1425 + return rc; | 1414 + return rc; |
1426 + } | 1415 + } |
1427 | 1416 |
1428 return leafWriterStepMerge(v, pWriter, pTerm, nTerm, dlReaders, nReaders); | 1417 return leafWriterStepMerge(v, pWriter, pTerm, nTerm, dlReaders, nReaders); |
1429 } | 1418 } |
1430 @@ -5429,10 +5704,14 @@ | 1419 @@ -5429,10 +5706,14 @@ |
1431 memset(&lrs, '\0', sizeof(lrs)); | 1420 memset(&lrs, '\0', sizeof(lrs)); |
1432 rc = leavesReadersInit(v, iLevel, lrs, &i); | 1421 rc = leavesReadersInit(v, iLevel, lrs, &i); |
1433 if( rc!=SQLITE_OK ) return rc; | 1422 if( rc!=SQLITE_OK ) return rc; |
1434 - assert( i==MERGE_COUNT ); | 1423 - assert( i==MERGE_COUNT ); |
1435 | 1424 |
1436 leafWriterInit(iLevel+1, idx, &writer); | 1425 leafWriterInit(iLevel+1, idx, &writer); |
1437 | 1426 |
1438 + if( i!=MERGE_COUNT ){ | 1427 + if( i!=MERGE_COUNT ){ |
1439 + rc = SQLITE_CORRUPT_BKPT; | 1428 + rc = SQLITE_CORRUPT_BKPT; |
1440 + goto err; | 1429 + goto err; |
1441 + } | 1430 + } |
1442 + | 1431 + |
1443 /* Since leavesReaderReorder() pushes readers at eof to the end, | 1432 /* Since leavesReaderReorder() pushes readers at eof to the end, |
1444 ** when the first reader is empty, all will be empty. | 1433 ** when the first reader is empty, all will be empty. |
1445 */ | 1434 */ |
1446 @@ -5475,12 +5754,14 @@ | 1435 @@ -5475,12 +5756,14 @@ |
1447 } | 1436 } |
1448 | 1437 |
1449 /* Accumulate the union of *acc and *pData into *acc. */ | 1438 /* Accumulate the union of *acc and *pData into *acc. */ |
1450 -static void docListAccumulateUnion(DataBuffer *acc, | 1439 -static void docListAccumulateUnion(DataBuffer *acc, |
1451 - const char *pData, int nData) { | 1440 - const char *pData, int nData) { |
1452 +static int docListAccumulateUnion(DataBuffer *acc, | 1441 +static int docListAccumulateUnion(DataBuffer *acc, |
1453 + const char *pData, int nData) { | 1442 + const char *pData, int nData) { |
1454 DataBuffer tmp = *acc; | 1443 DataBuffer tmp = *acc; |
1455 + int rc; | 1444 + int rc; |
1456 dataBufferInit(acc, tmp.nData+nData); | 1445 dataBufferInit(acc, tmp.nData+nData); |
1457 - docListUnion(tmp.pData, tmp.nData, pData, nData, acc); | 1446 - docListUnion(tmp.pData, tmp.nData, pData, nData, acc); |
1458 + rc = docListUnion(tmp.pData, tmp.nData, pData, nData, acc); | 1447 + rc = docListUnion(tmp.pData, tmp.nData, pData, nData, acc); |
1459 dataBufferDestroy(&tmp); | 1448 dataBufferDestroy(&tmp); |
1460 + return rc; | 1449 + return rc; |
1461 } | 1450 } |
1462 | 1451 |
1463 /* TODO(shess) It might be interesting to explore different merge | 1452 /* TODO(shess) It might be interesting to explore different merge |
1464 @@ -5522,8 +5803,13 @@ | 1453 @@ -5522,8 +5805,13 @@ |
1465 int c = leafReaderTermCmp(&pReader->leafReader, pTerm, nTerm, isPrefix); | 1454 int c = leafReaderTermCmp(&pReader->leafReader, pTerm, nTerm, isPrefix); |
1466 if( c>0 ) break; /* Past any possible matches. */ | 1455 if( c>0 ) break; /* Past any possible matches. */ |
1467 if( c==0 ){ | 1456 if( c==0 ){ |
1468 + int iBuffer, nData; | 1457 + int iBuffer, nData; |
1469 const char *pData = leavesReaderData(pReader); | 1458 const char *pData = leavesReaderData(pReader); |
1470 - int iBuffer, nData = leavesReaderDataBytes(pReader); | 1459 - int iBuffer, nData = leavesReaderDataBytes(pReader); |
1471 + if( pData==NULL ){ | 1460 + if( pData==NULL ){ |
1472 + rc = SQLITE_CORRUPT_BKPT; | 1461 + rc = SQLITE_CORRUPT_BKPT; |
1473 + break; | 1462 + break; |
1474 + } | 1463 + } |
1475 + nData = leavesReaderDataBytes(pReader); | 1464 + nData = leavesReaderDataBytes(pReader); |
1476 | 1465 |
1477 /* Find the first empty buffer. */ | 1466 /* Find the first empty buffer. */ |
1478 for(iBuffer=0; iBuffer<nBuffers; ++iBuffer){ | 1467 for(iBuffer=0; iBuffer<nBuffers; ++iBuffer){ |
1479 @@ -5569,11 +5855,13 @@ | 1468 @@ -5569,11 +5857,13 @@ |
1480 ** with pData/nData. | 1469 ** with pData/nData. |
1481 */ | 1470 */ |
1482 dataBufferSwap(p, pAcc); | 1471 dataBufferSwap(p, pAcc); |
1483 - docListAccumulateUnion(pAcc, pData, nData); | 1472 - docListAccumulateUnion(pAcc, pData, nData); |
1484 + rc = docListAccumulateUnion(pAcc, pData, nData); | 1473 + rc = docListAccumulateUnion(pAcc, pData, nData); |
1485 + if( rc!=SQLITE_OK ) goto err; | 1474 + if( rc!=SQLITE_OK ) goto err; |
1486 | 1475 |
1487 /* Accumulate remaining doclists into pAcc. */ | 1476 /* Accumulate remaining doclists into pAcc. */ |
1488 for(++p; p<pAcc; ++p){ | 1477 for(++p; p<pAcc; ++p){ |
1489 - docListAccumulateUnion(pAcc, p->pData, p->nData); | 1478 - docListAccumulateUnion(pAcc, p->pData, p->nData); |
1490 + rc = docListAccumulateUnion(pAcc, p->pData, p->nData); | 1479 + rc = docListAccumulateUnion(pAcc, p->pData, p->nData); |
1491 + if( rc!=SQLITE_OK ) goto err; | 1480 + if( rc!=SQLITE_OK ) goto err; |
1492 | 1481 |
1493 /* dataBufferReset() could allow a large doclist to blow up | 1482 /* dataBufferReset() could allow a large doclist to blow up |
1494 ** our memory requirements. | 1483 ** our memory requirements. |
1495 @@ -5598,13 +5886,15 @@ | 1484 @@ -5598,13 +5888,15 @@ |
1496 if( out->nData==0 ){ | 1485 if( out->nData==0 ){ |
1497 dataBufferSwap(out, &(pBuffers[iBuffer])); | 1486 dataBufferSwap(out, &(pBuffers[iBuffer])); |
1498 }else{ | 1487 }else{ |
1499 - docListAccumulateUnion(out, pBuffers[iBuffer].pData, | 1488 - docListAccumulateUnion(out, pBuffers[iBuffer].pData, |
1500 - pBuffers[iBuffer].nData); | 1489 - pBuffers[iBuffer].nData); |
1501 + rc = docListAccumulateUnion(out, pBuffers[iBuffer].pData, | 1490 + rc = docListAccumulateUnion(out, pBuffers[iBuffer].pData, |
1502 + pBuffers[iBuffer].nData); | 1491 + pBuffers[iBuffer].nData); |
1503 + if( rc!=SQLITE_OK ) break; | 1492 + if( rc!=SQLITE_OK ) break; |
1504 } | 1493 } |
1505 } | 1494 } |
1506 } | 1495 } |
1507 } | 1496 } |
1508 | 1497 |
1509 +err: | 1498 +err: |
1510 while( nBuffers-- ){ | 1499 while( nBuffers-- ){ |
1511 dataBufferDestroy(&(pBuffers[nBuffers])); | 1500 dataBufferDestroy(&(pBuffers[nBuffers])); |
1512 } | 1501 } |
1513 @@ -5663,20 +5953,26 @@ | 1502 @@ -5663,20 +5955,26 @@ |
1514 ** node. Consider whether breaking symmetry is worthwhile. I suspect | 1503 ** node. Consider whether breaking symmetry is worthwhile. I suspect |
1515 ** it is not worthwhile. | 1504 ** it is not worthwhile. |
1516 */ | 1505 */ |
1517 -static void getChildrenContaining(const char *pData, int nData, | 1506 -static void getChildrenContaining(const char *pData, int nData, |
1518 - const char *pTerm, int nTerm, int isPrefix, | 1507 - const char *pTerm, int nTerm, int isPrefix, |
1519 - sqlite_int64 *piStartChild, | 1508 - sqlite_int64 *piStartChild, |
1520 - sqlite_int64 *piEndChild){ | 1509 - sqlite_int64 *piEndChild){ |
1521 +static int getChildrenContaining(const char *pData, int nData, | 1510 +static int getChildrenContaining(const char *pData, int nData, |
1522 + const char *pTerm, int nTerm, int isPrefix, | 1511 + const char *pTerm, int nTerm, int isPrefix, |
1523 + sqlite_int64 *piStartChild, | 1512 + sqlite_int64 *piStartChild, |
(...skipping 12 matching lines...) Expand all Loading... |
1536 if( interiorReaderTermCmp(&reader, pTerm, nTerm, 0)>0 ) break; | 1525 if( interiorReaderTermCmp(&reader, pTerm, nTerm, 0)>0 ) break; |
1537 - interiorReaderStep(&reader); | 1526 - interiorReaderStep(&reader); |
1538 + rc = interiorReaderStep(&reader); | 1527 + rc = interiorReaderStep(&reader); |
1539 + if( rc!=SQLITE_OK ){ | 1528 + if( rc!=SQLITE_OK ){ |
1540 + interiorReaderDestroy(&reader); | 1529 + interiorReaderDestroy(&reader); |
1541 + return rc; | 1530 + return rc; |
1542 + } | 1531 + } |
1543 } | 1532 } |
1544 *piStartChild = interiorReaderCurrentBlockid(&reader); | 1533 *piStartChild = interiorReaderCurrentBlockid(&reader); |
1545 | 1534 |
1546 @@ -5686,7 +5982,11 @@ | 1535 @@ -5686,7 +5984,11 @@ |
1547 */ | 1536 */ |
1548 while( !interiorReaderAtEnd(&reader) ){ | 1537 while( !interiorReaderAtEnd(&reader) ){ |
1549 if( interiorReaderTermCmp(&reader, pTerm, nTerm, isPrefix)>0 ) break; | 1538 if( interiorReaderTermCmp(&reader, pTerm, nTerm, isPrefix)>0 ) break; |
1550 - interiorReaderStep(&reader); | 1539 - interiorReaderStep(&reader); |
1551 + rc = interiorReaderStep(&reader); | 1540 + rc = interiorReaderStep(&reader); |
1552 + if( rc!=SQLITE_OK ){ | 1541 + if( rc!=SQLITE_OK ){ |
1553 + interiorReaderDestroy(&reader); | 1542 + interiorReaderDestroy(&reader); |
1554 + return rc; | 1543 + return rc; |
1555 + } | 1544 + } |
1556 } | 1545 } |
1557 *piEndChild = interiorReaderCurrentBlockid(&reader); | 1546 *piEndChild = interiorReaderCurrentBlockid(&reader); |
1558 | 1547 |
1559 @@ -5695,6 +5995,7 @@ | 1548 @@ -5695,6 +5997,7 @@ |
1560 /* Children must ascend, and if !prefix, both must be the same. */ | 1549 /* Children must ascend, and if !prefix, both must be the same. */ |
1561 assert( *piEndChild>=*piStartChild ); | 1550 assert( *piEndChild>=*piStartChild ); |
1562 assert( isPrefix || *piStartChild==*piEndChild ); | 1551 assert( isPrefix || *piStartChild==*piEndChild ); |
1563 + return rc; | 1552 + return rc; |
1564 } | 1553 } |
1565 | 1554 |
1566 /* Read block at iBlockid and pass it with other params to | 1555 /* Read block at iBlockid and pass it with other params to |
1567 @@ -5722,12 +6023,32 @@ | 1556 @@ -5722,12 +6025,32 @@ |
1568 if( rc!=SQLITE_OK ) return rc; | 1557 if( rc!=SQLITE_OK ) return rc; |
1569 | 1558 |
1570 rc = sqlite3_step(s); | 1559 rc = sqlite3_step(s); |
1571 - if( rc==SQLITE_DONE ) return SQLITE_ERROR; | 1560 - if( rc==SQLITE_DONE ) return SQLITE_ERROR; |
1572 + /* Corrupt if interior node references missing child node. */ | 1561 + /* Corrupt if interior node references missing child node. */ |
1573 + if( rc==SQLITE_DONE ) return SQLITE_CORRUPT_BKPT; | 1562 + if( rc==SQLITE_DONE ) return SQLITE_CORRUPT_BKPT; |
1574 if( rc!=SQLITE_ROW ) return rc; | 1563 if( rc!=SQLITE_ROW ) return rc; |
1575 | 1564 |
1576 - getChildrenContaining(sqlite3_column_blob(s, 0), sqlite3_column_bytes(s, 0), | 1565 - getChildrenContaining(sqlite3_column_blob(s, 0), sqlite3_column_bytes(s, 0), |
1577 - pTerm, nTerm, isPrefix, piStartChild, piEndChild); | 1566 - pTerm, nTerm, isPrefix, piStartChild, piEndChild); |
(...skipping 15 matching lines...) Expand all Loading... |
1593 + isPrefix, piStartChild, piEndChild); | 1582 + isPrefix, piStartChild, piEndChild); |
1594 + if( rc!=SQLITE_OK ){ | 1583 + if( rc!=SQLITE_OK ){ |
1595 + sqlite3_reset(s); | 1584 + sqlite3_reset(s); |
1596 + return rc; | 1585 + return rc; |
1597 + } | 1586 + } |
1598 + } | 1587 + } |
1599 + | 1588 + |
1600 /* We expect only one row. We must execute another sqlite3_step() | 1589 /* We expect only one row. We must execute another sqlite3_step() |
1601 * to complete the iteration; otherwise the table will remain | 1590 * to complete the iteration; otherwise the table will remain |
1602 * locked. */ | 1591 * locked. */ |
1603 @@ -5756,8 +6077,9 @@ | 1592 @@ -5756,8 +6079,9 @@ |
1604 /* Process pData as an interior node, then loop down the tree | 1593 /* Process pData as an interior node, then loop down the tree |
1605 ** until we find the set of leaf nodes to scan for the term. | 1594 ** until we find the set of leaf nodes to scan for the term. |
1606 */ | 1595 */ |
1607 - getChildrenContaining(pData, nData, pTerm, nTerm, isPrefix, | 1596 - getChildrenContaining(pData, nData, pTerm, nTerm, isPrefix, |
1608 - &iStartChild, &iEndChild); | 1597 - &iStartChild, &iEndChild); |
1609 + rc = getChildrenContaining(pData, nData, pTerm, nTerm, isPrefix, | 1598 + rc = getChildrenContaining(pData, nData, pTerm, nTerm, isPrefix, |
1610 + &iStartChild, &iEndChild); | 1599 + &iStartChild, &iEndChild); |
1611 + if( rc!=SQLITE_OK ) return rc; | 1600 + if( rc!=SQLITE_OK ) return rc; |
1612 while( iStartChild>iLeavesEnd ){ | 1601 while( iStartChild>iLeavesEnd ){ |
1613 sqlite_int64 iNextStart, iNextEnd; | 1602 sqlite_int64 iNextStart, iNextEnd; |
1614 rc = loadAndGetChildrenContaining(v, iStartChild, pTerm, nTerm, isPrefix, | 1603 rc = loadAndGetChildrenContaining(v, iStartChild, pTerm, nTerm, isPrefix, |
1615 @@ -5809,7 +6131,8 @@ | 1604 @@ -5809,7 +6133,8 @@ |
1616 DataBuffer result; | 1605 DataBuffer result; |
1617 int rc; | 1606 int rc; |
1618 | 1607 |
1619 - assert( nData>1 ); | 1608 - assert( nData>1 ); |
1620 + /* Corrupt if segment root can't be valid. */ | 1609 + /* Corrupt if segment root can't be valid. */ |
1621 + if( pData==NULL || nData<1 ) return SQLITE_CORRUPT_BKPT; | 1610 + if( pData==NULL || nData<1 ) return SQLITE_CORRUPT_BKPT; |
1622 | 1611 |
1623 /* This code should never be called with buffered updates. */ | 1612 /* This code should never be called with buffered updates. */ |
1624 assert( v->nPendingData<0 ); | 1613 assert( v->nPendingData<0 ); |
1625 @@ -5826,16 +6149,21 @@ | 1614 @@ -5826,16 +6151,21 @@ |
1626 DataBuffer merged; | 1615 DataBuffer merged; |
1627 DLReader readers[2]; | 1616 DLReader readers[2]; |
1628 | 1617 |
1629 - dlrInit(&readers[0], DL_DEFAULT, out->pData, out->nData); | 1618 - dlrInit(&readers[0], DL_DEFAULT, out->pData, out->nData); |
1630 - dlrInit(&readers[1], DL_DEFAULT, result.pData, result.nData); | 1619 - dlrInit(&readers[1], DL_DEFAULT, result.pData, result.nData); |
1631 - dataBufferInit(&merged, out->nData+result.nData); | 1620 - dataBufferInit(&merged, out->nData+result.nData); |
1632 - docListMerge(&merged, readers, 2); | 1621 - docListMerge(&merged, readers, 2); |
1633 - dataBufferDestroy(out); | 1622 - dataBufferDestroy(out); |
1634 - *out = merged; | 1623 - *out = merged; |
1635 - dlrDestroy(&readers[0]); | 1624 - dlrDestroy(&readers[0]); |
1636 - dlrDestroy(&readers[1]); | 1625 - dlrDestroy(&readers[1]); |
1637 + rc = dlrInit(&readers[0], DL_DEFAULT, out->pData, out->nData); | 1626 + rc = dlrInit(&readers[0], DL_DEFAULT, out->pData, out->nData); |
1638 + if( rc==SQLITE_OK ){ | 1627 + if( rc==SQLITE_OK ){ |
1639 + rc = dlrInit(&readers[1], DL_DEFAULT, result.pData, result.nData); | 1628 + rc = dlrInit(&readers[1], DL_DEFAULT, result.pData, result.nData); |
1640 + if( rc==SQLITE_OK ){ | 1629 + if( rc==SQLITE_OK ){ |
1641 + dataBufferInit(&merged, out->nData+result.nData); | 1630 + dataBufferInit(&merged, out->nData+result.nData); |
1642 + rc = docListMerge(&merged, readers, 2); | 1631 + rc = docListMerge(&merged, readers, 2); |
1643 + dataBufferDestroy(out); | 1632 + dataBufferDestroy(out); |
1644 + *out = merged; | 1633 + *out = merged; |
1645 + dlrDestroy(&readers[1]); | 1634 + dlrDestroy(&readers[1]); |
1646 + } | 1635 + } |
1647 + dlrDestroy(&readers[0]); | 1636 + dlrDestroy(&readers[0]); |
1648 + } | 1637 + } |
1649 } | 1638 } |
1650 } | 1639 } |
1651 + | 1640 + |
1652 dataBufferDestroy(&result); | 1641 dataBufferDestroy(&result); |
1653 return rc; | 1642 return rc; |
1654 } | 1643 } |
1655 @@ -5869,11 +6197,20 @@ | 1644 @@ -5869,11 +6199,20 @@ |
1656 const char *pData = sqlite3_column_blob(s, 2); | 1645 const char *pData = sqlite3_column_blob(s, 2); |
1657 const int nData = sqlite3_column_bytes(s, 2); | 1646 const int nData = sqlite3_column_bytes(s, 2); |
1658 const sqlite_int64 iLeavesEnd = sqlite3_column_int64(s, 1); | 1647 const sqlite_int64 iLeavesEnd = sqlite3_column_int64(s, 1); |
1659 + | 1648 + |
1660 + /* Corrupt if we get back different types than we stored. */ | 1649 + /* Corrupt if we get back different types than we stored. */ |
1661 + if( sqlite3_column_type(s, 1)!=SQLITE_INTEGER || | 1650 + if( sqlite3_column_type(s, 1)!=SQLITE_INTEGER || |
1662 + sqlite3_column_type(s, 2)!=SQLITE_BLOB ){ | 1651 + sqlite3_column_type(s, 2)!=SQLITE_BLOB ){ |
1663 + rc = SQLITE_CORRUPT_BKPT; | 1652 + rc = SQLITE_CORRUPT_BKPT; |
1664 + goto err; | 1653 + goto err; |
1665 + } | 1654 + } |
1666 + | 1655 + |
1667 rc = loadSegment(v, pData, nData, iLeavesEnd, pTerm, nTerm, isPrefix, | 1656 rc = loadSegment(v, pData, nData, iLeavesEnd, pTerm, nTerm, isPrefix, |
1668 &doclist); | 1657 &doclist); |
1669 if( rc!=SQLITE_OK ) goto err; | 1658 if( rc!=SQLITE_OK ) goto err; |
1670 } | 1659 } |
1671 if( rc==SQLITE_DONE ){ | 1660 if( rc==SQLITE_DONE ){ |
1672 + rc = SQLITE_OK; | 1661 + rc = SQLITE_OK; |
1673 if( doclist.nData!=0 ){ | 1662 if( doclist.nData!=0 ){ |
1674 /* TODO(shess) The old term_select_all() code applied the column | 1663 /* TODO(shess) The old term_select_all() code applied the column |
1675 ** restrict as we merged segments, leading to smaller buffers. | 1664 ** restrict as we merged segments, leading to smaller buffers. |
1676 @@ -5881,13 +6218,13 @@ | 1665 @@ -5881,13 +6220,13 @@ |
1677 ** system is checked in. | 1666 ** system is checked in. |
1678 */ | 1667 */ |
1679 if( iColumn==v->nColumn) iColumn = -1; | 1668 if( iColumn==v->nColumn) iColumn = -1; |
1680 - docListTrim(DL_DEFAULT, doclist.pData, doclist.nData, | 1669 - docListTrim(DL_DEFAULT, doclist.pData, doclist.nData, |
1681 - iColumn, iType, out); | 1670 - iColumn, iType, out); |
1682 + rc = docListTrim(DL_DEFAULT, doclist.pData, doclist.nData, | 1671 + rc = docListTrim(DL_DEFAULT, doclist.pData, doclist.nData, |
1683 + iColumn, iType, out); | 1672 + iColumn, iType, out); |
1684 } | 1673 } |
1685 - rc = SQLITE_OK; | 1674 - rc = SQLITE_OK; |
1686 } | 1675 } |
1687 | 1676 |
1688 err: | 1677 err: |
1689 + sqlite3_reset(s); /* So we don't leave a lock. */ | 1678 + sqlite3_reset(s); /* So we don't leave a lock. */ |
1690 dataBufferDestroy(&doclist); | 1679 dataBufferDestroy(&doclist); |
1691 return rc; | 1680 return rc; |
1692 } | 1681 } |
1693 @@ -6250,6 +6587,7 @@ | 1682 @@ -6250,6 +6589,7 @@ |
1694 LeafWriter *pWriter){ | 1683 LeafWriter *pWriter){ |
1695 int i, rc = SQLITE_OK; | 1684 int i, rc = SQLITE_OK; |
1696 DataBuffer doclist, merged, tmp; | 1685 DataBuffer doclist, merged, tmp; |
1697 + const char *pData; | 1686 + const char *pData; |
1698 | 1687 |
1699 /* Order the readers. */ | 1688 /* Order the readers. */ |
1700 i = nReaders; | 1689 i = nReaders; |
1701 @@ -6270,14 +6608,20 @@ | 1690 @@ -6270,14 +6610,20 @@ |
1702 if( 0!=optLeavesReaderTermCmp(&readers[0], &readers[i]) ) break; | 1691 if( 0!=optLeavesReaderTermCmp(&readers[0], &readers[i]) ) break; |
1703 } | 1692 } |
1704 | 1693 |
1705 + pData = optLeavesReaderData(&readers[0]); | 1694 + pData = optLeavesReaderData(&readers[0]); |
1706 + if( pData==NULL ){ | 1695 + if( pData==NULL ){ |
1707 + rc = SQLITE_CORRUPT_BKPT; | 1696 + rc = SQLITE_CORRUPT_BKPT; |
1708 + break; | 1697 + break; |
1709 + } | 1698 + } |
1710 + | 1699 + |
1711 /* Special-case for no merge. */ | 1700 /* Special-case for no merge. */ |
1712 if( i==1 ){ | 1701 if( i==1 ){ |
1713 /* Trim deletions from the doclist. */ | 1702 /* Trim deletions from the doclist. */ |
1714 dataBufferReset(&merged); | 1703 dataBufferReset(&merged); |
1715 - docListTrim(DL_DEFAULT, | 1704 - docListTrim(DL_DEFAULT, |
1716 - optLeavesReaderData(&readers[0]), | 1705 - optLeavesReaderData(&readers[0]), |
1717 - optLeavesReaderDataBytes(&readers[0]), | 1706 - optLeavesReaderDataBytes(&readers[0]), |
1718 - -1, DL_DEFAULT, &merged); | 1707 - -1, DL_DEFAULT, &merged); |
1719 + rc = docListTrim(DL_DEFAULT, pData, | 1708 + rc = docListTrim(DL_DEFAULT, pData, |
1720 + optLeavesReaderDataBytes(&readers[0]), | 1709 + optLeavesReaderDataBytes(&readers[0]), |
1721 + -1, DL_DEFAULT, &merged); | 1710 + -1, DL_DEFAULT, &merged); |
1722 + if( rc!=SQLITE_OK ) break; | 1711 + if( rc!=SQLITE_OK ) break; |
1723 }else{ | 1712 }else{ |
1724 DLReader dlReaders[MERGE_COUNT]; | 1713 DLReader dlReaders[MERGE_COUNT]; |
1725 int iReader, nReaders; | 1714 int iReader, nReaders; |
1726 @@ -6285,9 +6629,10 @@ | 1715 @@ -6285,9 +6631,10 @@ |
1727 /* Prime the pipeline with the first reader's doclist. After | 1716 /* Prime the pipeline with the first reader's doclist. After |
1728 ** one pass index 0 will reference the accumulated doclist. | 1717 ** one pass index 0 will reference the accumulated doclist. |
1729 */ | 1718 */ |
1730 - dlrInit(&dlReaders[0], DL_DEFAULT, | 1719 - dlrInit(&dlReaders[0], DL_DEFAULT, |
1731 - optLeavesReaderData(&readers[0]), | 1720 - optLeavesReaderData(&readers[0]), |
1732 - optLeavesReaderDataBytes(&readers[0])); | 1721 - optLeavesReaderDataBytes(&readers[0])); |
1733 + rc = dlrInit(&dlReaders[0], DL_DEFAULT, | 1722 + rc = dlrInit(&dlReaders[0], DL_DEFAULT, |
1734 + pData, | 1723 + pData, |
1735 + optLeavesReaderDataBytes(&readers[0])); | 1724 + optLeavesReaderDataBytes(&readers[0])); |
1736 + if( rc!=SQLITE_OK ) break; | 1725 + if( rc!=SQLITE_OK ) break; |
1737 iReader = 1; | 1726 iReader = 1; |
1738 | 1727 |
1739 assert( iReader<i ); /* Must execute the loop at least once. */ | 1728 assert( iReader<i ); /* Must execute the loop at least once. */ |
1740 @@ -6295,24 +6640,34 @@ | 1729 @@ -6295,24 +6642,34 @@ |
1741 /* Merge 16 inputs per pass. */ | 1730 /* Merge 16 inputs per pass. */ |
1742 for( nReaders=1; iReader<i && nReaders<MERGE_COUNT; | 1731 for( nReaders=1; iReader<i && nReaders<MERGE_COUNT; |
1743 iReader++, nReaders++ ){ | 1732 iReader++, nReaders++ ){ |
1744 - dlrInit(&dlReaders[nReaders], DL_DEFAULT, | 1733 - dlrInit(&dlReaders[nReaders], DL_DEFAULT, |
1745 - optLeavesReaderData(&readers[iReader]), | 1734 - optLeavesReaderData(&readers[iReader]), |
1746 - optLeavesReaderDataBytes(&readers[iReader])); | 1735 - optLeavesReaderDataBytes(&readers[iReader])); |
1747 + pData = optLeavesReaderData(&readers[iReader]); | 1736 + pData = optLeavesReaderData(&readers[iReader]); |
1748 + if( pData==NULL ){ | 1737 + if( pData==NULL ){ |
1749 + rc = SQLITE_CORRUPT_BKPT; | 1738 + rc = SQLITE_CORRUPT_BKPT; |
1750 + break; | 1739 + break; |
(...skipping 23 matching lines...) Expand all Loading... |
1774 | 1763 |
1775 + if( rc!=SQLITE_OK ) goto err; | 1764 + if( rc!=SQLITE_OK ) goto err; |
1776 + | 1765 + |
1777 /* Accumulated doclist to reader 0 for next pass. */ | 1766 /* Accumulated doclist to reader 0 for next pass. */ |
1778 - dlrInit(&dlReaders[0], DL_DEFAULT, doclist.pData, doclist.nData); | 1767 - dlrInit(&dlReaders[0], DL_DEFAULT, doclist.pData, doclist.nData); |
1779 + rc = dlrInit(&dlReaders[0], DL_DEFAULT, doclist.pData, doclist.nData); | 1768 + rc = dlrInit(&dlReaders[0], DL_DEFAULT, doclist.pData, doclist.nData); |
1780 + if( rc!=SQLITE_OK ) goto err; | 1769 + if( rc!=SQLITE_OK ) goto err; |
1781 } | 1770 } |
1782 | 1771 |
1783 /* Destroy reader that was left in the pipeline. */ | 1772 /* Destroy reader that was left in the pipeline. */ |
1784 @@ -6320,8 +6675,9 @@ | 1773 @@ -6320,8 +6677,9 @@ |
1785 | 1774 |
1786 /* Trim deletions from the doclist. */ | 1775 /* Trim deletions from the doclist. */ |
1787 dataBufferReset(&merged); | 1776 dataBufferReset(&merged); |
1788 - docListTrim(DL_DEFAULT, doclist.pData, doclist.nData, | 1777 - docListTrim(DL_DEFAULT, doclist.pData, doclist.nData, |
1789 - -1, DL_DEFAULT, &merged); | 1778 - -1, DL_DEFAULT, &merged); |
1790 + rc = docListTrim(DL_DEFAULT, doclist.pData, doclist.nData, | 1779 + rc = docListTrim(DL_DEFAULT, doclist.pData, doclist.nData, |
1791 + -1, DL_DEFAULT, &merged); | 1780 + -1, DL_DEFAULT, &merged); |
1792 + if( rc!=SQLITE_OK ) goto err; | 1781 + if( rc!=SQLITE_OK ) goto err; |
1793 } | 1782 } |
1794 | 1783 |
1795 /* Only pass doclists with hits (skip if all hits deleted). */ | 1784 /* Only pass doclists with hits (skip if all hits deleted). */ |
1796 @@ -6401,6 +6757,14 @@ | 1785 @@ -6401,6 +6759,14 @@ |
1797 const char *pRootData = sqlite3_column_blob(s, 2); | 1786 const char *pRootData = sqlite3_column_blob(s, 2); |
1798 int nRootData = sqlite3_column_bytes(s, 2); | 1787 int nRootData = sqlite3_column_bytes(s, 2); |
1799 | 1788 |
1800 + /* Corrupt if we get back different types than we stored. */ | 1789 + /* Corrupt if we get back different types than we stored. */ |
1801 + if( sqlite3_column_type(s, 0)!=SQLITE_INTEGER || | 1790 + if( sqlite3_column_type(s, 0)!=SQLITE_INTEGER || |
1802 + sqlite3_column_type(s, 1)!=SQLITE_INTEGER || | 1791 + sqlite3_column_type(s, 1)!=SQLITE_INTEGER || |
1803 + sqlite3_column_type(s, 2)!=SQLITE_BLOB ){ | 1792 + sqlite3_column_type(s, 2)!=SQLITE_BLOB ){ |
1804 + rc = SQLITE_CORRUPT_BKPT; | 1793 + rc = SQLITE_CORRUPT_BKPT; |
1805 + break; | 1794 + break; |
1806 + } | 1795 + } |
1807 + | 1796 + |
1808 assert( i<nReaders ); | 1797 assert( i<nReaders ); |
1809 rc = leavesReaderInit(v, -1, iStart, iEnd, pRootData, nRootData, | 1798 rc = leavesReaderInit(v, -1, iStart, iEnd, pRootData, nRootData, |
1810 &readers[i].reader); | 1799 &readers[i].reader); |
1811 @@ -6414,6 +6778,8 @@ | 1800 @@ -6414,6 +6780,8 @@ |
1812 if( rc==SQLITE_DONE ){ | 1801 if( rc==SQLITE_DONE ){ |
1813 assert( i==nReaders ); | 1802 assert( i==nReaders ); |
1814 rc = optimizeInternal(v, readers, nReaders, &writer); | 1803 rc = optimizeInternal(v, readers, nReaders, &writer); |
1815 + }else{ | 1804 + }else{ |
1816 + sqlite3_reset(s); /* So we don't leave a lock. */ | 1805 + sqlite3_reset(s); /* So we don't leave a lock. */ |
1817 } | 1806 } |
1818 | 1807 |
1819 while( i-- > 0 ){ | 1808 while( i-- > 0 ){ |
1820 @@ -6477,9 +6843,18 @@ | 1809 @@ -6477,9 +6845,18 @@ |
1821 const sqlite_int64 iEndBlockid = sqlite3_column_int64(s, 1); | 1810 const sqlite_int64 iEndBlockid = sqlite3_column_int64(s, 1); |
1822 const char *pRootData = sqlite3_column_blob(s, 2); | 1811 const char *pRootData = sqlite3_column_blob(s, 2); |
1823 const int nRootData = sqlite3_column_bytes(s, 2); | 1812 const int nRootData = sqlite3_column_bytes(s, 2); |
1824 + int rc; | 1813 + int rc; |
1825 LeavesReader reader; | 1814 LeavesReader reader; |
1826 - int rc = leavesReaderInit(v, 0, iStartBlockid, iEndBlockid, | 1815 - int rc = leavesReaderInit(v, 0, iStartBlockid, iEndBlockid, |
1827 - pRootData, nRootData, &reader); | 1816 - pRootData, nRootData, &reader); |
1828 + | 1817 + |
1829 + /* Corrupt if we get back different types than we stored. */ | 1818 + /* Corrupt if we get back different types than we stored. */ |
1830 + if( sqlite3_column_type(s, 0)!=SQLITE_INTEGER || | 1819 + if( sqlite3_column_type(s, 0)!=SQLITE_INTEGER || |
1831 + sqlite3_column_type(s, 1)!=SQLITE_INTEGER || | 1820 + sqlite3_column_type(s, 1)!=SQLITE_INTEGER || |
1832 + sqlite3_column_type(s, 2)!=SQLITE_BLOB ){ | 1821 + sqlite3_column_type(s, 2)!=SQLITE_BLOB ){ |
1833 + return SQLITE_CORRUPT_BKPT; | 1822 + return SQLITE_CORRUPT_BKPT; |
1834 + } | 1823 + } |
1835 + | 1824 + |
1836 + rc = leavesReaderInit(v, 0, iStartBlockid, iEndBlockid, | 1825 + rc = leavesReaderInit(v, 0, iStartBlockid, iEndBlockid, |
1837 + pRootData, nRootData, &reader); | 1826 + pRootData, nRootData, &reader); |
1838 if( rc!=SQLITE_OK ) return rc; | 1827 if( rc!=SQLITE_OK ) return rc; |
1839 | 1828 |
1840 while( rc==SQLITE_OK && !leavesReaderAtEnd(&reader) ){ | 1829 while( rc==SQLITE_OK && !leavesReaderAtEnd(&reader) ){ |
1841 @@ -6641,16 +7016,19 @@ | 1830 @@ -6641,16 +7018,19 @@ |
1842 const char *pData, int nData){ | 1831 const char *pData, int nData){ |
1843 DataBuffer dump; | 1832 DataBuffer dump; |
1844 DLReader dlReader; | 1833 DLReader dlReader; |
1845 + int rc; | 1834 + int rc; |
1846 | 1835 |
1847 assert( pData!=NULL && nData>0 ); | 1836 assert( pData!=NULL && nData>0 ); |
1848 | 1837 |
1849 + rc = dlrInit(&dlReader, DL_DEFAULT, pData, nData); | 1838 + rc = dlrInit(&dlReader, DL_DEFAULT, pData, nData); |
1850 + if( rc!=SQLITE_OK ) return rc; | 1839 + if( rc!=SQLITE_OK ) return rc; |
1851 dataBufferInit(&dump, 0); | 1840 dataBufferInit(&dump, 0); |
1852 - dlrInit(&dlReader, DL_DEFAULT, pData, nData); | 1841 - dlrInit(&dlReader, DL_DEFAULT, pData, nData); |
1853 - for( ; !dlrAtEnd(&dlReader); dlrStep(&dlReader) ){ | 1842 - for( ; !dlrAtEnd(&dlReader); dlrStep(&dlReader) ){ |
1854 + for( ; rc==SQLITE_OK && !dlrAtEnd(&dlReader); rc = dlrStep(&dlReader) ){ | 1843 + for( ; rc==SQLITE_OK && !dlrAtEnd(&dlReader); rc = dlrStep(&dlReader) ){ |
1855 char buf[256]; | 1844 char buf[256]; |
1856 PLReader plReader; | 1845 PLReader plReader; |
1857 | 1846 |
1858 - plrInit(&plReader, &dlReader); | 1847 - plrInit(&plReader, &dlReader); |
1859 + rc = plrInit(&plReader, &dlReader); | 1848 + rc = plrInit(&plReader, &dlReader); |
1860 + if( rc!=SQLITE_OK ) break; | 1849 + if( rc!=SQLITE_OK ) break; |
1861 if( DL_DEFAULT==DL_DOCIDS || plrAtEnd(&plReader) ){ | 1850 if( DL_DEFAULT==DL_DOCIDS || plrAtEnd(&plReader) ){ |
1862 sqlite3_snprintf(sizeof(buf), buf, "[%lld] ", dlrDocid(&dlReader)); | 1851 sqlite3_snprintf(sizeof(buf), buf, "[%lld] ", dlrDocid(&dlReader)); |
1863 dataBufferAppend(&dump, buf, strlen(buf)); | 1852 dataBufferAppend(&dump, buf, strlen(buf)); |
1864 @@ -6661,7 +7039,8 @@ | 1853 @@ -6661,7 +7041,8 @@ |
1865 dlrDocid(&dlReader), iColumn); | 1854 dlrDocid(&dlReader), iColumn); |
1866 dataBufferAppend(&dump, buf, strlen(buf)); | 1855 dataBufferAppend(&dump, buf, strlen(buf)); |
1867 | 1856 |
1868 - for( ; !plrAtEnd(&plReader); plrStep(&plReader) ){ | 1857 - for( ; !plrAtEnd(&plReader); plrStep(&plReader) ){ |
1869 + for( ; !plrAtEnd(&plReader); rc = plrStep(&plReader) ){ | 1858 + for( ; !plrAtEnd(&plReader); rc = plrStep(&plReader) ){ |
1870 + if( rc!=SQLITE_OK ) break; | 1859 + if( rc!=SQLITE_OK ) break; |
1871 if( plrColumn(&plReader)!=iColumn ){ | 1860 if( plrColumn(&plReader)!=iColumn ){ |
1872 iColumn = plrColumn(&plReader); | 1861 iColumn = plrColumn(&plReader); |
1873 sqlite3_snprintf(sizeof(buf), buf, "] %d[", iColumn); | 1862 sqlite3_snprintf(sizeof(buf), buf, "] %d[", iColumn); |
1874 @@ -6682,6 +7061,7 @@ | 1863 @@ -6682,6 +7063,7 @@ |
1875 dataBufferAppend(&dump, buf, strlen(buf)); | 1864 dataBufferAppend(&dump, buf, strlen(buf)); |
1876 } | 1865 } |
1877 plrDestroy(&plReader); | 1866 plrDestroy(&plReader); |
1878 + if( rc!= SQLITE_OK ) break; | 1867 + if( rc!= SQLITE_OK ) break; |
1879 | 1868 |
1880 assert( dump.nData>0 ); | 1869 assert( dump.nData>0 ); |
1881 dump.nData--; /* Overwrite trailing space. */ | 1870 dump.nData--; /* Overwrite trailing space. */ |
1882 @@ -6690,6 +7070,10 @@ | 1871 @@ -6690,6 +7072,10 @@ |
1883 } | 1872 } |
1884 } | 1873 } |
1885 dlrDestroy(&dlReader); | 1874 dlrDestroy(&dlReader); |
1886 + if( rc!=SQLITE_OK ){ | 1875 + if( rc!=SQLITE_OK ){ |
1887 + dataBufferDestroy(&dump); | 1876 + dataBufferDestroy(&dump); |
1888 + return rc; | 1877 + return rc; |
1889 + } | 1878 + } |
1890 | 1879 |
1891 assert( dump.nData>0 ); | 1880 assert( dump.nData>0 ); |
1892 dump.nData--; /* Overwrite trailing space. */ | 1881 dump.nData--; /* Overwrite trailing space. */ |
1893 @@ -6701,6 +7085,7 @@ | 1882 @@ -6701,6 +7087,7 @@ |
1894 sqlite3_result_text(pContext, dump.pData, dump.nData, sqlite3_free); | 1883 sqlite3_result_text(pContext, dump.pData, dump.nData, sqlite3_free); |
1895 dump.pData = NULL; | 1884 dump.pData = NULL; |
1896 dump.nData = dump.nCapacity = 0; | 1885 dump.nData = dump.nCapacity = 0; |
1897 + return SQLITE_OK; | 1886 + return SQLITE_OK; |
1898 } | 1887 } |
1899 | 1888 |
1900 /* Implements dump_doclist() for use in inspecting the fts3 index from | 1889 /* Implements dump_doclist() for use in inspecting the fts3 index from |
1901 @@ -6987,7 +7372,11 @@ | 1890 @@ -6987,7 +7374,11 @@ |
1902 ** module with sqlite. | 1891 ** module with sqlite. |
1903 */ | 1892 */ |
1904 if( SQLITE_OK==rc | 1893 if( SQLITE_OK==rc |
1905 +#if CHROMIUM_FTS3_CHANGES && !SQLITE_TEST | 1894 +#if CHROMIUM_FTS3_CHANGES && !SQLITE_TEST |
1906 + /* fts3_tokenizer() disabled for security reasons. */ | 1895 + /* fts3_tokenizer() disabled for security reasons. */ |
1907 +#else | 1896 +#else |
1908 && SQLITE_OK==(rc = sqlite3Fts3InitHashTable(db, pHash, "fts3_tokenizer")) | 1897 && SQLITE_OK==(rc = sqlite3Fts3InitHashTable(db, pHash, "fts3_tokenizer")) |
1909 +#endif | 1898 +#endif |
1910 && SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1)) | 1899 && SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1)) |
1911 && SQLITE_OK==(rc = sqlite3_overload_function(db, "offsets", -1)) | 1900 && SQLITE_OK==(rc = sqlite3_overload_function(db, "offsets", -1)) |
1912 && SQLITE_OK==(rc = sqlite3_overload_function(db, "optimize", -1)) | 1901 && SQLITE_OK==(rc = sqlite3_overload_function(db, "optimize", -1)) |
1913 Index: ext/fts3/fts3_icu.c | 1902 Index: ext/fts3/fts3_icu.c |
1914 =================================================================== | 1903 =================================================================== |
1915 --- ext/fts3/fts3_icu.c»(revision 48758) | 1904 --- ext/fts3/fts3_icu.c»(revision 48811) |
1916 +++ ext/fts3/fts3_icu.c (working copy) | 1905 +++ ext/fts3/fts3_icu.c (working copy) |
1917 @@ -198,7 +198,7 @@ | 1906 @@ -198,7 +198,7 @@ |
1918 | 1907 |
1919 while( iStart<iEnd ){ | 1908 while( iStart<iEnd ){ |
1920 int iWhite = iStart; | 1909 int iWhite = iStart; |
1921 - U8_NEXT(pCsr->aChar, iWhite, pCsr->nChar, c); | 1910 - U8_NEXT(pCsr->aChar, iWhite, pCsr->nChar, c); |
1922 + U16_NEXT(pCsr->aChar, iWhite, pCsr->nChar, c); | 1911 + U16_NEXT(pCsr->aChar, iWhite, pCsr->nChar, c); |
1923 if( u_isspace(c) ){ | 1912 if( u_isspace(c) ){ |
1924 iStart = iWhite; | 1913 iStart = iWhite; |
1925 }else{ | 1914 }else{ |
| 1915 Index: ext/fts3/fts3_tokenizer.c |
| 1916 =================================================================== |
| 1917 --- ext/fts3/fts3_tokenizer.c (revision 48811) |
| 1918 +++ ext/fts3/fts3_tokenizer.c (working copy) |
| 1919 @@ -33,6 +33,7 @@ |
| 1920 #include "fts3_hash.h" |
| 1921 #include "fts3_tokenizer.h" |
| 1922 #include <assert.h> |
| 1923 +#include <stddef.h> |
| 1924 |
| 1925 /* |
| 1926 ** Implementation of the SQL scalar function for accessing the underlying |
OLD | NEW |