]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Report the correct authorization context in the authorization callback
authordrh <drh@noemail.net>
Fri, 25 Apr 2003 17:52:11 +0000 (17:52 +0000)
committerdrh <drh@noemail.net>
Fri, 25 Apr 2003 17:52:11 +0000 (17:52 +0000)
when coding an INSTEAD OF trigger on an update or delete. (CVS 936)

FossilOrigin-Name: 67746833fc8de3afff80db413bd63a362bb28218

manifest
manifest.uuid
src/auth.c
src/delete.c
src/sqliteInt.h
src/trigger.c
src/update.c
test/auth.test

index 137279ac8c9f91828a8f832c7aee518f0a941362..59b527de1f2989cca03dd6aa0440b6e4da43c36f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\stests\sto\sinsure\sVACUUM\sworks\sin\sthe\spresence\sof\sI/O\serrors.\s\sFix\ssome\nproblems\sthat\scame\sto\slight\sby\sthese\stests.\s(CVS\s935)
-D 2003-04-25T15:37:58
+C Report\sthe\scorrect\sauthorization\scontext\sin\sthe\sauthorization\scallback\nwhen\scoding\san\sINSTEAD\sOF\strigger\son\san\supdate\sor\sdelete.\s(CVS\s936)
+D 2003-04-25T17:52:11
 F Makefile.in 004acec253ecdde985c8ecd5b7c9accdb210378f
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -20,13 +20,13 @@ F spec.template 238f7db425a78dc1bb7682e56e3834c7270a3f5e
 F sqlite.1 83f4a9d37bdf2b7ef079a82d54eaf2e3509ee6ea
 F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
 F src/attach.c 7ebc7487de43e357a64226f8abef81f2669f2183
-F src/auth.c a4afd27964fb9f661147115790c8ae2ee230ebcc
+F src/auth.c 3be3c7434592117f049703966b940e0b07088ae2
 F src/btree.c 077d75aee4ed63f3628698611ba43c87097d458d
 F src/btree.h 23c50e00709de16a5dce1fcea9c0429cc955ff0e
 F src/btree_rb.c 8e00e40be264716e1929987878672e55d9e0e76d
 F src/build.c d5a26baeffa5bc49b4b7009a7723c6ab7e1b02d9
 F src/copy.c 44b13fd4d2444fb53bff8a5ecee1c5f6f86a8263
-F src/delete.c 23d33fd8967c6cc492943bbecea93be6491edc6a
+F src/delete.c 0f7c26aaebc417ad66a2a1099e59cc4056512c31
 F src/encode.c faf03741efe921755ec371cf4a6984536de00042
 F src/expr.c 46e2bb93abd6c70e67c8cdc5d92fdcd0b95498f3
 F src/func.c 882c3ed5a02be18cd904715c7ec62947a34a3605
@@ -47,7 +47,7 @@ F src/select.c dfc13cb62ba658c4463179713c40ee25a062b2ba
 F src/shell.c e0b3da1f44a2cc72daf41a4559b1c5f0545944a5
 F src/shell.tcl 27ecbd63dd88396ad16d81ab44f73e6c0ea9d20e
 F src/sqlite.h.in eec06462cba262c0ee03f38462a18a4bc66dda4e
-F src/sqliteInt.h 5d15d1dea3f0c497a78c6a123eec5b4b92811c1c
+F src/sqliteInt.h 0c7474068c37a5aad715810c8190266edcbd4f4c
 F src/table.c eed2098c9b577aa17f8abe89313a9c4413f57d63
 F src/tclsqlite.c 9e25f98f1765afa0716144ef57abda75c88f688d
 F src/test1.c 4484806861a3099670188a09e12f858ec65aa56c
@@ -55,8 +55,8 @@ F src/test2.c 5014337d8576b731cce5b5a14bec4f0daf432700
 F src/test3.c 30985ebdfaf3ee1462a9b0652d3efbdc8d9798f5
 F src/threadtest.c d641a5219e718e18a1a80a50eb9bb549f451f42e
 F src/tokenize.c 067d1a477a94af7712ca74e09aaa6bd0f7299527
