| 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 |