]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the SQLITE_PREPARE_FROM_DDL flag to sqlite3_prepare_v3(). Use this to prevent...
authordan <Dan Kennedy>
Mon, 22 Dec 2025 15:22:02 +0000 (15:22 +0000)
committerdan <Dan Kennedy>
Mon, 22 Dec 2025 15:22:02 +0000 (15:22 +0000)
FossilOrigin-Name: 26f39ac806a5582fab1497e38a4ce68dad2b79df8c8aade43c4e21eed7576931

12 files changed:
ext/fts3/fts3.c
ext/fts3/fts3Int.h
ext/fts3/fts3_write.c
manifest
manifest.uuid
src/delete.c
src/expr.c
src/select.c
src/sqlite.h.in
src/vdbe.h
test/fts3comp1.test
test/fts4content.test

index f178abafed974f683b2666be4ed9d2f82c05db7d..368e9b189ae511687f97ada12b54832f5e5a22a2 100644 (file)
@@ -1816,9 +1816,7 @@ static int fts3CursorSeekStmt(Fts3Cursor *pCsr){
       zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
       if( !zSql ) return SQLITE_NOMEM;
       p->bLock++;
-      rc = sqlite3_prepare_v3(
-          p->db, zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0
-      );
+      rc = sqlite3Fts3PrepareStmt(p, zSql, 1, 1, &pCsr->pStmt);
       p->bLock--;
       sqlite3_free(zSql);
     }