-F src/trigger.c e763f4015c96e06b694184ead5754985c1dfdae0
-F src/update.c b7fa7c427b74aee6db56ecfa09e5e151e6f9fa6a
+F src/trigger.c 62d1e1b837a98f1fa7511c77977d51c8516ddb65
+F src/update.c f40376ed2e092a7040c6fc6fa0add59fad5c5e76
 F src/util.c 87635cfdfffa056a8d3147719357aa442374f78c
 F src/vacuum.c 14ac3073203fa021e01ffe33db56968ad79a8344
 F src/vdbe.c 48098080d2b5d35d4cc28ac2a4855c7730f6ee7b
@@ -64,7 +64,7 @@ F src/vdbe.h 985c24f312d10f9ef8f9a8b8ea62fcdf68e82f21
 F src/where.c f632cd30f013163484a4d60c249d36fe31f5be12
 F test/all.test 569a92a8ee88f5300c057cc4a8f50fbbc69a3242
 F test/attach.test b311c83e370e6b22b79a8279317039440ce64862
-F test/auth.test d25a76f21494b61483787caa7b28c713bc7c7c7f
+F test/auth.test dee78be1f4f920bd6b15c4c947ce4d01bfe2826d
 F test/bigfile.test 1cd8256d4619c39bea48147d344f348823e78678
 F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
 F test/btree.test 1e3463c7838e7e71bbf37c9c6e45beee9c8975ba
@@ -165,7 +165,7 @@ F www/speed.tcl cb4c10a722614aea76d2c51f32ee43400d5951be
 F www/sqlite.tcl ae3dcfb077e53833b59d4fcc94d8a12c50a44098
 F www/tclsqlite.tcl 1db15abeb446aad0caf0b95b8b9579720e4ea331
 F www/vdbe.tcl 2013852c27a02a091d39a766bc87cff329f21218
-P c3b1f84dfce13b2523c9923e4270577862ca0595
-R 40330553c4eb619fb11602a7f62ead1c
+P 8d3e879349fc9523c72cb46111e0058b57ce9341
+R fbd9cacc0c39e890456b02e579584ea3
 U drh
-Z 09a1f9c6aa9e8c12d787618e6052f340
+Z d170dde2366e1aeda159869f0f0e19bb
index 0e2dd63f429baf6650be269fd088d2a660c96545..977ffff6c92cab6c9eae8a55f2b3a780528b093d 100644 (file)
@@ -1 +1 @@
-8d3e879349fc9523c72cb46111e0058b57ce9341
\ No newline at end of file
+67746833fc8de3afff80db413bd63a362bb28218
\ No newline at end of file
index 4703ba0132921c53a515c9d575ad20aae657c1a4..2a5a8f5648a278a427ce9c22b2d7e548375363c3 100644 (file)
@@ -14,7 +14,7 @@
 ** systems that do not need this facility may omit it by recompiling
 ** the library with -DSQLITE_OMIT_AUTHORIZATION=1
 **
-** $Id: auth.c,v 1.7 2003/04/24 01:45:04 drh Exp $
+** $Id: auth.c,v 1.8 2003/04/25 17:52:11 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -173,4 +173,32 @@ int sqliteAuthCheck(
   return rc;
 }
 
+/*
+** Push an authorization context.  After this routine is called, the
+** zArg3 argument to authorization callbacks will be zContext until
+** popped.  Or if pParse==0, this routine is a no-op.
+*/
+void sqliteAuthContextPush(
+  Parse *pParse,
+  AuthContext *pContext, 
+  const char *zContext
+){
+  pContext->pParse = pParse;
+  if( pParse ){
+    pContext->zAuthContext = pParse->zAuthContext;
+    pParse->zAuthContext = zContext;
+  }
+}
+
+/*
+** Pop an authorization context that was previously pushed
+** by sqliteAuthContextPush
+*/
+void sqliteAuthContextPop(AuthContext *pContext){
+  if( pContext->pParse ){
+    pContext->pParse->zAuthContext = pContext->zAuthContext;
+    pContext->pParse = 0;
+  }
+}
+
 #endif /* SQLITE_OMIT_AUTHORIZATION */
index 7d0003578e0033d713e02380b0d0a816b6b09159..14c7a20e16e74b3359f18c6c3e1a346a2bcb3f95 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle DELETE FROM statements.
 **
