diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 570ff429de..b490ef2454 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -708,26 +708,29 @@ sqlite3_free(buf.p); } if( rc==SQLITE_OK ){ + u8 *aOut; /* Read blob data into this buffer */ int nByte = sqlite3_blob_bytes(p->pReader); if( pBuf ){ fts5BufferZero(pBuf); - if( SQLITE_OK==fts5BufferGrow(&rc, pBuf, nByte) ){ - rc = sqlite3_blob_read(p->pReader, pBuf->p, nByte, 0); - if( rc==SQLITE_OK ) pBuf->n = nByte; - } + fts5BufferGrow(&rc, pBuf, nByte); + aOut = pBuf->p; + pBuf->n = nByte; }else{ - pRet = (Fts5Data*)fts5IdxMalloc(p, sizeof(Fts5Data) + nByte); - if( !pRet ) return 0; - - pRet->n = nByte; - pRet->p = (u8*)&pRet[1]; - pRet->nRef = 1; - rc = sqlite3_blob_read(p->pReader, pRet->p, nByte, 0); - if( rc!=SQLITE_OK ){ - sqlite3_free(pRet); - pRet = 0; + pRet = (Fts5Data*)sqlite3Fts5MallocZero(&rc, nByte+sizeof(Fts5Data)); + if( pRet ){ + pRet->n = nByte; + aOut = pRet->p = (u8*)&pRet[1]; + pRet->nRef = 1; } } + + if( rc==SQLITE_OK ){ + rc = sqlite3_blob_read(p->pReader, aOut, nByte, 0); + } + if( rc!=SQLITE_OK ){ + sqlite3_free(pRet); + pRet = 0; + } } p->rc = rc; p->nRead++; @@ -2981,6 +2984,7 @@ static void fts5IndexMergeLevel( pStruct = *ppStruct; } fts5StructureExtendLevel(&p->rc, pStruct, iLvl+1, 1, 0); + if( p->rc ) return; pLvl = &pStruct->aLevel[iLvl]; pLvlOut = &pStruct->aLevel[iLvl+1]; diff --git a/ext/fts5/test/fts5aa.test b/ext/fts5/test/fts5aa.test index 8f4f92833d..c7e1169301 100644 --- a/ext/fts5/test/fts5aa.test +++ b/ext/fts5/test/fts5aa.test @@ -21,8 +21,6 @@ ifcapable !fts5 { return } -if 0 { - do_execsql_test 1.0 { CREATE VIRTUAL TABLE t1 USING fts5(a, b, c); SELECT name, sql FROM sqlite_master; @@ -302,8 +300,6 @@ do_test 12.3 { string is integer $res } {1} -} - #------------------------------------------------------------------------- # reset_db diff --git a/ext/fts5/test/fts5fault1.test b/ext/fts5/test/fts5fault1.test index 7685b8bb79..8f24368336 100644 --- a/ext/fts5/test/fts5fault1.test +++ b/ext/fts5/test/fts5fault1.test @@ -29,6 +29,7 @@ ifcapable !fts5 { # 3: DELETE statement # 4: MATCH expressions # +# if 1 { @@ -70,8 +71,6 @@ do_faultsim_test 3 -prep { faultsim_test_result {0 {}} } -} - reset_db do_execsql_test 4.0 { CREATE VIRTUAL TABLE t2 USING fts5(a, b); @@ -108,5 +107,116 @@ foreach {tn expr res} { " } +#------------------------------------------------------------------------- +# The following tests use a larger database populated with random data. +# +# The database page size is set to 512 bytes and the FTS5 page size left +# at the default 1000 bytes. This means that reading a node may require +# pulling an overflow page from disk, which is an extra opportunity for +# an error to occur. +# +reset_db +do_execsql_test 5.0.1 { + PRAGMA main.page_size = 512; + CREATE VIRTUAL TABLE x1 USING fts5(a, b); + PRAGMA main.page_size; +} {512} + +proc rnddoc {n} { + set map [list 0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j] + set doc [list] + for {set i 0} {$i < $n} {incr i} { + lappend doc [string map $map [format %.3d [expr int(rand()*1000)]]] + } + set doc +} +db func rnddoc rnddoc + +do_execsql_test 5.0.2 { + WITH r(a, b) AS ( + SELECT rnddoc(6), rnddoc(6) UNION ALL + SELECT rnddoc(6), rnddoc(6) FROM r + ) + INSERT INTO x1 SELECT * FROM r LIMIT 10000; +} + +set res [db one { + SELECT count(*) FROM x1 WHERE x1.a LIKE '%abc%' OR x1.b LIKE '%abc%'} +] + +do_faultsim_test 5.1 -faults oom* -body { + execsql { SELECT count(*) FROM x1 WHERE x1 MATCH 'abc' } +} -test { + faultsim_test_result [list 0 $::res] +} +do_faultsim_test 5.2 -faults oom* -body { + execsql { SELECT count(*) FROM x1 WHERE x1 MATCH 'abcd' } +} -test { + faultsim_test_result [list 0 0] +} + +proc test_astar {a b} { + return [expr { [regexp {a[^ ][^ ]} $a] || [regexp {a[^ ][^ ]} $b] }] +} +db func test_astar test_astar + +set res [db one { SELECT count(*) FROM x1 WHERE test_astar(a, b) } ] +do_faultsim_test 5.3 -faults oom* -body { + execsql { SELECT count(*) FROM x1 WHERE x1 MATCH 'a*' } +} -test { + faultsim_test_result [list 0 $::res] +} + +do_faultsim_test 5.4 -faults oom* -prep { + db close + sqlite3 db test.db +} -body { + execsql { INSERT INTO x1 VALUES('a b c d', 'e f g h') } +} -test { + faultsim_test_result [list 0 {}] +} + +} + +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 6.0 { + CREATE VIRTUAL TABLE x1 USING fts5(x); + INSERT INTO x1(x1, rank) VALUES('automerge', 0); + + INSERT INTO x1 VALUES('a b c'); -- 1 + INSERT INTO x1 VALUES('a b c'); -- 2 + INSERT INTO x1 VALUES('a b c'); -- 3 + INSERT INTO x1 VALUES('a b c'); -- 4 + INSERT INTO x1 VALUES('a b c'); -- 5 + INSERT INTO x1 VALUES('a b c'); -- 6 + INSERT INTO x1 VALUES('a b c'); -- 7 + INSERT INTO x1 VALUES('a b c'); -- 8 + INSERT INTO x1 VALUES('a b c'); -- 9 + INSERT INTO x1 VALUES('a b c'); -- 10 + INSERT INTO x1 VALUES('a b c'); -- 11 + INSERT INTO x1 VALUES('a b c'); -- 12 + INSERT INTO x1 VALUES('a b c'); -- 13 + INSERT INTO x1 VALUES('a b c'); -- 14 + INSERT INTO x1 VALUES('a b c'); -- 15 + + SELECT count(*) FROM x1_data; +} {17} + +faultsim_save_and_close + +do_faultsim_test 6.1 -faults oom-tr* -prep { + faultsim_restore_and_reopen +} -body { + execsql { INSERT INTO x1 VALUES('d e f') } +} -test { + faultsim_test_result [list 0 {}] + if {$testrc==0} { + set nCnt [db one {SELECT count(*) FROM x1_data}] + if {$nCnt!=3} { error "expected 3 entries but there are $nCnt" } + } +} + finish_test diff --git a/manifest b/manifest index 00449bb1e2..dc57aa2d28 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Handle\sthe\scase\swhere\sa\stokenizer\sdetermines\sthat\sthere\sare\szero\stokens\sin\san\sfts5\squery\sterm. -D 2015-01-19T11:15:36.619 +C Add\sextra\sfault\sinjection\stests\sto\sfts5. +D 2015-01-20T20:34:17.734 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 7cd23e4fc91004a6bd081623e1bc6932e44828c0 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -112,7 +112,7 @@ F ext/fts5/fts5_buffer.c 32dd3c950392346ca69a0f1803501766c5c954f9 F ext/fts5/fts5_config.c 33534ca25198cc62c54ff7d285d455c57ad19399 F ext/fts5/fts5_expr.c 8a0e643768666dc2bffe74104141274809699808 F ext/fts5/fts5_hash.c 63fa8379c5f2ac107d47c2b7d9ac04c95ef8a279 -F ext/fts5/fts5_index.c 33473b527bc0a20fe4d262c2b7b4b67d6c4db5a2 +F ext/fts5/fts5_index.c 8c34dd95f780ff4010af75643a1960bbde70045d F ext/fts5/fts5_storage.c 8bc9e5b6654e1545e9513def277ef3f025921664 F ext/fts5/fts5_tcl.c 1293fac2bb26903fd3d5cdee59c5885ba7e620d5 F ext/fts5/fts5_tokenize.c 7c61d5c35c3449597bdeaa54dd48afe26852c7b0 @@ -120,7 +120,7 @@ F ext/fts5/fts5_unicode2.c 9c7dd640d1f014bf5c3ee029759adfbb4d7e95a9 F ext/fts5/fts5parse.y 777da8e5819f75c217982c79c29d014c293acac9 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl 08e939096a07eb77a7a986613e960f31d3cab2cc -F ext/fts5/test/fts5aa.test 59f5f2ca67338eb1755c96ef18881d7bcb1ff78c +F ext/fts5/test/fts5aa.test ad7eb7ace215e999a0bda9aa078dbdade20afa1e F ext/fts5/test/fts5ab.test 91a3faac09ad9fab5f71494db6e4071963281536 F ext/fts5/test/fts5ac.test 48181b7c873da0e3b4a3316760fcb90d88e7fbd8 F ext/fts5/test/fts5ad.test 3b01eec8516d5631909716514e2e585a45ef0eb1 @@ -136,7 +136,7 @@ F ext/fts5/test/fts5auxdata.test c69b86092bf1a157172de5f9169731af3403179b F ext/fts5/test/fts5content.test 4234e0b11e003fe1e80472aa637f70464396fdd0 F ext/fts5/test/fts5ea.test 04695560a444fcc00c3c4f27783bdcfbf71f030c F ext/fts5/test/fts5eb.test 728a1f23f263548f5c29b29dfb851b5f2dbe723e -F ext/fts5/test/fts5fault1.test f3f4c6ed15cc7a4dc8d517c0d1969d8e5a35a65c +F ext/fts5/test/fts5fault1.test 2c077402045f0b4e69ae1de6cfa51b0c4c5044c2 F ext/fts5/test/fts5near.test 3f9f64e16cac82725d03d4e04c661090f0b3b947 F ext/fts5/test/fts5optimize.test 0028c90a7817d3e576d1148fc8dff17d89054e54 F ext/fts5/test/fts5porter.test 50322599823cb8080a99f0ec0c39f7d0c12bcb5e @@ -1278,7 +1278,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P f30afd209aa4ce42766b1493750c4f5b5f1e9502 -R 135edaa34728516c82a7de0e97543966 +P 75f3d17f864072dfa2caee182b86cc4b9972d691 +R 2673080f53da5e5812b6adb8f1a6e570 U dan -Z 1a9767fbfdd382ad5aed7027717883f2 +Z 0775369c7a1d21779f81072190cb8e04 diff --git a/manifest.uuid b/manifest.uuid index 4caf7a4ed4..0d30b38a60 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -75f3d17f864072dfa2caee182b86cc4b9972d691 \ No newline at end of file +f45a0dc0a8911c8aac5a1028ac4f543a709656e7 \ No newline at end of file