Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch zipfile-timestamp-fix Excluding Merge-Ins
This is equivalent to a diff from 02ba8a7b to 4eb5b24c
2018-01-31
| ||
20:18 | When creating a new archive entry, have zipfile store UTC instead of local time in the legacy MS-DOS format timestamp field. (check-in: b730d187 user: dan tags: trunk) | |
19:45 | Fix a test case in zipfile.test. (Closed-Leaf check-in: 4eb5b24c user: dan tags: zipfile-timestamp-fix) | |
19:13 | When creating a new archive entry, have zipfile store UTC instead of local time in the legacy MS-DOS format timestamp field. (check-in: e2114df1 user: dan tags: zipfile-timestamp-fix) | |
16:50 | Improve the omit-left-join optimization so that it works in some cases when the RHS is subject to a UNIQUE but not NOT NULL constraint. (check-in: 02ba8a7b user: drh tags: trunk) | |
14:07 | Fix a failing assert() in the new code on this branch. (Closed-Leaf check-in: 74d857d1 user: dan tags: omit-left-join-fix) | |
01:38 | Changes to the autoconf tarball so that it does not try to use system() when building on iOS. (check-in: 32ed9c10 user: drh tags: trunk) | |
Changes to ext/misc/zipfile.c.
︙ | ︙ | |||
682 683 684 685 686 687 688 | ** File modification date: ** Bits 00-04: day ** Bits 05-08: month (1-12) ** Bits 09-15: years from 1980 ** ** https://msdn.microsoft.com/en-us/library/9kkf9tah.aspx */ | | > > > | | | | | > | > > > > > > > > | > | > > > | > | < | | | | > > > > > > | > > > > | | < < | < | | > > > > > | 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 | ** File modification date: ** Bits 00-04: day ** Bits 05-08: month (1-12) ** Bits 09-15: years from 1980 ** ** https://msdn.microsoft.com/en-us/library/9kkf9tah.aspx */ static u32 zipfileMtime(ZipfileCDS *pCDS){ int Y = (1980 + ((pCDS->mDate >> 9) & 0x7F)); int M = ((pCDS->mDate >> 5) & 0x0F); int D = (pCDS->mDate & 0x1F); int B = -13; int sec = (pCDS->mTime & 0x1F)*2; int min = (pCDS->mTime >> 5) & 0x3F; int hr = (pCDS->mTime >> 11) & 0x1F; /* JD = INT(365.25 * (Y+4716)) + INT(30.6001 * (M+1)) + D + B - 1524.5 */ /* Calculate the JD in seconds for noon on the day in question */ if( M<3 ){ Y = Y-1; M = M+12; } i64 JD = (i64)(24*60*60) * ( (int)(365.25 * (Y + 4716)) + (int)(30.6001 * (M + 1)) + D + B - 1524 ); /* Correct the JD for the time within the day */ JD += (hr-12) * 3600 + min * 60 + sec; /* Convert JD to unix timestamp (the JD epoch is 2440587.5) */ return (u32)(JD - (i64)(24405875) * 24*60*6); } /* ** The opposite of zipfileMtime(). This function populates the mTime and ** mDate fields of the CDS structure passed as the first argument according ** to the UNIX timestamp value passed as the second. */ static void zipfileMtimeToDos(ZipfileCDS *pCds, u32 mUnixTime){ /* Convert unix timestamp to JD (2440588 is noon on 1/1/1970) */ i64 JD = (i64)2440588 + mUnixTime / (24*60*60); int A, B, C, D, E; int yr, mon, day; int hr, min, sec; A = (int)((JD - 1867216.25)/36524.25); A = JD + 1 + A - (A/4); B = A + 1524; C = (int)((B - 122.1)/365.25); D = (36525*(C&32767))/100; E = (int)((B-D)/30.6001); day = B - D - (int)(30.6001*E); mon = (E<14 ? E-1 : E-13); yr = mon>2 ? C-4716 : C-4715; hr = (mUnixTime % (24*60*60)) / (60*60); min = (mUnixTime % (60*60)) / 60; sec = (mUnixTime % 60); pCds->mDate = (u16)(day + (mon << 5) + ((yr-1980) << 9)); pCds->mTime = (u16)(sec/2 + (min<<5) + (hr<<11)); assert( mUnixTime<315507600 || mUnixTime==zipfileMtime(pCds) || ((mUnixTime % 2) && mUnixTime-1==zipfileMtime(pCds)) /* || (mUnixTime % 2) */ ); } /* ** If aBlob is not NULL, then it is a pointer to a buffer (nBlob bytes in ** size) containing an entire zip archive image. Or, if aBlob is NULL, ** then pFile is a file-handle open on a zip file. In either case, this ** function creates a ZipfileEntry object based on the zip archive entry |
︙ | ︙ |
Changes to test/zipfile.test.
︙ | ︙ | |||
43 44 45 46 47 48 49 50 51 52 53 54 55 56 | FROM fsdir('test_unzip') WHERE name!='test_unzip' ORDER BY name }] set res } } # Argument $file is the name of a zip archive on disk. This function # executes test cases to check that the results of each of the following # are the same: # # SELECT * FROM zipfile($file) # SELECT * FROM zipfile( readfile($file) ) | > > > > > > > > > > > > | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | FROM fsdir('test_unzip') WHERE name!='test_unzip' ORDER BY name }] set res } } # The argument is a blob (not a hex string) containing a zip archive. # This proc removes the extended timestamp fields from the archive # and returns the result. # proc remove_timestamps {blob} { set hex [binary encode hex $blob] set hex [string map {55540500 00000500} $hex] binary decode hex $hex } # Argument $file is the name of a zip archive on disk. This function # executes test cases to check that the results of each of the following # are the same: # # SELECT * FROM zipfile($file) # SELECT * FROM zipfile( readfile($file) ) |
︙ | ︙ | |||
363 364 365 366 367 368 369 370 | do_catchsql_test 4.1 { CREATE VIRTUAL TABLE yyy USING zipfile(); } {1 {zipfile constructor requires one argument}} do_catchsql_test 4.2 { CREATE VIRTUAL TABLE yyy USING zipfile('test.zip', 'test.zip'); } {1 {zipfile constructor requires one argument}} | > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 | do_catchsql_test 4.1 { CREATE VIRTUAL TABLE yyy USING zipfile(); } {1 {zipfile constructor requires one argument}} do_catchsql_test 4.2 { CREATE VIRTUAL TABLE yyy USING zipfile('test.zip', 'test.zip'); } {1 {zipfile constructor requires one argument}} #-------------------------------------------------------------------------- db func rt remove_timestamps do_execsql_test 5.0 { WITH c(name,mtime,data) AS ( SELECT 'a.txt', 946684800, 'abc' ) SELECT name,mtime,data FROM zipfile( ( SELECT rt( zipfile(name,NULL,mtime,data) ) FROM c ) ) } { a.txt 946684800 abc } if {[info vars ::UNZIP]!=""} { ifcapable datetime { load_static_extension db fileio forcedelete test1.zip test2.zip do_test 6.0 { execsql { WITH c(name,mtime,data) AS ( SELECT 'a.txt', 946684800, 'abc' UNION ALL SELECT 'b.txt', 1000000000, 'abc' UNION ALL SELECT 'c.txt', 1111111000, 'abc' ) SELECT writefile('test1.zip', rt( zipfile(name, NULL, mtime, data) ) ), writefile('test2.zip', ( zipfile(name, NULL, mtime, data) ) ) FROM c; } forcedelete test_unzip file mkdir test_unzip exec unzip -d test_unzip test1.zip db eval { SELECT name, strftime('%s', mtime, 'unixepoch', 'localtime') FROM fsdir('test_unzip') WHERE name!='test_unzip' ORDER BY name } } [list {*}{ test_unzip/a.txt 946684800 test_unzip/b.txt 1000000000 test_unzip/c.txt 1111111000 }] do_test 6.1 { forcedelete test_unzip file mkdir test_unzip exec unzip -d test_unzip test2.zip db eval { SELECT name, mtime FROM fsdir('test_unzip') WHERE name!='test_unzip' ORDER BY name } } [list {*}{ test_unzip/a.txt 946684800 test_unzip/b.txt 1000000000 test_unzip/c.txt 1111111000 }] } } finish_test |
Changes to test/zipfile2.test.
︙ | ︙ | |||
66 67 68 69 70 71 72 | 140000080000D4A52BEC09F3B6E0110000001100000005000900000000000000 0000A48100000000612E747874555405000140420F00504B01021E0314000008 0000D4A52BECD98916A71100000011000000050009000000000000000000A481 3D000000622E747874555405000140420F00504B050600000000020002007800 00007A0000000000 } | > > > | | | | | | > > | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | 140000080000D4A52BEC09F3B6E0110000001100000005000900000000000000 0000A48100000000612E747874555405000140420F00504B01021E0314000008 0000D4A52BECD98916A71100000011000000050009000000000000000000A481 3D000000622E747874555405000140420F00504B050600000000020002007800 00007A0000000000 } if 0 { # This test is broken - the archive generated is slightly different # depending on the zlib version used. do_execsql_test 3.1 { WITH contents(name,mtime,data) AS ( VALUES('a.txt', 1000000, 'contents of a.txt') UNION ALL VALUES('b.txt', 1000000, 'contents of b.txt') ) SELECT quote( zipfile(name,NULL,mtime,data) ) FROM contents; } [blobliteral $archive] } set blob [blob $archive] do_execsql_test 3.2 { SELECT name,mtime,data FROM zipfile($blob) } { a.txt 1000000 {contents of a.txt} b.txt 1000000 {contents of b.txt} |
︙ | ︙ | |||
94 95 96 97 98 99 100 101 102 103 104 105 106 107 | set a [string replace $archive $idx [expr $idx+3] 0000] set blob [blob $a] do_catchsql_test 3.3.$i { SELECT name,mtime,data FROM zipfile($blob) } {/1 .*/} } set L [findall 5554 $archive] for {set i 0} {$i < [llength $L]} {incr i} { set idx [lindex $L $i] set a [string replace $archive $idx [expr $idx+3] 1234] set blob [blob $a] do_execsql_test 3.4.$i { SELECT name,data FROM zipfile($blob) | > | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | set a [string replace $archive $idx [expr $idx+3] 0000] set blob [blob $a] do_catchsql_test 3.3.$i { SELECT name,mtime,data FROM zipfile($blob) } {/1 .*/} } # Change the "extra info id" for all extended-timestamp fields. set L [findall 5554 $archive] for {set i 0} {$i < [llength $L]} {incr i} { set idx [lindex $L $i] set a [string replace $archive $idx [expr $idx+3] 1234] set blob [blob $a] do_execsql_test 3.4.$i { SELECT name,data FROM zipfile($blob) |
︙ | ︙ | |||
119 120 121 122 123 124 125 | SELECT name,data FROM zipfile($blob) } { a.txt {contents of a.txt} b.txt {contents of b.txt} } } | < | | | | | | | | | | < > | < | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | SELECT name,data FROM zipfile($blob) } { a.txt {contents of a.txt} b.txt {contents of b.txt} } } # set blob [db one { # WITH contents(name,mtime,data) AS ( # VALUES('a.txt', 1000000, 'aaaaaaaaaaaaaaaaaaaaaaa') # ) SELECT quote( zipfile(name,NULL,mtime,data) ) FROM contents; # }] # set blob [string range $blob 2 end] # set blob [string range $blob 0 end-1] # while {[string length $blob]>0} { # puts [string range $blob 0 63] # set blob [string range $blob 64 end] # } # exit set archive2 { 504B0304140000080800D4A52BEC08F54C6E050000001700000005000900612E 747874555405000140420F004B4CC40A00504B01021E03140000080800D4A52B EC08F54C6E0500000017000000050009000000000000000000A4810000000061 2E747874555405000140420F00504B050600000000010001003C000000310000 000000 |
︙ | ︙ | |||
155 156 157 158 159 160 161 162 163 164 165 | set L [findall 17000000 $archive2] set a $archive2 foreach i $L { set a [string replace $a $i [expr $i+7] 16000000] } set blob [blob $a] do_catchsql_test 4.1 { SELECT name,mtime,data,method FROM zipfile($blob) } {1 {inflate() failed (0)}} finish_test | > | 159 160 161 162 163 164 165 166 167 168 169 170 | set L [findall 17000000 $archive2] set a $archive2 foreach i $L { set a [string replace $a $i [expr $i+7] 16000000] } set blob [blob $a] do_catchsql_test 4.1 { SELECT name,mtime,data,method FROM zipfile($blob) } {1 {inflate() failed (0)}} finish_test |