-** $Id: delete.c,v 1.54 2003/04/24 01:45:04 drh Exp $
+** $Id: delete.c,v 1.55 2003/04/25 17:52:11 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -68,12 +68,14 @@ void sqliteDeleteFrom(
   int base;              /* Index of the first available table cursor */
   sqlite *db;            /* Main database structure */
   int isView;            /* True if attempting to delete from a view */
+  AuthContext sContext;  /* Authorization context */
 
   int row_triggers_exist = 0;  /* True if any triggers exist */
   int before_triggers;         /* True if there are BEFORE triggers */
   int after_triggers;          /* True if there are AFTER triggers */
   int oldIdx = -1;             /* Cursor for the OLD table of AFTER triggers */
 
+  sContext.pParse = 0;
   if( pParse->nErr || sqlite_malloc_failed ){
     pTabList = 0;
     goto delete_from_cleanup;
@@ -127,6 +129,12 @@ void sqliteDeleteFrom(
     }
   }
 
+  /* Start the view context
+  */
+  if( isView ){
+    sqliteAuthContextPush(pParse, &sContext, pTab->zName);
+  }
+
   /* Begin generating code.
   */
   v = sqliteGetVdbe(pParse);
@@ -303,6 +311,7 @@ void sqliteDeleteFrom(
   }
 
 delete_from_cleanup:
+  sqliteAuthContextPop(&sContext);
   sqliteSrcListDelete(pTabList);
   sqliteExprDelete(pWhere);
   return;
index 7027b30a96c4fe8e452b0705705cfa1ccbdcfbef..c68ccd94c01e7f7d7f32d875e8cbf26541b0abba 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.180 2003/04/24 01:45:04 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.181 2003/04/25 17:52:11 drh Exp $
 */
 #include "config.h"
 #include "sqlite.h"
@@ -219,6 +219,7 @@ typedef struct TriggerStep TriggerStep;
 typedef struct TriggerStack TriggerStack;
 typedef struct FKey FKey;
 typedef struct Db Db;
+typedef struct AuthContext AuthContext;
 
 /*
 ** Each database file to be accessed by the system is an instance
@@ -834,6 +835,15 @@ struct Parse {
   TriggerStack *trigStack;  /* Trigger actions being coded */
 };
 
+/*
+** An instance of the following structure can be declared on a stack and used
+** to save the Parse.zAuthContext value so that it can be restored later.
+*/
+struct AuthContext {
+  const char *zAuthContext;   /* Put saved Parse.zAuthContext here */
+  Parse *pParse;              /* The Parse structure */
+};
+
 /*
  * Each trigger present in the database schema is stored as an instance of
  * struct Trigger. 
@@ -1111,9 +1121,13 @@ void sqliteDeferForeignKey(Parse*, int);
 #ifndef SQLITE_OMIT_AUTHORIZATION
   void sqliteAuthRead(Parse*,Expr*,SrcList*,int);
   int sqliteAuthCheck(Parse*,int, const char*, const char*, const char*);
+  void sqliteAuthContextPush(Parse*, AuthContext*, const char*);
+  void sqliteAuthContextPop(AuthContext*);
 #else
 # define sqliteAuthRead(a,b,c,d)
 # define sqliteAuthCheck(a,b,c,d)    SQLITE_OK
+# define sqliteAuthContextPush(a,b,c)
+# define sqliteAuthContextPop(a)
 #endif
 void sqliteAttach(Parse*, Token*, Token*);
 void sqliteDetach(Parse*, Token*);
index 0abe7ee0d6912850dd0eab78062f0721d0750656..b07b8c5a8781f4872ec45645b44d9e5082d4e8d0 100644 (file)
@@ -661,7 +661,7 @@ int sqliteCodeRowTrigger(
       int endTrigger;
       SrcList dummyTablist;
       Expr * whenExpr;
-      const char *zSavedAuthContext;
+      AuthContext sContext;
 
       dummyTablist.nSrc = 0;
 
@@ -673,8 +673,7 @@ int sqliteCodeRowTrigger(
       pTriggerStack->pNext = pParse->trigStack;
       pTriggerStack->ignoreJump = ignoreJump;
       pParse->trigStack = pTriggerStack;
-      zSavedAuthContext = pParse->zAuthContext;
-      pParse->zAuthContext = pTrigger->name;
+      sqliteAuthContextPush(pParse, &sContext, pTrigger->name);
 
       /* code the WHEN clause */
       endTrigger = sqliteVdbeMakeLabel(pParse->pVdbe);
