]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Ensure that tables names are dequoted exactly once by the trigger and FK logic. Cherr...
authordan <dan@noemail.net>
Wed, 20 May 2015 20:30:37 +0000 (20:30 +0000)
committerdan <dan@noemail.net>
Wed, 20 May 2015 20:30:37 +0000 (20:30 +0000)
FossilOrigin-Name: bd357739d74bfc97064e515645bce0834e586649

manifest
manifest.uuid
src/fkey.c
src/sqliteInt.h
src/trigger.c
test/fkey1.test
test/triggerC.test

index 4e959360d37b5cc5cd7b8ac3c39fd8ab47204599..a3fb5a5d806c34388087159e0c0a0dbbd61c32d1 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\san\sobscure\sproblem\swith\s"INSERT\sINTO\stbl(cols)\sSELECT"\sstatements\swhere\sthe\sSELECT\sis\sa\scompound\swith\san\sORDER\sBY\sand\s"cols"\sis\sa\sstrict\ssubset\sof\stbl's\scolumns.\sCherrypick\sof\s[718d5d0eab04].
-D 2015-05-20T20:27:00.289
+C Ensure\sthat\stables\snames\sare\sdequoted\sexactly\sonce\sby\sthe\strigger\sand\sFK\slogic.\sCherrypick\sof\s[59e92bd9521f]\sand\s[9d887b92f808].
+D 2015-05-20T20:30:37.354
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -178,7 +178,7 @@ F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
 F src/delete.c bcf8f72126cea80fc3d5bc5494cf19b3f8935aaf
 F src/expr.c 1686997ef7a2ccb6db0a9215761a138bd8e182a0
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
-F src/fkey.c 8545f3b36da47473e10800ea4fb0810fd4062514
+F src/fkey.c 5fadcfb51f6c8e249ab795348612e2793a59c826
 F src/func.c bbb724b74ed96ca42675a7274646a71dd52bcda7
 F src/global.c 1e4bd956dc2f608f87d2a929abc4a20db65f30e4
 F src/hash.c d139319967164f139c8d1bb8a11b14db9c4ba3cd
@@ -227,7 +227,7 @@ F src/shell.c 75bb7bd2c80bb44861598f322a417c4bafe98fd7
 F src/sqlite.h.in ed9d35990c61f0388ca6405706455c4095310553
 F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
-F src/sqliteInt.h 10038993697680d281fa7dfb2c7219646e59fec1
+F src/sqliteInt.h 978e6e01780b5d7dd328e1247ca878e074f64f6c
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -278,7 +278,7 @@ F src/test_vfs.c f84075a388527892ff184988f43b69ce69b8083c
 F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
 F src/tokenize.c ae45399d6252b4d736af43bee1576ce7bff86aec
-F src/trigger.c 66f3470b03b52b395e839155786966e3e037fddb
+F src/trigger.c 274874731e060355be9ed25c670190775654ac25
 F src/update.c ea336ce7b8b3fc5e316ba8f082e6445babf81059
 F src/utf.c a0314e637768a030e6e84a957d0c4f6ba910cc05
 F src/util.c 3076bdd51cdbf60a6e2e57fada745be37133c73e
@@ -473,7 +473,7 @@ F test/extension01.test 00d13cec817f331a687a243e0e5a2d87b0e358c9
 F test/fallocate.test 3e979af17dfa7e5e9dda5eba1a696c04fa9d47f7
 F test/filectrl.test 14fa712e42c4cb791e09dfd58a6a03efb47ef13a
 F test/filefmt.test cb34663f126cbc2d358af552dcaf5c72769b0146
-F test/fkey1.test e1d1fa84cde579185ea01358436839703e415a5b
+F test/fkey1.test de5b287f6a480b36bd51e8debcf48168e26e4ed2
 F test/fkey2.test 32ca728bcb854feed72d1406ea375fe423eebff2
 F test/fkey3.test 76d475c80b84ee7a5d062e56ccb6ea68882e2b49
 F test/fkey4.test 86446017011273aad8f9a99c1a65019e7bd9ca9d
