From: dan Date: Sat, 27 Sep 2025 16:13:56 +0000 (+0000) Subject: Fix authorization callbacks for the new commands on this branch. X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=32c49bd6e6be4e5796439526e1d7c6ddd5ed3c96;p=thirdparty%2Fsqlite.git Fix authorization callbacks for the new commands on this branch. FossilOrigin-Name: 0165e2afa8b640c9d7a31414f06144e089844dc13691f06f363a50d14fec62bc --- diff --git a/manifest b/manifest index d9014583b4..4b8f457a96 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sexperimental\simplementations\sof\sALTER\sTABLE\scommands\sto\sadd\sand\sdrop\sCHECK\sand\sNOT\sNULL\sconstraints. -D 2025-09-27T14:59:21.750 +C Fix\sauthorization\scallbacks\sfor\sthe\snew\scommands\son\sthis\sbranch. +D 2025-09-27T16:13:56.339 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -670,7 +670,7 @@ F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 1b9c24374a85dfc7eb8fa7c4266ee0db4f9609cceecfc5481cd8307e5af04366 F sqlite3.pc.in e6dee284fba59ef500092fdc1843df3be8433323a3733c91da96690a50a5b398 -F src/alter.c 8eeaacd19f6b5948600c7d567c1e22a906d60777c1de8be0d2caa6b68a058a3a +F src/alter.c b126042887cccd2c6476685f634cbcfa7b7f2812ca4dc96bbb6d606fa9ba56e6 F src/analyze.c 03bcfc083fc0cccaa9ded93604e1d4244ea245c17285d463ef6a60425fcb247d F src/attach.c 9af61b63b10ee702b1594ecd24fb8cea0839cfdb6addee52fba26fa879f5db9d F src/auth.c 54ab9c6c5803b47c0d45b76ce27eff22a03b4b1f767c5945a3a4eb13aa4c78dc @@ -726,7 +726,7 @@ F src/os_win.c f81a7cffdfe8c593a840895b3f64290714f0186b06302d2c397012252d830374 F src/os_win.h 4c247cdb6d407c75186c94a1e84d5a22cbae4adcec93fcae8d2bc1f956fd1f19 F src/pager.c 113f9149092ccff6cf90e97c2611200e5a237f13d26c394bc9fd933377852764 F src/pager.h 6137149346e6c8a3ddc1eeb40aee46381e9bc8b0fcc6dda8a1efde993c2275b8 -F src/parse.y 853bfe037292ab3731b0753a92291d248161e721dd6893affb9d181d65f43702 +F src/parse.y 834ba749a6a9f34ef49ad4dd30531252739f6f796f1589d0c4ba548385276535 F src/pcache.c 588cc3c5ccaaadde689ed35ce5c5c891a1f7b1f4d1f56f6cf0143b74d8ee6484 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 F src/pcache1.c 131ca0daf4e66b4608d2945ae76d6ed90de3f60539afbd5ef9ec65667a5f2fcd @@ -741,7 +741,7 @@ F src/shell.c.in 0ab96b4d875ec03e1b5d0c97aa3f2f68d3b6c926f270488e26f3088d1755481 F src/sqlite.h.in 5732519a2acb09066032ceac21f25996eb3f28f807a4468e30633c7c70faae1c F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479 F src/sqlite3ext.h 3f0c4ed6934e7309a61c6f3c30f70a30a5b869f785bb3d9f721a36c5e4359126 -F src/sqliteInt.h 9e65623e73c1c6d45e8bba3bad2d86d90cc289b2923ca35a26db5328d9f1ed60 +F src/sqliteInt.h d555ae8089e7032ae47823a58150f424e2f8715eaadc0eb3071a5c3de028a8a7 F src/sqliteLimit.h fe70bd8983e5d317a264f2ea97473b359faf3ebb0827877a76813f5cf0cdc364 F src/status.c 0e72e4f6be6ccfde2488eb63210297e75f569f3ce9920f6c3d77590ec6ce5ffd F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 @@ -839,7 +839,7 @@ F test/alter4.test 37cafe164067a6590a0ee4cec780bddbbaa33dc50b11542dcfbe0e6562649 F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959 F test/alterauth2.test 48967abae0494d9a300d1c92473d99fcb66edfcc23579c89322f033f49410adc F test/altercol.test b43fb5725332f4cf8cff0280605202c1672e808281accea60a066d2ccc5129e5 -F test/altercons.test 2e05836679a139317b8ac18c48c86d814b38011a7f225cbd52880fc8bc22c2f5 +F test/altercons.test 33fb8117e669b14536a7cf5df694a6027e5773c2e5d12dd2a240c7b2046c9cc5 F test/altercorrupt.test 2e1d705342cf9d7de884518ddbb053fd52d7e60d2b8869b7b63b2fda68435c12 F test/alterdropcol.test a653a3945f964d26845ec0cd0a8e74189f46de3119a984c5bc45457da392612e F test/alterdropcol2.test 527fce683b200d620f560f666c44ae33e22728e990a10a48a543280dfd4b4d41 @@ -2170,11 +2170,8 @@ F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd7227350 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b44650f907e9cb4ec908bb7525488e309946fac9d84cdac4cdde730527a440a9 -R 62bf02b8a31c34d045e943408d7ca34a -T *branch * alter-table-constraints -T *sym-alter-table-constraints * -T -sym-trunk * +P d939b25d76fe70a3255cfe38097d4489323028cd05e5512a98dce06b48eee445 +R df87aa2ddd3ec2e579d06904451a2687 U dan -Z df1bd70c76c4689d412ec3f686f545c6 +Z afa946c19eec2db0cf6e37984f361e84 # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index 8d93d0bad3..f37679958e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d939b25d76fe70a3255cfe38097d4489323028cd05e5512a98dce06b48eee445 +0165e2afa8b640c9d7a31414f06144e089844dc13691f06f363a50d14fec62bc diff --git a/src/alter.c b/src/alter.c index 23847470a4..f8692c0cdc 100644 --- a/src/alter.c +++ b/src/alter.c @@ -563,7 +563,7 @@ exit_begin_add_column: ** Or, if pTab is not a view or virtual table, zero is returned. */ #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) -static int isRealTable(Parse *pParse, Table *pTab, int bDrop){ +static int isRealTable(Parse *pParse, Table *pTab, int iOp){ const char *zType = 0; #ifndef SQLITE_OMIT_VIEW if( IsView(pTab) ){ @@ -576,9 +576,12 @@ static int isRealTable(Parse *pParse, Table *pTab, int bDrop){ } #endif if( zType ){ + const char *azMsg[] = { + "rename columns of", "drop column from", "edit constraints of" + }; + assert( iOp>=0 && iOpzName + azMsg[iOp], zType, pTab->zName ); return 1; } @@ -2633,11 +2636,64 @@ static int alterFindCol(Parse *pParse, Table *pTab, Token *pCol, int *piCol){ } } +#ifndef SQLITE_OMIT_AUTHORIZATION + if( rc==SQLITE_OK ){ + const char *zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName; + const char *zCol = pTab->aCol[iCol].zCnName; + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, zCol) ){ + pTab = 0; + } + } +#endif + sqlite3DbFree(db, zName); *piCol = iCol; return rc; } + +/* +** Find the table named by the first entry in source list pSrc. If successful, +** return a pointer to the Table structure and set output variable (*pzDb) +** to point to the name of the database containin the table (i.e. "main", +** "temp" or the name of an attached database). +** +** If the table cannot be located, return NULL. The value of the two output +** parameters is undefined in this case. +*/ +static Table *alterFindTable( + Parse *pParse, + SrcList *pSrc, + int *piDb, + const char **pzDb, + int bAuth +){ + sqlite3 *db = pParse->db; + Table *pTab = 0; + assert( sqlite3BtreeHoldsAllMutexes(db) ); + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + if( pTab ){ + int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + *pzDb = db->aDb[iDb].zDbSName; + *piDb = iDb; + + if( SQLITE_OK!=isRealTable(pParse, pTab, 2) + || SQLITE_OK!=isAlterableTable(pParse, pTab) + ){ + pTab = 0; + } + } +#ifndef SQLITE_OMIT_AUTHORIZATION + if( pTab && bAuth ){ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, *pzDb, pTab->zName, 0) ){ + pTab = 0; + } + } +#endif + sqlite3SrcListDelete(db, pSrc); + return pTab; +} + void alterDropConstraint( Parse *pParse, SrcList *pSrc, @@ -2650,26 +2706,14 @@ void alterDropConstraint( const char *zDb = 0; char *zArg = 0; - /* Look up the table being altered. */ - assert( sqlite3BtreeHoldsAllMutexes(db) ); - pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); - if( !pTab ) goto exit_drop_cons; - - /* Make sure this is not an attempt to ALTER a view, virtual table or - ** system table. */ - if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_drop_cons; - if( SQLITE_OK!=isRealTable(pParse, pTab, 1) ) goto exit_drop_cons; - - /* Edit the sqlite_schema table */ - iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - assert( iDb>=0 ); - zDb = db->aDb[iDb].zDbSName; + pTab = alterFindTable(pParse, pSrc, &iDb, &zDb, pCons!=0); + if( !pTab ) return; if( pCons ){ zArg = sqlite3MPrintf(db, "%.*Q", pCons->n, pCons->z); }else{ int iCol; - if( alterFindCol(pParse, pTab, pCol, &iCol) ) goto exit_drop_cons; + if( alterFindCol(pParse, pTab, pCol, &iCol) ) return; zArg = sqlite3MPrintf(db, "%d", iCol); } @@ -2684,9 +2728,6 @@ void alterDropConstraint( /* Finally, reload the database schema. */ renameReloadSchema(pParse, iDb, INITFLAG_AlterDropCons); - - exit_drop_cons: - sqlite3SrcListDelete(db, pSrc); } @@ -2724,34 +2765,6 @@ static void failConstraintFunc( sqlite3_result_error_code(ctx, err); } -/* -** Find the table named by the first entry in source list pSrc. If successful, -** return a pointer to the Table structure and set output variable (*pzDb) -** to point to the name of the database containin the table (i.e. "main", -** "temp" or the name of an attached database). -** -** If the table cannot be located, return NULL. The value of the two output -** parameters is undefined in this case. -*/ -static Table *alterFindTable( - Parse *pParse, - SrcList *pSrc, - int *piDb, - const char **pzDb -){ - sqlite3 *db = pParse->db; - Table *pTab = 0; - assert( sqlite3BtreeHoldsAllMutexes(db) ); - pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); - sqlite3SrcListDelete(db, pSrc); - if( pTab ){ - int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - *pzDb = db->aDb[iDb].zDbSName; - *piDb = iDb; - } - return pTab; -} - /* ** Prepare a statement of the form: ** @@ -2760,7 +2773,8 @@ static Table *alterFindTable( void sqlite3AlterSetNotNull( Parse *pParse, SrcList *pSrc, - Token *pCol + Token *pCol, + Token *pFirst ){ Table *pTab = 0; int iCol = 0; @@ -2771,7 +2785,7 @@ void sqlite3AlterSetNotNull( int t = 0; /* Look up the table being altered. */ - pTab = alterFindTable(pParse, pSrc, &iDb, &zDb); + pTab = alterFindTable(pParse, pSrc, &iDb, &zDb, 0); if( !pTab ) return; /* Find the column being altered. */ @@ -2779,12 +2793,8 @@ void sqlite3AlterSetNotNull( return; } - /* Find the start of the constraint definition */ - pCons = &pCol->z[pCol->n]; - pCons += getConstraintToken((const u8*)pCons, &t); - pCons += getWhitespace((const u8*)pCons); - /* Find the length in bytes of the constraint definition */ + pCons = pFirst->z; nCons = pParse->sLastToken.z - pCons; if( pCons[nCons-1]==';' ) nCons--; while( sqlite3Isspace(pCons[nCons-1]) ) nCons--; @@ -2868,7 +2878,7 @@ void sqlite3AlterAddConstraint( int nCons; /* Look up the table being altered. */ - pTab = alterFindTable(pParse, pSrc, &iDb, &zDb); + pTab = alterFindTable(pParse, pSrc, &iDb, &zDb, 1); if( !pTab ) return; /* If this new constraint has a name, check that it is not a duplicate of diff --git a/src/parse.y b/src/parse.y index bcc3e61b2a..cfd1b5d4cb 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1856,8 +1856,8 @@ cmd ::= ALTER TABLE fullname(X) DROP CONSTRAINT nm(Y). { cmd ::= ALTER TABLE fullname(X) ALTER kwcolumn_opt nm(Y) DROP NOT NULL. { sqlite3AlterDropNotNull(pParse, X, &Y); } -cmd ::= ALTER TABLE fullname(X) ALTER kwcolumn_opt nm(Y) SET NOT NULL onconf. { - sqlite3AlterSetNotNull(pParse, X, &Y); +cmd ::= ALTER TABLE fullname(X) ALTER kwcolumn_opt nm(Y) SET NOT(Z) NULL onconf. { + sqlite3AlterSetNotNull(pParse, X, &Y, &Z); } cmd ::= ALTER TABLE fullname(X) ADD CONSTRAINT(Y) nm(Z) CHECK LP(A) expr RP(B) onconf. { diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 81cfbf8ab3..94e387ace1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -5451,7 +5451,7 @@ void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*); void sqlite3AlterDropConstraint(Parse*, SrcList*, Token*); void sqlite3AlterDropNotNull(Parse*, SrcList*, Token*); void sqlite3AlterAddConstraint(Parse*,SrcList*,Token*,Token*,const char*,int); -void sqlite3AlterSetNotNull(Parse*, SrcList*, Token*); +void sqlite3AlterSetNotNull(Parse*, SrcList*, Token*, Token*); int sqlite3GetToken(const unsigned char *, int *); void sqlite3NestedParse(Parse*, const char*, ...); void sqlite3ExpirePreparedStatements(sqlite3*, int); diff --git a/test/altercons.test b/test/altercons.test index af70d0f562..e145d31ad2 100644 --- a/test/altercons.test +++ b/test/altercons.test @@ -228,4 +228,46 @@ do_execsql_test 6.4.1 { SELECT sql FROM sqlite_schema WHERE tbl_name='b1' } {{CREATE TABLE b1(a, b, CONSTRAINT abc CHECK (a!=2))}} +#------------------------------------------------------------------------- +# Try attaching a NOT NULL to a generated column. +# +reset_db +do_execsql_test 7.0 { + CREATE TABLE x1(a, b AS (a+1)); + INSERT INTO x1 VALUES(1), (2), (3), (NULL); +} + +do_catchsql_test 7.1 { + ALTER TABLE x1 ALTER b SET NOT NULL; +} {1 {constraint failed}} + +do_catchsql_test 7.2 { + DELETE FROM x1 WHERE b IS NULL; + ALTER TABLE x1 ALTER b SET NOT NULL; +} {0 {}} + +do_execsql_test 7.3 { + SELECT b FROM x1 +} {2 3 4} + +do_catchsql_test 7.4 { + ALTER TABLE x1 ALTER rowid SET NOT NULL; +} {1 {no such column: rowid}} + +do_execsql_test 7.5 { + CREATE VIEW v1 AS SELECT a, b FROM x1; +} +do_catchsql_test 7.6 { + ALTER TABLE v1 RENAME a TO c; +} {1 {cannot rename columns of view "v1"}} +do_catchsql_test 7.7 { + ALTER TABLE v1 ALTER a SET NOT NULL; +} {1 {cannot edit constraints of view "v1"}} +do_catchsql_test 7.8 { + ALTER TABLE sqlite_schema ALTER sql SET NOT NULL; +} {1 {table sqlite_master may not be altered}} +do_catchsql_test 7.9 { + ALTER TABLE v1 ALTER a DROP NOT NULL +} {1 {cannot edit constraints of view "v1"}} + finish_test