mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-24 08:21:29 +03:00
Enhance the enforcement of SQLITE_VTAB_DIRECTONLY so that it applies to
DML statements within triggers. Do not allow DML stratements against virtual tables within triggers unless either the virtual table is SQLITE_VTAB_INNOCUOUS or PRAGMA trusted_schema is ON. FossilOrigin-Name: 9433ea4070f52135be64569057f439e7bdb4b3f425d87167c9ebda50011210c1
This commit is contained in:
38
src/delete.c
38
src/delete.c
@@ -61,18 +61,42 @@ void sqlite3CodeChangeCount(Vdbe *v, int regCounter, const char *zColName){
|
||||
** 1) It is a virtual table and no implementation of the xUpdate method
|
||||
** has been provided
|
||||
**
|
||||
** 2) It is a system table (i.e. sqlite_schema), this call is not
|
||||
** 2) A trigger is currently being coded and the table is a virtual table
|
||||
** that is SQLITE_VTAB_DIRECTONLY or if PRAGMA trusted_schema=OFF and
|
||||
** the table is not SQLITE_VTAB_INNOCUOUS.
|
||||
**
|
||||
** 3) It is a system table (i.e. sqlite_schema), this call is not
|
||||
** part of a nested parse and writable_schema pragma has not
|
||||
** been specified
|
||||
**
|
||||
** 3) The table is a shadow table, the database connection is in
|
||||
** 4) The table is a shadow table, the database connection is in
|
||||
** defensive mode, and the current sqlite3_prepare()
|
||||
** is for a top-level SQL statement.
|
||||
*/
|
||||
static int vtabIsReadOnly(Parse *pParse, Table *pTab){
|
||||
if( sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ){
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Within triggers:
|
||||
** * Do not allow DELETE, INSERT, or UPDATE of SQLITE_VTAB_DIRECTONLY
|
||||
** virtual tables
|
||||
** * Only allow DELETE, INSERT, or UPDATE of non-SQLITE_VTAB_INNOCUOUS
|
||||
** virtual tables if PRAGMA trusted_schema=ON.
|
||||
*/
|
||||
if( pParse->pToplevel!=0
|
||||
&& pTab->u.vtab.p->eVtabRisk >
|
||||
((pParse->db->flags & SQLITE_TrustedSchema)!=0)
|
||||
){
|
||||
sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"",
|
||||
pTab->zName);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int tabIsReadOnly(Parse *pParse, Table *pTab){
|
||||
sqlite3 *db;
|
||||
if( IsVirtual(pTab) ){
|
||||
return sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0;
|
||||
return vtabIsReadOnly(pParse, pTab);
|
||||
}
|
||||
if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0;
|
||||
db = pParse->db;
|
||||
@@ -84,9 +108,11 @@ static int tabIsReadOnly(Parse *pParse, Table *pTab){
|
||||
}
|
||||
|
||||
/*
|
||||
** Check to make sure the given table is writable. If it is not
|
||||
** writable, generate an error message and return 1. If it is
|
||||
** writable return 0;
|
||||
** Check to make sure the given table is writable.
|
||||
**
|
||||
** If pTab is not writable -> generate an error message and return 1.
|
||||
** If pTab is writable but other errors have occurred -> return 1.
|
||||
** If pTab is writable and no prior errors -> return 0;
|
||||
*/
|
||||
int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
|
||||
if( tabIsReadOnly(pParse, pTab) ){
|
||||
|
||||
Reference in New Issue
Block a user