@@ -3393,9 +3391,7 @@ static int fts3FilterMethod(
     }
     if( zSql ){
       p->bLock++;
-      rc = sqlite3_prepare_v3(
-          p->db,zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0
-      );
+      rc = sqlite3Fts3PrepareStmt(p, zSql, 1, 1, &pCsr->pStmt);
       p->bLock--;
       sqlite3_free(zSql);
     }else{
@@ -4018,6 +4014,7 @@ static int fts3IntegrityMethod(
 
   UNUSED_PARAMETER(isQuick);
   rc = sqlite3Fts3IntegrityCheck(p, &bOk);
+  assert( pVtab->zErrMsg==0 || rc!=SQLITE_OK );
   assert( rc!=SQLITE_CORRUPT_VTAB );
   if( rc==SQLITE_ERROR || (rc&0xFF)==SQLITE_CORRUPT ){
     *pzErr = sqlite3_mprintf("unable to validate the inverted index for"
index e98b90a7534af1518faaf6815ebe9da079cd141d..556635defa904e597c34fe8040822065e298e28f 100644 (file)
@@ -601,6 +601,15 @@ int sqlite3Fts3Incrmerge(Fts3Table*,int,int);
   (*(u8*)(p)&0x80) ? sqlite3Fts3GetVarint32(p, piVal) : (*piVal=*(u8*)(p), 1) \
 )
 
+int sqlite3Fts3PrepareStmt(
+  Fts3Table *p,                   /* Prepare for this connection */
+  const char *zSql,               /* SQL to prepare */
+  int bPersist,                   /* True to set SQLITE_PREPARE_PERSISTENT */
+  int bAllowVtab,                 /* True to omit SQLITE_PREPARE_NO_VTAB */
+  sqlite3_stmt **pp               /* OUT: Prepared statement */
+);
+
+
 /* fts3.c */
 void sqlite3Fts3ErrMsg(char**,const char*,...);
 int sqlite3Fts3PutVarint(char *, sqlite3_int64);
index d9074d37ab05fb253ade0540f0006fd11b6c2e12..1b8bca70f2f06c6372662572d1f937748f5c2ba3 100644 (file)
@@ -273,6 +273,24 @@ struct SegmentNode {
 #define SQL_UPDATE_LEVEL_IDX          38
 #define SQL_UPDATE_LEVEL              39
 
+/*
+** Wrapper around sqlite3_prepare_v3() to ensure that SQLITE_PREPARE_FROM_DDL
+** is always set.
+*/
+int sqlite3Fts3PrepareStmt(
+  Fts3Table *p,                   /* Prepare for this connection */
+  const char *zSql,               /* SQL to prepare */
+  int bPersist,                   /* True to set SQLITE_PREPARE_PERSISTENT */
+  int bAllowVtab,                 /* True to omit SQLITE_PREPARE_NO_VTAB */
+  sqlite3_stmt **pp               /* OUT: Prepared statement */
+){
+  int f = SQLITE_PREPARE_FROM_DDL
+         |((bAllowVtab==0) ? SQLITE_PREPARE_NO_VTAB : 0)
+         |(bPersist ? SQLITE_PREPARE_PERSISTENT : 0);
+
+  return sqlite3_prepare_v3(p->db, zSql, -1, f, pp, NULL);
+}
+
 /*
 ** This function is used to obtain an SQLite prepared statement handle
 ** for the statement identified by the second argument. If successful,
@@ -398,12 +416,12 @@ static int fts3SqlStmt(
   
   pStmt = p->aStmt[eStmt];
   if( !pStmt ){
-    int f = SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB;
+    int bAllowVtab = 0;
     char *zSql;
     if( eStmt==SQL_CONTENT_INSERT ){
       zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist);
     }else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){
-      f &= ~SQLITE_PREPARE_NO_VTAB;
+      bAllowVtab = 1;
       zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist);
     }else{
       zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName);
@@ -411,7 +429,7 @@ static int fts3SqlStmt(
     if( !zSql ){
       rc = SQLITE_NOMEM;
     }else{
-      rc = sqlite3_prepare_v3(p->db, zSql, -1, f, &pStmt, NULL);
+      rc = sqlite3Fts3PrepareStmt(p, zSql, 1, bAllowVtab, &pStmt);
       sqlite3_free(zSql);
       assert( rc==SQLITE_OK || pStmt==0 );
       p->aStmt[eStmt] = pStmt;
@@ -3578,7 +3596,7 @@ static int fts3DoRebuild(Fts3Table *p){
     if( !zSql ){
       rc = SQLITE_NOMEM;
     }else{
-      rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
+      rc = sqlite3Fts3PrepareStmt(p, zSql, 0, 1, &pStmt);
       sqlite3_free(zSql);
     }
 
@@ -5331,7 +5349,7 @@ int sqlite3Fts3IntegrityCheck(Fts3Table *p, int *pbOk){
     if( !zSql ){
       rc = SQLITE_NOMEM;
     }else{
-      rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
+      rc = sqlite3Fts3PrepareStmt(p, zSql, 0, 1, &pStmt);
       sqlite3_free(zSql);
     }
 
index 86f203311a2e17f43dab2390a561e0178e517323..43c3df6b92d78eaed9f8fdb957656dff8d66952f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sspurious\serror\slog\sreports\scaused\sby\s[d25c8a6222d4e3f2].\s\sSee\n[forum:/forumpost/d2326687662430c1|forum\spost\sd2326687662].
-D 2025-12-22T12:33:27.145
+C Add\sthe\sSQLITE_PREPARE_FROM_DDL\sflag\sto\ssqlite3_prepare_v3().\sUse\sthis\sto\sprevent\sfts3/4\stables\sin\snon-trusted\sschemas\sfrom\scalling\sunsafe\sSQL\sfunctions.
+D 2025-12-22T15:22:02.051
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -79,9 +79,9 @@ F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c
 F ext/fts3/README.syntax b72477722e9b4fe43f8403227d790a1c94221bfad15c27863a4b36d1052e892b
 F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d
 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
-F ext/fts3/fts3.c 4f02858ab845a97bedf06e6cc1fba49a81fe5e00a26df68d0ad0f00a5814fa70
+F ext/fts3/fts3.c 6cc7bbc307f27e7b6ee2e1d5ff63ffff4df3b42529dfe00eb34ddded417961b3
 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
-F ext/fts3/fts3Int.h ed9b8bc5ed5be402069651e49d4855cb849af706cf3fe68548f58a2c21eefc7f
+F ext/fts3/fts3Int.h fd6051f7aa4db93e05fdc703ef35faf79f78170419e809139109d7aef28f4170
 F ext/fts3/fts3_aux.c 7eab82a9cf0830f6551ba3abfdbe73ed39e322a4d3940ee82fbf723674ecd9f3
 F ext/fts3/fts3_expr.c 5c13796638d8192c388777166075cdc8bc4b6712024cd5b72c31acdbefce5984
 F ext/fts3/fts3_hash.c d9dba473741445789330c7513d4f65737c92df23c3212784312931641814672a
@@ -97,7 +97,7 @@ F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
 F ext/fts3/fts3_tokenizer1.c c1de4ae28356ad98ccb8b2e3388a7fdcce7607b5523738c9afb6275dab765154
 F ext/fts3/fts3_unicode.c de426ff05c1c2e7bce161cf6b706638419c3a1d9c2667de9cb9dc0458c18e226
 F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f
-F ext/fts3/fts3_write.c 3a412c62e39c72283e34a51ec60c59eee6d684882fea7156b09a9733bd1f10e8
+F ext/fts3/fts3_write.c d218b687fb55bce8c9340c6dbb368a10d94647cbe39801d85492d576a4e7da75
 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
 F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73
 F ext/fts3/tool/fts3view.c 413c346399159df81f86c4928b7c4a455caab73bfbc8cd68f950f632e5751674
@@ -686,8 +686,8 @@ F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 F src/date.c e19e0cfff9a41bfdd884c655755f6f00bca4c1a22272b56e0dd6667b7ea893a2
 F src/dbpage.c c9ea81c11727f27e02874611e92773e68e2a90a875ef2404b084564c235fd91f
 F src/dbstat.c 73362c0df0f40ad5523a6f5501224959d0976757b511299bf892313e79d14f5c
-F src/delete.c 03a77ba20e54f0f42ebd8eddf15411ed6bdb06a2c472ac4b6b336521bf7cea42
-F src/expr.c b4530f3e23d8ea38c7de4c7b55af52d43156c79128c042a580e670776f59a9bc
+F src/delete.c e020dde34838369e2f0eff75f25c44a4e56a41262593f7c48d1223689d674e4d
+F src/expr.c 252e62742f5bb01517377c93057b6040ab954034ec3dde4d6fc583565d859a9c
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c c065da737307a29e4d240ac727758dbf4102cb3218a1f651eb689b6a6fa12531
 F src/func.c 0b802107498048d3dcac0b757720bcb8506507ce02159e213ab8161458eb293b
@@ -736,9 +736,9 @@ F src/printf.c b1b29b5e58e1530d5daeee5963d3c318d8ab2d7e38437580e28755753e0c1ded
 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c
 F src/resolve.c 47aa7fdc9ec4c19b103ac5e79d7887d30119b5675309facf5eed1118391c868b
 F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97
-F src/select.c 9d55dc7bfea75b7aec14e819b9f65ca97472cea301ac5115d45ad435a63f7350
+F src/select.c 85852256d860f3ba5be4a9edc1238e68dbea082a0167f31b7345c821ae45775d
 F src/shell.c.in c4b775c664c339ac0351549a998b5f8816bf2496af5385e3937050c1fb5688fe
-F src/sqlite.h.in b7d0e99d1384e73882f3157d86e0cd886d0c510d8db2b288b1d17631d6f26089
+F src/sqlite.h.in ecdd8ee84fe9e30d51433a4cc7951bb0423f588943f5d6f32c6c6ea779662f90
 F src/sqlite3.rc 015537e6ac1eec6c7050e17b616c2ffe6f70fca241835a84a4f0d5937383c479
 F src/sqlite3ext.h 5d5330f5f8461f5ce74960436ddcfa53ecd09c2b8b23901e22ae38aec3243998
 F src/sqliteInt.h af67bc95fa6b66cd3c7f3d18d2d040ad386e4cbb02965ee318cc721ee9d5fa45
@@ -804,7 +804,7 @@ F src/utf.c 7267c3fb9e2467020507601af3354c2446c61f444387e094c779dccd5ca62165
 F src/util.c 36fb1150062957280777655976f3f9a75db236cb8207a0770ceae8d5ec17fcd3
 F src/vacuum.c 1bacdd0a81d2b5dc1c508fbf0d938c89fa78dd8d5b46ec92686d44030d4f4789
 F src/vdbe.c b44c366e83412d3b8c190feb1f029b7d02e1bd69252a57b32f195107f0d03964
-F src/vdbe.h be33bd7b17f2ec92939642416030491508c51071f6c14e27cd195983fec56b63
+F src/vdbe.h 966d0677a540b7ea6549b7c4e1312fc0d830fce3a235a58c801f2cc31cf5ecf9
 F src/vdbeInt.h 2aaeb6df2938b181b4700a9328688a3986f2bba71e8b96f6a80671316618fa49
 F src/vdbeapi.c 6a2181cfd27c86b4cc1d8abb27ae11f3b3f0357567814fa276ec37b043542938
 F src/vdbeaux.c 908d8a191aed444b2e4c920159249127f3ff67b94c56a16fad1dfdf9c7488f20
@@ -1153,7 +1153,7 @@ F test/fts3aux1.test 1880eaa75c586cd10f53080479a2b819b3915ae7ce55c4e0ba8f1fe05ac
 F test/fts3aux2.test 2459e7fa3e22734aed237d1e2ae192f5541c4d8b218956ad2d90754977bf907f
 F test/fts3b.test c15c4a9d04e210d0be67e54ce6a87b927168fbf9c1e3faec8c1a732c366fd491
 F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958
-F test/fts3comp1.test a0f5b16a2df44dd0b15751787130af2183167c0c
+F test/fts3comp1.test f1b05ece56481f3973ece6a968cbabeeb0866c43f5375318313c003518ac53fb
 F test/fts3conf.test c9cd45433b6787d48a43e84949aa2eb8b3b3d242bac7276731c1476290d31f29
 F test/fts3corrupt.test 6732477c5ace050c5758a40a8b5706c8c0cccd416b9c558e0e15224805a40e57
 F test/fts3corrupt2.test e318f0676e5e78d5a4b702637e2bb25265954c08a1b1e4aaf93c7880bb0c67d0
@@ -1203,7 +1203,7 @@ F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d
 F test/fts3varint.test 0b84a3fd4eba8a39f3687523804d18f3b322e6d4539a55bf342079c3614f2ada
 F test/fts4aa.test 0e6bfd6a81695a39b23e448dda25d864e63dda75bde6949c45ddc95426c6c3f5
 F test/fts4check.test f0ea5e5581951d8ef7a341eea14486daf6c5f516a2f3273b0d5e8cb8a6cd3bd2
-F test/fts4content.test 73bbb123420d2c46ef2fb3b24761e9acdb78b0877179d3a5d7d57aada08066f6
+F test/fts4content.test 7f441866207f5b1e76e0f18bde5d9925d1ee8f60388054613dd14a29a79f0bc4
 F test/fts4docid.test e33c383cfbdff0284685604d256f347a18fdbf01
 F test/fts4growth.test 289833c34ad45a5e6e6133b53b6a71647231fb89d36ddcb8d9c87211b6721d7f
 F test/fts4growth2.test 13ad4e76451af6e6906c95cdc725d01b00044269
@@ -2187,8 +2187,8 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P f43d3339c1f06aabcb8e678ed4b91a490cfd0bc880c642ce9c1138c7e08cb360
-R 368416e9322dccc113e01f13b887d649
-U drh
-Z 991a818d717546a1f42472b805bde58a
+P 403dafc7790a2e8d1772537800760addc47d3e3555bda343c3991d56c1b36e70
+R 7581ed8e32b81aa2384ce190ebdf96b2
+U dan
+Z 1915d46eae49cba5052e06a07b4e8b93
 # Remove this line to create a well-formed Fossil manifest.
index baaa5c4372dc1aea361f4ef6f3ea331b9de39b2c..81b7170f2f44cbde7cb71cb604c66a5c7c91bf68 100644 (file)
@@ -1 +1 @@
-403dafc7790a2e8d1772537800760addc47d3e3555bda343c3991d56c1b36e70
+26f39ac806a5582fab1497e38a4ce68dad2b79df8c8aade43c4e21eed7576931
index 8fac7c2f329dab82b4d3318c34df48bd0aebe032..19fd5b2cda69ae399353205df117d1721e193b1e 100644 (file)
@@ -86,7 +86,7 @@ static int vtabIsReadOnly(Parse *pParse, Table *pTab){
   **   *  Only allow DELETE, INSERT, or UPDATE of non-SQLITE_VTAB_INNOCUOUS
   **      virtual tables if PRAGMA trusted_schema=ON.
   */
-  if( pParse->pToplevel!=0
+  if( (pParse->pToplevel!=0 || (pParse->prepFlags & SQLITE_PREPARE_FROM_DDL))
    && pTab->u.vtab.p->eVtabRisk >
            ((pParse->db->flags & SQLITE_TrustedSchema)!=0)
   ){
index 3eea5439eebe8d4be0668f56e318592db7c4132d..198467deaca72248ecce2b665040e4193e0db7b9 100644 (file)
@@ -1280,7 +1280,9 @@ void sqlite3ExprFunctionUsable(
 ){
   assert( !IN_RENAME_OBJECT );
   assert( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 );
-  if( ExprHasProperty(pExpr, EP_FromDDL) ){
+  if( ExprHasProperty(pExpr, EP_FromDDL) 
+   || pParse->prepFlags & SQLITE_PREPARE_FROM_DDL
+  ){
     if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0
      || (pParse->db->flags & SQLITE_TrustedSchema)==0
     ){
index 7a5f8c65d739d487ceeb843a62cc3acba07690c1..662b01a12fe5a06b97e68279731bcfedc1c48a56 100644 (file)
@@ -6181,7 +6181,7 @@ static int selectExpander(Walker *pWalker, Select *p){
         }
 #ifndef SQLITE_OMIT_VIRTUALTABLE
         else if( ALWAYS(IsVirtual(pTab))
-         && pFrom->fg.fromDDL
+         && (pFrom->fg.fromDDL || (pParse->prepFlags & SQLITE_PREPARE_FROM_DDL))
          && ALWAYS(pTab->u.vtab.p!=0)
          && pTab->u.vtab.p->eVtabRisk > ((db->flags & SQLITE_TrustedSchema)!=0)
         ){
index 8d50c206068b9c82fda307b75dd46ad2c1a5bbf0..154fddcd56297037c4bdd64761d790c10d83bfbf 100644 (file)
@@ -4433,12 +4433,20 @@ int sqlite3_limit(sqlite3*, int id, int newVal);
 ** fails, the sqlite3_prepare_v3() call returns the same error indications
 ** with or without this flag; it just omits the call to [sqlite3_log()] that
 ** logs the error.
+**
+** [[SQLITE_PREPARE_FROM_DDL]] <dt>SQLITE_PREPARE_FROM_DDL</dt>
+** <dd>The SQLITE_PREPARE_FROM_DDL causes the SQL compiler to behave as if
+** the SQL statement was part of a database schema. This only makes a
+** difference if the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is set to off.
+** This flag may be used by virtual table implementations that do not
+** completely control the SQL commands that they evaluate.
 ** </dl>
 */
 #define SQLITE_PREPARE_PERSISTENT              0x01
 #define SQLITE_PREPARE_NORMALIZE               0x02
 #define SQLITE_PREPARE_NO_VTAB                 0x04
 #define SQLITE_PREPARE_DONT_LOG                0x10
+#define SQLITE_PREPARE_FROM_DDL                0x20
 
 /*
 ** CAPI3REF: Compiling An SQL Statement
index 28df764bc64d2c7de1616b09998ee82c6d73b37e..a2905eae4d382657bb3a9da1182f0ed080385593 100644 (file)
@@ -186,7 +186,7 @@ typedef struct VdbeOpList VdbeOpList;
 ** Additional non-public SQLITE_PREPARE_* flags
 */
 #define SQLITE_PREPARE_SAVESQL  0x80  /* Preserve SQL text */
-#define SQLITE_PREPARE_MASK     0x1f  /* Mask of public flags */
+#define SQLITE_PREPARE_MASK     0x3f  /* Mask of public flags */
 
 /*
 ** Prototypes for the VDBE interface.  See comments on the implementation
index 9f13aaa64ea59748dcad5ecd26c736ffda1be442..63f0e1f556677639da1edbc90637245d0cc95c86 100644 (file)
@@ -112,4 +112,51 @@ do_catchsql_test 2.2 {
   CREATE VIRTUAL TABLE t2 USING fts4(x, uncompress=unzip)
 } {1 {missing compress parameter in fts4 constructor}}
 
+#--------------------------------------------------------------------------
+reset_db
+do_execsql_test 3.0 {
+  PRAGMA trusted_schema = OFF;
+}
+
+set ::myfunc_invoked 0
+proc myfunc {data} {
+  incr ::myfunc_invoked
+  return $data
+}
+db func myfunc myfunc
+
+do_execsql_test 3.1 {
+  CREATE VIEW v1 AS SELECT myfunc('xyz');
+}
+
+do_catchsql_test 3.2 {
+  SELECT * FROM v1
+} {1 {unsafe use of myfunc()}}
+
+do_execsql_test 3.3 {
+  CREATE VIRTUAL TABLE f1 USING fts4(x, compress=myfunc, uncompress=myfunc);
+}
+
+do_catchsql_test 3.4 {
+  INSERT INTO f1(rowid, x) VALUES(123, 'one two three');
+} {1 {SQL logic error}}
+
+do_test 3.5 {
+  set ::myfunc_invoked
+} {0}
+
+do_execsql_test 3.6.1 {
+  CREATE TABLE t1(x);
+  CREATE TABLE t2(y);
+
+  CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
+    INSERT INTO t2 VALUES( myfunc(new.x) );
+  END;
+}
+
+do_catchsql_test 3.6.2 {
+  INSERT INTO t1 VALUES('hello world');
+} {1 {unsafe use of myfunc()}}
+  
+
 finish_test
index 980586ea3aa864464c49b2d3db8771fac4a7cef5..8268e734a86c6d5d28d01693738db213b4ea4ea8 100644 (file)
@@ -638,7 +638,6 @@ do_catchsql_test 11.1 {
 # Check that an fts4 table cannot be its own content table.
 #
 reset_db
-breakpoint
 do_execsql_test 12.1.1 {
   CREATE VIRTUAL TABLE t1 USING fts4(a, content=t1 );
   INSERT INTO t1(rowid, a) VALUES(1, 'abc');
@@ -669,6 +668,64 @@ do_catchsql_test 12.2.4 {
   SELECT count(*) FROM t1;
 } {1 {SQL logic error}}
 
+#---------------------------------------------------------------------------
+# Check that an fts4 table cannot read from an unsafe vtab in a non-trusted 
+# schema.
+reset_db
+do_execsql_test 13.0 {
+  PRAGMA trusted_schema = off;
+  CREATE VIRTUAL TABLE t1 USING fts4(data, content=sqlite_dbpage);
+}
+
+do_catchsql_test 13.1 {
+  INSERT INTO t1(t1) VALUES('rebuild');
+} {1 {SQL logic error}}
+
+proc vtab_command {method args} {
+  switch -- $method {
+    xConnect {
+      return "CREATE TABLE t1(a)"
+    }
+
+    xBestIndex {
+      return ""
+    }
+
+    xFilter {
+      return [list sql {SELECT 1, 123}]
+    }
+
+    xUpdate {
+      return 123
+    }
+  }
+
+  return {}
+}
+
+register_tcl_module db xyz
+
+do_execsql_test 13.2.0 {
+  CREATE VIRTUAL TABLE aa USING tcl(vtab_command);
+}
+
+do_execsql_test 13.2.1 {
+  INSERT INTO aa VALUES('one two three');
+}
+
+do_test 13.2.2 {
+  set ::stmt [sqlite3_prepare_v3 db \
+    "INSERT INTO aa VALUES('one two three');" -1 0x00
+  ]
+  sqlite3_finalize $::stmt
+} {SQLITE_OK}
 
+do_test 13.2.2 {
+  list [catch {
+    set ::stmt [sqlite3_prepare_v3 db \
+      "INSERT INTO aa VALUES('one two three');" -1 0x20
+    ]
+  } msg] $msg
+} {1 {(1) unsafe use of virtual table "aa"}}
 
 finish_test