gitlab.com/CoiaPrant/sqlite3@v1.19.1/testdata/tcl/zipfile2.test (about) 1 # 2018 January 30 2 # 3 # The author disclaims copyright to this source code. In place of 4 # a legal notice, here is a blessing: 5 # 6 # May you do good and not evil. 7 # May you find forgiveness for yourself and forgive others. 8 # May you share freely, never taking more than you give. 9 # 10 #*********************************************************************** 11 # 12 13 package require Tcl 8.6 14 15 set testdir [file dirname $argv0] 16 source $testdir/tester.tcl 17 set testprefix zipfile2 18 19 ifcapable !vtab { 20 finish_test; return 21 } 22 if {[catch {load_static_extension db zipfile} error]} { 23 puts "Skipping zipfile2 tests, hit load error: $error" 24 finish_test; return 25 } 26 27 proc blobliteral {str} { 28 set concat [string map {" " "" "\n" ""} $str] 29 return "X'$concat'" 30 } 31 32 proc blob {str} { 33 binary decode hex $str 34 } 35 36 proc findall {needle haystack} { 37 set L [list] 38 set start 0 39 while { [set idx [string first $needle $haystack $start]]>=0 } { 40 lappend L $idx 41 set start [expr $idx+1] 42 } 43 set L 44 } 45 46 do_execsql_test 1.0 { 47 CREATE VIRTUAL TABLE aaa USING zipfile('testzip'); 48 CREATE VIRTUAL TABLE bbb USING zipfile("testzip"); 49 CREATE VIRTUAL TABLE ccc USING zipfile(`testzip`); 50 CREATE VIRTUAL TABLE ddd USING zipfile([testzip]); 51 CREATE VIRTUAL TABLE eee USING zipfile(testzip); 52 CREATE VIRTUAL TABLE fff USING zipfile('test''zip'); 53 } 54 55 do_test 2.0 { 56 forcedelete testdir 57 file mkdir testdir 58 execsql { CREATE VIRTUAL TABLE hhh USING zipfile('testdir') } 59 lindex [catchsql { 60 SELECT * FROM hhh; 61 INSERT INTO hhh(name, data) VALUES('1.txt', 'file data'); 62 }] 0 63 } 1 64 65 66 set archive { 67 504B0304140000080000D4A52BEC09F3B6E0110000001100000005000900612E 68 747874555405000140420F00636F6E74656E7473206F6620612E747874504B03 69 04140000080000D4A52BECD98916A7110000001100000005000900622E747874 70 555405000140420F00636F6E74656E7473206F6620622E747874504B01021E03 71 140000080000D4A52BEC09F3B6E0110000001100000005000900000000000000 72 0000A48100000000612E747874555405000140420F00504B01021E0314000008 73 0000D4A52BECD98916A71100000011000000050009000000000000000000A481 74 3D000000622E747874555405000140420F00504B050600000000020002007800 75 00007A0000000000 76 } 77 78 if 0 { 79 # This test is broken - the archive generated is slightly different 80 # depending on the zlib version used. 81 do_execsql_test 3.1 { 82 WITH contents(name,mtime,data) AS ( 83 VALUES('a.txt', 1000000, 'contents of a.txt') UNION ALL 84 VALUES('b.txt', 1000000, 'contents of b.txt') 85 ) SELECT quote( zipfile(name,NULL,mtime,data) ) FROM contents; 86 } [blobliteral $archive] 87 } 88 89 90 set blob [blob $archive] 91 do_execsql_test 3.2 { 92 SELECT name,mtime,data FROM zipfile($blob) 93 } { 94 a.txt 1000000 {contents of a.txt} 95 b.txt 1000000 {contents of b.txt} 96 } 97 98 # Corrupt each of the 0x50 0x4B (ascii "PK") headers in the file 99 # Test that in each case this causes an error. 100 # 101 set L [findall 504B $archive] 102 for {set i 0} {$i < [llength $L]} {incr i} { 103 set idx [lindex $L $i] 104 set a [string replace $archive $idx [expr $idx+3] 0000] 105 set blob [blob $a] 106 do_catchsql_test 3.3.$i { 107 SELECT name,mtime,data FROM zipfile($blob) 108 } {/1 .*/} 109 } 110 111 # Change the "extra info id" for all extended-timestamp fields. 112 set L [findall 5554 $archive] 113 for {set i 0} {$i < [llength $L]} {incr i} { 114 set idx [lindex $L $i] 115 set a [string replace $archive $idx [expr $idx+3] 1234] 116 set blob [blob $a] 117 do_execsql_test 3.4.$i { 118 SELECT name,data FROM zipfile($blob) 119 } { 120 a.txt {contents of a.txt} 121 b.txt {contents of b.txt} 122 } 123 } 124 125 for {set i 0} {$i < [llength $L]} {incr i} { 126 set idx [lindex $L $i] 127 set a [string replace $archive [expr $idx+8] [expr $idx+9] 00] 128 set blob [blob $a] 129 do_execsql_test 3.5.$i { 130 SELECT name,data FROM zipfile($blob) 131 } { 132 a.txt {contents of a.txt} 133 b.txt {contents of b.txt} 134 } 135 } 136 137 # set blob [db one { 138 # WITH contents(name,mtime,data) AS ( 139 # VALUES('a.txt', 1000000, 'aaaaaaaaaaaaaaaaaaaaaaa') 140 # ) SELECT quote( zipfile(name,NULL,mtime,data) ) FROM contents; 141 # }] 142 # set blob [string range $blob 2 end] 143 # set blob [string range $blob 0 end-1] 144 # while {[string length $blob]>0} { 145 # puts [string range $blob 0 63] 146 # set blob [string range $blob 64 end] 147 # } 148 # exit 149 150 set archive2 { 151 504B0304140000080800D4A52BEC08F54C6E050000001700000005000900612E 152 747874555405000140420F004B4CC40A00504B01021E03140000080800D4A52B 153 EC08F54C6E0500000017000000050009000000000000000000A4810000000061 154 2E747874555405000140420F00504B050600000000010001003C000000310000 155 000000 156 } 157 set blob [blob $archive2] 158 do_execsql_test 4.0 { 159 SELECT name,mtime,data,method FROM zipfile($blob) 160 } { 161 a.txt 1000000 aaaaaaaaaaaaaaaaaaaaaaa 8 162 } 163 164 set L [findall 17000000 $archive2] 165 set a $archive2 166 foreach i $L { set a [string replace $a $i [expr $i+7] 16000000] } 167 set blob [blob $a] 168 do_catchsql_test 4.1 { 169 SELECT name,mtime,data,method FROM zipfile($blob) 170 } {1 {inflate() failed (0)}} 171 172 # Check the response to an unknown compression method (set data to NULL). 173 set blob [blob [string map {0800 0900} $archive2]] 174 do_execsql_test 4.2 { 175 SELECT name,mtime,data IS NULL,method FROM zipfile($blob) 176 } {a.txt 1000000 1 9} 177 178 # Corrupt the EOCDS signature bytes in various ways. 179 foreach {tn sub} { 180 1 {504B0500} 181 2 {504B0006} 182 3 {50000506} 183 4 {004B0506} 184 } { 185 set blob [blob [string map [list 504B0506 $sub] $archive2]] 186 do_catchsql_test 4.3.$tn { 187 SELECT * FROM zipfile($blob) 188 } {1 {cannot find end of central directory record}} 189 } 190 191 #------------------------------------------------------------------------- 192 # Test that a zero-length file with a '/' at the end is treated as 193 # a directory (data IS NULL). Even if the mode doesn't indicate 194 # that it is a directory. 195 196 do_test 5.0 { 197 set blob [db one { 198 WITH c(n, d) AS ( 199 SELECT 'notadir', '' 200 ) 201 SELECT zipfile(n, d) FROM c 202 }] 203 204 set hex [binary encode hex $blob] 205 set hex [string map {6e6f7461646972 6e6f746164692f} $hex] 206 set blob2 [binary decode hex $hex] 207 208 execsql { SELECT name, data IS NULL FROM zipfile($blob2) } 209 } {notadi/ 1} 210 211 #------------------------------------------------------------------------- 212 # Test that duplicate entries may not be created using UPDATE 213 # statements. 214 # 215 forcedelete test.zip 216 do_execsql_test 6.0 { 217 CREATE VIRTUAL TABLE temp.zip USING zipfile('test.zip'); 218 INSERT INTO temp.zip (name,data) VALUES ('test1','test'); 219 INSERT INTO temp.zip (name,data) VALUES ('test2','test'); 220 } 221 do_catchsql_test 6.1 { 222 UPDATE temp.zip SET name='test1' WHERE name='test2' 223 } {1 {duplicate name: "test1"}} 224 225 forcedelete test.zip 226 do_catchsql_test 6.2 { 227 DROP TABLE zip; 228 CREATE VIRTUAL TABLE temp.zip USING zipfile('test.zip'); 229 INSERT INTO temp.zip (name,data) VALUES ('test','test'); 230 UPDATE temp.zip set name=name||'new' where name='test'; 231 INSERT INTO temp.zip (name,data) VALUES ('test','test'); 232 UPDATE temp.zip set name=name||'new' where name='test'; 233 } {1 {duplicate name: "testnew"}} 234 235 forcedelete test.zip 236 do_execsql_test 6.3 { 237 INSERT INTO temp.zip (name,data) VALUES ('test1','test'); 238 INSERT INTO temp.zip (name,data) VALUES ('test2','test'); 239 UPDATE OR REPLACE zip SET name='test2' WHERE name='test1'; 240 SELECT name FROM zip; 241 } {test2} 242 243 finish_test