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