diff options
-rw-r--r-- | manifest | 25 | ||||
-rw-r--r-- | manifest.uuid | 2 | ||||
-rw-r--r-- | src/auth.c | 8 | ||||
-rw-r--r-- | src/build.c | 19 | ||||
-rw-r--r-- | src/parse.y | 4 | ||||
-rw-r--r-- | src/sqlite.h.in | 5 | ||||
-rw-r--r-- | src/sqliteInt.h | 4 | ||||
-rw-r--r-- | src/tclsqlite.c | 4 | ||||
-rw-r--r-- | src/vtab.c | 32 | ||||
-rw-r--r-- | test/vtab3.test | 142 |
10 files changed, 205 insertions, 40 deletions
@@ -1,5 +1,5 @@ -C Arrange\sfor\ssqlite3_last_insert_rowid()\sto\swork\swith\svirtual\stables.\s(CVS\s3259) -D 2006-06-16T06:17:47 +C Add\ssome\stests\s(and\sfixes)\sfor\svirtual\stables\sand\sthe\sauthorization\scallback.\sStill\smore\sto\scome.\s(CVS\s3260) +D 2006-06-16T08:01:03 F Makefile.in f839b470345d3cb4b0644068474623fe2464b5d3 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -33,10 +33,10 @@ F sqlite3.pc.in 985b9bf34192a549d7d370e0f0b6b34a4f61369a F src/alter.c 451b34fc4eb2475ca76a2e86b21e1030a9428091 F src/analyze.c 7d2b7ab9a9c2fd6e55700f69064dfdd3e36d7a8a F src/attach.c 27a31d3b89d7ebb5b358847607b1ec795384123c -F src/auth.c 9ae84d2d94eb96195e04515715e08e85963e96c2 +F src/auth.c 902f4722661c796b97f007d9606bd7529c02597f F src/btree.c ed343b3dbcbc7da9ac481ef2b98c4239fe6d9629 F src/btree.h 40055cfc09defd1146bc5b922399c035f969e56d -F src/build.c a295396a6a5624604c729c3b895902c8b2b1dc5e +F src/build.c 28208a9049d7bf61f16fcb4bb850406857135953 F src/callback.c fd9bb39f7ff6b52bad8365617abc61c720640429 F src/complete.c 7d1a44be8f37de125fcafd3d3a018690b3799675 F src/date.c cd2bd5d1ebc6fa12d6312f69789ae5b0a2766f2e @@ -64,7 +64,7 @@ F src/os_win.c c6976ae50b61fb5b7dce399e578aa1865f02b84f F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b F src/pager.c 7ef4c5098b378d81d3687919d9de99ea99bbb6bb F src/pager.h 43f32f3847421f7502cfbb66f4eb2302b8033818 -F src/parse.y 14ce6fb228b5a06fd5c10999aed2cbbfafe630a7 +F src/parse.y e0831a269fbbd21414bb367fd0b806569c934683 F src/pragma.c 27d5e395c5d950931c7ac4fe610e7c2993e2fa55 F src/prepare.c 6dc945dab34cf97364c661d2b7a12be65d338267 F src/printf.c 7029e5f7344a478394a02c52837ff296ee1ab240 @@ -72,11 +72,11 @@ F src/random.c d40f8d356cecbd351ccfab6eaedd7ec1b54f5261 F src/select.c 38eda11d950ed5e631ea9054f84a4a8b9e9b39d8 F src/server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/shell.c ad73192b30a338a58fe81183d4a5d5a1d4e51d36 -F src/sqlite.h.in 2fc589cf9b550c5bb8b0bac6414389e2057940d1 +F src/sqlite.h.in 77b42d1bb5deafa04ae156d24cd243c2d75800ac F src/sqlite3ext.h fc8647211af0caa9d8e49ab31624b357c1332380 -F src/sqliteInt.h 5eb64f1dd9a8b237d147962bc57637d87e044ff4 +F src/sqliteInt.h 2eb48bd25f5fccce86d80e6872b045ed61b91687 F src/table.c f64ec4fbfe333f8df925bc6ba494f55e05b0e75e -F src/tclsqlite.c c03bf44bd9f629d4c8d6545788c647b2e846b523 +F src/tclsqlite.c c408a49ae44525fc69757b4ed39f6ca0f56549a5 F src/test1.c 40f20775903bc76d3be3e7c026dddcbc221c1cb0 F src/test2.c ca74a1d8aeb7d9606e8f6b762c5daf85c1a3f92b F src/test3.c 86e99724ee898b119ed575ef9f98618afe7e5e5d @@ -104,7 +104,7 @@ F src/vdbeapi.c 6af0e7160af260052a7a4500464221a03dada75f F src/vdbeaux.c 85f2184f536219d3c20c66f1403ef77321d1e715 F src/vdbefifo.c 9efb94c8c3f4c979ebd0028219483f88e57584f5 F src/vdbemem.c 5f0afe3b92bb2c037f8d5d697f7c151fa50783a3 -F src/vtab.c 745148c6f83f7c146ce93cc22c6716ff05a246e2 +F src/vtab.c cb5a2b23a241e657a8ee7c2b03574f6afa27214a F src/where.c d7c3cc011834882b2d58ebb3a6a1a569ead7ebd7 F tclinstaller.tcl 046e3624671962dc50f0481d7c25b38ef803eb42 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 @@ -292,6 +292,7 @@ F test/vacuum2.test 5aea8c88a65cb29f7d175296e7c819c6158d838c F test/varint.test ab7b110089a08b9926ed7390e7e97bdefeb74102 F test/view.test 16e2774fe35e47a07ac4471b7f0bcc948b1aa6d5 F test/vtab1.test a31c323cf158bf7326b3a4af4156b1bdd98cf8a8 +F test/vtab3.test b3ea5dfdc36ba23ba5136928b6c307c5125ababc F test/where.test ee7c9a6659b07e1ee61177f6e7ff71565ee2c9df F test/where2.test a16476a5913e75cf65b38f2daa6157a6b7791394 F test/where3.test 3b5ad2c58069e12be2bd86bc5e211a82810521aa @@ -367,7 +368,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P d65d83d38321258a7bb8c38f4b2657650b0f1033 -R cbf7f69fafe0127b012e719eed74f4d3 +P afa39a46320e9996a5478ea6e19eb4c2014327ac +R e864f985538904b7098e2d0d1765152d U danielk1977 -Z 33e3dbe7c063b046d5656223c8b15932 +Z b35d7828e5c540d613e21e95c6dfce99 diff --git a/manifest.uuid b/manifest.uuid index a45225230..0b1a8c6b4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -afa39a46320e9996a5478ea6e19eb4c2014327ac
\ No newline at end of file +9497c66e5533ec143d0efda4a419e4bdf922ae8c
\ No newline at end of file diff --git a/src/auth.c b/src/auth.c index 964ae66a6..fe05a68af 100644 --- a/src/auth.c +++ b/src/auth.c @@ -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.24 2006/01/13 13:55:45 drh Exp $ +** $Id: auth.c,v 1.25 2006/06/16 08:01:03 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -182,8 +182,10 @@ int sqlite3AuthCheck( sqlite3 *db = pParse->db; int rc; - /* Don't do any authorization checks if the database is initialising. */ - if( db->init.busy ){ + /* Don't do any authorization checks if the database is initialising + ** or if the parser is being invoked from within sqlite3_declare_vtab. + */ + if( db->init.busy || IN_DECLARE_VTAB ){ return SQLITE_OK; } diff --git a/src/build.c b/src/build.c index 124f9a624..9f9eea17e 100644 --- a/src/build.c +++ b/src/build.c @@ -22,7 +22,7 @@ ** COMMIT ** ROLLBACK ** -** $Id: build.c,v 1.401 2006/06/15 07:29:01 danielk1977 Exp $ +** $Id: build.c,v 1.402 2006/06/16 08:01:03 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> @@ -711,6 +711,7 @@ void sqlite3StartTable( Token *pName2, /* Second part of the name of the table or view */ int isTemp, /* True if this is a TEMP table */ int isView, /* True if this is a VIEW */ + int isVirtual, /* True if this is a VIRTUAL table */ int noErr /* Do nothing if table already exists */ ){ Table *pTable; @@ -774,7 +775,7 @@ void sqlite3StartTable( code = SQLITE_CREATE_TABLE; } } - if( sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){ + if( !isVirtual && sqlite3AuthCheck(pParse, code, zName, 0, zDb) ){ goto begin_table_error; } } @@ -862,8 +863,8 @@ void sqlite3StartTable( ** The rowid value is needed by the code that sqlite3EndTable will ** generate. */ -#ifndef SQLITE_OMIT_VIEW - if( isView ){ +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) + if( isView || isVirtual ){ sqlite3VdbeAddOp(v, OP_Integer, 0, 0); }else #endif @@ -1588,7 +1589,7 @@ void sqlite3CreateView( sqlite3SelectDelete(pSelect); return; } - sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0); + sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, 0); p = pParse->pNewTable; if( p==0 || pParse->nErr ){ sqlite3SelectDelete(pSelect); @@ -1886,6 +1887,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ int code; const char *zTab = SCHEMA_TABLE(iDb); const char *zDb = db->aDb[iDb].zName; + const char *zArg2 = 0; if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){ goto exit_drop_table; } @@ -1895,6 +1897,9 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ }else{ code = SQLITE_DROP_VIEW; } + }else if( IsVirtual(pTab) ){ + code = SQLITE_DROP_VTABLE; + zArg2 = pTab->pMod->zName; }else{ if( !OMIT_TEMPDB && iDb==1 ){ code = SQLITE_DROP_TEMP_TABLE; @@ -1902,7 +1907,7 @@ void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ code = SQLITE_DROP_TABLE; } } - if( sqlite3AuthCheck(pParse, code, pTab->zName, 0, zDb) ){ + if( sqlite3AuthCheck(pParse, code, pTab->zName, zArg2, zDb) ){ goto exit_drop_table; } if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){ @@ -2231,7 +2236,7 @@ void sqlite3CreateIndex( int nExtra = 0; char *zExtra; - if( pParse->nErr || sqlite3MallocFailed() ){ + if( pParse->nErr || sqlite3MallocFailed() || IN_DECLARE_VTAB ){ goto exit_create_index; } diff --git a/src/parse.y b/src/parse.y index 9b760ecb1..c346b6f78 100644 --- a/src/parse.y +++ b/src/parse.y @@ -14,7 +14,7 @@ ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** -** @(#) $Id: parse.y,v 1.203 2006/06/13 15:37:26 drh Exp $ +** @(#) $Id: parse.y,v 1.204 2006/06/16 08:01:04 danielk1977 Exp $ */ // All token codes are small integers with #defines that begin with "TK_" @@ -126,7 +126,7 @@ cmd ::= ROLLBACK trans_opt. {sqlite3RollbackTransaction(pParse);} // cmd ::= create_table create_table_args. create_table ::= CREATE temp(T) TABLE ifnotexists(E) nm(Y) dbnm(Z). { - sqlite3StartTable(pParse,&Y,&Z,T,0,E); + sqlite3StartTable(pParse,&Y,&Z,T,0,0,E); } %type ifnotexists {int} ifnotexists(A) ::= . {A = 0;} diff --git a/src/sqlite.h.in b/src/sqlite.h.in index f210bfa42..6fefee6a5 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -12,7 +12,7 @@ ** This header file defines the interface that the SQLite library ** presents to client programs. ** -** @(#) $Id: sqlite.h.in,v 1.178 2006/06/16 06:17:47 danielk1977 Exp $ +** @(#) $Id: sqlite.h.in,v 1.179 2006/06/16 08:01:04 danielk1977 Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ @@ -466,7 +466,8 @@ int sqlite3_set_authorizer( #define SQLITE_ALTER_TABLE 26 /* Database Name Table Name */ #define SQLITE_REINDEX 27 /* Index Name NULL */ #define SQLITE_ANALYZE 28 /* Table Name NULL */ - +#define SQLITE_CREATE_VTABLE 29 /* Table Name Module Name */ +#define SQLITE_DROP_VTABLE 30 /* Table Name Module Name */ /* ** The return value of the authorization function should be one of the diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f51ead317..bec2be02c 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.506 2006/06/15 04:28:13 danielk1977 Exp $ +** @(#) $Id: sqliteInt.h,v 1.507 2006/06/16 08:01:04 danielk1977 Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ @@ -1560,7 +1560,7 @@ void sqlite3RollbackInternalChanges(sqlite3*); void sqlite3CommitInternalChanges(sqlite3*); Table *sqlite3ResultSetOfSelect(Parse*,char*,Select*); void sqlite3OpenMasterTable(Parse *, int); -void sqlite3StartTable(Parse*,Token*,Token*,int,int,int); +void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int); void sqlite3AddColumn(Parse*,Token*); void sqlite3AddNotNull(Parse*, int); void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int); diff --git a/src/tclsqlite.c b/src/tclsqlite.c index f988926f4..896738db0 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -11,7 +11,7 @@ ************************************************************************* ** A TCL Interface to SQLite ** -** $Id: tclsqlite.c,v 1.159 2006/06/15 15:59:20 danielk1977 Exp $ +** $Id: tclsqlite.c,v 1.160 2006/06/16 08:01:04 danielk1977 Exp $ */ #ifndef NO_TCL /* Omit this whole file if TCL is unavailable */ @@ -543,6 +543,8 @@ static int auth_callback( case SQLITE_ALTER_TABLE : zCode="SQLITE_ALTER_TABLE"; break; case SQLITE_REINDEX : zCode="SQLITE_REINDEX"; break; case SQLITE_ANALYZE : zCode="SQLITE_ANALYZE"; break; + case SQLITE_CREATE_VTABLE : zCode="SQLITE_CREATE_VTABLE"; break; + case SQLITE_DROP_VTABLE : zCode="SQLITE_DROP_VTABLE"; break; default : zCode="????"; break; } Tcl_DStringInit(&str); diff --git a/src/vtab.c b/src/vtab.c index e870a2b34..2b647b12e 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to help implement virtual tables. ** -** $Id: vtab.c,v 1.13 2006/06/15 07:29:01 danielk1977 Exp $ +** $Id: vtab.c,v 1.14 2006/06/16 08:01:04 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE #include "sqliteInt.h" @@ -89,22 +89,34 @@ void sqlite3VtabBeginParse( Token *pName2, /* Name of new table or NULL */ Token *pModuleName /* Name of the module for the virtual table */ ){ + int iDb; /* The database the table is being created in */ Table *pTable; /* The new virtual table */ + Token *pDummy; /* Dummy arg for sqlite3TwoPartName() */ - /* TODO: The 5th argument to sqlite3StartTable() - isView - is being - ** passed a true value at present. This prevents sqlite3StartTable() - ** from coding OP_CreateTable, which is correct, but causes it - ** to invoke the authorization function as if a CREATE VIEW statement - ** were attempted, which is incorrect. - */ - sqlite3StartTable(pParse, pName1, pName2, 0, 1, 0); - + sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0); pTable = pParse->pNewTable; - if( pTable==0 ) return; + if( pTable==0 || pParse->nErr ) return; + assert( 0==pTable->pIndex ); + pTable->isVirtual = 1; pTable->nModuleArg = 0; addModuleArgument(pTable, sqlite3NameFromToken(pModuleName)); pParse->sNameToken.n = pModuleName->z + pModuleName->n - pName1->z; + +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Creating a virtual table invokes the authorization callback twice. + ** The first invocation, to obtain permission to INSERT a row into the + ** sqlite_master table, has already been made by sqlite3StartTable(). + ** The second call, to obtain permission to create the table, is made now. + */ + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pDummy); + assert( iDb>=0 ); + if( sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, + pTable->azModuleArg[0], pParse->db->aDb[iDb].zName) + ){ + return; + } +#endif } /* diff --git a/test/vtab3.test b/test/vtab3.test new file mode 100644 index 000000000..49d12e318 --- /dev/null +++ b/test/vtab3.test @@ -0,0 +1,142 @@ +# 2006 June 10 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is the authorisation callback and virtual tables. +# +# $Id: vtab3.test,v 1.1 2006/06/16 08:01:04 danielk1977 Exp $ + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable !vtab { + finish_test + return +} + +set ::auth_fail 0 +set ::auth_log [list] +set ::auth_filter [list SQLITE_READ SQLITE_UPDATE SQLITE_SELECT SQLITE_PRAGMA] + +proc auth {code arg1 arg2 arg3 arg4} { + if {[lsearch $::auth_filter $code]>-1} { + return SQLITE_OK + } + lappend ::auth_log $code $arg1 $arg2 $arg3 $arg4 + incr ::auth_fail -1 + if {$::auth_fail == 0} { + return SQLITE_DENY + } + return SQLITE_OK +} + +do_test vtab3-1.1 { + execsql { + CREATE TABLE elephant( + name VARCHAR(32), + color VARCHAR(16), + age INTEGER, + UNIQUE(name, color) + ); + } +} {} + + +do_test vtab3-1.2 { + register_echo_module [sqlite3_connection_pointer db] + db authorizer ::auth + execsql { + CREATE VIRTUAL TABLE pachyderm USING echo(elephant); + } + set ::auth_log +} [list \ + SQLITE_INSERT sqlite_master {} main {} \ + SQLITE_CREATE_VTABLE pachyderm echo main {} \ +] + +do_test vtab3-1.3 { + set ::auth_log [list] + execsql { + DROP TABLE pachyderm; + } + set ::auth_log +} [list \ + SQLITE_DELETE sqlite_master {} main {} \ + SQLITE_DROP_VTABLE pachyderm echo main {} \ + SQLITE_DELETE pachyderm {} main {} \ + SQLITE_DELETE sqlite_master {} main {} \ +] + +do_test vtab3-1.4 { + set ::auth_fail 1 + catchsql { + CREATE VIRTUAL TABLE pachyderm USING echo(elephant); + } +} {1 {not authorized}} +do_test vtab3-1.5 { + execsql { + SELECT name FROM sqlite_master WHERE type = 'table'; + } +} {elephant} + +do_test vtab3-1.5 { + set ::auth_fail 2 + catchsql { + CREATE VIRTUAL TABLE pachyderm USING echo(elephant); + } +} {1 {not authorized}} +do_test vtab3-1.6 { + execsql { + SELECT name FROM sqlite_master WHERE type = 'table'; + } +} {elephant} + +do_test vtab3-1.5 { + set ::auth_fail 3 + catchsql { + CREATE VIRTUAL TABLE pachyderm USING echo(elephant); + } +} {0 {}} +do_test vtab3-1.6 { + execsql { + SELECT name FROM sqlite_master WHERE type = 'table'; + } +} {elephant pachyderm} + +foreach i [list 1 2 3 4] { + set ::auth_fail $i + do_test vtab3-1.7.$i.1 { + set rc [catch { + execsql {DROP TABLE pachyderm;} + } msg] + if {$msg eq "authorization denied"} {set msg "not authorized"} + list $rc $msg + } {1 {not authorized}} + do_test vtab3-1.7.$i.2 { + execsql { + SELECT name FROM sqlite_master WHERE type = 'table'; + } + } {elephant pachyderm} +} +do_test vtab3-1.8.1 { + set ::auth_fail 0 + catchsql { + DROP TABLE pachyderm; + } +} {0 {}} +do_test vtab3-1.8.2 { + execsql { + SELECT name FROM sqlite_master WHERE type = 'table'; + } +} {elephant} + +finish_test + + |