]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Do not allow virtual table constructors to be called recursively. Cherrypick of ...
authordan <dan@noemail.net>
Wed, 20 May 2015 19:50:57 +0000 (19:50 +0000)
committerdan <dan@noemail.net>
Wed, 20 May 2015 19:50:57 +0000 (19:50 +0000)
FossilOrigin-Name: 023a29baf0de7e4d2e7a7b5bc184bbad6eb34b8d

ext/fts3/fts3.c
manifest
manifest.uuid
src/vtab.c
test/fts4content.test

index 4ea6bf327fb4acc1cb5ebeda51536bc24058c46e..afcd45f65934865d1b472490c68307e1d33263da 100644 (file)
@@ -1013,7 +1013,8 @@ static int fts3ContentColumns(
   const char *zTbl,               /* Name of content table */
   const char ***pazCol,           /* OUT: Malloc'd array of column names */
   int *pnCol,                     /* OUT: Size of array *pazCol */
-  int *pnStr                      /* OUT: Bytes of string content */
+  int *pnStr,                     /* OUT: Bytes of string content */
+  char **pzErr                    /* OUT: error message */
 ){
   int rc = SQLITE_OK;             /* Return code */
   char *zSql;                     /* "SELECT *" statement on zTbl */  
@@ -1024,6 +1025,9 @@ static int fts3ContentColumns(
     rc = SQLITE_NOMEM;
   }else{
     rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
+    if( rc!=SQLITE_OK ){
+      *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
+    }
   }
   sqlite3_free(zSql);
 
@@ -1275,7 +1279,7 @@ static int fts3InitVtab(
     if( nCol==0 ){
       sqlite3_free((void*)aCol); 
       aCol = 0;
-      rc = fts3ContentColumns(db, argv[1], zContent, &aCol, &nCol, &nString);
+      rc = fts3ContentColumns(db, argv[1], zContent,&aCol,&nCol,&nString,pzErr);
 
       /* If a languageid= option was specified, remove the language id
       ** column from the aCol[] array. */ 
index 2d4444eaca819795ee2894734450d26a4390cfd4..c74e75ed94a1edd7b83d552864402057fe1d2f48 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Avoid\ssigned\sinteger\soverflow\swhen\sconverting\soversized\sin-line\sinteger\s\nwidths\sand\sprecisions\sin\sprintf().\sCherrypick\sof\s[c494171f77dc],\s[5ce4e7d7651e],\s[95625ef3adc3]\sand\s[8e4ac2ce2441].
-D 2015-05-20T19:48:55.227
+C Do\snot\sallow\svirtual\stable\sconstructors\sto\sbe\scalled\srecursively.\sCherrypick\sof\s[0a72726da215]
+D 2015-05-20T19:50:57.913
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -78,7 +78,7 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
 F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
-F ext/fts3/fts3.c d41ed0df225b099b78fcecac1bf181a801002cfd
+F ext/fts3/fts3.c 31686f9b19c791f804f61a3a2efdf8c92108c3a1
 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
 F ext/fts3/fts3Int.h 53d4eca1fb23eab00681fb028fb82eb5705c1e21
 F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365
@@ -292,7 +292,7 @@ F src/vdbeblob.c 9205ce9d3b064d9600f8418a897fc88b5687d9ac
 F src/vdbemem.c d90a1e8acf8b63dc9d14cbbea12bfec6cec31394
 F src/vdbesort.c f7f5563bf7d4695ca8f3203f3bf9de96d04ed0b3
 F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767
-F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
+F src/vtab.c d2713ff716e99b30e899bf822d9e3faa2488e7ce
 F src/wal.c 264df50a1b33124130b23180ded2e2c5663c652a
 F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
 F src/walker.c 11edb74d587bc87b33ca96a5173e3ec1b8389e45
@@ -574,7 +574,7 @@ F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d
 F test/fts3varint.test 752c08ed5d32c5d7dc211b056f4ed68a76b7e36e
 F test/fts4aa.test 0c3152322c7f0b548cc942ad763eaba0da87ccca
 F test/fts4check.test 74d77f6cdb768ac49df5afda575cef14ae3d239a
-F test/fts4content.test 2e7252557d6d24afa101d9ba1de710d6140e6d06
+F test/fts4content.test abb0c77bc3da3df64fec72e00844d2257a90025d
 F test/fts4docid.test e33c383cfbdff0284685604d256f347a18fdbf01
 F test/fts4growth.test df10fde9f47cf5c71861e63fd8efcd573c4f7e53
 F test/fts4growth2.test 2f063be1902a73cd087355837c52fed42ac11a5d
@@ -1186,11 +1186,8 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P 4125477e63fd3a71dce262e0866d3e39cec765f1
-Q +5ce4e7d7651e5c72a59f03f7aeb366291e62ab57
-Q +8e4ac2ce24415926247961b00a62425ae85d6ffb
-Q +95625ef3adc3c408d67e70f877f390445fbb8292
-Q +c494171f77dc2e5e04cb6d865e688448f04e5920
-R 4b6e5530dadb627f38b2aa53dc82cd07
+P b330c7ff6fd1230cde2c246ba0f9d81f056ea61f
+Q +0a72726da21581ab16cb3e964bd825b8f2e931e4
+R 7854d9795f43d69006b5074f7b0af8e5
 U dan
-Z 46e842739206c835d8bd7b51ff043562
+Z 13ca4c0d3ce46f357af6c683f6dac961
index af10c4c2e6613da627b1eb256c20a26407d264f7..232f1b09ac648aa3b4fa9dd719be45b73b3bae7c 100644 (file)
@@ -1 +1 @@
-b330c7ff6fd1230cde2c246ba0f9d81f056ea61f
\ No newline at end of file
+023a29baf0de7e4d2e7a7b5bc184bbad6eb34b8d
\ No newline at end of file
index ca0db214cc5ce651aa09147f9d6381b52b0af4fd..f72f5deda9e1e5cf1d8408cb3392e7b71acffd88 100644 (file)
@@ -24,6 +24,8 @@
 struct VtabCtx {
   VTable *pVTable;    /* The virtual table being constructed */
   Table *pTab;        /* The Table object to which the virtual table belongs */
+  VtabCtx *pPrior;    /* Parent context (if any) */
+  int bDeclared;      /* True after sqlite3_declare_vtab() is called */
 };
 
 /*
@@ -474,15 +476,27 @@ static int vtabCallConstructor(
   int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
   char **pzErr
 ){
-  VtabCtx sCtx, *pPriorCtx;
+  VtabCtx sCtx;
   VTable *pVTable;
   int rc;
   const char *const*azArg = (const char *const*)pTab->azModuleArg;
   int nArg = pTab->nModuleArg;
   char *zErr = 0;
-  char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
+  char *zModuleName;
   int iDb;
+  VtabCtx *pCtx;
+
+  /* Check that the virtual-table is not already being initialized */
+  for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){
+    if( pCtx->pTab==pTab ){
+      *pzErr = sqlite3MPrintf(db, 
+          "vtable constructor called recursively: %s", pTab->zName
+      );
+      return SQLITE_LOCKED;
+    }
+  }
 
+  zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
   if( !zModuleName ){
     return SQLITE_NOMEM;
   }
@@ -503,11 +517,13 @@ static int vtabCallConstructor(
   assert( xConstruct );
   sCtx.pTab = pTab;
   sCtx.pVTable = pVTable;
-  pPriorCtx = db->pVtabCtx;
+  sCtx.pPrior = db->pVtabCtx;
+  sCtx.bDeclared = 0;
   db->pVtabCtx = &sCtx;
   rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
-  db->pVtabCtx = pPriorCtx;
+  db->pVtabCtx = sCtx.pPrior;
   if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
+  assert( sCtx.pTab==pTab );
 
   if( SQLITE_OK!=rc ){
     if( zErr==0 ){
@@ -522,7 +538,7 @@ static int vtabCallConstructor(
     ** the sqlite3_vtab object if successful.  */
     pVTable->pVtab->pModule = pMod->pModule;
     pVTable->nRef = 1;
-    if( sCtx.pTab ){
+    if( sCtx.bDeclared==0 ){
       const char *zFormat = "vtable constructor did not declare schema: %s";
       *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
       sqlite3VtabUnlock(pVTable);
@@ -692,18 +708,19 @@ int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
 ** virtual table module.
 */
 int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
+  VtabCtx *pCtx = db->pVtabCtx;
   Parse *pParse;
-
   int rc = SQLITE_OK;
   Table *pTab;
   char *zErr = 0;
 
   sqlite3_mutex_enter(db->mutex);
-  if( !db->pVtabCtx || !(pTab = db->pVtabCtx->pTab) ){
+  if( !pCtx || pCtx->bDeclared ){
     sqlite3Error(db, SQLITE_MISUSE, 0);
     sqlite3_mutex_leave(db->mutex);
     return SQLITE_MISUSE_BKPT;
   }
+  pTab = pCtx->pTab;
   assert( (pTab->tabFlags & TF_Virtual)!=0 );
 
   pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
@@ -726,7 +743,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
         pParse->pNewTable->nCol = 0;
         pParse->pNewTable->aCol = 0;
       }
-      db->pVtabCtx->pTab = 0;
+      pCtx->bDeclared = 1;
     }else{
       sqlite3Error(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
       sqlite3DbFree(db, zErr);
index 6b2cd3cc8ee3c40508fa30439e3c25d0c37af3b3..481c6ec0085681e390522b38c47641fc29d7e6f6 100644 (file)
@@ -48,6 +48,9 @@ ifcapable !fts3 {
 #
 #   9.* - Test using content=xxx where xxx is a virtual table.
 #
+#   11.* - Test that circular references (e.g. "t1(content=t1)") are
+#          detected.
+#
 
 do_execsql_test 1.1.1 {
   CREATE TABLE t1(a, b, c);
@@ -406,7 +409,7 @@ do_execsql_test 5.1.7 {
 # 
 do_catchsql_test 6.1.1 {
   CREATE VIRTUAL TABLE ft7 USING fts4(content=t7);
-} {1 {vtable constructor failed: ft7}}
+} {1 {no such table: main.t7}}
 
 do_execsql_test 6.2.1 {
   CREATE TABLE t7(one, two);
@@ -433,7 +436,7 @@ do_execsql_test 6.2.3 {
 }
 do_catchsql_test 6.2.4 {
   SELECT * FROM ft7;
-} {1 {vtable constructor failed: ft7}}
+} {1 {no such table: main.t7}}
 do_execsql_test 6.2.5 {
   CREATE TABLE t7(x, y);
   INSERT INTO t7 VALUES('A B', 'B A');
@@ -622,4 +625,15 @@ do_execsql_test 10.7 {
   {...c d [e] f g...}
 }
 
+#-------------------------------------------------------------------------
+# Test cases 11.*
+# 
+reset_db
+
+do_catchsql_test 11.1 {
+  CREATE VIRTUAL TABLE x1 USING fts4(content=x1);
+} {1 {vtable constructor called recursively: x1}}
+
+
 finish_test
+