diff --git a/0004-null-ref-in-trigger.patch b/0004-null-ref-in-trigger.patch new file mode 100644 index 0000000000000000000000000000000000000000..b0575ddee6ac3ea0c0173f149400390cca9f5552 --- /dev/null +++ b/0004-null-ref-in-trigger.patch @@ -0,0 +1,351 @@ +diff -rNu sqlite_before/src/attach.c sqlite_after/src/attach.c +--- sqlite_before/src/attach.c 2021-09-05 20:50:58.133474476 +0800 ++++ sqlite_after/src/attach.c 2021-09-05 20:52:09.414798420 +0800 +@@ -434,6 +434,63 @@ + #endif /* SQLITE_OMIT_ATTACH */ + + /* ++** Expression callback used by sqlite3FixAAAA() routines. ++*/ ++static int fixExprCb(Walker *p, Expr *pExpr){ ++ DbFixer *pFix = p->u.pFix; ++ if( !pFix->bTemp ) ExprSetProperty(pExpr, EP_FromDDL); ++ if( pExpr->op==TK_VARIABLE ){ ++ if( pFix->pParse->db->init.busy ){ ++ pExpr->op = TK_NULL; ++ }else{ ++ sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); ++ return WRC_Abort; ++ } ++ } ++ return WRC_Continue; ++} ++ ++/* ++** Select callback used by sqlite3FixAAAA() routines. ++*/ ++static int fixSelectCb(Walker *p, Select *pSelect){ ++ DbFixer *pFix = p->u.pFix; ++ int i; ++ struct SrcList_item *pItem; ++ sqlite3 *db = pFix->pParse->db; ++ int iDb = sqlite3FindDbName(db, pFix->zDb); ++ SrcList *pList = pSelect->pSrc; ++ ++ if( NEVER(pList==0) ) return WRC_Continue; ++ for(i=0, pItem=pList->a; inSrc; i++, pItem++){ ++ if( pFix->bTemp==0 ){ ++ if( pItem->zDatabase && iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){ ++ sqlite3ErrorMsg(pFix->pParse, ++ "%s %T cannot reference objects in database %s", ++ pFix->zType, pFix->pName, pItem->zDatabase); ++ return WRC_Abort; ++ } ++ sqlite3DbFree(db, pItem->zDatabase); ++ pItem->zDatabase = 0; ++ pItem->pSchema = pFix->pSchema; ++ pItem->fg.fromDDL = 1; ++ } ++#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) ++ if( sqlite3WalkExpr(&pFix->w, pList->a[i].pOn) ) return WRC_Abort; ++#endif ++ } ++ if( pSelect->pWith ){ ++ int i; ++ for(i=0; ipWith->nCte; i++){ ++ if( sqlite3WalkSelect(p, pSelect->pWith->a[i].pSelect) ){ ++ return WRC_Abort; ++ } ++ } ++ } ++ return WRC_Continue; ++} ++ ++/* + ** Initialize a DbFixer structure. This routine must be called prior + ** to passing the structure to one of the sqliteFixAAAA() routines below. + */ +@@ -444,9 +501,7 @@ + const char *zType, /* "view", "trigger", or "index" */ + const Token *pName /* Name of the view, trigger, or index */ + ){ +- sqlite3 *db; +- +- db = pParse->db; ++ sqlite3 *db = pParse->db; + assert( db->nDb>iDb ); + pFix->pParse = pParse; + pFix->zDb = db->aDb[iDb].zDbSName; +@@ -454,6 +509,13 @@ + pFix->zType = zType; + pFix->pName = pName; + pFix->bTemp = (iDb==1); ++ pFix->w.pParse = pParse; ++ pFix->w.xExprCallback = fixExprCb; ++ pFix->w.xSelectCallback = fixSelectCb; ++ pFix->w.xSelectCallback2 = 0; ++ pFix->w.walkerDepth = 0; ++ pFix->w.eCode = 0; ++ pFix->w.u.pFix = pFix; + } + + /* +@@ -474,115 +536,27 @@ + DbFixer *pFix, /* Context of the fixation */ + SrcList *pList /* The Source list to check and modify */ + ){ +- int i; +- struct SrcList_item *pItem; +- sqlite3 *db = pFix->pParse->db; +- int iDb = sqlite3FindDbName(db, pFix->zDb); +- +- if( NEVER(pList==0) ) return 0; +- +- for(i=0, pItem=pList->a; inSrc; i++, pItem++){ +- if( pFix->bTemp==0 ){ +- if( pItem->zDatabase && iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){ +- sqlite3ErrorMsg(pFix->pParse, +- "%s %T cannot reference objects in database %s", +- pFix->zType, pFix->pName, pItem->zDatabase); +- return 1; +- } +- sqlite3DbFree(db, pItem->zDatabase); +- pItem->zDatabase = 0; +- pItem->pSchema = pFix->pSchema; +- pItem->fg.fromDDL = 1; +- } +-#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) +- if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; +- if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; +-#endif +- if( pItem->fg.isTabFunc && sqlite3FixExprList(pFix, pItem->u1.pFuncArg) ){ +- return 1; +- } ++ int res = 0; ++ if( pList ){ ++ Select s; ++ memset(&s, 0, sizeof(s)); ++ s.pSrc = pList; ++ res = sqlite3WalkSelect(&pFix->w, &s); + } +- return 0; ++ return res; + } + #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) + int sqlite3FixSelect( + DbFixer *pFix, /* Context of the fixation */ + Select *pSelect /* The SELECT statement to be fixed to one database */ + ){ +- while( pSelect ){ +- if( sqlite3FixExprList(pFix, pSelect->pEList) ){ +- return 1; +- } +- if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){ +- return 1; +- } +- if( sqlite3FixExpr(pFix, pSelect->pWhere) ){ +- return 1; +- } +- if( sqlite3FixExprList(pFix, pSelect->pGroupBy) ){ +- return 1; +- } +- if( sqlite3FixExpr(pFix, pSelect->pHaving) ){ +- return 1; +- } +- if( sqlite3FixExprList(pFix, pSelect->pOrderBy) ){ +- return 1; +- } +- if( sqlite3FixExpr(pFix, pSelect->pLimit) ){ +- return 1; +- } +- if( pSelect->pWith ){ +- int i; +- for(i=0; ipWith->nCte; i++){ +- if( sqlite3FixSelect(pFix, pSelect->pWith->a[i].pSelect) ){ +- return 1; +- } +- } +- } +- pSelect = pSelect->pPrior; +- } +- return 0; ++ return sqlite3WalkSelect(&pFix->w, pSelect); + } + int sqlite3FixExpr( + DbFixer *pFix, /* Context of the fixation */ + Expr *pExpr /* The expression to be fixed to one database */ + ){ +- while( pExpr ){ +- if( !pFix->bTemp ) ExprSetProperty(pExpr, EP_FromDDL); +- if( pExpr->op==TK_VARIABLE ){ +- if( pFix->pParse->db->init.busy ){ +- pExpr->op = TK_NULL; +- }else{ +- sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); +- return 1; +- } +- } +- if( ExprHasProperty(pExpr, EP_TokenOnly|EP_Leaf) ) break; +- if( ExprHasProperty(pExpr, EP_xIsSelect) ){ +- if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1; +- }else{ +- if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1; +- } +- if( sqlite3FixExpr(pFix, pExpr->pRight) ){ +- return 1; +- } +- pExpr = pExpr->pLeft; +- } +- return 0; +-} +-int sqlite3FixExprList( +- DbFixer *pFix, /* Context of the fixation */ +- ExprList *pList /* The expression to be fixed to one database */ +-){ +- int i; +- struct ExprList_item *pItem; +- if( pList==0 ) return 0; +- for(i=0, pItem=pList->a; inExpr; i++, pItem++){ +- if( sqlite3FixExpr(pFix, pItem->pExpr) ){ +- return 1; +- } +- } +- return 0; ++ return sqlite3WalkExpr(&pFix->w, pExpr); + } + #endif + +@@ -592,25 +566,20 @@ + TriggerStep *pStep /* The trigger step be fixed to one database */ + ){ + while( pStep ){ +- if( sqlite3FixSelect(pFix, pStep->pSelect) ){ +- return 1; +- } +- if( sqlite3FixExpr(pFix, pStep->pWhere) ){ +- return 1; +- } +- if( sqlite3FixExprList(pFix, pStep->pExprList) ){ +- return 1; +- } +- if( pStep->pFrom && sqlite3FixSrcList(pFix, pStep->pFrom) ){ ++ if( sqlite3WalkSelect(&pFix->w, pStep->pSelect) ++ || sqlite3WalkExpr(&pFix->w, pStep->pWhere) ++ || sqlite3WalkExprList(&pFix->w, pStep->pExprList) ++ || sqlite3FixSrcList(pFix, pStep->pFrom) ++ ){ + return 1; + } + #ifndef SQLITE_OMIT_UPSERT + if( pStep->pUpsert ){ + Upsert *pUp = pStep->pUpsert; +- if( sqlite3FixExprList(pFix, pUp->pUpsertTarget) +- || sqlite3FixExpr(pFix, pUp->pUpsertTargetWhere) +- || sqlite3FixExprList(pFix, pUp->pUpsertSet) +- || sqlite3FixExpr(pFix, pUp->pUpsertWhere) ++ if( sqlite3WalkExprList(&pFix->w, pUp->pUpsertTarget) ++ || sqlite3WalkExpr(&pFix->w, pUp->pUpsertTargetWhere) ++ || sqlite3WalkExprList(&pFix->w, pUp->pUpsertSet) ++ || sqlite3WalkExpr(&pFix->w, pUp->pUpsertWhere) + ){ + return 1; + } +@@ -618,6 +587,7 @@ + #endif + pStep = pStep->pNext; + } ++ + return 0; + } + #endif +diff -rNu sqlite_before/src/sqliteInt.h sqlite_after/src/sqliteInt.h +--- sqlite_before/src/sqliteInt.h 2021-09-05 20:50:58.137474551 +0800 ++++ sqlite_after/src/sqliteInt.h 2021-09-05 20:52:09.418798495 +0800 +@@ -1137,6 +1137,7 @@ + typedef struct CollSeq CollSeq; + typedef struct Column Column; + typedef struct Db Db; ++typedef struct DbFixer DbFixer; + typedef struct Schema Schema; + typedef struct Expr Expr; + typedef struct ExprList ExprList; +@@ -3651,21 +3652,6 @@ + }; + + /* +-** The following structure contains information used by the sqliteFix... +-** routines as they walk the parse tree to make database references +-** explicit. +-*/ +-typedef struct DbFixer DbFixer; +-struct DbFixer { +- Parse *pParse; /* The parsing context. Error messages written here */ +- Schema *pSchema; /* Fix items to this schema */ +- u8 bTemp; /* True for TEMP schema entries */ +- const char *zDb; /* Make sure all objects are contained in this database */ +- const char *zType; /* Type of the container - used for error messages */ +- const Token *pName; /* Name of the container - used for error messages */ +-}; +- +-/* + ** An objected used to accumulate the text of a string where we + ** do not necessarily know how big the string will be in the end. + */ +@@ -3815,9 +3801,25 @@ + struct RenameCtx *pRename; /* RENAME COLUMN context */ + struct Table *pTab; /* Table of generated column */ + struct SrcList_item *pSrcItem; /* A single FROM clause item */ ++ DbFixer *pFix; + } u; + }; + ++/* ++** The following structure contains information used by the sqliteFix... ++** routines as they walk the parse tree to make database references ++** explicit. ++*/ ++struct DbFixer { ++ Parse *pParse; /* The parsing context. Error messages written here */ ++ Walker w; /* Walker object */ ++ Schema *pSchema; /* Fix items to this schema */ ++ u8 bTemp; /* True for TEMP schema entries */ ++ const char *zDb; /* Make sure all objects are contained in this database */ ++ const char *zType; /* Type of the container - used for error messages */ ++ const Token *pName; /* Name of the container - used for error messages */ ++}; ++ + /* Forward declarations */ + int sqlite3WalkExpr(Walker*, Expr*); + int sqlite3WalkExprList(Walker*, ExprList*); +@@ -4527,7 +4529,6 @@ + int sqlite3FixSrcList(DbFixer*, SrcList*); + int sqlite3FixSelect(DbFixer*, Select*); + int sqlite3FixExpr(DbFixer*, Expr*); +-int sqlite3FixExprList(DbFixer*, ExprList*); + int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); + int sqlite3RealSameAsInt(double,sqlite3_int64); + void sqlite3Int64ToText(i64,char*); +diff -rNu sqlite_before/test/altertab3.test sqlite_after/test/altertab3.test +--- sqlite_before/test/altertab3.test 2021-09-05 20:50:58.137474551 +0800 ++++ sqlite_after/test/altertab3.test 2021-09-05 20:52:09.422798569 +0800 +@@ -253,7 +253,7 @@ + + do_catchsql_test 11.2 { + ALTER TABLE t1 RENAME TO t1x; +-} {1 {error in trigger b: no such table: abc}} ++} {1 {error in trigger b: no such table: main.abc}} + + do_execsql_test 11.3 { + DROP TRIGGER b; +diff -rNu sqlite_before/test/triggerE.test sqlite_after/test/triggerE.test +--- sqlite_before/test/triggerE.test 2021-09-05 20:50:58.137474551 +0800 ++++ sqlite_after/test/triggerE.test 2021-09-05 20:52:09.462799312 +0800 +@@ -58,6 +58,8 @@ + 8 { BEFORE UPDATE ON t1 BEGIN UPDATE t2 SET c = ?; END; } + 9 { BEFORE UPDATE ON t1 BEGIN UPDATE t2 SET c = 1 WHERE d = ?; END; } + 10 { AFTER INSERT ON t1 BEGIN SELECT * FROM pragma_stats(?); END; } ++ 11 { BEFORE INSERT ON t1 BEGIN ++ INSERT INTO t1 SELECT max(b) OVER(ORDER BY $1) FROM t1; END } + } { + catchsql {drop trigger tr1} + do_catchsql_test 1.1.$tn "CREATE TRIGGER tr1 $defn" [list 1 $errmsg] diff --git a/sqlite.spec b/sqlite.spec index 4c9d3870198026ac99b7ce54e5dde2707606a6ea..48c0e61978b5cb2ec8779e845d62d4051b603b79 100644 --- a/sqlite.spec +++ b/sqlite.spec @@ -6,7 +6,7 @@ Name: sqlite Version: 3.34.0 -Release: 2 +Release: 3 Summary: Embeded SQL database License: Public Domain URL: http://www.sqlite.org/ @@ -18,6 +18,7 @@ Source2: https://www.sqlite.org/2020/sqlite-autoconf-%{extver}.tar.gz Patch1: 0001-sqlite-no-malloc-usable-size.patch Patch2: 0002-remove-fail-testcase-in-no-free-fd-situation.patch Patch3: 0003-infinite-loop-in-trim-function.patch +Patch4: 0004-null-ref-in-trigger.patch BuildRequires: gcc autoconf tcl tcl-devel BuildRequires: ncurses-devel readline-devel glibc-devel @@ -63,6 +64,7 @@ This contains man files and HTML files for the using of sqlite. %patch1 -p1 %patch2 -p1 %patch3 -p1 +%patch4 -p1 rm -f %{name}-doc-%{extver}/sqlite.css~ || : @@ -133,6 +135,9 @@ make test %{_mandir}/man*/* %changelog +* Fri Sep 3 2021 wbq_sky - 3.34.0-3 +- fix the null reference in the tigger statement. + * Fri Sep 3 2021 wbq_sky - 3.34.0-2 - fix the infinite loop problem in the trim function while the pattern is well formed.