000001 # 2008 October 27
000002 #
000003 # The author disclaims copyright to this source code. In place of
000004 # a legal notice, here is a blessing:
000005 #
000006 # May you do good and not evil.
000007 # May you find forgiveness for yourself and forgive others.
000008 # May you share freely, never taking more than you give.
000009 #
000010 #***********************************************************************
000011 #
000012 # Test that the truncate optimization is disabled if the SQLITE_DELETE
000013 # authorization callback returns SQLITE_IGNORE.
000014 #
000015 # Test that authorizer is disabled during schema parsing.
000016
000017 set testdir [file dirname $argv0]
000018 source $testdir/tester.tcl
000019
000020 # disable this test if the SQLITE_OMIT_AUTHORIZATION macro is
000021 # defined during compilation.
000022 if {[catch {db auth {}} msg]} {
000023 finish_test
000024 return
000025 }
000026
000027 # Disable the statement cache for these tests.
000028 #
000029 db cache size 0
000030
000031 db authorizer ::auth
000032 proc auth {code arg1 arg2 arg3 arg4 args} {
000033 if {$code=="SQLITE_DELETE"} {
000034 return $::authcode
000035 }
000036 return SQLITE_OK
000037 }
000038
000039 #--------------------------------------------------------------------------
000040 # The following tests - auth3-1.* - test that return values of SQLITE_DENY,
000041 # SQLITE_IGNORE, SQLITE_OK and <invalid> are correctly handled when returned
000042 # by an SQLITE_DELETE authorization callback triggered by a
000043 # "DELETE FROM <table-name>" statement.
000044 #
000045 do_test auth3-1.1 {
000046 execsql {
000047 CREATE TABLE t1(a,b,c);
000048 INSERT INTO t1 VALUES(1, 2, 3);
000049 INSERT INTO t1 VALUES(4, 5, 6);
000050 }
000051 } {}
000052 do_test auth3.1.2 {
000053 set ::authcode SQLITE_DENY
000054 catchsql { DELETE FROM t1 }
000055 } {1 {not authorized}}
000056 # EVIDENCE-OF: R-64962-58611 If the authorizer callback returns any
000057 # value other than SQLITE_IGNORE, SQLITE_OK, or SQLITE_DENY then the
000058 # sqlite3_prepare_v2() or equivalent call that triggered the authorizer
000059 # will fail with an error message.
000060 do_test auth3.1.3 {
000061 set ::authcode SQLITE_INVALID
000062 catchsql { DELETE FROM t1 }
000063 } {1 {authorizer malfunction}}
000064 do_test auth3.1.4 {
000065 execsql { SELECT * FROM t1 }
000066 } {1 2 3 4 5 6}
000067 do_test auth3-1.5 {
000068 set ::authcode SQLITE_IGNORE
000069 execsql {
000070 DELETE FROM t1;
000071 SELECT * FROM t1;
000072 }
000073 } {}
000074 do_test auth3-1.6 {
000075 set ::authcode SQLITE_OK
000076 execsql {
000077 INSERT INTO t1 VALUES(1, 2, 3);
000078 INSERT INTO t1 VALUES(4, 5, 6);
000079 DELETE FROM t1;
000080 SELECT * FROM t1;
000081 }
000082 } {}
000083
000084 #--------------------------------------------------------------------------
000085 # These tests - auth3-2.* - test that returning SQLITE_IGNORE really does
000086 # disable the truncate optimization.
000087 #
000088 do_test auth3-2.1 {
000089 set ::authcode SQLITE_OK
000090 execsql {
000091 INSERT INTO t1 VALUES(1, 2, 3);
000092 INSERT INTO t1 VALUES(4, 5, 6);
000093 }
000094 set sqlite_search_count 0
000095 execsql {
000096 DELETE FROM t1;
000097 }
000098 set sqlite_search_count
000099 } {0}
000100
000101 do_test auth3-2.2 {
000102 set ::authcode SQLITE_IGNORE
000103 execsql {
000104 INSERT INTO t1 VALUES(1, 2, 3);
000105 INSERT INTO t1 VALUES(4, 5, 6);
000106 }
000107 set sqlite_search_count 0
000108 execsql {
000109 DELETE FROM t1;
000110 }
000111 set sqlite_search_count
000112 } {1}
000113
000114 # 2016-07-28. A problem report from a private client complaining about
000115 # an authorizer failure during an ALTER TABLE. The solution (I think) is
000116 # to disable the authorizer during schema parsing.
000117 #
000118 ifcapable altertable {
000119 proc auth {code args} {
000120 if {$code=="SQLITE_READ" && [regexp {DoNotRead} $args]} {
000121 return SQLITE_DENY
000122 }
000123 return SQLITE_OK
000124 }
000125 do_execsql_test auth3-3.0 {
000126 CREATE TEMPORARY TABLE TempTable (
000127 key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,
000128 value TEXT NOT NULL ON CONFLICT FAIL);
000129 ALTER TABLE TempTable RENAME TO DoNotRead;
000130 SELECT name FROM temp.sqlite_master;
000131 } {DoNotRead sqlite_autoindex_DoNotRead_1}
000132 }
000133
000134 finish_test