diff options
author | Michael BrĂ¼ning <michael.bruning@qt.io> | 2020-02-25 17:57:14 +0100 |
---|---|---|
committer | Michael BrĂ¼ning <michael.bruning@qt.io> | 2020-03-02 12:29:56 +0000 |
commit | dcfdd7e5cacd2cf01df7a9a467a7eeeee3348d1d (patch) | |
tree | 7d4aa7f4fc74e9b4e4566c6f36cc46db7be4583a | |
parent | 18b9ecb1968ba754b3a84de7c1b7678e2771fd0f (diff) | |
download | qtwebengine-chromium-dcfdd7e5cacd2cf01df7a9a467a7eeeee3348d1d.tar.gz |
[Backport] Fix multiple CVEs and security bugs in sqlite
Update sqlite to include several bug fix backports.
Fixes the following security bugs:
* CVE-2019-19926 Inappropriate implementation in SQLite
* CVE-2020-6405 Out of bounds read in SQLite
* CVE-2019-19923 Out of bounds memory access in SQLite
* CVE-2019-19925: Multiple vulnerabilities in SQLite
* Security bug 1033461
Change-Id: I8da8585cad43e9b8656645c054d6cf6cbebc2a1a
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
43 files changed, 1671 insertions, 173 deletions
diff --git a/chromium/third_party/sqlite/BUILD.gn b/chromium/third_party/sqlite/BUILD.gn index c69fca85608..3d1ef78195b 100644 --- a/chromium/third_party/sqlite/BUILD.gn +++ b/chromium/third_party/sqlite/BUILD.gn @@ -493,6 +493,19 @@ fuzzer_test("sqlite3_fts3_lpm_fuzzer") { ] } +fuzzer_test("sqlite3_shadow_table_fuzzer") { + sources = [ + "fuzz/shadow_table_fuzzer.cc", + ] + deps = [ + ":sqlite", + ] + additional_configs = [ + ":sqlite_warnings", + ] +} + + fuzzer_test("sqlite3_select_printf_lpm_fuzzer") { sources = [ "fuzz/sql_printf_fuzzer.cc", diff --git a/chromium/third_party/sqlite/amalgamation/shell/shell.c b/chromium/third_party/sqlite/amalgamation/shell/shell.c index a7275a2327a..f3998bdf7c8 100644 --- a/chromium/third_party/sqlite/amalgamation/shell/shell.c +++ b/chromium/third_party/sqlite/amalgamation/shell/shell.c @@ -5827,6 +5827,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]); } diff --git a/chromium/third_party/sqlite/amalgamation/sqlite3.c b/chromium/third_party/sqlite/amalgamation/sqlite3.c index 7ce150836e5..e78063807fb 100644 --- a/chromium/third_party/sqlite/amalgamation/sqlite3.c +++ b/chromium/third_party/sqlite/amalgamation/sqlite3.c @@ -17933,6 +17933,7 @@ struct Select { #define SF_IncludeHidden 0x20000 /* Include hidden columns in output */ #define SF_ComplexResult 0x40000 /* Result contains subquery or function */ #define SF_WhereBegin 0x80000 /* Really a WhereBegin() call. Debug Only */ +#define SF_View 0x0200000 /* SELECT statement is a view */ /* ** The results of a SELECT can be distributed in several ways, as defined @@ -19113,6 +19114,7 @@ SQLITE_PRIVATE void sqlite3EndTransaction(Parse*,int); SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*); SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *); SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*); +SQLITE_PRIVATE u32 sqlite3IsTrueOrFalse(const char*); SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr*); SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr*); SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*); @@ -19506,6 +19508,12 @@ SQLITE_PRIVATE Module *sqlite3VtabCreateModule( ); # define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) #endif +SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db); +#ifndef SQLITE_OMIT_VIRTUALTABLE +SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName); +#else +# define sqlite3ShadowTableName(A,B) 0 +#endif SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*); SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*); SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*); @@ -30574,6 +30582,7 @@ SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ sqlite3DbFree(db, pParse->zErrMsg); pParse->zErrMsg = zMsg; pParse->rc = SQLITE_ERROR; + pParse->pWith = 0; } } @@ -30767,7 +30776,7 @@ static LONGDOUBLE_TYPE sqlite3Pow10(int E){ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ #ifndef SQLITE_OMIT_FLOATING_POINT int incr; - const char *zEnd = z + length; + const char *zEnd; /* sign * significand * (10 ^ (esign * exponent)) */ int sign = 1; /* sign of significand */ i64 s = 0; /* significand */ @@ -30781,9 +30790,11 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 en assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); *pResult = 0.0; /* Default return value, in case of an error */ + if( length==0 ) return 0; if( enc==SQLITE_UTF8 ){ incr = 1; + zEnd = z + length; }else{ int i; incr = 2; @@ -75245,8 +75256,7 @@ SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){ return pMem->u.i; }else if( flags & MEM_Real ){ return doubleToInt64(pMem->u.r); - }else if( flags & (MEM_Str|MEM_Blob) ){ - assert( pMem->z || pMem->n==0 ); + }else if( (flags & (MEM_Str|MEM_Blob))!=0 && pMem->z!=0 ){ return memIntValue(pMem); }else{ return 0; @@ -99322,18 +99332,33 @@ SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){ } /* +** Check the input string to see if it is "true" or "false" (in any case). +** +** If the string is.... Return +** "true" EP_IsTrue +** "false" EP_IsFalse +** anything else 0 +*/ +SQLITE_PRIVATE u32 sqlite3IsTrueOrFalse(const char *zIn){ + if( sqlite3StrICmp(zIn, "true")==0 ) return EP_IsTrue; + if( sqlite3StrICmp(zIn, "false")==0 ) return EP_IsFalse; + return 0; +} + + +/* ** If the input expression is an ID with the name "true" or "false" ** then convert it into an TK_TRUEFALSE term. Return non-zero if ** the conversion happened, and zero if the expression is unaltered. */ SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){ + u32 v; assert( pExpr->op==TK_ID || pExpr->op==TK_STRING ); if( !ExprHasProperty(pExpr, EP_Quoted) - && (sqlite3StrICmp(pExpr->u.zToken, "true")==0 - || sqlite3StrICmp(pExpr->u.zToken, "false")==0) + && (v = sqlite3IsTrueOrFalse(pExpr->u.zToken))!=0 ){ pExpr->op = TK_TRUEFALSE; - ExprSetProperty(pExpr, pExpr->u.zToken[4]==0 ? EP_IsTrue : EP_IsFalse); + ExprSetProperty(pExpr, v); return 1; } return 0; @@ -103199,9 +103224,8 @@ SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){ static int isAlterableTable(Parse *pParse, Table *pTab){ if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) #ifndef SQLITE_OMIT_VIRTUALTABLE - || ( (pTab->tabFlags & TF_Shadow) - && (pParse->db->flags & SQLITE_Defensive) - && pParse->db->nVdbeExec==0 + || ( (pTab->tabFlags & TF_Shadow)!=0 + && sqlite3ReadOnlyShadowTables(pParse->db) ) #endif ){ @@ -103902,6 +103926,7 @@ static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){ static int renameUnmapSelectCb(Walker *pWalker, Select *p){ Parse *pParse = pWalker->pParse; int i; + if( p->selFlags & SF_View ) return WRC_Prune; if( ALWAYS(p->pEList) ){ ExprList *pList = p->pEList; for(i=0; i<pList->nExpr; i++){ @@ -104006,6 +104031,7 @@ static void renameWalkWith(Walker *pWalker, Select *pSelect){ ** descend into sub-select statements. */ static int renameColumnSelectCb(Walker *pWalker, Select *p){ + if( p->selFlags & SF_View ) return WRC_Prune; renameWalkWith(pWalker, p); return WRC_Continue; } @@ -104471,8 +104497,9 @@ static void renameColumnFunc( if( sParse.pNewTable ){ Select *pSelect = sParse.pNewTable->pSelect; if( pSelect ){ + pSelect->selFlags &= ~SF_View; sParse.rc = SQLITE_OK; - sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, 0); + sqlite3SelectPrep(&sParse, pSelect, 0); rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); if( rc==SQLITE_OK ){ sqlite3WalkSelect(&sWalker, pSelect); @@ -104584,6 +104611,7 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ int i; RenameCtx *p = pWalker->u.pRename; SrcList *pSrc = pSelect->pSrc; + if( pSelect->selFlags & SF_View ) return WRC_Prune; if( pSrc==0 ){ assert( pWalker->pParse->db->mallocFailed ); return WRC_Abort; @@ -104663,10 +104691,13 @@ static void renameTableFunc( if( pTab->pSelect ){ if( isLegacy==0 ){ + Select *pSelect = pTab->pSelect; NameContext sNC; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = &sParse; + assert( pSelect->selFlags & SF_View ); + pSelect->selFlags &= ~SF_View; sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC); if( sParse.nErr ) rc = sParse.rc; sqlite3WalkSelect(&sWalker, pTab->pSelect); @@ -108498,13 +108529,14 @@ SQLITE_PRIVATE int sqlite3CheckObjectName( } } }else{ - if( pParse->nested==0 - && 0==sqlite3StrNICmp(zName, "sqlite_", 7) + if( (pParse->nested==0 && 0==sqlite3StrNICmp(zName, "sqlite_", 7)) + || (sqlite3ReadOnlyShadowTables(db) && sqlite3ShadowTableName(db, zName)) ){ sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName); return SQLITE_ERROR; } + } return SQLITE_OK; } @@ -109644,7 +109676,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ ** zName is temporarily modified while this routine is running, but is ** restored to its original value prior to this routine returning. */ -static int isShadowTableName(sqlite3 *db, char *zName){ +SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName){ char *zTail; /* Pointer to the last "_" in zName */ Table *pTab; /* Table that zName is a shadow of */ Module *pMod; /* Module for the virtual table */ @@ -109662,8 +109694,6 @@ static int isShadowTableName(sqlite3 *db, char *zName){ if( pMod->pModule->xShadowName==0 ) return 0; return pMod->pModule->xShadowName(zTail+1); } -#else -# define isShadowTableName(x,y) 0 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ /* @@ -109705,7 +109735,7 @@ SQLITE_PRIVATE void sqlite3EndTable( p = pParse->pNewTable; if( p==0 ) return; - if( pSelect==0 && isShadowTableName(db, p->zName) ){ + if( pSelect==0 && sqlite3ShadowTableName(db, p->zName) ){ p->tabFlags |= TF_Shadow; } @@ -109976,6 +110006,7 @@ SQLITE_PRIVATE void sqlite3CreateView( ** allocated rather than point to the input string - which means that ** they will persist after the current sqlite3_exec() call returns. */ + pSelect->selFlags |= SF_View; if( IN_RENAME_OBJECT ){ p->pSelect = pSelect; pSelect = 0; @@ -110389,17 +110420,32 @@ SQLITE_PRIVATE void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, in } /* +** Return TRUE if shadow tables should be read-only in the current +** context. +*/ +SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db){ +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( (db->flags & SQLITE_Defensive)!=0 + && db->pVtabCtx==0 + && db->nVdbeExec==0 + ){ + return 1; + } +#endif + return 0; +} + +/* ** Return true if it is not allowed to drop the given table */ -static int tableMayNotBeDropped(Parse *pParse, Table *pTab){ +static int tableMayNotBeDropped(sqlite3 *db, Table *pTab){ if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ if( sqlite3StrNICmp(pTab->zName+7, "stat", 4)==0 ) return 0; if( sqlite3StrNICmp(pTab->zName+7, "parameters", 10)==0 ) return 0; return 1; } - if( pTab->tabFlags & TF_Shadow ){ - sqlite3 *db = pParse->db; - if( (db->flags & SQLITE_Defensive)!=0 && db->nVdbeExec==0 ) return 1; + if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){ + return 1; } return 0; } @@ -110473,7 +110519,7 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, } } #endif - if( tableMayNotBeDropped(pParse, pTab) ){ + if( tableMayNotBeDropped(db, pTab) ){ sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName); goto exit_drop_table; } @@ -113042,11 +113088,7 @@ static int tabIsReadOnly(Parse *pParse, Table *pTab){ return sqlite3WritableSchema(db)==0 && pParse->nested==0; } assert( pTab->tabFlags & TF_Shadow ); - return (db->flags & SQLITE_Defensive)!=0 -#ifndef SQLITE_OMIT_VIRTUALTABLE - && db->pVtabCtx==0 -#endif - && db->nVdbeExec==0; + return sqlite3ReadOnlyShadowTables(db); } /* @@ -127601,7 +127643,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList( zName = pEList->a[i].zSpan; } } - if( zName ){ + if( zName && !sqlite3IsTrueOrFalse(zName) ){ zName = sqlite3DbStrDup(db, zName); }else{ zName = sqlite3MPrintf(db,"column%d",i+1); @@ -128426,6 +128468,7 @@ static int multiSelect( } #endif } + if( pParse->nErr ) goto multi_select_end; /* Compute collating sequences used by ** temporary tables needed to implement the compound select. @@ -129217,6 +129260,7 @@ static void substSelect( ** (3b) the FROM clause of the subquery may not contain a virtual ** table and ** (3c) the outer query may not be an aggregate. +** (3d) the outer query may not be DISTINCT. ** ** (4) The subquery can not be DISTINCT. ** @@ -129413,8 +129457,11 @@ static int flattenSubquery( */ if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){ isLeftJoin = 1; - if( pSubSrc->nSrc>1 || isAgg || IsVirtual(pSubSrc->a[0].pTab) ){ - /* (3a) (3c) (3b) */ + if( pSubSrc->nSrc>1 /* (3a) */ + || isAgg /* (3b) */ + || IsVirtual(pSubSrc->a[0].pTab) /* (3c) */ + || (p->selFlags & SF_Distinct)!=0 /* (3d) */ + ){ return 0; } } @@ -129814,7 +129861,7 @@ static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){ int i; WhereConst *pConst; if( pExpr->op!=TK_COLUMN ) return WRC_Continue; - if( ExprHasProperty(pExpr, EP_FixedCol) ) return WRC_Continue; + if( ExprHasProperty(pExpr, EP_FixedCol|EP_FromJoin) ) return WRC_Continue; pConst = pWalker->u.pConst; for(i=0; i<pConst->nConst; i++){ Expr *pColumn = pConst->apExpr[i*2]; @@ -130287,6 +130334,9 @@ static int withExpand( With *pWith; /* WITH clause that pCte belongs to */ assert( pFrom->pTab==0 ); + if( pParse->nErr ){ + return SQLITE_ERROR; + } pCte = searchWith(pParse->pWith, pFrom, &pWith); if( pCte ){ @@ -133203,8 +133253,12 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const ch Table *pTab = tableOfTrigger(pTrigger); if( pTab ){ Trigger **pp; - for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext)); - *pp = (*pp)->pNext; + for(pp=&pTab->pTrigger; *pp; pp=&((*pp)->pNext)){ + if( *pp==pTrigger ){ + *pp = (*pp)->pNext; + break; + } + } } } sqlite3DeleteTrigger(db, pTrigger); @@ -147584,9 +147638,11 @@ static ExprList *exprListAppendList( int nInit = pList ? pList->nExpr : 0; for(i=0; i<pAppend->nExpr; i++){ Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0); + assert( pDup==0 || !ExprHasProperty(pDup, EP_MemToken) ); if( bIntToNull && pDup && pDup->op==TK_INTEGER ){ pDup->op = TK_NULL; pDup->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse); + pDup->u.zToken = 0; } pList = sqlite3ExprListAppend(pParse, pList, pDup); if( pList ) pList->a[nInit+i].sortFlags = pAppend->a[i].sortFlags; @@ -161319,6 +161375,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 @@ -161700,6 +161759,7 @@ SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table*,int,int); SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char**,const char*,...); SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64); SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *); +SQLITE_PRIVATE int sqlite3Fts3GetVarintU(const char *, sqlite_uint64 *); SQLITE_PRIVATE int sqlite3Fts3GetVarintBounded(const char*,const char*,sqlite3_int64*); SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *); SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64); @@ -161787,18 +161847,6 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); 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( @@ -161843,12 +161891,7 @@ SQLITE_PRIVATE 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. -*/ -SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){ +SQLITE_PRIVATE int sqlite3Fts3GetVarintU(const char *pBuf, sqlite_uint64 *v){ const unsigned char *p = (const unsigned char*)pBuf; const unsigned char *pStart = p; u32 a; @@ -161871,6 +161914,15 @@ SQLITE_PRIVATE 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. +*/ +SQLITE_PRIVATE 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. @@ -163963,12 +164015,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); } } } @@ -163997,9 +164049,9 @@ static void fts3PutDeltaVarint3( ){ sqlite3_int64 iWrite; if( bDescIdx==0 || *pbFirst==0 ){ - iWrite = iVal - *piPrev; + iWrite = (u64)iVal - (u64)*piPrev; }else{ - iWrite = *piPrev - iVal; + iWrite = (u64)*piPrev - (u64)iVal; } assert( *pbFirst || *piPrev==0 ); assert_fts3_nc( *pbFirst==0 || iWrite>0 ); @@ -164019,7 +164071,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 @@ -165993,15 +166046,16 @@ static void fts3EvalDlPhraseNext( u8 *pbEof ){ char *pIter; /* Used to iterate through aAll */ - char *pEnd = &pDL->aAll[pDL->nAll]; /* 1 byte past end of aAll */ + char *pEnd; /* 1 byte past end of aAll */ if( pDL->pNextDocid ){ pIter = pDL->pNextDocid; + assert( pDL->aAll!=0 || pIter==0 ); }else{ pIter = pDL->aAll; } - if( pIter>=pEnd ){ + if( pIter==0 || pIter>=(pEnd = pDL->aAll + pDL->nAll) ){ /* We have already reached the end of this doclist. EOF. */ *pbEof = 1; }else{ @@ -171977,7 +172031,7 @@ static int fts3SqlStmt( ** returns zero rows. */ /* 28 */ "SELECT level, count(*) AS cnt FROM %Q.'%q_segdir' " " GROUP BY level HAVING cnt>=?" - " ORDER BY (level %% 1024) ASC LIMIT 1", + " ORDER BY (level %% 1024) ASC, 2 DESC LIMIT 1", /* Estimate the upper limit on the number of leaf nodes in a new segment ** created by merging the oldest :2 segments from absolute level :1. See @@ -172338,7 +172392,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 ); @@ -173171,18 +173225,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; } @@ -173921,6 +173975,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++; @@ -174617,9 +174672,9 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderStep( ** doclist. */ sqlite3_int64 iDelta; if( p->bDescIdx && nDoclist>0 ){ - iDelta = iPrev - iDocid; + iDelta = (i64)((u64)iPrev - (u64)iDocid); }else{ - iDelta = iDocid - iPrev; + iDelta = (i64)((u64)iDocid - (u64)iPrev); } if( iDelta<=0 && (nDoclist>0 || iDelta!=iDocid) ){ return FTS_CORRUPT_VTAB; @@ -174906,7 +174961,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( @@ -176486,13 +176541,17 @@ static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){ const int nHint = pHint->n; int i; - i = pHint->n-2; + i = pHint->n-1; + if( (pHint->a[i] & 0x80) ) return FTS_CORRUPT_VTAB; while( i>0 && (pHint->a[i-1] & 0x80) ) i--; + if( i==0 ) return FTS_CORRUPT_VTAB; + i--; while( i>0 && (pHint->a[i-1] & 0x80) ) i--; pHint->n = i; i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel); i += fts3GetVarint32(&pHint->a[i], pnInput); + assert( i<=nHint ); if( i!=nHint ) return FTS_CORRUPT_VTAB; return SQLITE_OK; @@ -176562,8 +176621,14 @@ SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ rc = fts3IncrmergeHintPop(&hint, &iHintAbsLevel, &nHintSeg); if( nSeg<0 || (iAbsLevel % nMod) >= (iHintAbsLevel % nMod) ){ + /* Based on the scan in the block above, it is known that there + ** are no levels with a relative level smaller than that of + ** iAbsLevel with more than nSeg segments, or if nSeg is -1, + ** no levels with more than nMin segments. Use this to limit the + ** value of nHintSeg to avoid a large memory allocation in case the + ** merge-hint is corrupt*/ iAbsLevel = iHintAbsLevel; - nSeg = nHintSeg; + nSeg = MIN(MAX(nMin,nSeg), nHintSeg); bUseHint = 1; bDirtyHint = 1; }else{ @@ -176576,7 +176641,7 @@ SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ /* If nSeg is less that zero, then there is no level with at least ** nMin segments and no hint in the %_stat table. No work to do. ** Exit early in this case. */ - if( nSeg<0 ) break; + if( nSeg<=0 ) break; /* Open a cursor to iterate through the contents of the oldest nSeg ** indexes of absolute level iAbsLevel. If this cursor is opened using @@ -176813,12 +176878,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; @@ -176826,8 +176891,8 @@ static u64 fts3ChecksumIndex( if( iVal ){ pCsr += sqlite3Fts3GetVarint(pCsr, &iCol); }else{ - pCsr += sqlite3Fts3GetVarint(pCsr, &iVal); - iDocid += iVal; + pCsr += sqlite3Fts3GetVarintU(pCsr, &iVal); + iDocid = (i64)((u64)iDocid + iVal); } }else{ iPos += (iVal - 2); @@ -177954,7 +178019,7 @@ static int fts3BestSnippet( /* Set the *pmSeen output variable. */ for(i=0; i<nList; i++){ if( sIter.aPhrase[i].pHead ){ - *pmSeen |= (u64)1 << i; + *pmSeen |= (u64)1 << (i%64); } } @@ -224660,7 +224725,7 @@ SQLITE_API int sqlite3_stmt_init( #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ /************** End of stmt.c ************************************************/ -#if __LINE__!=224663 +#if __LINE__!=224728 #undef SQLITE_SOURCE_ID #define SQLITE_SOURCE_ID "2019-10-10 20:19:45 18db032d058f1436ce3dea84081f4ee5a0f2259ad97301d43c426bc7f3dfalt2" #endif diff --git a/chromium/third_party/sqlite/patched/ext/fts3/fts3.c b/chromium/third_party/sqlite/patched/ext/fts3/fts3.c index 8d48f22fec2..5cef6aa2370 100644 --- a/chromium/third_party/sqlite/patched/ext/fts3/fts3.c +++ b/chromium/third_party/sqlite/patched/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. @@ -2484,12 +2476,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); } } } @@ -2518,9 +2510,9 @@ static void fts3PutDeltaVarint3( ){ sqlite3_int64 iWrite; if( bDescIdx==0 || *pbFirst==0 ){ - iWrite = iVal - *piPrev; + iWrite = (u64)iVal - (u64)*piPrev; }else{ - iWrite = *piPrev - iVal; + iWrite = (u64)*piPrev - (u64)iVal; } assert( *pbFirst || *piPrev==0 ); assert_fts3_nc( *pbFirst==0 || iWrite>0 ); @@ -2540,7 +2532,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 @@ -4514,15 +4507,16 @@ static void fts3EvalDlPhraseNext( u8 *pbEof ){ char *pIter; /* Used to iterate through aAll */ - char *pEnd = &pDL->aAll[pDL->nAll]; /* 1 byte past end of aAll */ + char *pEnd; /* 1 byte past end of aAll */ if( pDL->pNextDocid ){ pIter = pDL->pNextDocid; + assert( pDL->aAll!=0 || pIter==0 ); }else{ pIter = pDL->aAll; } - if( pIter>=pEnd ){ + if( pIter==0 || pIter>=(pEnd = pDL->aAll + pDL->nAll) ){ /* We have already reached the end of this doclist. EOF. */ *pbEof = 1; }else{ diff --git a/chromium/third_party/sqlite/patched/ext/fts3/fts3Int.h b/chromium/third_party/sqlite/patched/ext/fts3/fts3Int.h index 5cafa1fe9b9..44bf78ef8f1 100644 --- a/chromium/third_party/sqlite/patched/ext/fts3/fts3Int.h +++ b/chromium/third_party/sqlite/patched/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 @@ -577,6 +580,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/chromium/third_party/sqlite/patched/ext/fts3/fts3_snippet.c b/chromium/third_party/sqlite/patched/ext/fts3/fts3_snippet.c index dda71c3985a..6eae82dbc3f 100644 --- a/chromium/third_party/sqlite/patched/ext/fts3/fts3_snippet.c +++ b/chromium/third_party/sqlite/patched/ext/fts3/fts3_snippet.c @@ -560,7 +560,7 @@ static int fts3BestSnippet( /* Set the *pmSeen output variable. */ for(i=0; i<nList; i++){ if( sIter.aPhrase[i].pHead ){ - *pmSeen |= (u64)1 << i; + *pmSeen |= (u64)1 << (i%64); } } diff --git a/chromium/third_party/sqlite/patched/ext/fts3/fts3_write.c b/chromium/third_party/sqlite/patched/ext/fts3/fts3_write.c index 953b9d86959..f30bf343635 100644 --- a/chromium/third_party/sqlite/patched/ext/fts3/fts3_write.c +++ b/chromium/third_party/sqlite/patched/ext/fts3/fts3_write.c @@ -335,7 +335,7 @@ static int fts3SqlStmt( ** returns zero rows. */ /* 28 */ "SELECT level, count(*) AS cnt FROM %Q.'%q_segdir' " " GROUP BY level HAVING cnt>=?" - " ORDER BY (level %% 1024) ASC LIMIT 1", + " ORDER BY (level %% 1024) ASC, 2 DESC LIMIT 1", /* Estimate the upper limit on the number of leaf nodes in a new segment ** created by merging the oldest :2 segments from absolute level :1. See @@ -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 ); @@ -1529,18 +1529,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; } @@ -2279,6 +2279,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++; @@ -2975,9 +2976,9 @@ int sqlite3Fts3SegReaderStep( ** doclist. */ sqlite3_int64 iDelta; if( p->bDescIdx && nDoclist>0 ){ - iDelta = iPrev - iDocid; + iDelta = (i64)((u64)iPrev - (u64)iDocid); }else{ - iDelta = iDocid - iPrev; + iDelta = (i64)((u64)iDocid - (u64)iPrev); } if( iDelta<=0 && (nDoclist>0 || iDelta!=iDocid) ){ return FTS_CORRUPT_VTAB; @@ -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( @@ -4844,13 +4845,17 @@ static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){ const int nHint = pHint->n; int i; - i = pHint->n-2; + i = pHint->n-1; + if( (pHint->a[i] & 0x80) ) return FTS_CORRUPT_VTAB; while( i>0 && (pHint->a[i-1] & 0x80) ) i--; + if( i==0 ) return FTS_CORRUPT_VTAB; + i--; while( i>0 && (pHint->a[i-1] & 0x80) ) i--; pHint->n = i; i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel); i += fts3GetVarint32(&pHint->a[i], pnInput); + assert( i<=nHint ); if( i!=nHint ) return FTS_CORRUPT_VTAB; return SQLITE_OK; @@ -4920,8 +4925,14 @@ int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ rc = fts3IncrmergeHintPop(&hint, &iHintAbsLevel, &nHintSeg); if( nSeg<0 || (iAbsLevel % nMod) >= (iHintAbsLevel % nMod) ){ + /* Based on the scan in the block above, it is known that there + ** are no levels with a relative level smaller than that of + ** iAbsLevel with more than nSeg segments, or if nSeg is -1, + ** no levels with more than nMin segments. Use this to limit the + ** value of nHintSeg to avoid a large memory allocation in case the + ** merge-hint is corrupt*/ iAbsLevel = iHintAbsLevel; - nSeg = nHintSeg; + nSeg = MIN(MAX(nMin,nSeg), nHintSeg); bUseHint = 1; bDirtyHint = 1; }else{ @@ -4934,7 +4945,7 @@ int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ /* If nSeg is less that zero, then there is no level with at least ** nMin segments and no hint in the %_stat table. No work to do. ** Exit early in this case. */ - if( nSeg<0 ) break; + if( nSeg<=0 ) break; /* Open a cursor to iterate through the contents of the oldest nSeg ** indexes of absolute level iAbsLevel. If this cursor is opened using @@ -5171,12 +5182,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; @@ -5184,8 +5195,8 @@ static u64 fts3ChecksumIndex( if( iVal ){ pCsr += sqlite3Fts3GetVarint(pCsr, &iCol); }else{ - pCsr += sqlite3Fts3GetVarint(pCsr, &iVal); - iDocid += iVal; + pCsr += sqlite3Fts3GetVarintU(pCsr, &iVal); + iDocid = (i64)((u64)iDocid + iVal); } }else{ iPos += (iVal - 2); diff --git a/chromium/third_party/sqlite/patched/ext/misc/zipfile.c b/chromium/third_party/sqlite/patched/ext/misc/zipfile.c index 5a88389bf2d..1dc47a7d9ae 100644 --- a/chromium/third_party/sqlite/patched/ext/misc/zipfile.c +++ b/chromium/third_party/sqlite/patched/ext/misc/zipfile.c @@ -1618,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]); } diff --git a/chromium/third_party/sqlite/patched/src/alter.c b/chromium/third_party/sqlite/patched/src/alter.c index 7be2d830cda..48282c57b3b 100644 --- a/chromium/third_party/sqlite/patched/src/alter.c +++ b/chromium/third_party/sqlite/patched/src/alter.c @@ -31,9 +31,8 @@ static int isAlterableTable(Parse *pParse, Table *pTab){ if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) #ifndef SQLITE_OMIT_VIRTUALTABLE - || ( (pTab->tabFlags & TF_Shadow) - && (pParse->db->flags & SQLITE_Defensive) - && pParse->db->nVdbeExec==0 + || ( (pTab->tabFlags & TF_Shadow)!=0 + && sqlite3ReadOnlyShadowTables(pParse->db) ) #endif ){ @@ -734,6 +733,7 @@ static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){ static int renameUnmapSelectCb(Walker *pWalker, Select *p){ Parse *pParse = pWalker->pParse; int i; + if( p->selFlags & SF_View ) return WRC_Prune; if( ALWAYS(p->pEList) ){ ExprList *pList = p->pEList; for(i=0; i<pList->nExpr; i++){ @@ -838,6 +838,7 @@ static void renameWalkWith(Walker *pWalker, Select *pSelect){ ** descend into sub-select statements. */ static int renameColumnSelectCb(Walker *pWalker, Select *p){ + if( p->selFlags & SF_View ) return WRC_Prune; renameWalkWith(pWalker, p); return WRC_Continue; } @@ -1303,8 +1304,9 @@ static void renameColumnFunc( if( sParse.pNewTable ){ Select *pSelect = sParse.pNewTable->pSelect; if( pSelect ){ + pSelect->selFlags &= ~SF_View; sParse.rc = SQLITE_OK; - sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, 0); + sqlite3SelectPrep(&sParse, pSelect, 0); rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); if( rc==SQLITE_OK ){ sqlite3WalkSelect(&sWalker, pSelect); @@ -1416,6 +1418,7 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ int i; RenameCtx *p = pWalker->u.pRename; SrcList *pSrc = pSelect->pSrc; + if( pSelect->selFlags & SF_View ) return WRC_Prune; if( pSrc==0 ){ assert( pWalker->pParse->db->mallocFailed ); return WRC_Abort; @@ -1495,10 +1498,13 @@ static void renameTableFunc( if( pTab->pSelect ){ if( isLegacy==0 ){ + Select *pSelect = pTab->pSelect; NameContext sNC; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = &sParse; + assert( pSelect->selFlags & SF_View ); + pSelect->selFlags &= ~SF_View; sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC); if( sParse.nErr ) rc = sParse.rc; sqlite3WalkSelect(&sWalker, pTab->pSelect); diff --git a/chromium/third_party/sqlite/patched/src/build.c b/chromium/third_party/sqlite/patched/src/build.c index 6d30cd76a13..9a9a33e9564 100644 --- a/chromium/third_party/sqlite/patched/src/build.c +++ b/chromium/third_party/sqlite/patched/src/build.c @@ -856,13 +856,14 @@ int sqlite3CheckObjectName( } } }else{ - if( pParse->nested==0 - && 0==sqlite3StrNICmp(zName, "sqlite_", 7) + if( (pParse->nested==0 && 0==sqlite3StrNICmp(zName, "sqlite_", 7)) + || (sqlite3ReadOnlyShadowTables(db) && sqlite3ShadowTableName(db, zName)) ){ sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName); return SQLITE_ERROR; } + } return SQLITE_OK; } @@ -2002,7 +2003,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ ** zName is temporarily modified while this routine is running, but is ** restored to its original value prior to this routine returning. */ -static int isShadowTableName(sqlite3 *db, char *zName){ +int sqlite3ShadowTableName(sqlite3 *db, const char *zName){ char *zTail; /* Pointer to the last "_" in zName */ Table *pTab; /* Table that zName is a shadow of */ Module *pMod; /* Module for the virtual table */ @@ -2020,8 +2021,6 @@ static int isShadowTableName(sqlite3 *db, char *zName){ if( pMod->pModule->xShadowName==0 ) return 0; return pMod->pModule->xShadowName(zTail+1); } -#else -# define isShadowTableName(x,y) 0 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ /* @@ -2063,7 +2062,7 @@ void sqlite3EndTable( p = pParse->pNewTable; if( p==0 ) return; - if( pSelect==0 && isShadowTableName(db, p->zName) ){ + if( pSelect==0 && sqlite3ShadowTableName(db, p->zName) ){ p->tabFlags |= TF_Shadow; } @@ -2334,6 +2333,7 @@ void sqlite3CreateView( ** allocated rather than point to the input string - which means that ** they will persist after the current sqlite3_exec() call returns. */ + pSelect->selFlags |= SF_View; if( IN_RENAME_OBJECT ){ p->pSelect = pSelect; pSelect = 0; @@ -2747,17 +2747,32 @@ void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){ } /* +** Return TRUE if shadow tables should be read-only in the current +** context. +*/ +int sqlite3ReadOnlyShadowTables(sqlite3 *db){ +#ifndef SQLITE_OMIT_VIRTUALTABLE + if( (db->flags & SQLITE_Defensive)!=0 + && db->pVtabCtx==0 + && db->nVdbeExec==0 + ){ + return 1; + } +#endif + return 0; +} + +/* ** Return true if it is not allowed to drop the given table */ -static int tableMayNotBeDropped(Parse *pParse, Table *pTab){ +static int tableMayNotBeDropped(sqlite3 *db, Table *pTab){ if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ if( sqlite3StrNICmp(pTab->zName+7, "stat", 4)==0 ) return 0; if( sqlite3StrNICmp(pTab->zName+7, "parameters", 10)==0 ) return 0; return 1; } - if( pTab->tabFlags & TF_Shadow ){ - sqlite3 *db = pParse->db; - if( (db->flags & SQLITE_Defensive)!=0 && db->nVdbeExec==0 ) return 1; + if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){ + return 1; } return 0; } @@ -2831,7 +2846,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ } } #endif - if( tableMayNotBeDropped(pParse, pTab) ){ + if( tableMayNotBeDropped(db, pTab) ){ sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName); goto exit_drop_table; } diff --git a/chromium/third_party/sqlite/patched/src/delete.c b/chromium/third_party/sqlite/patched/src/delete.c index dcb117f2e10..cde8e1a292a 100644 --- a/chromium/third_party/sqlite/patched/src/delete.c +++ b/chromium/third_party/sqlite/patched/src/delete.c @@ -70,11 +70,7 @@ static int tabIsReadOnly(Parse *pParse, Table *pTab){ return sqlite3WritableSchema(db)==0 && pParse->nested==0; } assert( pTab->tabFlags & TF_Shadow ); - return (db->flags & SQLITE_Defensive)!=0 -#ifndef SQLITE_OMIT_VIRTUALTABLE - && db->pVtabCtx==0 -#endif - && db->nVdbeExec==0; + return sqlite3ReadOnlyShadowTables(db); } /* diff --git a/chromium/third_party/sqlite/patched/src/expr.c b/chromium/third_party/sqlite/patched/src/expr.c index e8b1f31c42a..760978c482d 100644 --- a/chromium/third_party/sqlite/patched/src/expr.c +++ b/chromium/third_party/sqlite/patched/src/expr.c @@ -1815,18 +1815,33 @@ int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){ } /* +** Check the input string to see if it is "true" or "false" (in any case). +** +** If the string is.... Return +** "true" EP_IsTrue +** "false" EP_IsFalse +** anything else 0 +*/ +u32 sqlite3IsTrueOrFalse(const char *zIn){ + if( sqlite3StrICmp(zIn, "true")==0 ) return EP_IsTrue; + if( sqlite3StrICmp(zIn, "false")==0 ) return EP_IsFalse; + return 0; +} + + +/* ** If the input expression is an ID with the name "true" or "false" ** then convert it into an TK_TRUEFALSE term. Return non-zero if ** the conversion happened, and zero if the expression is unaltered. */ int sqlite3ExprIdToTrueFalse(Expr *pExpr){ + u32 v; assert( pExpr->op==TK_ID || pExpr->op==TK_STRING ); if( !ExprHasProperty(pExpr, EP_Quoted) - && (sqlite3StrICmp(pExpr->u.zToken, "true")==0 - || sqlite3StrICmp(pExpr->u.zToken, "false")==0) + && (v = sqlite3IsTrueOrFalse(pExpr->u.zToken))!=0 ){ pExpr->op = TK_TRUEFALSE; - ExprSetProperty(pExpr, pExpr->u.zToken[4]==0 ? EP_IsTrue : EP_IsFalse); + ExprSetProperty(pExpr, v); return 1; } return 0; diff --git a/chromium/third_party/sqlite/patched/src/select.c b/chromium/third_party/sqlite/patched/src/select.c index 429d3dc817a..2c9b4d9e01a 100644 --- a/chromium/third_party/sqlite/patched/src/select.c +++ b/chromium/third_party/sqlite/patched/src/select.c @@ -1980,7 +1980,7 @@ int sqlite3ColumnsFromExprList( zName = pEList->a[i].zSpan; } } - if( zName ){ + if( zName && !sqlite3IsTrueOrFalse(zName) ){ zName = sqlite3DbStrDup(db, zName); }else{ zName = sqlite3MPrintf(db,"column%d",i+1); @@ -2805,6 +2805,7 @@ static int multiSelect( } #endif } + if( pParse->nErr ) goto multi_select_end; /* Compute collating sequences used by ** temporary tables needed to implement the compound select. @@ -3596,6 +3597,7 @@ static void substSelect( ** (3b) the FROM clause of the subquery may not contain a virtual ** table and ** (3c) the outer query may not be an aggregate. +** (3d) the outer query may not be DISTINCT. ** ** (4) The subquery can not be DISTINCT. ** @@ -3792,8 +3794,11 @@ static int flattenSubquery( */ if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){ isLeftJoin = 1; - if( pSubSrc->nSrc>1 || isAgg || IsVirtual(pSubSrc->a[0].pTab) ){ - /* (3a) (3c) (3b) */ + if( pSubSrc->nSrc>1 /* (3a) */ + || isAgg /* (3b) */ + || IsVirtual(pSubSrc->a[0].pTab) /* (3c) */ + || (p->selFlags & SF_Distinct)!=0 /* (3d) */ + ){ return 0; } } @@ -4193,7 +4198,7 @@ static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){ int i; WhereConst *pConst; if( pExpr->op!=TK_COLUMN ) return WRC_Continue; - if( ExprHasProperty(pExpr, EP_FixedCol) ) return WRC_Continue; + if( ExprHasProperty(pExpr, EP_FixedCol|EP_FromJoin) ) return WRC_Continue; pConst = pWalker->u.pConst; for(i=0; i<pConst->nConst; i++){ Expr *pColumn = pConst->apExpr[i*2]; @@ -4666,6 +4671,9 @@ static int withExpand( With *pWith; /* WITH clause that pCte belongs to */ assert( pFrom->pTab==0 ); + if( pParse->nErr ){ + return SQLITE_ERROR; + } pCte = searchWith(pParse->pWith, pFrom, &pWith); if( pCte ){ diff --git a/chromium/third_party/sqlite/patched/src/sqliteInt.h b/chromium/third_party/sqlite/patched/src/sqliteInt.h index 81aa0dc1872..970ef817f3e 100644 --- a/chromium/third_party/sqlite/patched/src/sqliteInt.h +++ b/chromium/third_party/sqlite/patched/src/sqliteInt.h @@ -2912,6 +2912,7 @@ struct Select { #define SF_IncludeHidden 0x20000 /* Include hidden columns in output */ #define SF_ComplexResult 0x40000 /* Result contains subquery or function */ #define SF_WhereBegin 0x80000 /* Really a WhereBegin() call. Debug Only */ +#define SF_View 0x0200000 /* SELECT statement is a view */ /* ** The results of a SELECT can be distributed in several ways, as defined @@ -4092,6 +4093,7 @@ void sqlite3EndTransaction(Parse*,int); void sqlite3Savepoint(Parse*, int, Token*); void sqlite3CloseSavepoints(sqlite3 *); void sqlite3LeaveMutexAndCloseZombie(sqlite3*); +u32 sqlite3IsTrueOrFalse(const char*); int sqlite3ExprIdToTrueFalse(Expr*); int sqlite3ExprTruthValue(const Expr*); int sqlite3ExprIsConstant(Expr*); @@ -4485,6 +4487,12 @@ void sqlite3AutoLoadExtensions(sqlite3*); ); # define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) #endif +int sqlite3ReadOnlyShadowTables(sqlite3 *db); +#ifndef SQLITE_OMIT_VIRTUALTABLE + int sqlite3ShadowTableName(sqlite3 *db, const char *zName); +#else +# define sqlite3ShadowTableName(A,B) 0 +#endif int sqlite3VtabEponymousTableInit(Parse*,Module*); void sqlite3VtabEponymousTableClear(sqlite3*,Module*); void sqlite3VtabMakeWritable(Parse*,Table*); diff --git a/chromium/third_party/sqlite/patched/src/trigger.c b/chromium/third_party/sqlite/patched/src/trigger.c index 64ccfdeb081..8a756ca47d8 100644 --- a/chromium/third_party/sqlite/patched/src/trigger.c +++ b/chromium/third_party/sqlite/patched/src/trigger.c @@ -662,8 +662,12 @@ void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){ Table *pTab = tableOfTrigger(pTrigger); if( pTab ){ Trigger **pp; - for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext)); - *pp = (*pp)->pNext; + for(pp=&pTab->pTrigger; *pp; pp=&((*pp)->pNext)){ + if( *pp==pTrigger ){ + *pp = (*pp)->pNext; + break; + } + } } } sqlite3DeleteTrigger(db, pTrigger); diff --git a/chromium/third_party/sqlite/patched/src/util.c b/chromium/third_party/sqlite/patched/src/util.c index d70b93bb79b..0d12b8d53a4 100644 --- a/chromium/third_party/sqlite/patched/src/util.c +++ b/chromium/third_party/sqlite/patched/src/util.c @@ -192,6 +192,7 @@ void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ sqlite3DbFree(db, pParse->zErrMsg); pParse->zErrMsg = zMsg; pParse->rc = SQLITE_ERROR; + pParse->pWith = 0; } } @@ -385,7 +386,7 @@ static LONGDOUBLE_TYPE sqlite3Pow10(int E){ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ #ifndef SQLITE_OMIT_FLOATING_POINT int incr; - const char *zEnd = z + length; + const char *zEnd; /* sign * significand * (10 ^ (esign * exponent)) */ int sign = 1; /* sign of significand */ i64 s = 0; /* significand */ @@ -399,9 +400,11 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); *pResult = 0.0; /* Default return value, in case of an error */ + if( length==0 ) return 0; if( enc==SQLITE_UTF8 ){ incr = 1; + zEnd = z + length; }else{ int i; incr = 2; diff --git a/chromium/third_party/sqlite/patched/src/vdbemem.c b/chromium/third_party/sqlite/patched/src/vdbemem.c index 4a39db0523f..1689ccee835 100644 --- a/chromium/third_party/sqlite/patched/src/vdbemem.c +++ b/chromium/third_party/sqlite/patched/src/vdbemem.c @@ -594,8 +594,7 @@ i64 sqlite3VdbeIntValue(Mem *pMem){ return pMem->u.i; }else if( flags & MEM_Real ){ return doubleToInt64(pMem->u.r); - }else if( flags & (MEM_Str|MEM_Blob) ){ - assert( pMem->z || pMem->n==0 ); + }else if( (flags & (MEM_Str|MEM_Blob))!=0 && pMem->z!=0 ){ return memIntValue(pMem); }else{ return 0; diff --git a/chromium/third_party/sqlite/patched/src/window.c b/chromium/third_party/sqlite/patched/src/window.c index c251cd01974..2d79ffe63d6 100644 --- a/chromium/third_party/sqlite/patched/src/window.c +++ b/chromium/third_party/sqlite/patched/src/window.c @@ -883,9 +883,11 @@ static ExprList *exprListAppendList( int nInit = pList ? pList->nExpr : 0; for(i=0; i<pAppend->nExpr; i++){ Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0); + assert( pDup==0 || !ExprHasProperty(pDup, EP_MemToken) ); if( bIntToNull && pDup && pDup->op==TK_INTEGER ){ pDup->op = TK_NULL; pDup->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse); + pDup->u.zToken = 0; } pList = sqlite3ExprListAppend(pParse, pList, pDup); if( pList ) pList->a[nInit+i].sortFlags = pAppend->a[i].sortFlags; diff --git a/chromium/third_party/sqlite/patches/0001-Don-t-allow-shadow-tables-to-be-dropped-in-defensive.patch b/chromium/third_party/sqlite/patches/0001-Don-t-allow-shadow-tables-to-be-dropped-in-defensive.patch index e7136203224..8e75eb71a5c 100644 --- a/chromium/third_party/sqlite/patches/0001-Don-t-allow-shadow-tables-to-be-dropped-in-defensive.patch +++ b/chromium/third_party/sqlite/patches/0001-Don-t-allow-shadow-tables-to-be-dropped-in-defensive.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Darwin Huang <huangdarwin@chromium.org> Date: Tue, 19 Nov 2019 14:09:07 -0800 -Subject: [PATCH 1/8] Don't allow shadow tables to be dropped in defensive +Subject: [PATCH 01/25] Don't allow shadow tables to be dropped in defensive mode. Backports https://www.sqlite.org/src/info/70390bbca49e7066 @@ -83,5 +83,5 @@ index fcbf6fb5de44..c5766e22717d 100644 } } -- -2.24.0.432.g9d3f5f5b63-goog +2.25.0.rc1.283.g88dfdc4193-goog diff --git a/chromium/third_party/sqlite/patches/0002-Improve-shadow-table-corruption-detection-in-fts3.patch b/chromium/third_party/sqlite/patches/0002-Improve-shadow-table-corruption-detection-in-fts3.patch index 60436fa436a..5976c619aab 100644 --- a/chromium/third_party/sqlite/patches/0002-Improve-shadow-table-corruption-detection-in-fts3.patch +++ b/chromium/third_party/sqlite/patches/0002-Improve-shadow-table-corruption-detection-in-fts3.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Darwin Huang <huangdarwin@chromium.org> Date: Tue, 19 Nov 2019 14:32:48 -0800 -Subject: [PATCH 2/8] Improve shadow table corruption detection in fts3 +Subject: [PATCH 02/25] Improve shadow table corruption detection in fts3 Backports https://www.sqlite.org/src/info/04b2873be5aedeb1 @@ -148,5 +148,5 @@ index 8ea4ff186fc6..b7c6cd5a4be9 100644 return rc; -- -2.24.0.432.g9d3f5f5b63-goog +2.25.0.rc1.283.g88dfdc4193-goog diff --git a/chromium/third_party/sqlite/patches/0003-Shadow-Table-Corruption-Detection-improvements-in-ft.patch b/chromium/third_party/sqlite/patches/0003-Shadow-Table-Corruption-Detection-improvements-in-ft.patch index 8756fdb88e3..c90e5b49615 100644 --- a/chromium/third_party/sqlite/patches/0003-Shadow-Table-Corruption-Detection-improvements-in-ft.patch +++ b/chromium/third_party/sqlite/patches/0003-Shadow-Table-Corruption-Detection-improvements-in-ft.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Darwin Huang <huangdarwin@chromium.org> Date: Tue, 19 Nov 2019 15:04:03 -0800 -Subject: [PATCH 3/8] Shadow Table Corruption Detection improvements in fts3 +Subject: [PATCH 03/25] Shadow Table Corruption Detection improvements in fts3 Backports https://www.sqlite.org/src/info/51525f9c3235967b @@ -107,5 +107,5 @@ index b7c6cd5a4be9..c28358c17479 100644 #endif -- -2.24.0.432.g9d3f5f5b63-goog +2.25.0.rc1.283.g88dfdc4193-goog diff --git a/chromium/third_party/sqlite/patches/0004-Remove-reachable-NEVER-in-fts3.patch b/chromium/third_party/sqlite/patches/0004-Remove-reachable-NEVER-in-fts3.patch index efa0441c740..ab4b24893d1 100644 --- a/chromium/third_party/sqlite/patches/0004-Remove-reachable-NEVER-in-fts3.patch +++ b/chromium/third_party/sqlite/patches/0004-Remove-reachable-NEVER-in-fts3.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Darwin Huang <huangdarwin@chromium.org> Date: Tue, 19 Nov 2019 15:05:43 -0800 -Subject: [PATCH 4/8] Remove reachable NEVER in fts3 +Subject: [PATCH 04/25] Remove reachable NEVER in fts3 Backports https://www.sqlite.org/src/info/8bd75bf636f72f32 @@ -24,5 +24,5 @@ index c28358c17479..11ac562a17f8 100644 nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; -- -2.24.0.432.g9d3f5f5b63-goog +2.25.0.rc1.283.g88dfdc4193-goog diff --git a/chromium/third_party/sqlite/patches/0005-Better-corruption-detection-in-fts3.patch b/chromium/third_party/sqlite/patches/0005-Better-corruption-detection-in-fts3.patch index ee1c3b94bdf..4eeb96e9ebe 100644 --- a/chromium/third_party/sqlite/patches/0005-Better-corruption-detection-in-fts3.patch +++ b/chromium/third_party/sqlite/patches/0005-Better-corruption-detection-in-fts3.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Darwin Huang <huangdarwin@chromium.org> Date: Tue, 19 Nov 2019 15:17:18 -0800 -Subject: [PATCH 5/8] Better % corruption detection in fts3. +Subject: [PATCH 05/25] Better % corruption detection in fts3. Backports https://www.sqlite.org/src/info/1e449687881f4d38 @@ -226,5 +226,5 @@ index 095c522026f6..c516c34d564a 100644 + finish_test -- -2.24.0.432.g9d3f5f5b63-goog +2.25.0.rc1.283.g88dfdc4193-goog diff --git a/chromium/third_party/sqlite/patches/0006-Detect-Prevent-infinite-recursion.patch b/chromium/third_party/sqlite/patches/0006-Detect-Prevent-infinite-recursion.patch index 171ca674f78..604771b3d89 100644 --- a/chromium/third_party/sqlite/patches/0006-Detect-Prevent-infinite-recursion.patch +++ b/chromium/third_party/sqlite/patches/0006-Detect-Prevent-infinite-recursion.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Darwin Huang <huangdarwin@chromium.org> Date: Tue, 19 Nov 2019 15:19:40 -0800 -Subject: [PATCH 6/8] Detect/Prevent infinite recursion +Subject: [PATCH 06/25] Detect/Prevent infinite recursion Backports https://www.sqlite.org/src/info/dfcf081d842629a0 @@ -52,5 +52,5 @@ index c516c34d564a..ddb6c177cf0a 100644 finish_test -- -2.24.0.432.g9d3f5f5b63-goog +2.25.0.rc1.283.g88dfdc4193-goog diff --git a/chromium/third_party/sqlite/patches/0007-Improve-corruption-detection-in-fts4.patch b/chromium/third_party/sqlite/patches/0007-Improve-corruption-detection-in-fts4.patch index 034118d2596..ffa7a351aec 100644 --- a/chromium/third_party/sqlite/patches/0007-Improve-corruption-detection-in-fts4.patch +++ b/chromium/third_party/sqlite/patches/0007-Improve-corruption-detection-in-fts4.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Darwin Huang <huangdarwin@chromium.org> Date: Tue, 19 Nov 2019 15:34:00 -0800 -Subject: [PATCH 7/8] Improve corruption detection in fts4 +Subject: [PATCH 07/25] Improve corruption detection in fts4 Backports https://www.sqlite.org/src/info/10f8a3b718e0f47b @@ -51,5 +51,5 @@ index ddb6c177cf0a..ac477f4706dc 100644 db close sqlite3 db :memory: -- -2.24.0.432.g9d3f5f5b63-goog +2.25.0.rc1.283.g88dfdc4193-goog diff --git a/chromium/third_party/sqlite/patches/0008-Further-improve-corruption-detection-in-fts3.patch b/chromium/third_party/sqlite/patches/0008-Further-improve-corruption-detection-in-fts3.patch index 1dc29d26750..245483b1e97 100644 --- a/chromium/third_party/sqlite/patches/0008-Further-improve-corruption-detection-in-fts3.patch +++ b/chromium/third_party/sqlite/patches/0008-Further-improve-corruption-detection-in-fts3.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Darwin Huang <huangdarwin@chromium.org> Date: Wed, 20 Nov 2019 10:58:51 -0800 -Subject: [PATCH 8/8] Further improve corruption detection in fts3 +Subject: [PATCH 08/25] Further improve corruption detection in fts3 Backports https://sqlite.org/src/info/a0f6d526baecd061 (aka https://sqlite.org/src/info/a0f6d526baecd061a5e2) @@ -39,5 +39,5 @@ index 146c507b5d0b..953b9d86959e 100644 return FTS_CORRUPT_VTAB; } -- -2.24.0.432.g9d3f5f5b63-goog +2.25.0.rc1.283.g88dfdc4193-goog diff --git a/chromium/third_party/sqlite/patches/0009-Make-sure-WITH-stack-is-disabled-after-error.patch b/chromium/third_party/sqlite/patches/0009-Make-sure-WITH-stack-is-disabled-after-error.patch new file mode 100644 index 00000000000..8c9fb2ba5c2 --- /dev/null +++ b/chromium/third_party/sqlite/patches/0009-Make-sure-WITH-stack-is-disabled-after-error.patch @@ -0,0 +1,64 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darwin Huang <huangdarwin@chromium.org> +Date: Tue, 3 Dec 2019 13:56:38 -0800 +Subject: [PATCH 09/25] Make sure WITH stack is disabled after error + +Backports https://sqlite.org/src/info/de6e6d6846d6a41c + +Bug: 1021016 +--- + third_party/sqlite/patched/src/select.c | 3 +++ + third_party/sqlite/patched/src/util.c | 1 + + third_party/sqlite/patched/test/with3.test | 10 +++++++++- + 3 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/third_party/sqlite/patched/src/select.c b/third_party/sqlite/patched/src/select.c +index 429d3dc817aa..ba70a2bdec78 100644 +--- a/third_party/sqlite/patched/src/select.c ++++ b/third_party/sqlite/patched/src/select.c +@@ -4666,6 +4666,9 @@ static int withExpand( + With *pWith; /* WITH clause that pCte belongs to */ + + assert( pFrom->pTab==0 ); ++ if( pParse->nErr ){ ++ return SQLITE_ERROR; ++ } + + pCte = searchWith(pParse->pWith, pFrom, &pWith); + if( pCte ){ +diff --git a/third_party/sqlite/patched/src/util.c b/third_party/sqlite/patched/src/util.c +index d70b93bb79b7..430cdb64742f 100644 +--- a/third_party/sqlite/patched/src/util.c ++++ b/third_party/sqlite/patched/src/util.c +@@ -192,6 +192,7 @@ void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ + sqlite3DbFree(db, pParse->zErrMsg); + pParse->zErrMsg = zMsg; + pParse->rc = SQLITE_ERROR; ++ pParse->pWith = 0; + } + } + +diff --git a/third_party/sqlite/patched/test/with3.test b/third_party/sqlite/patched/test/with3.test +index f651207d2901..99b64e957ffa 100644 +--- a/third_party/sqlite/patched/test/with3.test ++++ b/third_party/sqlite/patched/test/with3.test +@@ -30,7 +30,15 @@ do_catchsql_test 1.0 { + SELECT 5 FROM t0 UNION SELECT 8 FROM m + ) + SELECT * FROM i; +-} {1 {no such table: m}} ++} {1 {no such table: t0}} ++ ++# 2019-11-09 dbfuzzcheck find ++do_catchsql_test 1.1 { ++ CREATE VIEW v1(x,y) AS ++ WITH t1(a,b) AS (VALUES(1,2)) ++ SELECT * FROM nosuchtable JOIN t1; ++ SELECT * FROM v1; ++} {1 {no such table: main.nosuchtable}} + + # Additional test cases that came out of the work to + # fix for Kostya's problem. +-- +2.25.0.rc1.283.g88dfdc4193-goog + diff --git a/chromium/third_party/sqlite/patches/0010-Avoid-zero-offset.patch b/chromium/third_party/sqlite/patches/0010-Avoid-zero-offset.patch new file mode 100644 index 00000000000..cd3295c10db --- /dev/null +++ b/chromium/third_party/sqlite/patches/0010-Avoid-zero-offset.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darwin Huang <huangdarwin@chromium.org> +Date: Tue, 3 Dec 2019 13:59:19 -0800 +Subject: [PATCH 10/25] Avoid zero offset + +Backports https://www.sqlite.org/src/info/3ce804e99bbef83d + +Bug: 1026862, 1028772 +--- + third_party/sqlite/patched/src/vdbemem.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/third_party/sqlite/patched/src/vdbemem.c b/third_party/sqlite/patched/src/vdbemem.c +index 4a39db0523f5..1689ccee8356 100644 +--- a/third_party/sqlite/patched/src/vdbemem.c ++++ b/third_party/sqlite/patched/src/vdbemem.c +@@ -594,8 +594,7 @@ i64 sqlite3VdbeIntValue(Mem *pMem){ + return pMem->u.i; + }else if( flags & MEM_Real ){ + return doubleToInt64(pMem->u.r); +- }else if( flags & (MEM_Str|MEM_Blob) ){ +- assert( pMem->z || pMem->n==0 ); ++ }else if( (flags & (MEM_Str|MEM_Blob))!=0 && pMem->z!=0 ){ + return memIntValue(pMem); + }else{ + return 0; +-- +2.25.0.rc1.283.g88dfdc4193-goog + diff --git a/chromium/third_party/sqlite/patches/0011-Avoid-zero-offset-of-nullptr.patch b/chromium/third_party/sqlite/patches/0011-Avoid-zero-offset-of-nullptr.patch new file mode 100644 index 00000000000..fc04756b251 --- /dev/null +++ b/chromium/third_party/sqlite/patches/0011-Avoid-zero-offset-of-nullptr.patch @@ -0,0 +1,38 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darwin Huang <huangdarwin@chromium.org> +Date: Tue, 3 Dec 2019 14:01:40 -0800 +Subject: [PATCH 11/25] Avoid zero offset of nullptr + +Backports https://www.sqlite.org/src/info/85d95abec4a596eb + +Bug: 1028615 +--- + third_party/sqlite/patched/ext/fts3/fts3.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/third_party/sqlite/patched/ext/fts3/fts3.c b/third_party/sqlite/patched/ext/fts3/fts3.c +index 8d48f22fec24..26aee1788429 100644 +--- a/third_party/sqlite/patched/ext/fts3/fts3.c ++++ b/third_party/sqlite/patched/ext/fts3/fts3.c +@@ -4514,15 +4514,16 @@ static void fts3EvalDlPhraseNext( + u8 *pbEof + ){ + char *pIter; /* Used to iterate through aAll */ +- char *pEnd = &pDL->aAll[pDL->nAll]; /* 1 byte past end of aAll */ ++ char *pEnd; /* 1 byte past end of aAll */ + + if( pDL->pNextDocid ){ + pIter = pDL->pNextDocid; ++ assert( pDL->aAll!=0 || pIter==0 ); + }else{ + pIter = pDL->aAll; + } + +- if( pIter>=pEnd ){ ++ if( pIter==0 || pIter>=(pEnd = pDL->aAll + pDL->nAll) ){ + /* We have already reached the end of this doclist. EOF. */ + *pbEof = 1; + }else{ +-- +2.25.0.rc1.283.g88dfdc4193-goog + diff --git a/chromium/third_party/sqlite/patches/0012-Fix-buffer-overread.patch b/chromium/third_party/sqlite/patches/0012-Fix-buffer-overread.patch new file mode 100644 index 00000000000..faea332557f --- /dev/null +++ b/chromium/third_party/sqlite/patches/0012-Fix-buffer-overread.patch @@ -0,0 +1,61 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darwin Huang <huangdarwin@chromium.org> +Date: Mon, 16 Dec 2019 11:49:51 -0800 +Subject: [PATCH 12/25] Fix buffer overread + +Backports https://www.sqlite.org/src/info/e01fdbf9f700e1bd + +Bug: 1028722, 1029027, 1029210, 1029506 +--- + third_party/sqlite/patched/ext/fts3/fts3_write.c | 6 +++++- + third_party/sqlite/patched/test/fts3corrupt4.test | 13 +++++++++++++ + 2 files changed, 18 insertions(+), 1 deletion(-) + +diff --git a/third_party/sqlite/patched/ext/fts3/fts3_write.c b/third_party/sqlite/patched/ext/fts3/fts3_write.c +index 953b9d86959e..47692c52c882 100644 +--- a/third_party/sqlite/patched/ext/fts3/fts3_write.c ++++ b/third_party/sqlite/patched/ext/fts3/fts3_write.c +@@ -4844,13 +4844,17 @@ static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){ + const int nHint = pHint->n; + int i; + +- i = pHint->n-2; ++ i = pHint->n-1; ++ if( (pHint->a[i] & 0x80) ) return FTS_CORRUPT_VTAB; + while( i>0 && (pHint->a[i-1] & 0x80) ) i--; ++ if( i==0 ) return FTS_CORRUPT_VTAB; ++ i--; + while( i>0 && (pHint->a[i-1] & 0x80) ) i--; + + pHint->n = i; + i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel); + i += fts3GetVarint32(&pHint->a[i], pnInput); ++ assert( i<=nHint ); + if( i!=nHint ) return FTS_CORRUPT_VTAB; + + return SQLITE_OK; +diff --git a/third_party/sqlite/patched/test/fts3corrupt4.test b/third_party/sqlite/patched/test/fts3corrupt4.test +index 7f1a59619b51..b5d9c138a5ea 100644 +--- a/third_party/sqlite/patched/test/fts3corrupt4.test ++++ b/third_party/sqlite/patched/test/fts3corrupt4.test +@@ -5546,4 +5546,17 @@ do_catchsql_test 30.2 { + SELECT (matchinfo(null)) FROM t1 WHERE t1 MATCH 'ee*e*e*e*e*e*e*Re*e*e*e**' + } {1 {database disk image is malformed}} + ++#------------------------------------------------------------------------- ++# ++reset_db ++do_catchsql_test 32.0 { ++ CREATE VIRTUAL TABLE f USING fts3(a,b,tokenize=icu); ++ CREATE TABLE 'f_docsize'(docid INTEGER PRIMARY KEY, size BLOB); ++ CREATE TABLE 'f_stat'(id INTEGER PRIMARY KEY, value BLOB); ++ INSERT INTO f VALUES (1, '1234'); ++ INSERT INTO f_stat VALUES (1,x'0000000165656565db6569746565c5c52bc5c5c53e3a003bc502ffffffffc5c5c53e3a003bc502fffffffffb8b2afbfb6565f0740100650000000165656565db6569746565c5c52bc5c5c53e3a003bc502ffffffffc5c5c53e3a003b8b00c5c5c5c5c5bfc5'); ++ INSERT INTO f(f) VALUES ('merge=198,49'); ++} {1 {database disk image is malformed}} ++ ++ + finish_test +-- +2.25.0.rc1.283.g88dfdc4193-goog + diff --git a/chromium/third_party/sqlite/patches/0013-Fix-UB-warning.patch b/chromium/third_party/sqlite/patches/0013-Fix-UB-warning.patch new file mode 100644 index 00000000000..edd599bce52 --- /dev/null +++ b/chromium/third_party/sqlite/patches/0013-Fix-UB-warning.patch @@ -0,0 +1,40 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darwin Huang <huangdarwin@chromium.org> +Date: Mon, 16 Dec 2019 13:45:04 -0800 +Subject: [PATCH 13/25] Fix UB warning + +Backports https://sqlite.org/src/info/052fdf5e58b41cca + +Bug: 1032390 +--- + third_party/sqlite/patched/src/util.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/third_party/sqlite/patched/src/util.c b/third_party/sqlite/patched/src/util.c +index 430cdb64742f..0d12b8d53a4c 100644 +--- a/third_party/sqlite/patched/src/util.c ++++ b/third_party/sqlite/patched/src/util.c +@@ -386,7 +386,7 @@ static LONGDOUBLE_TYPE sqlite3Pow10(int E){ + int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ + #ifndef SQLITE_OMIT_FLOATING_POINT + int incr; +- const char *zEnd = z + length; ++ const char *zEnd; + /* sign * significand * (10 ^ (esign * exponent)) */ + int sign = 1; /* sign of significand */ + i64 s = 0; /* significand */ +@@ -400,9 +400,11 @@ int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ + + assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); + *pResult = 0.0; /* Default return value, in case of an error */ ++ if( length==0 ) return 0; + + if( enc==SQLITE_UTF8 ){ + incr = 1; ++ zEnd = z + length; + }else{ + int i; + incr = 2; +-- +2.25.0.rc1.283.g88dfdc4193-goog + diff --git a/chromium/third_party/sqlite/patches/0014-Avoid-temp-trigger-crash.patch b/chromium/third_party/sqlite/patches/0014-Avoid-temp-trigger-crash.patch new file mode 100644 index 00000000000..e2b4c7b7ae0 --- /dev/null +++ b/chromium/third_party/sqlite/patches/0014-Avoid-temp-trigger-crash.patch @@ -0,0 +1,63 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darwin Huang <huangdarwin@chromium.org> +Date: Mon, 16 Dec 2019 13:48:39 -0800 +Subject: [PATCH 14/25] Avoid temp trigger crash + +Backports https://sqlite.org/src/info/c4cb9708d48ead10 + +Bug: 1028402 +--- + third_party/sqlite/patched/src/trigger.c | 8 ++++++-- + third_party/sqlite/patched/test/attach4.test | 19 +++++++++++++++++++ + 2 files changed, 25 insertions(+), 2 deletions(-) + +diff --git a/third_party/sqlite/patched/src/trigger.c b/third_party/sqlite/patched/src/trigger.c +index 64ccfdeb081e..8a756ca47d8e 100644 +--- a/third_party/sqlite/patched/src/trigger.c ++++ b/third_party/sqlite/patched/src/trigger.c +@@ -662,8 +662,12 @@ void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){ + Table *pTab = tableOfTrigger(pTrigger); + if( pTab ){ + Trigger **pp; +- for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext)); +- *pp = (*pp)->pNext; ++ for(pp=&pTab->pTrigger; *pp; pp=&((*pp)->pNext)){ ++ if( *pp==pTrigger ){ ++ *pp = (*pp)->pNext; ++ break; ++ } ++ } + } + } + sqlite3DeleteTrigger(db, pTrigger); +diff --git a/third_party/sqlite/patched/test/attach4.test b/third_party/sqlite/patched/test/attach4.test +index 54a2c649d5c4..958205697a15 100644 +--- a/third_party/sqlite/patched/test/attach4.test ++++ b/third_party/sqlite/patched/test/attach4.test +@@ -115,4 +115,23 @@ do_test 1.8 { + db close + foreach {name f} $files { forcedelete $f } + ++#------------------------------------------------------------------------- ++reset_db ++do_execsql_test 2.0 { ++ ATTACH DATABASE '' AS aux; ++ CREATE TABLE IF NOT EXISTS aux.t1(a, b); ++ CREATE TEMPORARY TRIGGER tr1 DELETE ON t1 BEGIN ++ DELETE FROM t1; ++ END; ++ CREATE TABLE temp.t1(a, b); ++} ++ ++do_execsql_test 2.1 { ++ DETACH DATABASE aux; ++} ++ ++do_execsql_test 2.2 { ++ DROP TRIGGER tr1; ++} ++ + finish_test +-- +2.25.0.rc1.283.g88dfdc4193-goog + diff --git a/chromium/third_party/sqlite/patches/0015-Fix-fts3-integer-overflows.patch b/chromium/third_party/sqlite/patches/0015-Fix-fts3-integer-overflows.patch new file mode 100644 index 00000000000..21fb72d1ad1 --- /dev/null +++ b/chromium/third_party/sqlite/patches/0015-Fix-fts3-integer-overflows.patch @@ -0,0 +1,274 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darwin Huang <huangdarwin@chromium.org> +Date: Mon, 16 Dec 2019 16:01:06 -0800 +Subject: [PATCH 15/25] Fix fts3 integer overflows + +Backports https://www.sqlite.org/src/info/3b873029ef1903f7 + +Bug: 1029002, 1030709 +--- + third_party/sqlite/patched/ext/fts3/fts3.c | 43 ++++++++----------- + third_party/sqlite/patched/ext/fts3/fts3Int.h | 4 ++ + .../sqlite/patched/ext/fts3/fts3_write.c | 29 +++++++------ + .../sqlite/patched/test/fts3corrupt4.test | 32 +++++++++++++- + 4 files changed, 68 insertions(+), 40 deletions(-) + +diff --git a/third_party/sqlite/patched/ext/fts3/fts3.c b/third_party/sqlite/patched/ext/fts3/fts3.c +index 26aee1788429..5cef6aa2370f 100644 +--- a/third_party/sqlite/patched/ext/fts3/fts3.c ++++ b/third_party/sqlite/patched/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; +@@ -391,6 +374,15 @@ int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){ + return (int)(p - pStart); + } + ++/* ++** 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]. +@@ -2484,12 +2476,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); + } + } + } +@@ -2518,9 +2510,9 @@ static void fts3PutDeltaVarint3( + ){ + sqlite3_int64 iWrite; + if( bDescIdx==0 || *pbFirst==0 ){ +- iWrite = iVal - *piPrev; ++ iWrite = (u64)iVal - (u64)*piPrev; + }else{ +- iWrite = *piPrev - iVal; ++ iWrite = (u64)*piPrev - (u64)iVal; + } + assert( *pbFirst || *piPrev==0 ); + assert_fts3_nc( *pbFirst==0 || iWrite>0 ); +@@ -2540,7 +2532,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 +diff --git a/third_party/sqlite/patched/ext/fts3/fts3Int.h b/third_party/sqlite/patched/ext/fts3/fts3Int.h +index 5cafa1fe9b91..44bf78ef8f17 100644 +--- a/third_party/sqlite/patched/ext/fts3/fts3Int.h ++++ b/third_party/sqlite/patched/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 +@@ -577,6 +580,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/third_party/sqlite/patched/ext/fts3/fts3_write.c b/third_party/sqlite/patched/ext/fts3/fts3_write.c +index 47692c52c882..8b6b729987c3 100644 +--- a/third_party/sqlite/patched/ext/fts3/fts3_write.c ++++ b/third_party/sqlite/patched/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 ); +@@ -1529,18 +1529,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; + } + + +@@ -2279,6 +2279,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++; +@@ -2975,9 +2976,9 @@ int sqlite3Fts3SegReaderStep( + ** doclist. */ + sqlite3_int64 iDelta; + if( p->bDescIdx && nDoclist>0 ){ +- iDelta = iPrev - iDocid; ++ iDelta = (i64)((u64)iPrev - (u64)iDocid); + }else{ +- iDelta = iDocid - iPrev; ++ iDelta = (i64)((u64)iDocid - (u64)iPrev); + } + if( iDelta<=0 && (nDoclist>0 || iDelta!=iDocid) ){ + return FTS_CORRUPT_VTAB; +@@ -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( +@@ -5175,12 +5176,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; +@@ -5188,8 +5189,8 @@ static u64 fts3ChecksumIndex( + if( iVal ){ + pCsr += sqlite3Fts3GetVarint(pCsr, &iCol); + }else{ +- pCsr += sqlite3Fts3GetVarint(pCsr, &iVal); +- iDocid += iVal; ++ pCsr += sqlite3Fts3GetVarintU(pCsr, &iVal); ++ iDocid = (i64)((u64)iDocid + iVal); + } + }else{ + iPos += (iVal - 2); +diff --git a/third_party/sqlite/patched/test/fts3corrupt4.test b/third_party/sqlite/patched/test/fts3corrupt4.test +index b5d9c138a5ea..45dd52fff29e 100644 +--- a/third_party/sqlite/patched/test/fts3corrupt4.test ++++ b/third_party/sqlite/patched/test/fts3corrupt4.test +@@ -5549,7 +5549,7 @@ do_catchsql_test 30.2 { + #------------------------------------------------------------------------- + # + reset_db +-do_catchsql_test 32.0 { ++do_catchsql_test 33.0 { + CREATE VIRTUAL TABLE f USING fts3(a,b,tokenize=icu); + CREATE TABLE 'f_docsize'(docid INTEGER PRIMARY KEY, size BLOB); + CREATE TABLE 'f_stat'(id INTEGER PRIMARY KEY, value BLOB); +@@ -5558,5 +5558,35 @@ do_catchsql_test 32.0 { + INSERT INTO f(f) VALUES ('merge=198,49'); + } {1 {database disk image is malformed}} + ++#------------------------------------------------------------------------- ++# ++reset_db ++do_execsql_test 34.0 { ++ CREATE VIRTUAL TABLE f USING fts3(a,b); ++ INSERT INTO f VALUES (1, '1234'); ++ INSERT INTO f_segdir VALUES (1,255,0,0,'1 255',x'00'); ++ UPDATE f_segdir SET level = 0 WHERE level IN ( ++ SELECT level FROM f_segdir LIMIT 1 OFFSET 1 ++ ); ++ INSERT INTO f_segdir VALUES (255,249,0,121,'0 0',x'00'); ++ INSERT INTO f_content VALUES (255,0,x'ff'); ++ INSERT INTO f_segdir VALUES (1,255,16,0,'1 255',x'00'); ++} ++ ++do_catchsql_test 34.1 { ++ UPDATE f SET b = x'00' WHERE b IN (SELECT b FROM f LIMIT 1 OFFSET 0); ++} {1 {database disk image is malformed}} ++ ++#------------------------------------------------------------------------- ++# ++reset_db ++do_execsql_test 35.0 { ++ CREATE VIRTUAL TABLE f USING fts3(a,b); ++ INSERT INTO f_segdir VALUES (1,255,0,0,'1 255',x'0001ff000001ff000001ff000001ff000001ff00c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5bec5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5'); ++} ++ ++do_catchsql_test 35.1 { ++ INSERT INTO f(f) VALUES ('integrity-check'); ++} {1 {database disk image is malformed}} + + finish_test +-- +2.25.0.rc1.283.g88dfdc4193-goog + diff --git a/chromium/third_party/sqlite/patches/0016-Avoid-infinite-recursion-in-ALTER-TABLE-code.patch b/chromium/third_party/sqlite/patches/0016-Avoid-infinite-recursion-in-ALTER-TABLE-code.patch new file mode 100644 index 00000000000..d8cb1467bc8 --- /dev/null +++ b/chromium/third_party/sqlite/patches/0016-Avoid-infinite-recursion-in-ALTER-TABLE-code.patch @@ -0,0 +1,137 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darwin Huang <huangdarwin@chromium.org> +Date: Wed, 18 Dec 2019 16:38:02 -0800 +Subject: [PATCH 16/25] Avoid infinite recursion in ALTER TABLE code + +Backports https://www.sqlite.org/src/info/1d2e53a39b87e364685e21de137655b6eee725e4c6d27fc90865072d7c5892b5 + +Bug: 1035371 +--- + third_party/sqlite/patched/src/alter.c | 9 +++++- + third_party/sqlite/patched/src/build.c | 1 + + third_party/sqlite/patched/src/sqliteInt.h | 1 + + .../sqlite/patched/test/altertab3.test | 31 +++++++++++++++++++ + 4 files changed, 41 insertions(+), 1 deletion(-) + +diff --git a/third_party/sqlite/patched/src/alter.c b/third_party/sqlite/patched/src/alter.c +index 7be2d830cdaa..7c4f55955c0b 100644 +--- a/third_party/sqlite/patched/src/alter.c ++++ b/third_party/sqlite/patched/src/alter.c +@@ -734,6 +734,7 @@ static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){ + static int renameUnmapSelectCb(Walker *pWalker, Select *p){ + Parse *pParse = pWalker->pParse; + int i; ++ if( p->selFlags & SF_View ) return WRC_Prune; + if( ALWAYS(p->pEList) ){ + ExprList *pList = p->pEList; + for(i=0; i<pList->nExpr; i++){ +@@ -838,6 +839,7 @@ static void renameWalkWith(Walker *pWalker, Select *pSelect){ + ** descend into sub-select statements. + */ + static int renameColumnSelectCb(Walker *pWalker, Select *p){ ++ if( p->selFlags & SF_View ) return WRC_Prune; + renameWalkWith(pWalker, p); + return WRC_Continue; + } +@@ -1303,8 +1305,9 @@ static void renameColumnFunc( + if( sParse.pNewTable ){ + Select *pSelect = sParse.pNewTable->pSelect; + if( pSelect ){ ++ pSelect->selFlags &= ~SF_View; + sParse.rc = SQLITE_OK; +- sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, 0); ++ sqlite3SelectPrep(&sParse, pSelect, 0); + rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); + if( rc==SQLITE_OK ){ + sqlite3WalkSelect(&sWalker, pSelect); +@@ -1416,6 +1419,7 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ + int i; + RenameCtx *p = pWalker->u.pRename; + SrcList *pSrc = pSelect->pSrc; ++ if( pSelect->selFlags & SF_View ) return WRC_Prune; + if( pSrc==0 ){ + assert( pWalker->pParse->db->mallocFailed ); + return WRC_Abort; +@@ -1495,10 +1499,13 @@ static void renameTableFunc( + + if( pTab->pSelect ){ + if( isLegacy==0 ){ ++ Select *pSelect = pTab->pSelect; + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = &sParse; + ++ assert( pSelect->selFlags & SF_View ); ++ pSelect->selFlags &= ~SF_View; + sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC); + if( sParse.nErr ) rc = sParse.rc; + sqlite3WalkSelect(&sWalker, pTab->pSelect); +diff --git a/third_party/sqlite/patched/src/build.c b/third_party/sqlite/patched/src/build.c +index 6d30cd76a136..e277f6d9da18 100644 +--- a/third_party/sqlite/patched/src/build.c ++++ b/third_party/sqlite/patched/src/build.c +@@ -2334,6 +2334,7 @@ void sqlite3CreateView( + ** allocated rather than point to the input string - which means that + ** they will persist after the current sqlite3_exec() call returns. + */ ++ pSelect->selFlags |= SF_View; + if( IN_RENAME_OBJECT ){ + p->pSelect = pSelect; + pSelect = 0; +diff --git a/third_party/sqlite/patched/src/sqliteInt.h b/third_party/sqlite/patched/src/sqliteInt.h +index 81aa0dc1872b..1f22ec9064b6 100644 +--- a/third_party/sqlite/patched/src/sqliteInt.h ++++ b/third_party/sqlite/patched/src/sqliteInt.h +@@ -2912,6 +2912,7 @@ struct Select { + #define SF_IncludeHidden 0x20000 /* Include hidden columns in output */ + #define SF_ComplexResult 0x40000 /* Result contains subquery or function */ + #define SF_WhereBegin 0x80000 /* Really a WhereBegin() call. Debug Only */ ++#define SF_View 0x0200000 /* SELECT statement is a view */ + + /* + ** The results of a SELECT can be distributed in several ways, as defined +diff --git a/third_party/sqlite/patched/test/altertab3.test b/third_party/sqlite/patched/test/altertab3.test +index 77c57d48a694..8f28d898f4f1 100644 +--- a/third_party/sqlite/patched/test/altertab3.test ++++ b/third_party/sqlite/patched/test/altertab3.test +@@ -362,6 +362,37 @@ do_execsql_test 16.2 { + ALTER TABLE t1 RENAME TO t1x; + } + ++#------------------------------------------------------------------------ ++# ++reset_db ++do_execsql_test 22.1 { ++ CREATE TABLE t1(a); ++ CREATE VIEW v2(b) AS SELECT * FROM v2; ++} ++ ++do_catchsql_test 22.2 { ++ ALTER TABLE t1 RENAME TO t4; ++} {1 {error in view v2: view v2 is circularly defined}} ++ ++do_execsql_test 22.3 { ++ DROP VIEW v2; ++ CREATE VIEW v2(b) AS WITH t3 AS (SELECT b FROM v2) SELECT * FROM t3; ++} ++ ++breakpoint ++do_catchsql_test 22.4 { ++ ALTER TABLE t1 RENAME TO t4; ++} {1 {error in view v2: view v2 is circularly defined}} ++ ++do_execsql_test 22.5 { ++ DROP VIEW v2; ++ CREATE VIEW v2(b) AS WITH t3 AS (SELECT b FROM v2) VALUES(1); ++} ++ ++do_catchsql_test 22.6 { ++ ALTER TABLE t1 RENAME TO t4; ++} {0 {}} ++ + #------------------------------------------------------------------------- + reset_db + do_execsql_test 17.1 { +-- +2.25.0.rc1.283.g88dfdc4193-goog + diff --git a/chromium/third_party/sqlite/patches/0017-Add-restrictions-on-shadow-table-changes-in-defensiv.patch b/chromium/third_party/sqlite/patches/0017-Add-restrictions-on-shadow-table-changes-in-defensiv.patch new file mode 100644 index 00000000000..10532585e0a --- /dev/null +++ b/chromium/third_party/sqlite/patches/0017-Add-restrictions-on-shadow-table-changes-in-defensiv.patch @@ -0,0 +1,203 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darwin Huang <huangdarwin@chromium.org> +Date: Thu, 19 Dec 2019 14:19:06 -0800 +Subject: [PATCH 17/25] Add restrictions on shadow table changes in defensive + mode + +Backports https://www.sqlite.org/src/info/bae76a5c40703871 + +Bug: 1034695 +--- + third_party/sqlite/patched/src/alter.c | 5 ++- + third_party/sqlite/patched/src/build.c | 36 +++++++++++++------ + third_party/sqlite/patched/src/delete.c | 6 +--- + third_party/sqlite/patched/src/sqliteInt.h | 6 ++++ + third_party/sqlite/patched/test/altertab.test | 24 ++++++++++--- + 5 files changed, 54 insertions(+), 23 deletions(-) + +diff --git a/third_party/sqlite/patched/src/alter.c b/third_party/sqlite/patched/src/alter.c +index 7c4f55955c0b..48282c57b3b6 100644 +--- a/third_party/sqlite/patched/src/alter.c ++++ b/third_party/sqlite/patched/src/alter.c +@@ -31,9 +31,8 @@ + static int isAlterableTable(Parse *pParse, Table *pTab){ + if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) + #ifndef SQLITE_OMIT_VIRTUALTABLE +- || ( (pTab->tabFlags & TF_Shadow) +- && (pParse->db->flags & SQLITE_Defensive) +- && pParse->db->nVdbeExec==0 ++ || ( (pTab->tabFlags & TF_Shadow)!=0 ++ && sqlite3ReadOnlyShadowTables(pParse->db) + ) + #endif + ){ +diff --git a/third_party/sqlite/patched/src/build.c b/third_party/sqlite/patched/src/build.c +index e277f6d9da18..9a9a33e95641 100644 +--- a/third_party/sqlite/patched/src/build.c ++++ b/third_party/sqlite/patched/src/build.c +@@ -856,13 +856,14 @@ int sqlite3CheckObjectName( + } + } + }else{ +- if( pParse->nested==0 +- && 0==sqlite3StrNICmp(zName, "sqlite_", 7) ++ if( (pParse->nested==0 && 0==sqlite3StrNICmp(zName, "sqlite_", 7)) ++ || (sqlite3ReadOnlyShadowTables(db) && sqlite3ShadowTableName(db, zName)) + ){ + sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", + zName); + return SQLITE_ERROR; + } ++ + } + return SQLITE_OK; + } +@@ -2002,7 +2003,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ + ** zName is temporarily modified while this routine is running, but is + ** restored to its original value prior to this routine returning. + */ +-static int isShadowTableName(sqlite3 *db, char *zName){ ++int sqlite3ShadowTableName(sqlite3 *db, const char *zName){ + char *zTail; /* Pointer to the last "_" in zName */ + Table *pTab; /* Table that zName is a shadow of */ + Module *pMod; /* Module for the virtual table */ +@@ -2020,8 +2021,6 @@ static int isShadowTableName(sqlite3 *db, char *zName){ + if( pMod->pModule->xShadowName==0 ) return 0; + return pMod->pModule->xShadowName(zTail+1); + } +-#else +-# define isShadowTableName(x,y) 0 + #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ + + /* +@@ -2063,7 +2062,7 @@ void sqlite3EndTable( + p = pParse->pNewTable; + if( p==0 ) return; + +- if( pSelect==0 && isShadowTableName(db, p->zName) ){ ++ if( pSelect==0 && sqlite3ShadowTableName(db, p->zName) ){ + p->tabFlags |= TF_Shadow; + } + +@@ -2747,18 +2746,33 @@ void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){ + sqliteViewResetAll(db, iDb); + } + ++/* ++** Return TRUE if shadow tables should be read-only in the current ++** context. ++*/ ++int sqlite3ReadOnlyShadowTables(sqlite3 *db){ ++#ifndef SQLITE_OMIT_VIRTUALTABLE ++ if( (db->flags & SQLITE_Defensive)!=0 ++ && db->pVtabCtx==0 ++ && db->nVdbeExec==0 ++ ){ ++ return 1; ++ } ++#endif ++ return 0; ++} ++ + /* + ** Return true if it is not allowed to drop the given table + */ +-static int tableMayNotBeDropped(Parse *pParse, Table *pTab){ ++static int tableMayNotBeDropped(sqlite3 *db, Table *pTab){ + if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ + if( sqlite3StrNICmp(pTab->zName+7, "stat", 4)==0 ) return 0; + if( sqlite3StrNICmp(pTab->zName+7, "parameters", 10)==0 ) return 0; + return 1; + } +- if( pTab->tabFlags & TF_Shadow ){ +- sqlite3 *db = pParse->db; +- if( (db->flags & SQLITE_Defensive)!=0 && db->nVdbeExec==0 ) return 1; ++ if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){ ++ return 1; + } + return 0; + } +@@ -2832,7 +2846,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ + } + } + #endif +- if( tableMayNotBeDropped(pParse, pTab) ){ ++ if( tableMayNotBeDropped(db, pTab) ){ + sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName); + goto exit_drop_table; + } +diff --git a/third_party/sqlite/patched/src/delete.c b/third_party/sqlite/patched/src/delete.c +index dcb117f2e108..cde8e1a292a1 100644 +--- a/third_party/sqlite/patched/src/delete.c ++++ b/third_party/sqlite/patched/src/delete.c +@@ -70,11 +70,7 @@ static int tabIsReadOnly(Parse *pParse, Table *pTab){ + return sqlite3WritableSchema(db)==0 && pParse->nested==0; + } + assert( pTab->tabFlags & TF_Shadow ); +- return (db->flags & SQLITE_Defensive)!=0 +-#ifndef SQLITE_OMIT_VIRTUALTABLE +- && db->pVtabCtx==0 +-#endif +- && db->nVdbeExec==0; ++ return sqlite3ReadOnlyShadowTables(db); + } + + /* +diff --git a/third_party/sqlite/patched/src/sqliteInt.h b/third_party/sqlite/patched/src/sqliteInt.h +index 1f22ec9064b6..2eb9ff559aac 100644 +--- a/third_party/sqlite/patched/src/sqliteInt.h ++++ b/third_party/sqlite/patched/src/sqliteInt.h +@@ -4486,6 +4486,12 @@ void sqlite3AutoLoadExtensions(sqlite3*); + ); + # define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) + #endif ++int sqlite3ReadOnlyShadowTables(sqlite3 *db); ++#ifndef SQLITE_OMIT_VIRTUALTABLE ++ int sqlite3ShadowTableName(sqlite3 *db, const char *zName); ++#else ++# define sqlite3ShadowTableName(A,B) 0 ++#endif + int sqlite3VtabEponymousTableInit(Parse*,Module*); + void sqlite3VtabEponymousTableClear(sqlite3*,Module*); + void sqlite3VtabMakeWritable(Parse*,Table*); +diff --git a/third_party/sqlite/patched/test/altertab.test b/third_party/sqlite/patched/test/altertab.test +index c5766e22717d..c6fbbbbb3185 100644 +--- a/third_party/sqlite/patched/test/altertab.test ++++ b/third_party/sqlite/patched/test/altertab.test +@@ -547,13 +547,29 @@ ifcapable fts3 { + } {1 {table y1_segments may not be modified}} + + do_catchsql_test 16.20 { +- ALTER TABLE y1_segments RENAME TO abc; +- } {1 {table y1_segments may not be altered}} +- +- do_catchsql_test 16.21 { + DROP TABLE y1_segments; + } {1 {table y1_segments may not be dropped}} + ++ do_catchsql_test 16.20 { ++ ALTER TABLE y1_segments RENAME TO abc; ++ } {1 {table y1_segments may not be altered}} ++ sqlite3_db_config db DEFENSIVE 0 ++ do_catchsql_test 16.22 { ++ ALTER TABLE y1_segments RENAME TO abc; ++ } {0 {}} ++ sqlite3_db_config db DEFENSIVE 1 ++ do_catchsql_test 16.23 { ++ CREATE TABLE y1_segments AS SELECT * FROM abc; ++ } {1 {object name reserved for internal use: y1_segments}} ++ do_catchsql_test 16.24 { ++ CREATE VIEW y1_segments AS SELECT * FROM abc; ++ } {1 {object name reserved for internal use: y1_segments}} ++ sqlite3_db_config db DEFENSIVE 0 ++ do_catchsql_test 16.25 { ++ ALTER TABLE abc RENAME TO y1_segments; ++ } {0 {}} ++ sqlite3_db_config db DEFENSIVE 1 ++ + do_execsql_test 16.30 { + ALTER TABLE y1 RENAME TO z1; + } +-- +2.25.0.rc1.283.g88dfdc4193-goog + diff --git a/chromium/third_party/sqlite/patches/0018-Avoid-ambiguous-true-and-false-return.patch b/chromium/third_party/sqlite/patches/0018-Avoid-ambiguous-true-and-false-return.patch new file mode 100644 index 00000000000..8af90b4b5b8 --- /dev/null +++ b/chromium/third_party/sqlite/patches/0018-Avoid-ambiguous-true-and-false-return.patch @@ -0,0 +1,118 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darwin Huang <huangdarwin@chromium.org> +Date: Tue, 7 Jan 2020 13:32:12 -0800 +Subject: [PATCH 18/25] Avoid ambiguous true and false return + +Backports https://www.sqlite.org/src/info/ff9492d3ff733c22 + +Bug: 1033461 +--- + third_party/sqlite/patched/src/expr.c | 21 ++++++++++++++++--- + third_party/sqlite/patched/src/select.c | 2 +- + third_party/sqlite/patched/src/sqliteInt.h | 1 + + third_party/sqlite/patched/test/with1.test | 24 ++++++++++++++++++++++ + 4 files changed, 44 insertions(+), 4 deletions(-) + +diff --git a/third_party/sqlite/patched/src/expr.c b/third_party/sqlite/patched/src/expr.c +index e8b1f31c42aa..760978c482d3 100644 +--- a/third_party/sqlite/patched/src/expr.c ++++ b/third_party/sqlite/patched/src/expr.c +@@ -1814,19 +1814,34 @@ int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){ + return WRC_Abort; + } + ++/* ++** Check the input string to see if it is "true" or "false" (in any case). ++** ++** If the string is.... Return ++** "true" EP_IsTrue ++** "false" EP_IsFalse ++** anything else 0 ++*/ ++u32 sqlite3IsTrueOrFalse(const char *zIn){ ++ if( sqlite3StrICmp(zIn, "true")==0 ) return EP_IsTrue; ++ if( sqlite3StrICmp(zIn, "false")==0 ) return EP_IsFalse; ++ return 0; ++} ++ ++ + /* + ** If the input expression is an ID with the name "true" or "false" + ** then convert it into an TK_TRUEFALSE term. Return non-zero if + ** the conversion happened, and zero if the expression is unaltered. + */ + int sqlite3ExprIdToTrueFalse(Expr *pExpr){ ++ u32 v; + assert( pExpr->op==TK_ID || pExpr->op==TK_STRING ); + if( !ExprHasProperty(pExpr, EP_Quoted) +- && (sqlite3StrICmp(pExpr->u.zToken, "true")==0 +- || sqlite3StrICmp(pExpr->u.zToken, "false")==0) ++ && (v = sqlite3IsTrueOrFalse(pExpr->u.zToken))!=0 + ){ + pExpr->op = TK_TRUEFALSE; +- ExprSetProperty(pExpr, pExpr->u.zToken[4]==0 ? EP_IsTrue : EP_IsFalse); ++ ExprSetProperty(pExpr, v); + return 1; + } + return 0; +diff --git a/third_party/sqlite/patched/src/select.c b/third_party/sqlite/patched/src/select.c +index ba70a2bdec78..be705c11d1b4 100644 +--- a/third_party/sqlite/patched/src/select.c ++++ b/third_party/sqlite/patched/src/select.c +@@ -1980,7 +1980,7 @@ int sqlite3ColumnsFromExprList( + zName = pEList->a[i].zSpan; + } + } +- if( zName ){ ++ if( zName && !sqlite3IsTrueOrFalse(zName) ){ + zName = sqlite3DbStrDup(db, zName); + }else{ + zName = sqlite3MPrintf(db,"column%d",i+1); +diff --git a/third_party/sqlite/patched/src/sqliteInt.h b/third_party/sqlite/patched/src/sqliteInt.h +index 2eb9ff559aac..970ef817f3e1 100644 +--- a/third_party/sqlite/patched/src/sqliteInt.h ++++ b/third_party/sqlite/patched/src/sqliteInt.h +@@ -4093,6 +4093,7 @@ void sqlite3EndTransaction(Parse*,int); + void sqlite3Savepoint(Parse*, int, Token*); + void sqlite3CloseSavepoints(sqlite3 *); + void sqlite3LeaveMutexAndCloseZombie(sqlite3*); ++u32 sqlite3IsTrueOrFalse(const char*); + int sqlite3ExprIdToTrueFalse(Expr*); + int sqlite3ExprTruthValue(const Expr*); + int sqlite3ExprIsConstant(Expr*); +diff --git a/third_party/sqlite/patched/test/with1.test b/third_party/sqlite/patched/test/with1.test +index 4fb074b2cf0a..e5787db704d1 100644 +--- a/third_party/sqlite/patched/test/with1.test ++++ b/third_party/sqlite/patched/test/with1.test +@@ -1140,4 +1140,28 @@ do_execsql_test 24.2 { + 3 1 1 3 + } + ++# 2020-01-02 chromium ticket 1033461 ++# Do not allow the generated name of a CTE be "true" or "false" as ++# such a label might be later confused for the boolean literals of ++# the same name, causing inconsistencies in the abstract syntax ++# tree. This problem first arose in version 3.23.0 when SQLite ++# began recognizing "true" and "false" as boolean literals, but also ++# had to continue to recognize "true" and "false" as identifiers for ++# backwards compatibility. ++# ++reset_db ++do_execsql_test 25.1 { ++ CREATE TABLE dual(dummy); ++ INSERT INTO dual(dummy) VALUES('X'); ++ WITH cte1 AS ( ++ SELECT TRUE, ( ++ WITH cte2 AS (SELECT avg(DISTINCT TRUE) FROM dual) ++ SELECT 2571 FROM cte2 ++ ) AS subquery1 ++ FROM dual ++ GROUP BY 1 ++ ) ++ SELECT (SELECT 1324 FROM cte1) FROM cte1; ++} {1324} ++ + finish_test +-- +2.25.0.rc1.283.g88dfdc4193-goog + diff --git a/chromium/third_party/sqlite/patches/0019-Fix-fts3-UB-uint64.patch b/chromium/third_party/sqlite/patches/0019-Fix-fts3-UB-uint64.patch new file mode 100644 index 00000000000..0d10779a060 --- /dev/null +++ b/chromium/third_party/sqlite/patches/0019-Fix-fts3-UB-uint64.patch @@ -0,0 +1,52 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darwin Huang <huangdarwin@chromium.org> +Date: Tue, 7 Jan 2020 13:34:37 -0800 +Subject: [PATCH 19/25] Fix fts3 UB uint64 + +Backports https://sqlite.org/src/info/e1f12978b53683114ab0 + +Bug: 1037786 +--- + third_party/sqlite/patched/ext/fts3/fts3_snippet.c | 2 +- + third_party/sqlite/patched/test/fts3snippet.test | 13 +++++++++++++ + 2 files changed, 14 insertions(+), 1 deletion(-) + +diff --git a/third_party/sqlite/patched/ext/fts3/fts3_snippet.c b/third_party/sqlite/patched/ext/fts3/fts3_snippet.c +index dda71c3985af..6eae82dbc3ff 100644 +--- a/third_party/sqlite/patched/ext/fts3/fts3_snippet.c ++++ b/third_party/sqlite/patched/ext/fts3/fts3_snippet.c +@@ -560,7 +560,7 @@ static int fts3BestSnippet( + /* Set the *pmSeen output variable. */ + for(i=0; i<nList; i++){ + if( sIter.aPhrase[i].pHead ){ +- *pmSeen |= (u64)1 << i; ++ *pmSeen |= (u64)1 << (i%64); + } + } + +diff --git a/third_party/sqlite/patched/test/fts3snippet.test b/third_party/sqlite/patched/test/fts3snippet.test +index ce565127b5a3..9ee37dc6263f 100644 +--- a/third_party/sqlite/patched/test/fts3snippet.test ++++ b/third_party/sqlite/patched/test/fts3snippet.test +@@ -587,5 +587,18 @@ do_execsql_test 5.1 { + {[a70] [a71] [a72]} + } + ++#------------------------------------------------------------------------- ++# Request a snippet from a query with more than 64 phrases. ++# ++reset_db ++do_execsql_test 6.0 { ++ CREATE VIRTUAL TABLE f USING fts3(b); ++ INSERT INTO f VALUES ( x'746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218'); ++} ++ ++do_execsql_test 6.1 { ++ SELECT length(snippet(f))>0 FROM f WHERE b MATCH x'1065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a010f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c2a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e082a011065616e656d655a616c702a2f65732e0f42014001380230018218021001081e0a3d746e6e6d64612e0f42'; ++} {1} ++ + set sqlite_fts3_enable_parentheses 0 + finish_test +-- +2.25.0.rc1.283.g88dfdc4193-goog + diff --git a/chromium/third_party/sqlite/patches/0020-Avoid-large-memory-alloc-for-corrupt-record.patch b/chromium/third_party/sqlite/patches/0020-Avoid-large-memory-alloc-for-corrupt-record.patch new file mode 100644 index 00000000000..42671c320cf --- /dev/null +++ b/chromium/third_party/sqlite/patches/0020-Avoid-large-memory-alloc-for-corrupt-record.patch @@ -0,0 +1,72 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darwin Huang <huangdarwin@chromium.org> +Date: Tue, 7 Jan 2020 13:38:31 -0800 +Subject: [PATCH 20/25] Avoid large memory alloc for corrupt record + +Backports https://www.sqlite.org/src/info/9add58fe9688d5c1 + +Bug: 1038213 +--- + third_party/sqlite/patched/ext/fts3/fts3_write.c | 12 +++++++++--- + third_party/sqlite/patched/test/fts3corrupt4.test | 9 +++++++++ + 2 files changed, 18 insertions(+), 3 deletions(-) + +diff --git a/third_party/sqlite/patched/ext/fts3/fts3_write.c b/third_party/sqlite/patched/ext/fts3/fts3_write.c +index 8b6b729987c3..f30bf343635d 100644 +--- a/third_party/sqlite/patched/ext/fts3/fts3_write.c ++++ b/third_party/sqlite/patched/ext/fts3/fts3_write.c +@@ -335,7 +335,7 @@ static int fts3SqlStmt( + ** returns zero rows. */ + /* 28 */ "SELECT level, count(*) AS cnt FROM %Q.'%q_segdir' " + " GROUP BY level HAVING cnt>=?" +- " ORDER BY (level %% 1024) ASC LIMIT 1", ++ " ORDER BY (level %% 1024) ASC, 2 DESC LIMIT 1", + + /* Estimate the upper limit on the number of leaf nodes in a new segment + ** created by merging the oldest :2 segments from absolute level :1. See +@@ -4925,8 +4925,14 @@ int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ + + rc = fts3IncrmergeHintPop(&hint, &iHintAbsLevel, &nHintSeg); + if( nSeg<0 || (iAbsLevel % nMod) >= (iHintAbsLevel % nMod) ){ ++ /* Based on the scan in the block above, it is known that there ++ ** are no levels with a relative level smaller than that of ++ ** iAbsLevel with more than nSeg segments, or if nSeg is -1, ++ ** no levels with more than nMin segments. Use this to limit the ++ ** value of nHintSeg to avoid a large memory allocation in case the ++ ** merge-hint is corrupt*/ + iAbsLevel = iHintAbsLevel; +- nSeg = nHintSeg; ++ nSeg = MIN(MAX(nMin,nSeg), nHintSeg); + bUseHint = 1; + bDirtyHint = 1; + }else{ +@@ -4939,7 +4945,7 @@ int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ + /* If nSeg is less that zero, then there is no level with at least + ** nMin segments and no hint in the %_stat table. No work to do. + ** Exit early in this case. */ +- if( nSeg<0 ) break; ++ if( nSeg<=0 ) break; + + /* Open a cursor to iterate through the contents of the oldest nSeg + ** indexes of absolute level iAbsLevel. If this cursor is opened using +diff --git a/third_party/sqlite/patched/test/fts3corrupt4.test b/third_party/sqlite/patched/test/fts3corrupt4.test +index 45dd52fff29e..ed670c72223c 100644 +--- a/third_party/sqlite/patched/test/fts3corrupt4.test ++++ b/third_party/sqlite/patched/test/fts3corrupt4.test +@@ -5589,4 +5589,13 @@ do_catchsql_test 35.1 { + INSERT INTO f(f) VALUES ('integrity-check'); + } {1 {database disk image is malformed}} + ++reset_db ++do_catchsql_test 36.0 { ++ CREATE VIRTUAL TABLE f USING fts3(a,tokenize=porter); ++ CREATE TABLE 'f_stat'(id INTEGER PRIMARY KEY, value BLOB); ++ INSERT INTO f VALUES (1); ++ INSERT INTO f_stat VALUES (1,x'00000000000101010119013d00ffff0400fa83717b71a69297979701f63d010101010101010101010101190000000000000000fa83717b71a601f63d01010101010101010101010119013d00ffffff0400fa83717b71a69297979701f63d010101010101010101010101190000000000000000fa83717b71a69201f63d010101f63d01010101010101010101010119013d00ffffff0400fa83717b71a6929797010101010101010101010119013d00ffff01f63d01010101010101010101010119013d00ffffff0400fa83717b71a69297979701f63d00fa03ffffffa69297979701f63d010101000000000101010101197e9797976567656565ffa63535354e'); ++ INSERT INTO f(f) VALUES ('merge=53,216'); ++} {0 {}} ++ + finish_test +-- +2.25.0.rc1.283.g88dfdc4193-goog + diff --git a/chromium/third_party/sqlite/patches/0021-Avoid-invalid-pointer-dereference-in-ORDER-BY.patch b/chromium/third_party/sqlite/patches/0021-Avoid-invalid-pointer-dereference-in-ORDER-BY.patch new file mode 100644 index 00000000000..75e5507ed7d --- /dev/null +++ b/chromium/third_party/sqlite/patches/0021-Avoid-invalid-pointer-dereference-in-ORDER-BY.patch @@ -0,0 +1,31 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darwin Huang <huangdarwin@chromium.org> +Date: Tue, 7 Jan 2020 13:42:03 -0800 +Subject: [PATCH 21/25] Avoid invalid pointer dereference in ORDER BY + +Backports https://sqlite.org/src/info/1ca0bd982ab1183bbafce0d260e4dceda5eb766ed2e7793374a88d1ae0bdd2ca + +Bug: 1038863 +--- + third_party/sqlite/patched/src/window.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/third_party/sqlite/patched/src/window.c b/third_party/sqlite/patched/src/window.c +index c251cd01974d..2d79ffe63d6d 100644 +--- a/third_party/sqlite/patched/src/window.c ++++ b/third_party/sqlite/patched/src/window.c +@@ -883,9 +883,11 @@ static ExprList *exprListAppendList( + int nInit = pList ? pList->nExpr : 0; + for(i=0; i<pAppend->nExpr; i++){ + Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0); ++ assert( pDup==0 || !ExprHasProperty(pDup, EP_MemToken) ); + if( bIntToNull && pDup && pDup->op==TK_INTEGER ){ + pDup->op = TK_NULL; + pDup->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse); ++ pDup->u.zToken = 0; + } + pList = sqlite3ExprListAppend(pParse, pList, pDup); + if( pList ) pList->a[nInit+i].sortFlags = pAppend->a[i].sortFlags; +-- +2.25.0.rc1.283.g88dfdc4193-goog + diff --git a/chromium/third_party/sqlite/patches/0022-Fix-zipfile-extension-INSERT-with-NULL-pathname.patch b/chromium/third_party/sqlite/patches/0022-Fix-zipfile-extension-INSERT-with-NULL-pathname.patch new file mode 100644 index 00000000000..2086fdf465f --- /dev/null +++ b/chromium/third_party/sqlite/patches/0022-Fix-zipfile-extension-INSERT-with-NULL-pathname.patch @@ -0,0 +1,50 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darwin Huang <huangdarwin@chromium.org> +Date: Tue, 7 Jan 2020 13:43:48 -0800 +Subject: [PATCH 22/25] Fix zipfile extension INSERT with NULL pathname + +Backports https://sqlite.org/src/info/a80f84b511231204658304226de3e075a55afc2e3f39ac063716f7a57f585c06 + +Bug: 1038863 +--- + third_party/sqlite/patched/ext/misc/zipfile.c | 1 + + third_party/sqlite/patched/test/zipfile.test | 13 +++++++++++++ + 2 files changed, 14 insertions(+) + +diff --git a/third_party/sqlite/patched/ext/misc/zipfile.c b/third_party/sqlite/patched/ext/misc/zipfile.c +index 5a88389bf2da..1dc47a7d9ae0 100644 +--- a/third_party/sqlite/patched/ext/misc/zipfile.c ++++ b/third_party/sqlite/patched/ext/misc/zipfile.c +@@ -1618,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]); + } +diff --git a/third_party/sqlite/patched/test/zipfile.test b/third_party/sqlite/patched/test/zipfile.test +index 25dc5d6497d1..f5c503d7f156 100644 +--- a/third_party/sqlite/patched/test/zipfile.test ++++ b/third_party/sqlite/patched/test/zipfile.test +@@ -795,4 +795,17 @@ if {$tcl_platform(platform)!="windows"} { + } {. ./x1.txt ./x2.txt} + } + ++# 2019-12-18 Yongheng and Rui fuzzer ++# ++do_execsql_test 13.10 { ++ DROP TABLE IF EXISTS t0; ++ DROP TABLE IF EXISTS t1; ++ CREATE TABLE t0(a,b,c,d,e,f,g); ++ REPLACE INTO t0(c,b,f) VALUES(10,10,10); ++ CREATE VIRTUAL TABLE t1 USING zipfile('h.zip'); ++ REPLACE INTO t1 SELECT * FROM t0; ++ SELECT quote(name),quote(mode),quote(mtime),quote(sz),quote(rawdata), ++ quote(data),quote(method) FROM t1; ++} {'' 10 10 2 X'3130' X'3130' 0} ++ + finish_test +-- +2.25.0.rc1.283.g88dfdc4193-goog + diff --git a/chromium/third_party/sqlite/patches/0023-Do-not-allow-constant-propagation-optimization-to-ap.patch b/chromium/third_party/sqlite/patches/0023-Do-not-allow-constant-propagation-optimization-to-ap.patch new file mode 100644 index 00000000000..5733bb22604 --- /dev/null +++ b/chromium/third_party/sqlite/patches/0023-Do-not-allow-constant-propagation-optimization-to-ap.patch @@ -0,0 +1,29 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darwin Huang <huangdarwin@chromium.org> +Date: Thu, 16 Jan 2020 15:34:48 -0800 +Subject: [PATCH 23/25] Do not allow constant-propagation optimization to apple + to ON/USING clause terms + +Backports: https://www.sqlite.org/src/info/1bc783da63d58b05 + +Bug: 1042145 +--- + third_party/sqlite/patched/src/select.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/third_party/sqlite/patched/src/select.c b/third_party/sqlite/patched/src/select.c +index be705c11d1b4..4ed359800a2b 100644 +--- a/third_party/sqlite/patched/src/select.c ++++ b/third_party/sqlite/patched/src/select.c +@@ -4193,7 +4193,7 @@ static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){ + int i; + WhereConst *pConst; + if( pExpr->op!=TK_COLUMN ) return WRC_Continue; +- if( ExprHasProperty(pExpr, EP_FixedCol) ) return WRC_Continue; ++ if( ExprHasProperty(pExpr, EP_FixedCol|EP_FromJoin) ) return WRC_Continue; + pConst = pWalker->u.pConst; + for(i=0; i<pConst->nConst; i++){ + Expr *pColumn = pConst->apExpr[i*2]; +-- +2.25.0.rc1.283.g88dfdc4193-goog + diff --git a/chromium/third_party/sqlite/patches/0024-Back-away-from-LEFT-JOIN-optimization.patch b/chromium/third_party/sqlite/patches/0024-Back-away-from-LEFT-JOIN-optimization.patch new file mode 100644 index 00000000000..65bff0e7c36 --- /dev/null +++ b/chromium/third_party/sqlite/patches/0024-Back-away-from-LEFT-JOIN-optimization.patch @@ -0,0 +1,65 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darwin Huang <huangdarwin@chromium.org> +Date: Thu, 16 Jan 2020 15:41:01 -0800 +Subject: [PATCH 24/25] Back away from LEFT JOIN optimization + +Backports https://sqlite.org/src/info/862974312edf00e9d1068115d1a39b7235b7db68b6d86b81d38a12f025a4748e + +Bug: 1042578 +--- + third_party/sqlite/patched/src/select.c | 8 ++++++-- + third_party/sqlite/patched/test/join.test | 13 +++++++++++++ + 2 files changed, 19 insertions(+), 2 deletions(-) + +diff --git a/third_party/sqlite/patched/src/select.c b/third_party/sqlite/patched/src/select.c +index 4ed359800a2b..ec764996fb1a 100644 +--- a/third_party/sqlite/patched/src/select.c ++++ b/third_party/sqlite/patched/src/select.c +@@ -3596,6 +3596,7 @@ static void substSelect( + ** (3b) the FROM clause of the subquery may not contain a virtual + ** table and + ** (3c) the outer query may not be an aggregate. ++** (3d) the outer query may not be DISTINCT. + ** + ** (4) The subquery can not be DISTINCT. + ** +@@ -3792,8 +3793,11 @@ static int flattenSubquery( + */ + if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){ + isLeftJoin = 1; +- if( pSubSrc->nSrc>1 || isAgg || IsVirtual(pSubSrc->a[0].pTab) ){ +- /* (3a) (3c) (3b) */ ++ if( pSubSrc->nSrc>1 /* (3a) */ ++ || isAgg /* (3b) */ ++ || IsVirtual(pSubSrc->a[0].pTab) /* (3c) */ ++ || (p->selFlags & SF_Distinct)!=0 /* (3d) */ ++ ){ + return 0; + } + } +diff --git a/third_party/sqlite/patched/test/join.test b/third_party/sqlite/patched/test/join.test +index c6c615f1351c..1c75041eb5ea 100644 +--- a/third_party/sqlite/patched/test/join.test ++++ b/third_party/sqlite/patched/test/join.test +@@ -905,5 +905,18 @@ do_execsql_test join-18.4 { + SELECT NOT(v0.a IS FALSE) FROM v0 + } {1} + ++# 2019-12-18 problem with a LEFT JOIN where the RHS is a view. ++# Detected by Yongheng and Rui. ++# Follows from the optimization attempt of check-in 41c27bc0ff1d3135 ++# on 2017-04-18 ++# ++reset_db ++do_execsql_test join-22.10 { ++ CREATE TABLE t0(a, b); ++ CREATE INDEX t0a ON t0(a); ++ INSERT INTO t0 VALUES(10,10),(10,11),(10,12); ++ SELECT DISTINCT c FROM t0 LEFT JOIN (SELECT a+1 AS c FROM t0) ORDER BY c ; ++} {11} ++ + finish_test + +-- +2.25.0.rc1.283.g88dfdc4193-goog + diff --git a/chromium/third_party/sqlite/patches/0025-Abort-early-in-sqlite3WindowRewrite.patch b/chromium/third_party/sqlite/patches/0025-Abort-early-in-sqlite3WindowRewrite.patch new file mode 100644 index 00000000000..d5927a867d0 --- /dev/null +++ b/chromium/third_party/sqlite/patches/0025-Abort-early-in-sqlite3WindowRewrite.patch @@ -0,0 +1,27 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Darwin Huang <huangdarwin@chromium.org> +Date: Thu, 16 Jan 2020 15:42:55 -0800 +Subject: [PATCH 25/25] Abort early in sqlite3WindowRewrite + +Backports https://sqlite.org/src/info/cba2a2a44cdf138a629109bb0ad088ed4ef67fc66bed3e0373554681a39615d2 + +Bug: 1042700 +--- + third_party/sqlite/patched/src/select.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/third_party/sqlite/patched/src/select.c b/third_party/sqlite/patched/src/select.c +index ec764996fb1a..2c9b4d9e01a7 100644 +--- a/third_party/sqlite/patched/src/select.c ++++ b/third_party/sqlite/patched/src/select.c +@@ -2805,6 +2805,7 @@ static int multiSelect( + } + #endif + } ++ if( pParse->nErr ) goto multi_select_end; + + /* Compute collating sequences used by + ** temporary tables needed to implement the compound select. +-- +2.25.0.rc1.283.g88dfdc4193-goog + |