@@ -692,7 +691,7 @@ int sqliteCodeRowTrigger(
 
       /* Pop the entry off the trigger stack */
       pParse->trigStack = pParse->trigStack->pNext;
-      pParse->zAuthContext = zSavedAuthContext;
+      sqliteAuthContextPop(&sContext);
       sqliteFree(pTriggerStack);
 
       sqliteVdbeResolveLabel(pParse->pVdbe, endTrigger);
index c1961426cfc9bdbd25ee459732bed5c2d9136080..cd98c82c06edb23170f8084ea2397bcde3fcac34 100644 (file)
@@ -12,7 +12,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle UPDATE statements.
 **
-** $Id: update.c,v 1.63 2003/04/24 01:45:05 drh Exp $
+** $Id: update.c,v 1.64 2003/04/25 17:52:11 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -49,6 +49,7 @@ void sqliteUpdate(
   Expr *pRecnoExpr;      /* Expression defining the new record number */
   int openAll;           /* True if all indices need to be opened */
   int isView;            /* Trying to update a view */
+  AuthContext sContext;  /* The authorization context */
 
   int before_triggers;         /* True if there are any BEFORE triggers */
   int after_triggers;          /* True if there are any AFTER triggers */
@@ -57,6 +58,7 @@ void sqliteUpdate(
   int newIdx      = -1;  /* index of trigger "new" temp table       */
   int oldIdx      = -1;  /* index of trigger "old" temp table       */
 
+  sContext.pParse = 0;
   if( pParse->nErr || sqlite_malloc_failed ) goto update_cleanup;
   db = pParse->db;
   assert( pTabList->nSrc==1 );
@@ -74,8 +76,10 @@ void sqliteUpdate(
   if( sqliteIsReadOnly(pParse, pTab, before_triggers) ){
     goto update_cleanup;
   }
-  if( isView && sqliteViewGetColumnNames(pParse, pTab) ){
-    goto update_cleanup;
+  if( isView ){
+    if( sqliteViewGetColumnNames(pParse, pTab) ){
+      goto update_cleanup;
+    }
   }
   aXRef = sqliteMalloc( sizeof(int) * pTab->nCol );
   if( aXRef==0 ) goto update_cleanup;
@@ -99,20 +103,12 @@ void sqliteUpdate(
     pParse->nTab++;
   }
 
-  /* Resolve the column names in all the expressions in both the
-  ** WHERE clause and in the new values.  Also find the column index
+  /* Resolve the column names in all the expressions of the
+  ** of the UPDATE statement.  Also find the column index
   ** for each column to be updated in the pChanges array.  For each
   ** column to be updated, make sure we have authorization to change
   ** that column.
   */
-  if( pWhere ){
-    if( sqliteExprResolveIds(pParse, base, pTabList, 0, pWhere) ){
-      goto update_cleanup;
-    }
-    if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
-      goto update_cleanup;
-    }
-  }
   chngRecno = 0;
   for(i=0; i<pChanges->nExpr; i++){
     if( sqliteExprResolveIds(pParse, base, pTabList, 0, pChanges->a[i].pExpr) ){
@@ -185,6 +181,24 @@ void sqliteUpdate(
     }
   }
 
+  /* Resolve the column names in all the expressions in the
+  ** WHERE clause.
+  */
+  if( pWhere ){
+    if( sqliteExprResolveIds(pParse, base, pTabList, 0, pWhere) ){
+      goto update_cleanup;
+    }
+    if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
+      goto update_cleanup;
+    }
+  }
+
+  /* Start the view context
+  */
+  if( isView ){
+    sqliteAuthContextPush(pParse, &sContext, pTab->zName);
+  }
+
   /* Begin generating code.
   */
   v = sqliteGetVdbe(pParse);
@@ -195,7 +209,8 @@ void sqliteUpdate(
   ** a temporary table.
   */
   if( isView ){
-    Select *pView = sqliteSelectDup(pTab->pSelect);
+    Select *pView;
+    pView = sqliteSelectDup(pTab->pSelect);
     sqliteSelect(pParse, pView, SRT_TempTable, base, 0, 0, 0);
     sqliteSelectDelete(pView);
   }
@@ -422,6 +437,7 @@ void sqliteUpdate(
   }
 
 update_cleanup:
+  sqliteAuthContextPop(&sContext);
   sqliteFree(apIdx);
   sqliteFree(aXRef);
   sqliteSrcListDelete(pTabList);
index e003c88c09c38dddb8ed0da6e3613a34b9e975de..84b3802e1b8eff026834f6446844db5593a74031 100644 (file)
@@ -12,7 +12,7 @@
 # focus of this script is testing the ATTACH and DETACH commands
 # and related functionality.
 #
-# $Id: auth.test,v 1.8 2003/04/22 20:30:40 drh Exp $
+# $Id: auth.test,v 1.9 2003/04/25 17:52:11 drh Exp $
 #
 
 set testdir [file dirname $argv0]
@@ -1714,5 +1714,74 @@ do_test auth-3.2 {
   }
 } {12 112 2 2 {} {} 8 108 8 8 {} {}}
 
+# Make sure the names of views and triggers are passed on on arg4.
+#
+do_test auth-4.1 {
+  proc auth {code arg1 arg2 arg3 arg4} {
+    lappend ::authargs $code $arg1 $arg2 $arg3 $arg4
+    return SQLITE_OK
+  }
+  set authargs {}
+  execsql {
+    UPDATE t2 SET a=a+1;
+  }
+  set authargs
+} [list \
+  SQLITE_READ   t2 a  main {} \
+  SQLITE_UPDATE t2 a  main {} \
+  SQLITE_INSERT tx {} main r1 \
+  SQLITE_READ   t2 a  main r1 \
+  SQLITE_READ   t2 a  main r1 \
+  SQLITE_READ   t2 b  main r1 \
+  SQLITE_READ   t2 b  main r1 \
+  SQLITE_READ   t2 c  main r1 \
+  SQLITE_READ   t2 c  main r1]
+do_test auth-4.2 {
+  execsql {
+    CREATE VIEW v1 AS SELECT a+b AS x FROM t2;
+    CREATE TABLE v1chng(x1,x2);
+    CREATE TRIGGER r2 INSTEAD OF UPDATE ON v1 BEGIN
+      INSERT INTO v1chng VALUES(OLD.x,NEW.x);
+    END;
+    SELECT * FROM v1;
+  }
+} {115 117}
+do_test auth-4.3 {
+  set authargs {}
+  execsql {
+    UPDATE v1 SET x=1 WHERE x=117
+  }
+  set authargs
+} [list \
+  SQLITE_UPDATE v1     x  main {} \
+  SQLITE_READ   v1     x  main {} \
+  SQLITE_SELECT {}     {} {}   v1 \
+  SQLITE_READ   t2     a  main v1 \
+  SQLITE_READ   t2     b  main v1 \
+  SQLITE_INSERT v1chng {} main r2 \
+  SQLITE_READ   v1     x  main r2 \
+  SQLITE_READ   v1     x  main r2]
+do_test auth-4.4 {
+  execsql {
+    CREATE TRIGGER r3 INSTEAD OF DELETE ON v1 BEGIN
+      INSERT INTO v1chng VALUES(OLD.x,NULL);
+    END;
+    SELECT * FROM v1;
+  }
+} {115 117}
+do_test auth-4.5 {
+  set authargs {}
+  execsql {
+    DELETE FROM v1 WHERE x=117
+  }
+  set authargs
+} [list \
+  SQLITE_DELETE v1     {} main {} \
+  SQLITE_READ   v1     x  main {} \
+  SQLITE_SELECT {}     {} {}   v1 \
+  SQLITE_READ   t2     a  main v1 \
+  SQLITE_READ   t2     b  main v1 \
+  SQLITE_INSERT v1chng {} main r3 \
+  SQLITE_READ   v1     x  main r3]
 
 finish_test