@@ -1034,7 +1034,7 @@ F test/trigger8.test 30cb0530bd7c4728055420e3f739aa00412eafa4
 F test/trigger9.test 5b0789f1c5c4600961f8e68511b825b87be53e31
 F test/triggerA.test fe5597f47ee21bacb4936dc827994ed94161e332
 F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe
-F test/triggerC.test a68980c5955d62ee24be6f97129d824f199f9a4c
+F test/triggerC.test 302d8995f5ffe63bbc15053abb3ef7a39cf5a092
 F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650
 F test/triggerE.test 355e9c5cbaed5cd039a60baad1fb2197caeb8e52
 F test/tt3_checkpoint.c 415eccce672d681b297485fc20f44cdf0eac93af
@@ -1186,8 +1186,9 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 7f3943fb01490180055312363cdd8a47642f4e9d
-Q +718d5d0eab045a874107e078a857226a80ab912d
-R 674066d8a74c7196d2f6ff9302d84144
+P 3cd2b7722186ad2b2a581b7f7e7782c59536e523
+Q +59e92bd9521f1e8315a9a7e7fd3d63b0c75eaf0e
+Q +9d887b92f8086961e045f8acb9ee7a443796d411
+R 0c68a1a4983e75713540bb859d2c365a
 U dan
-Z 8b40aaadaed2e2b26011aeadc2d4c018
+Z c00eee9d808bc1be37169bb3151d8ab7
index f1d562777244cf2d051bdb6f3d95155739cdaa5c..c248e90d7376ba9b681edf00b7a7a6ed6e4ffdc3 100644 (file)
@@ -1 +1 @@
-3cd2b7722186ad2b2a581b7f7e7782c59536e523
\ No newline at end of file
+bd357739d74bfc97064e515645bce0834e586649
\ No newline at end of file
index 50c10da822b2ae9fa425f44c34003fba75a3fb2b..fa17a595e1cc151da8281693fc949c5567582224 100644 (file)
@@ -1158,10 +1158,10 @@ static Trigger *fkActionTrigger(
       ** parent table are used for the comparison. */
       pEq = sqlite3PExpr(pParse, TK_EQ,
           sqlite3PExpr(pParse, TK_DOT, 
-            sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
-            sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
+            sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
+            sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
           , 0),
-          sqlite3PExpr(pParse, TK_ID, 0, 0, &tFromCol)
+          sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
       , 0);
       pWhere = sqlite3ExprAnd(db, pWhere, pEq);
 
@@ -1173,12 +1173,12 @@ static Trigger *fkActionTrigger(
       if( pChanges ){
         pEq = sqlite3PExpr(pParse, TK_IS,
             sqlite3PExpr(pParse, TK_DOT, 
-              sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
-              sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
+              sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
+              sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
               0),
             sqlite3PExpr(pParse, TK_DOT, 
-              sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
-              sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
+              sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
+              sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
               0),
             0);
         pWhen = sqlite3ExprAnd(db, pWhen, pEq);
@@ -1188,8 +1188,8 @@ static Trigger *fkActionTrigger(
         Expr *pNew;
         if( action==OE_Cascade ){
           pNew = sqlite3PExpr(pParse, TK_DOT, 
-            sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
-            sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
+            sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
+            sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
           , 0);
         }else if( action==OE_SetDflt ){
           Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
@@ -1236,13 +1236,12 @@ static Trigger *fkActionTrigger(
     pTrigger = (Trigger *)sqlite3DbMallocZero(db, 
         sizeof(Trigger) +         /* struct Trigger */
         sizeof(TriggerStep) +     /* Single step in trigger program */
-        nFrom + 1                 /* Space for pStep->target.z */
+        nFrom + 1                 /* Space for pStep->zTarget */
     );
     if( pTrigger ){
       pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1];
-      pStep->target.z = (char *)&pStep[1];
-      pStep->target.n = nFrom;
-      memcpy((char *)pStep->target.z, zFrom, nFrom);
+      pStep->zTarget = (char *)&pStep[1];
+      memcpy((char *)pStep->zTarget, zFrom, nFrom);
   
       pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
       pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE);
index 400aa492875f3fe1a15f7b0c8fa9020a6d8855d1..1b41482d8ce6a8e28614d76f850ab9cb79a3f064 100644 (file)
@@ -2621,7 +2621,7 @@ struct Trigger {
  * orconf    -> stores the ON CONFLICT algorithm
  * pSelect   -> If this is an INSERT INTO ... SELECT ... statement, then
  *              this stores a pointer to the SELECT statement. Otherwise NULL.
- * target    -> A token holding the quoted name of the table to insert into.
+ * zTarget   -> Dequoted name of the table to insert into.
  * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
  *              this stores values to be inserted. Otherwise NULL.
  * pIdList   -> If this is an INSERT INTO ... (<column-names>) VALUES ... 
@@ -2629,12 +2629,12 @@ struct Trigger {
  *              inserted into.
  *
  * (op == TK_DELETE)
- * target    -> A token holding the quoted name of the table to delete from.
+ * zTarget   -> Dequoted name of the table to delete from.
  * pWhere    -> The WHERE clause of the DELETE statement if one is specified.
  *              Otherwise NULL.
  * 
  * (op == TK_UPDATE)
- * target    -> A token holding the quoted name of the table to update rows of.
+ * zTarget   -> Dequoted name of the table to update.
  * pWhere    -> The WHERE clause of the UPDATE statement if one is specified.
  *              Otherwise NULL.
  * pExprList -> A list of the columns to update and the expressions to update
@@ -2646,8 +2646,8 @@ struct TriggerStep {
   u8 op;               /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
   u8 orconf;           /* OE_Rollback etc. */
   Trigger *pTrig;      /* The trigger that this step is a part of */
-  Select *pSelect;     /* SELECT statment or RHS of INSERT INTO .. SELECT ... */
-  Token target;        /* Target table for DELETE, UPDATE, INSERT */
+  Select *pSelect;     /* SELECT statement or RHS of INSERT INTO SELECT ... */
+  char *zTarget;       /* Target table for DELETE, UPDATE, INSERT */
   Expr *pWhere;        /* The WHERE clause for DELETE or UPDATE steps */
   ExprList *pExprList; /* SET clause for UPDATE. */
   IdList *pIdList;     /* Column names for INSERT */
index 01f7b21f74e7c7f0e19a9b3f55407fe94367100c..a7259d310623729ae4bbe22aff73c22591523a78 100644 (file)
@@ -375,12 +375,12 @@ static TriggerStep *triggerStepAllocate(
 ){
   TriggerStep *pTriggerStep;
 
-  pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n);
+  pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
   if( pTriggerStep ){
     char *z = (char*)&pTriggerStep[1];
     memcpy(z, pName->z, pName->n);
-    pTriggerStep->target.z = z;
-    pTriggerStep->target.n = pName->n;
+    sqlite3Dequote(z);
+    pTriggerStep->zTarget = z;
     pTriggerStep->op = op;
   }
   return pTriggerStep;
@@ -666,7 +666,7 @@ Trigger *sqlite3TriggersExist(
 }
 
 /*
-** Convert the pStep->target token into a SrcList and return a pointer
+** Convert the pStep->zTarget string into a SrcList and return a pointer
 ** to that SrcList.
 **
 ** This routine adds a specific database name, if needed, to the target when
@@ -679,17 +679,17 @@ static SrcList *targetSrcList(
   Parse *pParse,       /* The parsing context */
   TriggerStep *pStep   /* The trigger containing the target token */
 ){
+  sqlite3 *db = pParse->db;
   int iDb;             /* Index of the database to use */
   SrcList *pSrc;       /* SrcList to be returned */
 
-  pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0);
+  pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
   if( pSrc ){
     assert( pSrc->nSrc>0 );
-    assert( pSrc->a!=0 );
-    iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
+    pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget);
+    iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema);
     if( iDb==0 || iDb>=2 ){
-      sqlite3 *db = pParse->db;
-      assert( iDb<pParse->db->nDb );
+      assert( iDb<db->nDb );
       pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
     }
   }
index 90a4c44409ed94d68188651efe3eabeedc7ce3eb..0bd4939eb5621568b75c44b3f3a755b033e0ec5e 100644 (file)
@@ -121,4 +121,34 @@ do_test fkey1-3.5 {
   sqlite3_db_status db DBSTATUS_DEFERRED_FKS 0
 } {0 0 0}
 
+# Stress the dequoting logic.  The first test is not so bad.
+do_execsql_test fkey1-4.0 {
+  PRAGMA foreign_keys=ON;
+  CREATE TABLE "xx1"("xx2" TEXT PRIMARY KEY, "xx3" TEXT);
+  INSERT INTO "xx1"("xx2","xx3") VALUES('abc','def');
+  CREATE TABLE "xx4"("xx5" TEXT REFERENCES "xx1" ON DELETE CASCADE);
+  INSERT INTO "xx4"("xx5") VALUES('abc');
+  INSERT INTO "xx1"("xx2","xx3") VALUES('uvw','xyz');
+  SELECT 1, "xx5" FROM "xx4";
+  DELETE FROM "xx1";
+  SELECT 2, "xx5" FROM "xx4";
+} {1 abc}
+
+# This case is identical to the previous except the "xx" in each name
+# is changed to a single escaped double-quote character.
+do_execsql_test fkey1-4.1 {
+  PRAGMA foreign_keys=ON;
+  CREATE TABLE """1"("""2" TEXT PRIMARY KEY, """3" TEXT);
+  INSERT INTO """1"("""2","""3") VALUES('abc','def');
+  CREATE TABLE """4"("""5" TEXT REFERENCES """1" ON DELETE CASCADE);
+  INSERT INTO """4"("""5") VALUES('abc');
+  INSERT INTO """1"("""2","""3") VALUES('uvw','xyz');
+  SELECT 1, """5" FROM """4";
+  DELETE FROM """1";
+  SELECT 2, """5" FROM """4";
+} {1 abc}
+do_execsql_test fkey1-4.2 {
+  PRAGMA table_info="""1";
+} {0 {"2} TEXT 0 {} 1 1 {"3} TEXT 0 {} 0}
+
 finish_test
index 14cc0f01dd7e61f81163e2ff4accf7190bb053d0..3e47521fd11c71ddbf63b7507addedea33082da8 100644 (file)
@@ -12,6 +12,7 @@
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
+set testprefix triggerC
 ifcapable {!trigger} {
   finish_test
   return
@@ -993,4 +994,52 @@ reset_db
 optimization_control db factor-constants 0
 do_execsql_test triggerC-14.2 $SQL {1 2 3}
 
+#-------------------------------------------------------------------------
+# Check that table names used by trigger programs are dequoted exactly
+# once.
+#
+do_execsql_test 15.1.1 {
+  PRAGMA recursive_triggers = 1;
+  CREATE TABLE node(
+      id int not null primary key, 
+      pid int not null default 0 references node,
+      key varchar not null, 
+      path varchar default '',
+      unique(pid, key)
+      );
+  CREATE TRIGGER node_delete_referencing AFTER DELETE ON "node"
+    BEGIN
+    DELETE FROM "node" WHERE pid = old."id";
+  END;
+}
+do_execsql_test 15.1.2 {
+  INSERT INTO node(id, pid, key) VALUES(9, 0, 'test');
+  INSERT INTO node(id, pid, key) VALUES(90, 9, 'test1');
+  INSERT INTO node(id, pid, key) VALUES(900, 90, 'test2');
+  DELETE FROM node WHERE id=9;
+  SELECT * FROM node;
+}
+
+do_execsql_test 15.2.1 {
+  CREATE TABLE   x1  (x);
+
+  CREATE TABLE   x2  (a, b);
+  CREATE TABLE '"x2"'(a, b);
+
+  INSERT INTO x2 VALUES(1, 2);
+  INSERT INTO x2 VALUES(3, 4);
+  INSERT INTO '"x2"' SELECT * FROM x2;
+
+  CREATE TRIGGER x1ai AFTER INSERT ON x1 BEGIN
+    INSERT INTO """x2""" VALUES('x', 'y');
+    DELETE FROM """x2""" WHERE a=1;
+    UPDATE """x2""" SET b = 11 WHERE a = 3;
+  END;
+
+  INSERT INTO x1 VALUES('go!');
+}
+
+do_execsql_test 15.2.2 { SELECT * FROM x2;       } {1 2 3 4}
+do_execsql_test 15.2.3 { SELECT * FROM """x2"""; } {3 11 x y}
+
 finish_test