diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/fts3/fts3.c | 45 | ||||
-rw-r--r-- | ext/fts3/fts3Int.h | 4 | ||||
-rw-r--r-- | ext/fts3/fts3_write.c | 31 | ||||
-rw-r--r-- | ext/fts5/fts5_index.c | 50 | ||||
-rw-r--r-- | ext/fts5/fts5_main.c | 5 | ||||
-rw-r--r-- | ext/fts5/fts5_storage.c | 15 | ||||
-rw-r--r-- | ext/fts5/test/fts5corrupt3.test | 223 | ||||
-rw-r--r-- | ext/fts5/test/fts5integrity.test | 45 | ||||
-rw-r--r-- | ext/fts5/test/fts5misc.test | 72 | ||||
-rw-r--r-- | ext/fts5/test/fts5savepoint.test | 85 | ||||
-rw-r--r-- | ext/misc/regexp.c | 2 | ||||
-rw-r--r-- | ext/misc/zipfile.c | 22 | ||||
-rw-r--r-- | ext/rbu/sqlite3rbu.c | 2 | ||||
-rw-r--r-- | ext/rtree/geopoly.c | 8 | ||||
-rw-r--r-- | ext/rtree/rtree.c | 27 |
15 files changed, 552 insertions, 84 deletions
diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 5067c1cf0..77738eb54 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -308,18 +308,6 @@ SQLITE_EXTENSION_INIT1 #endif -/* -** The following are copied from sqliteInt.h. -** -** Constants for the largest and smallest possible 64-bit signed integers. -** These macros are designed to work correctly on both 32-bit and 64-bit -** compilers. -*/ -#ifndef SQLITE_AMALGAMATION -# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) -# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) -#endif - static int fts3EvalNext(Fts3Cursor *pCsr); static int fts3EvalStart(Fts3Cursor *pCsr); static int fts3TermSegReaderCursor( @@ -364,12 +352,7 @@ int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){ v = (*ptr++); \ if( (v & mask2)==0 ){ var = v; return ret; } -/* -** Read a 64-bit variable-length integer from memory starting at p[0]. -** Return the number of bytes read, or 0 on error. -** The value is stored in *v. -*/ -int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){ +int sqlite3Fts3GetVarintU(const char *pBuf, sqlite_uint64 *v){ const unsigned char *p = (const unsigned char*)pBuf; const unsigned char *pStart = p; u32 a; @@ -392,6 +375,15 @@ int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){ } /* +** Read a 64-bit variable-length integer from memory starting at p[0]. +** Return the number of bytes read, or 0 on error. +** The value is stored in *v. +*/ +int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){ + return sqlite3Fts3GetVarintU(pBuf, (sqlite3_uint64*)v); +} + +/* ** Read a 64-bit variable-length integer from memory starting at p[0] and ** not extending past pEnd[-1]. ** Return the number of bytes read, or 0 on error. @@ -2496,12 +2488,12 @@ static void fts3GetDeltaVarint3( if( *pp>=pEnd ){ *pp = 0; }else{ - sqlite3_int64 iVal; - *pp += sqlite3Fts3GetVarint(*pp, &iVal); + u64 iVal; + *pp += sqlite3Fts3GetVarintU(*pp, &iVal); if( bDescIdx ){ - *pVal -= iVal; + *pVal = (i64)((u64)*pVal - iVal); }else{ - *pVal += iVal; + *pVal = (i64)((u64)*pVal + iVal); } } } @@ -2531,10 +2523,10 @@ static void fts3PutDeltaVarint3( sqlite3_uint64 iWrite; if( bDescIdx==0 || *pbFirst==0 ){ assert_fts3_nc( *pbFirst==0 || iVal>=*piPrev ); - iWrite = iVal - *piPrev; + iWrite = (u64)iVal - (u64)*piPrev; }else{ assert_fts3_nc( *piPrev>=iVal ); - iWrite = *piPrev - iVal; + iWrite = (u64)*piPrev - (u64)iVal; } assert( *pbFirst || *piPrev==0 ); assert_fts3_nc( *pbFirst==0 || iWrite>0 ); @@ -2553,7 +2545,8 @@ static void fts3PutDeltaVarint3( ** Using this makes it easier to write code that can merge doclists that are ** sorted in either ascending or descending order. */ -#define DOCID_CMP(i1, i2) ((bDescDoclist?-1:1) * (i1-i2)) +/* #define DOCID_CMP(i1, i2) ((bDescDoclist?-1:1) * (i64)((u64)i1-i2)) */ +#define DOCID_CMP(i1, i2) ((bDescDoclist?-1:1) * (i1>i2?1:((i1==i2)?0:-1))) /* ** This function does an "OR" merge of two doclists (output contains all @@ -2967,7 +2960,7 @@ static int fts3SegReaderCursor( ** Fts3SegReaderPending might segfault, as the data structures used by ** fts4aux are not completely populated. So it's easiest to filter these ** calls out here. */ - if( iLevel<0 && p->aIndex ){ + if( iLevel<0 && p->aIndex && p->iPrevLangid==iLangid ){ Fts3SegReader *pSeg = 0; rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix||isScan, &pSeg); if( rc==SQLITE_OK && pSeg ){ diff --git a/ext/fts3/fts3Int.h b/ext/fts3/fts3Int.h index 26b23b66f..50370a910 100644 --- a/ext/fts3/fts3Int.h +++ b/ext/fts3/fts3Int.h @@ -196,6 +196,9 @@ typedef sqlite3_int64 i64; /* 8-byte signed integer */ # define TESTONLY(X) #endif +#define LARGEST_INT64 (0xffffffff|(((i64)0x7fffffff)<<32)) +#define SMALLEST_INT64 (((i64)-1) - LARGEST_INT64) + #endif /* SQLITE_AMALGAMATION */ #ifdef SQLITE_DEBUG @@ -578,6 +581,7 @@ int sqlite3Fts3Incrmerge(Fts3Table*,int,int); void sqlite3Fts3ErrMsg(char**,const char*,...); int sqlite3Fts3PutVarint(char *, sqlite3_int64); int sqlite3Fts3GetVarint(const char *, sqlite_int64 *); +int sqlite3Fts3GetVarintU(const char *, sqlite_uint64 *); int sqlite3Fts3GetVarintBounded(const char*,const char*,sqlite3_int64*); int sqlite3Fts3GetVarint32(const char *, int *); int sqlite3Fts3VarintLen(sqlite3_uint64); diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index a6b45aef2..203b48e2d 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -696,7 +696,7 @@ static int fts3PendingListAppend( assert( !p || p->iLastDocid<=iDocid ); if( !p || p->iLastDocid!=iDocid ){ - sqlite3_int64 iDelta = iDocid - (p ? p->iLastDocid : 0); + u64 iDelta = (u64)iDocid - (u64)(p ? p->iLastDocid : 0); if( p ){ assert( p->nData<p->nSpace ); assert( p->aData[p->nData]==0 ); @@ -1531,18 +1531,18 @@ static int fts3SegReaderNextDocid( }else{ rc = fts3SegReaderRequire(pReader, p, FTS3_VARINT_MAX); if( rc==SQLITE_OK ){ - sqlite3_int64 iDelta; - pReader->pOffsetList = p + sqlite3Fts3GetVarint(p, &iDelta); + u64 iDelta; + pReader->pOffsetList = p + sqlite3Fts3GetVarintU(p, &iDelta); if( pTab->bDescIdx ){ - pReader->iDocid -= iDelta; + pReader->iDocid = (i64)((u64)pReader->iDocid - iDelta); }else{ - pReader->iDocid += iDelta; + pReader->iDocid = (i64)((u64)pReader->iDocid + iDelta); } } } } - return SQLITE_OK; + return rc; } @@ -2281,6 +2281,7 @@ static int fts3SegWriterAdd( int rc; /* The current leaf node is full. Write it out to the database. */ + if( pWriter->iFree==LARGEST_INT64 ) return FTS_CORRUPT_VTAB; rc = fts3WriteSegment(p, pWriter->iFree++, pWriter->aData, nData); if( rc!=SQLITE_OK ) return rc; p->nLeafAdd++; @@ -2978,10 +2979,10 @@ int sqlite3Fts3SegReaderStep( sqlite3_int64 iDelta; if( p->bDescIdx && nDoclist>0 ){ if( iPrev<=iDocid ) return FTS_CORRUPT_VTAB; - iDelta = iPrev - iDocid; + iDelta = (i64)((u64)iPrev - (u64)iDocid); }else{ if( nDoclist>0 && iPrev>=iDocid ) return FTS_CORRUPT_VTAB; - iDelta = iDocid - iPrev; + iDelta = (i64)((u64)iDocid - (u64)iPrev); } nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0); @@ -3264,7 +3265,7 @@ static int fts3SegmentMerge( csr.zTerm, csr.nTerm, csr.aDoclist, csr.nDoclist); } if( rc!=SQLITE_OK ) goto finished; - assert( pWriter || bIgnoreEmpty ); + assert_fts3_nc( pWriter || bIgnoreEmpty ); if( iLevel!=FTS3_SEGCURSOR_PENDING ){ rc = fts3DeleteSegdir( @@ -5190,12 +5191,12 @@ static u64 fts3ChecksumIndex( i64 iDocid = 0; i64 iCol = 0; - i64 iPos = 0; + u64 iPos = 0; pCsr += sqlite3Fts3GetVarint(pCsr, &iDocid); while( pCsr<pEnd ){ - i64 iVal = 0; - pCsr += sqlite3Fts3GetVarint(pCsr, &iVal); + u64 iVal = 0; + pCsr += sqlite3Fts3GetVarintU(pCsr, &iVal); if( pCsr<pEnd ){ if( iVal==0 || iVal==1 ){ iCol = 0; @@ -5203,11 +5204,11 @@ static u64 fts3ChecksumIndex( if( iVal ){ pCsr += sqlite3Fts3GetVarint(pCsr, &iCol); }else{ - pCsr += sqlite3Fts3GetVarint(pCsr, &iVal); + pCsr += sqlite3Fts3GetVarintU(pCsr, &iVal); if( p->bDescIdx ){ - iDocid -= iVal; + iDocid = (i64)((u64)iDocid - iVal); }else{ - iDocid += iVal; + iDocid = (i64)((u64)iDocid + iVal); } } }else{ diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 015696f7b..eb20af816 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -5318,10 +5318,13 @@ int sqlite3Fts5IndexCharlenToBytelen( for(i=0; i<nChar; i++){ if( n>=nByte ) return 0; /* Input contains fewer than nChar chars */ if( (unsigned char)p[n++]>=0xc0 ){ - if( n>=nByte ) break; + if( n>=nByte ) return 0; while( (p[n] & 0xc0)==0x80 ){ n++; - if( n>=nByte ) break; + if( n>=nByte ){ + if( i+1==nChar ) break; + return 0; + } } } } @@ -5723,6 +5726,37 @@ static int fts5QueryCksum( return rc; } +/* +** Check if buffer z[], size n bytes, contains as series of valid utf-8 +** encoded codepoints. If so, return 0. Otherwise, if the buffer does not +** contain valid utf-8, return non-zero. +*/ +static int fts5TestUtf8(const char *z, int n){ + assert_nc( n>0 ); + int i = 0; + while( i<n ){ + if( (z[i] & 0x80)==0x00 ){ + i++; + }else + if( (z[i] & 0xE0)==0xC0 ){ + if( i+1>=n || (z[i+1] & 0xC0)!=0x80 ) return 1; + i += 2; + }else + if( (z[i] & 0xF0)==0xE0 ){ + if( i+2>=n || (z[i+1] & 0xC0)!=0x80 || (z[i+2] & 0xC0)!=0x80 ) return 1; + i += 3; + }else + if( (z[i] & 0xF8)==0xF0 ){ + if( i+3>=n || (z[i+1] & 0xC0)!=0x80 || (z[i+2] & 0xC0)!=0x80 ) return 1; + if( (z[i+2] & 0xC0)!=0x80 ) return 1; + i += 3; + }else{ + return 1; + } + } + + return 0; +} /* ** This function is also purely an internal test. It does not contribute to @@ -5763,8 +5797,14 @@ static void fts5TestTerm( ** This check may only be performed if the hash table is empty. This ** is because the hash table only supports a single scan query at ** a time, and the multi-iter loop from which this function is called - ** is already performing such a scan. */ - if( p->nPendingData==0 ){ + ** is already performing such a scan. + ** + ** Also only do this if buffer zTerm contains nTerm bytes of valid + ** utf-8. Otherwise, the last part of the buffer contents might contain + ** a non-utf-8 sequence that happens to be a prefix of a valid utf-8 + ** character stored in the main fts index, which will cause the + ** test to fail. */ + if( p->nPendingData==0 && 0==fts5TestUtf8(zTerm, nTerm) ){ if( iIdx>0 && rc==SQLITE_OK ){ int f = flags|FTS5INDEX_QUERY_TEST_NOIDX; ck2 = 0; @@ -5897,8 +5937,8 @@ static void fts5IndexIntegrityCheckSegment( i64 iRow; /* Rowid for this leaf */ Fts5Data *pLeaf; /* Data for this leaf */ + const char *zIdxTerm = (const char*)sqlite3_column_blob(pStmt, 1); int nIdxTerm = sqlite3_column_bytes(pStmt, 1); - const char *zIdxTerm = (const char*)sqlite3_column_text(pStmt, 1); int iIdxLeaf = sqlite3_column_int(pStmt, 2); int bIdxDlidx = sqlite3_column_int(pStmt, 3); diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index 0980c5b4d..347bf7f23 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -289,7 +289,10 @@ static void fts5CheckTransactionState(Fts5FullTable *p, int op, int iSavepoint){ case FTS5_ROLLBACKTO: assert( p->ts.eState==1 ); assert( iSavepoint>=-1 ); - assert( iSavepoint<=p->ts.iSavepoint ); + /* The following assert() can fail if another vtab strikes an error + ** within an xSavepoint() call then SQLite calls xRollbackTo() - without + ** having called xSavepoint() on this vtab. */ + /* assert( iSavepoint<=p->ts.iSavepoint ); */ p->ts.iSavepoint = iSavepoint; break; } diff --git a/ext/fts5/fts5_storage.c b/ext/fts5/fts5_storage.c index c5bf8024d..22f90c0ef 100644 --- a/ext/fts5/fts5_storage.c +++ b/ext/fts5/fts5_storage.c @@ -613,10 +613,11 @@ int sqlite3Fts5StorageRebuild(Fts5Storage *p){ for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){ ctx.szCol = 0; if( pConfig->abUnindexed[ctx.iCol]==0 ){ + const char *zText = (const char*)sqlite3_column_text(pScan, ctx.iCol+1); + int nText = sqlite3_column_bytes(pScan, ctx.iCol+1); rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, - (const char*)sqlite3_column_text(pScan, ctx.iCol+1), - sqlite3_column_bytes(pScan, ctx.iCol+1), + zText, nText, (void*)&ctx, fts5StorageInsertCallback ); @@ -738,10 +739,11 @@ int sqlite3Fts5StorageIndexInsert( for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){ ctx.szCol = 0; if( pConfig->abUnindexed[ctx.iCol]==0 ){ + const char *zText = (const char*)sqlite3_value_text(apVal[ctx.iCol+2]); + int nText = sqlite3_value_bytes(apVal[ctx.iCol+2]); rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, - (const char*)sqlite3_value_text(apVal[ctx.iCol+2]), - sqlite3_value_bytes(apVal[ctx.iCol+2]), + zText, nText, (void*)&ctx, fts5StorageInsertCallback ); @@ -910,10 +912,11 @@ int sqlite3Fts5StorageIntegrity(Fts5Storage *p){ rc = sqlite3Fts5TermsetNew(&ctx.pTermset); } if( rc==SQLITE_OK ){ + const char *zText = (const char*)sqlite3_column_text(pScan, i+1); + int nText = sqlite3_column_bytes(pScan, i+1); rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, - (const char*)sqlite3_column_text(pScan, i+1), - sqlite3_column_bytes(pScan, i+1), + zText, nText, (void*)&ctx, fts5StorageIntegrityCallback ); diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test index 2d6856d05..4e0ae64a9 100644 --- a/ext/fts5/test/fts5corrupt3.test +++ b/ext/fts5/test/fts5corrupt3.test @@ -9886,6 +9886,229 @@ do_catchsql_test 67.1 { ), * FROM ttt('e') } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- +# +reset_db +do_test 68.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 32768 pagesize 4096 filename crash-41234e232809e7.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 08 .....@ ........ +| 32: 00 00 00 02 00 00 00 01 00 00 00 09 00 00 00 04 ................ +| 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6 +| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 0d 92 00 00 00 00 ...k............ +| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet +| 3488: 32 74 32 08 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE +| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta +| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c +| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB +| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k +| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v) +| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[. +| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d +| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize +| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't +| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN +| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE +| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...! +| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont +| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR +| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c +| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG +| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY, +| 3776: 63 30 2c 20 63 31 2c 20 63 32 29 69 04 07 17 19 c0, c1, c2)i.... +| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt +| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB +| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi +| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P +| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid +| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT +| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t +| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da +| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE +| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT +| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY +| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8.. +| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR +| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB +| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5 +| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c)......... +| page 3 offset 8192 +| 0: 0d 00 00 00 03 0c 94 00 0f e6 0f ef 0c 94 00 00 ................ +| 16: 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................ +| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J.......... +| 3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06 ...+.00......... +| 3248: 1f 02 03 01 02 03 01 02 03 01 08 32 30 31 36 30 ...........20160 +| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 00 01 34 01 609...........4. +| 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 04 01 02 ..........5..... +| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 04 ......0000000... +| 3312: 01 02 04 01 02 03 f1 06 62 69 6e 62 72 79 03 06 ........binbry.. +| 3328: 01 02 02 03 06 01 02 02 03 06 01 02 01 03 16 01 ................ +| 3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................ +| 3376: 03 04 71 02 02 03 06 11 02 02 01 08 63 6f 6d 70 ..q.........comp +| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d +| 3408: 62 73 74 61 74 07 02 03 01 02 03 01 02 03 02 04 bstat........... +| 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 06 65 ebug...........e +| 3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 nable........... +| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 03 02 ................ +| 3472: 00 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 ................ +| 3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................ +| 3504: 02 01 02 02 02 08 78 74 65 6e 73 69 6f 6e 1f 02 ......xtension.. +| 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03 .........fts4... +| 3536: 01 02 03 01 02 03 04 01 35 0d 02 03 01 02 03 01 ........5....... +| 3552: 02 03 01 03 66 63 63 01 02 03 01 02 03 01 02 03 ....fcc......... +| 3568: 02 06 65 6f 70 6f 6c 79 10 02 03 01 02 03 01 02 ..eopoly........ +| 3584: 03 01 05 6a 73 6f 5e 31 13 02 03 01 02 03 01 02 ...jso^1........ +| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load......... +| 3616: 01 03 6d 61 78 1c 02 02 01 02 02 01 02 02 02 05 ..max........... +| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory........... +| 3648: 73 79 73 35 16 02 03 01 02 03 01 02 03 01 06 6e sys5...........n +| 3664: 6f 63 61 73 65 02 06 01 02 02 03 06 01 02 02 03 ocase........... +| 3680: 06 01 02 02 03 06 01 02 02 03 06 01 02 02 13 06 ................ +| 3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ +| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 02 ...omit......... +| 3744: 01 05 72 74 72 65 65 19 02 03 01 02 03 01 02 03 ..rtree......... +| 3760: 04 02 69 6d 01 06 01 02 02 03 06 01 12 02 03 06 ..im............ +| 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ +| 3792: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................ +| 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01 ..threadsafe.... +| 3840: 02 02 01 02 02 01 04 76 74 61 62 07 02 04 01 02 .......vtab..... +| 3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01 ......x......... +| 3872: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................ +| 3888: 01 06 01 01 02 01 06 01 01 02 01 05 f1 01 02 01 ................ +| 3904: 06 01 01 02 01 06 01 5b 02 01 06 01 01 02 01 06 .......[........ +| 3920: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................ +| 3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................ +| 3952: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................ +| 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................ +| 3984: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................ +| 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................ +| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................ +| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................ +| 4048: 12 44 13 11 0f 47 13 0f 0c 0e 11 10 0f 0e 10 0f .D...G.......... +| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$. +| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............ +| page 4 offset 12288 +| 0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0b 01 02 ................ +| page 5 offset 16384 +| 0: 0d 00 00 00 24 0c 0a 00 0f d8 0f af 0f 86 0f 74 ....$..........t +| 16: 0f 61 0f 4e 0f 2f 0f 0f 0e ef 0e d7 0e be 0e a5 .a.N./.......... +| 32: 0e 8d 0e 74 0e 5b 0e 40 0e 24 0e 08 0d ef 0d d5 ...t.[.@.$...... +| 48: 0d bb 0d a0 0d 84 0d 68 0d 4f 0d 35 0d 1b 0c fb .......h.O.5.... +| 64: 0c da 0c b9 0c 99 0c 78 0c 57 0c 3e 0c 24 0c 0a .......x.W.>.$.. +| 3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f ...........$..%. +| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI +| 3104: 4f 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 OARY.#..%..THREA +| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 22 DSAFE=0XNOCASE.. +| 3136: 05 00 25 0f 17 54 48 52 45 41 44 53 41 46 45 3d ..%..THREADSAFE= +| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM +| 3168: 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 4f IT LOAD EXTENSIO +| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O +| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI +| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3.. +| 3232: 4f 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMIT LOAD EXTENS +| 3248: 49 4f 4e 58 52 54 52 49 4d 1f 1e 05 00 33 0f 19 IONXRTRIM....3.. +| 3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30 MAX MEMORY=50000 +| 3280: 30 30 30 58 42 49 4e 41 52 59 1f 1d 05 00 33 0f 000XBINARY....3. +| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000 +| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 33 0000XNOCASE....3 +| 3328: 0f 17 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 ..MAX MEMORY=500 +| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....% +| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB +| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB +| 3392: 4c 45 20 52 54 52 46 45 58 4e 4f 43 41 53 45 17 LE RTRFEXNOCASE. +| 3408: 19 05 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 ...%..ENABLE RTR +| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E +| 3440: 49 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49 IABLE MEMSYS5XBI +| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL +| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE +| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME +| 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 00 25 MSYS5XRTRIM....% +| 3520: 0f 19 45 4e 41 42 4c 45 20 4a 53 4f 4e 31 58 42 ..ENABLE JSON1XB +| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB +| 3552: 4c 45 20 4a 53 4f 4e 31 58 4e 4f 43 41 53 45 17 LE JSON1XNOCASE. +| 3568: 13 05 00 25 0f 17 45 4e 41 42 4c 45 20 4a 53 4f ...%..ENABLE JSO +| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E +| 3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 57 42 49 NABLE GEOPOLYWBI +| 3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL +| 3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 42 41 53 45 E GEOPOLYXNOBASE +| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE +| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....# +| 3680: 0f 19 45 4e 41 42 4c 45 20 46 54 53 35 58 42 49 ..ENABLE FTS5XBI +| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL +| 3712: 45 20 46 54 53 35 58 4e 4f 43 41 53 45 16 0d 05 E FTS5XNOCASE... +| 3728: 00 23 0f 17 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X +| 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB +| 3760: 4c 45 20 46 54 53 34 58 42 49 4e 41 52 59 17 0b LE FTS4XBINARY.. +| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4 +| 3792: 58 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e XNOCASE....#..EN +| 3808: 41 42 4c 45 20 46 54 53 34 58 52 54 52 49 4d 1e ABLE FTS4XRTRIM. +| 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY. +| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE. +| 3888: 07 05 00 31 0f 17 b7 4e 41 42 4c 45 20 44 42 53 ...1...NABLE DBS +| 3904: 54 41 54 20 66 54 41 42 58 52 54 52 49 4d 11 06 TAT fTABXRTRIM.. +| 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 49 4e 41 52 .....DEBUGXBINAR +| 3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO +| 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG +| 3968: 58 62 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d XbTRIM'...C..COM +| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0 +| 4000: 32 30 31 36 30 36 30 39 52 02 4a 4e 41 52 59 27 20160609R.JNARY' +| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3d 67 ...C..COMPILER=g +| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060 +| 4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 43 9XNOCASE&...C..C +| 4064: 4f 4d 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e OMPILER=gcc-5.4. +| 4080: 30 20 32 30 31 36 30 36 30 39 58 52 54 52 49 4d 0 20160609XRTRIM +| page 6 offset 20480 +| 0: 0d 00 00 00 24 0e e0 00 0f f8 0f f0 0f e8 0f e0 ....$........... +| 16: 0f d8 0f d0 0f c8 0f c0 0f b8 0f b0 0f a8 0f a0 ................ +| 32: 0f 98 0f 90 0f 88 0f 80 0f 78 0f 70 0f 68 0f 60 .........x.p.h.` +| 48: 0f 58 0f 50 0f 48 0f 40 0f 38 0f 30 0f 28 0f 20 .X.P.H.@.8.0.(. +| 64: 0f 18 0f 10 0f 08 0f 00 0e f8 0e f0 0e e8 0e e0 ................ +| 3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01 .$.......#...... +| 3824: 06 22 03 00 12 02 01 01 06 21 03 00 12 03 01 01 .........!...... +| 3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 01 01 . .............. +| 3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01 ................ +| 3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01 ................ +| 3888: 06 1a 03 00 12 02 01 01 06 19 03 00 12 02 01 01 ................ +| 3904: 06 18 03 00 12 02 01 01 06 17 03 00 12 02 01 01 ................ +| 3920: 06 16 03 00 12 02 01 01 06 15 03 00 12 02 01 01 ................ +| 3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01 ................ +| 3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01 ................ +| 3968: 06 10 03 00 12 02 01 01 06 0f 03 00 12 02 01 01 ................ +| 3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 01 01 ................ +| 4000: 06 0c 03 00 12 02 01 01 06 0b 03 00 12 02 01 01 ................ +| 4016: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01 ................ +| 4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01 ................ +| 4048: 06 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01 ................ +| 4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01 ................ +| 4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................ +| page 7 offset 24576 +| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. +| page 8 offset 28672 +| 0: 0d 00 00 00 03 0f d6 00 0f f4 0f e9 0f d6 00 00 ................ +| 4048: 00 00 00 00 00 00 11 04 02 2b 69 6e 74 65 67 72 .........+integr +| 4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62 ity-check....reb +| 4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 5d 69 71 a5 uild....opti]iq. +| end crash-41234e232809e7.db +.testctrl prng_seed 1 db +}]} {} + +do_catchsql_test 68.1 { + PRAGMA reverse_unordered_selects=ON; + INSERT INTO t1(t1) SELECT x FROM t2; +} {1 {database disk image is malformed}} + + sqlite3_fts5_may_be_corrupt 0 finish_test diff --git a/ext/fts5/test/fts5integrity.test b/ext/fts5/test/fts5integrity.test index 25c727730..72cdeb3e3 100644 --- a/ext/fts5/test/fts5integrity.test +++ b/ext/fts5/test/fts5integrity.test @@ -210,4 +210,49 @@ foreach {tn pgsz} { } {1000} } +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 7.0 { + PRAGMA encoding = 'UTF-16'; + CREATE VIRTUAL TABLE vt0 USING fts5(c0); + INSERT INTO vt0 VALUES (x'46f0'); + SELECT quote(c0) FROM vt0; +} {X'46F0'} +do_execsql_test 7.1 { + INSERT INTO vt0(vt0) VALUES('integrity-check'); +} +do_execsql_test 7.2 { + INSERT INTO vt0(vt0) VALUES('rebuild'); +} +do_execsql_test 7.3 { + INSERT INTO vt0(vt0) VALUES('integrity-check'); +} +do_execsql_test 7.4 { + UPDATE vt0 SET c0=''; +} +do_execsql_test 7.5 { + INSERT INTO vt0(vt0) VALUES('integrity-check'); +} + +#------------------------------------------------------------------------- +# Ticket 7a458c2a5f4 +# +reset_db +do_execsql_test 8.0 { + PRAGMA locking_mode = EXCLUSIVE; + PRAGMA journal_mode = PERSIST; + CREATE VIRTUAL TABLE vt0 USING fts5(c0); +} {exclusive persist} +do_execsql_test 8.1 { + PRAGMA data_version +} {1} +do_execsql_test 8.2 { + INSERT INTO vt0(vt0) VALUES('integrity-check'); + PRAGMA data_version; +} {1} +do_execsql_test 8.1 { + INSERT INTO vt0(vt0, rank) VALUES('usermerge', 2); +} + finish_test diff --git a/ext/fts5/test/fts5misc.test b/ext/fts5/test/fts5misc.test index e2f4b2d09..9abc92b23 100644 --- a/ext/fts5/test/fts5misc.test +++ b/ext/fts5/test/fts5misc.test @@ -250,6 +250,78 @@ do_execsql_test 9.2 { -4764623217061966105 8324454597464624651 } +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 10.0 { + CREATE VIRTUAL TABLE vt1 USING fts5(c1, c2, prefix = 1, tokenize = "ascii"); + INSERT INTO vt1 VALUES (x'e4', '䔬'); +} + +do_execsql_test 10.1 { + SELECT quote(CAST(c1 AS blob)), quote(CAST(c2 AS blob)) FROM vt1 +} {X'E4' X'E494AC'} + +do_execsql_test 10.2 { + INSERT INTO vt1(vt1) VALUES('integrity-check'); +} + +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 11.0 { + CREATE VIRTUAL TABLE vt0 USING fts5( + c0, prefix = 71, tokenize = "porter ascii", prefix = 9 + ); +} {} +do_execsql_test 11.1 { + BEGIN; + INSERT INTO vt0(c0) VALUES (x'e8'); +} +do_execsql_test 11.2 { + INSERT INTO vt0(vt0) VALUES('integrity-check'); +} + +#------------------------------------------------------------------------- +# Ticket [752fdbf6] +# +reset_db +do_execsql_test 11.0 { + PRAGMA encoding = 'UTF-16'; + CREATE VIRTUAL TABLE vt0 USING fts5(c0, c1); + INSERT INTO vt0(vt0, rank) VALUES('pgsz', '37'); + INSERT INTO vt0(c0, c1) VALUES (0.66077, 1957391816); +} +do_execsql_test 11.1 { + INSERT INTO vt0(vt0) VALUES('integrity-check'); +} + +#------------------------------------------------------------------------- +# Ticket [7c0e06b16] +# +do_execsql_test 12.0 { + CREATE TABLE t1(a, b, rank); + INSERT INTO t1 VALUES('a', 'hello', ''); + INSERT INTO t1 VALUES('b', 'world', ''); + + CREATE VIRTUAL TABLE ft USING fts5(a); + INSERT INTO ft VALUES('b'); + INSERT INTO ft VALUES('y'); + + CREATE TABLE t2(x, y, ft); + INSERT INTO t2 VALUES(1, 2, 'x'); + INSERT INTO t2 VALUES(3, 4, 'b'); +} + +do_execsql_test 12.1 { + SELECT * FROM t1 NATURAL JOIN ft WHERE ft MATCH('b') +} {b world {}} +do_execsql_test 12.2 { + SELECT * FROM ft NATURAL JOIN t1 WHERE ft MATCH('b') +} {b world {}} +do_execsql_test 12.3 { + SELECT * FROM t2 JOIN ft USING (ft) +} {3 4 b b} finish_test diff --git a/ext/fts5/test/fts5savepoint.test b/ext/fts5/test/fts5savepoint.test new file mode 100644 index 000000000..e431f9f5f --- /dev/null +++ b/ext/fts5/test/fts5savepoint.test @@ -0,0 +1,85 @@ +# 2019 Dec 26 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5savepoint + +# If SQLITE_ENABLE_FTS5 is defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE ft USING fts5(c); + BEGIN; + SAVEPOINT one; + INSERT INTO ft VALUES('a'); + SAVEPOINT two; + INSERT INTO ft VALUES('b'); + RELEASE two; + SAVEPOINT four; + INSERT INTO ft VALUES('c'); + RELEASE four; + SAVEPOINT three; + INSERT INTO ft VALUES('d'); + ROLLBACK TO three; + COMMIT; + SELECT * FROM ft +} {a b c} + +reset_db +do_catchsql_test 2.0 { + CREATE VIRTUAL TABLE ft1 USING fts5(c); + CREATE VIRTUAL TABLE ft2 USING fts5(c); + DROP TABLE ft2_idx; + BEGIN; + INSERT INTO ft2 VALUES('a'); + INSERT INTO ft1 VALUES('a'); + SAVEPOINT two; + INSERT INTO ft1 VALUES('b'); + COMMIT; +} {1 {SQL logic error}} + +reset_db +ifcapable fts3 { + do_execsql_test 3.0 { + CREATE VIRTUAL TABLE vt0 USING fts5(c0); + CREATE VIRTUAL TABLE vt1 USING fts4(c0); + INSERT INTO vt1(c0) VALUES(0); + } + + do_execsql_test 3.1 { + BEGIN; + UPDATE vt1 SET c0 = 0; + INSERT INTO vt1(c0) VALUES (0), (0); + UPDATE vt0 SET c0 = 0; + INSERT INTO vt1(c0) VALUES (0); + UPDATE vt1 SET c0 = 0; + INSERT INTO vt1(vt1) VALUES('automerge=1'); + UPDATE vt1 SET c0 = 0; + } + + do_catchsql_test 3.2 { + DROP TABLE vt1; + } {1 {SQL logic error}} + + do_execsql_test 3.3 { + SAVEPOINT x; + INSERT INTO vt0 VALUES('x'); + COMMIT; + INSERT INTO vt0(vt0) VALUES('integrity-check'); + } +} + +finish_test + diff --git a/ext/misc/regexp.c b/ext/misc/regexp.c index 3359109ab..a97290511 100644 --- a/ext/misc/regexp.c +++ b/ext/misc/regexp.c @@ -156,7 +156,7 @@ static unsigned re_next_char(ReInput *p){ && (p->z[p->i+1]&0xc0)==0x80 ){ c = (c&0x0f)<<12 | ((p->z[p->i]&0x3f)<<6) | (p->z[p->i+1]&0x3f); p->i += 2; - if( c<=0x3ff || (c>=0xd800 && c<=0xdfff) ) c = 0xfffd; + if( c<=0x7ff || (c>=0xd800 && c<=0xdfff) ) c = 0xfffd; }else if( (c&0xf8)==0xf0 && p->i+3<p->mx && (p->z[p->i]&0xc0)==0x80 && (p->z[p->i+1]&0xc0)==0x80 && (p->z[p->i+2]&0xc0)==0x80 ){ c = (c&0x07)<<18 | ((p->z[p->i]&0x3f)<<12) | ((p->z[p->i+1]&0x3f)<<6) diff --git a/ext/misc/zipfile.c b/ext/misc/zipfile.c index 0d66f6a6f..326228337 100644 --- a/ext/misc/zipfile.c +++ b/ext/misc/zipfile.c @@ -999,7 +999,6 @@ static int zipfileDeflate( int res; str.next_out = aOut; str.avail_out = nAlloc; - deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); res = deflate(&str, Z_FINISH); if( res==Z_STREAM_END ){ *ppOut = aOut; @@ -1434,8 +1433,8 @@ static int zipfileGetMode( ** identical, ignoring any trailing '/' character in either path. */ static int zipfileComparePath(const char *zA, const char *zB, int nB){ int nA = (int)strlen(zA); - if( zA[nA-1]=='/' ) nA--; - if( zB[nB-1]=='/' ) nB--; + if( nA>0 && zA[nA-1]=='/' ) nA--; + if( nB>0 && zB[nB-1]=='/' ) nB--; if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0; return 1; } @@ -1619,6 +1618,7 @@ static int zipfileUpdate( if( rc==SQLITE_OK ){ zPath = (const char*)sqlite3_value_text(apVal[2]); + if( zPath==0 ) zPath = ""; nPath = (int)strlen(zPath); mTime = zipfileGetTime(apVal[4]); } @@ -1628,11 +1628,15 @@ static int zipfileUpdate( ** '/'. This appears to be required for compatibility with info-zip ** (the unzip command on unix). It does not create directories ** otherwise. */ - if( zPath[nPath-1]!='/' ){ + if( nPath<=0 || zPath[nPath-1]!='/' ){ zFree = sqlite3_mprintf("%s/", zPath); - if( zFree==0 ){ rc = SQLITE_NOMEM; } zPath = (const char*)zFree; - nPath++; + if( zFree==0 ){ + rc = SQLITE_NOMEM; + nPath = 0; + }else{ + nPath = (int)strlen(zPath); + } } } @@ -2025,19 +2029,19 @@ void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){ ** at the end of the path. Or, if this is not a directory and the path ** ends in '/' it is an error. */ if( bIsDir==0 ){ - if( zName[nName-1]=='/' ){ + if( nName>0 && zName[nName-1]=='/' ){ zErr = sqlite3_mprintf("non-directory name must not end with /"); rc = SQLITE_ERROR; goto zipfile_step_out; } }else{ - if( zName[nName-1]!='/' ){ + if( nName==0 || zName[nName-1]!='/' ){ zName = zFree = sqlite3_mprintf("%s/", zName); - nName++; if( zName==0 ){ rc = SQLITE_NOMEM; goto zipfile_step_out; } + nName = (int)strlen(zName); }else{ while( nName>1 && zName[nName-2]=='/' ) nName--; } diff --git a/ext/rbu/sqlite3rbu.c b/ext/rbu/sqlite3rbu.c index 5c2ae9545..b2e23b165 100644 --- a/ext/rbu/sqlite3rbu.c +++ b/ext/rbu/sqlite3rbu.c @@ -4959,7 +4959,7 @@ static const char *rbuMainToWal(const char *zName, int flags){ }else{ while( *z==0 ) z++; } - z += (n + 8 + 1); + z += (n + 8 + 2); return z; } diff --git a/ext/rtree/geopoly.c b/ext/rtree/geopoly.c index fa58838a3..312f337b1 100644 --- a/ext/rtree/geopoly.c +++ b/ext/rtree/geopoly.c @@ -1345,17 +1345,11 @@ static int geopolyFilter( RtreeNode *pRoot = 0; int rc = SQLITE_OK; int iCell = 0; - sqlite3_stmt *pStmt; rtreeReference(pRtree); /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ - freeCursorConstraints(pCsr); - sqlite3_free(pCsr->aPoint); - pStmt = pCsr->pReadAux; - memset(pCsr, 0, sizeof(RtreeCursor)); - pCsr->base.pVtab = (sqlite3_vtab*)pRtree; - pCsr->pReadAux = pStmt; + resetCursor(pCsr); pCsr->iStrategy = idxNum; if( idxNum==1 ){ diff --git a/ext/rtree/rtree.c b/ext/rtree/rtree.c index b4d15f6cb..1eef1a1b5 100644 --- a/ext/rtree/rtree.c +++ b/ext/rtree/rtree.c @@ -1065,9 +1065,12 @@ static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ /* -** Free the RtreeCursor.aConstraint[] array and its contents. +** Reset a cursor back to its initial state. */ -static void freeCursorConstraints(RtreeCursor *pCsr){ +static void resetCursor(RtreeCursor *pCsr){ + Rtree *pRtree = (Rtree *)(pCsr->base.pVtab); + int ii; + sqlite3_stmt *pStmt; if( pCsr->aConstraint ){ int i; /* Used to iterate through constraint array */ for(i=0; i<pCsr->nConstraint; i++){ @@ -1080,6 +1083,13 @@ static void freeCursorConstraints(RtreeCursor *pCsr){ sqlite3_free(pCsr->aConstraint); pCsr->aConstraint = 0; } + for(ii=0; ii<RTREE_CACHE_SZ; ii++) nodeRelease(pRtree, pCsr->aNode[ii]); + sqlite3_free(pCsr->aPoint); + pStmt = pCsr->pReadAux; + memset(pCsr, 0, sizeof(RtreeCursor)); + pCsr->base.pVtab = (sqlite3_vtab*)pRtree; + pCsr->pReadAux = pStmt; + } /* @@ -1087,13 +1097,10 @@ static void freeCursorConstraints(RtreeCursor *pCsr){ */ static int rtreeClose(sqlite3_vtab_cursor *cur){ Rtree *pRtree = (Rtree *)(cur->pVtab); - int ii; RtreeCursor *pCsr = (RtreeCursor *)cur; assert( pRtree->nCursor>0 ); - freeCursorConstraints(pCsr); + resetCursor(pCsr); sqlite3_finalize(pCsr->pReadAux); - sqlite3_free(pCsr->aPoint); - for(ii=0; ii<RTREE_CACHE_SZ; ii++) nodeRelease(pRtree, pCsr->aNode[ii]); sqlite3_free(pCsr); pRtree->nCursor--; nodeBlobReset(pRtree); @@ -1799,17 +1806,11 @@ static int rtreeFilter( int ii; int rc = SQLITE_OK; int iCell = 0; - sqlite3_stmt *pStmt; rtreeReference(pRtree); /* Reset the cursor to the same state as rtreeOpen() leaves it in. */ - freeCursorConstraints(pCsr); - sqlite3_free(pCsr->aPoint); - pStmt = pCsr->pReadAux; - memset(pCsr, 0, sizeof(RtreeCursor)); - pCsr->base.pVtab = (sqlite3_vtab*)pRtree; - pCsr->pReadAux = pStmt; + resetCursor(pCsr); pCsr->iStrategy = idxNum; if( idxNum==1 ){ |