libarchive/test/test_read_format_zip_comment_stored.c \
libarchive/test/test_read_format_zip_filename.c \
libarchive/test/test_read_format_zip_mac_metadata.c \
+ libarchive/test/test_read_format_zip_sfx.c \
libarchive/test/test_read_large.c \
libarchive/test/test_read_pax_truncated.c \
libarchive/test/test_read_position.c \
libarchive/test/test_read_format_zip_filename_utf8_ru.zip.uu \
libarchive/test/test_read_format_zip_length_at_end.zip.uu \
libarchive/test/test_read_format_zip_mac_metadata.zip.uu \
+ libarchive/test/test_read_format_zip_sfx.uu \
libarchive/test/test_read_format_zip_symlink.zip.uu \
libarchive/test/test_read_format_zip_ux.zip.uu \
libarchive/test/test_read_large_splitted_rar_aa.uu \
struct zip {
/* Structural information about the archive. */
+ int64_t end_of_central_directory_offset;
int64_t central_directory_offset;
size_t central_directory_size;
size_t central_directory_entries;
zip->central_directory_entries = archive_le16dec(p + 10);
zip->central_directory_size = archive_le32dec(p + 12);
zip->central_directory_offset = archive_le32dec(p + 16);
+ zip->end_of_central_directory_offset = filesize;
/* Just one volume, so central dir must all be on this volume. */
if (zip->central_directory_entries != archive_le16dec(p + 8))
slurp_central_directory(struct archive_read *a, struct zip *zip)
{
unsigned i;
+ int64_t correction;
static const struct archive_rb_tree_ops rb_ops = {
&cmp_node, &cmp_key
};
&rsrc_cmp_node, &rsrc_cmp_key
};
+ /*
+ * Consider the archive file we are reading may be SFX.
+ * So we have to calculate a SFX header size to revise
+ * ZIP header offsets.
+ */
+ correction = zip->end_of_central_directory_offset -
+ (zip->central_directory_offset + zip->central_directory_size);
+ /* The central directory offset is relative value, and so
+ * we revise this offset for SFX. */
+ zip->central_directory_offset += correction;
+
__archive_read_seek(a, zip->central_directory_offset, SEEK_SET);
zip->offset = zip->central_directory_offset;
__archive_rb_tree_init(&zip->tree, &rb_ops);
/* disk_start = archive_le16dec(p + 34); */ /* Better be zero. */
/* internal_attributes = archive_le16dec(p + 36); */ /* text bit */
external_attributes = archive_le32dec(p + 38);
- zip_entry->local_header_offset = archive_le32dec(p + 42);
+ zip_entry->local_header_offset =
+ archive_le32dec(p + 42) + correction;
/* If we can't guess the mode, leave it zero here;
when we read the local file header we might get
test_read_format_zip_comment_stored.c
test_read_format_zip_filename.c
test_read_format_zip_mac_metadata.c
+ test_read_format_zip_sfx.c
test_read_large.c
test_read_pax_truncated.c
test_read_position.c
--- /dev/null
+/*-
+ * Copyright (c) 2012 Michihiro NAKAJIMA
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "test.h"
+__FBSDID("$FreeBSD$");
+
+/*
+ * Read a zip file that is a SFX.
+ */
+DEFINE_TEST(test_read_format_zip_sfx)
+{
+ const char *refname = "test_read_format_zip_sfx";
+ char *p;
+ size_t s;
+ struct archive *a;
+ struct archive_entry *ae;
+
+ extract_reference_file(refname);
+ p = slurpfile(&s, refname);
+
+ /* Symlinks can only be extracted with the seeking reader. */
+ assert((a = archive_read_new()) != NULL);
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a));
+ assertEqualIntA(a, ARCHIVE_OK, read_open_memory_seek(a, p, s, 1));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("file0", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG | 0644, archive_entry_mode(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("build.sh", archive_entry_pathname(ae));
+ assertEqualInt(AE_IFREG | 0755, archive_entry_mode(ae));
+ assertEqualInt(23, archive_entry_size(ae));
+
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a));
+}
--- /dev/null
+begin 644 test_read_format_zip_sfx
+M!5@J$E]]1]?.)[Z/+RR:J';4YIJ7H0[7:BO"S8^VFB`_M_2)627VRG7%.)ZR
+M->RL72GY3(0UJMJ0;.F=<-36\SK.=/A%FK!K4Z0URPF<&M#E<@RXT`A04/Z\
+M<^0G>R,X8]@8XDDNJY6M`)Q".-::"%RS&VR!DZ_:>D2?J2W="_<P5N5M]]PJ
+M&!O^,VUD!7LUW?771M-Q"KS.HL7P+R/'1._KA6`3?M/8-2LMYS0_`TSQ*]C@
+M>+^EV*LRQR6=M7'6<;4-9>QC><TW/^PNF!Z%=$V1CRF]%XP#023PRV>@*<'9
+M/I<2W=CTNY/`P:EB;N!VD.N^;=8Z)1MJNOW`@8S9Z/X\U4^#H>WZQ>-61Y+W
+M(K*N/]YP(XU?S7^FL2DM15A6H-!:D"W`W/DQN(2IZ12!O<K;KU>_3"Y6MC9`
+MY#9LR=$B?G%0HZZ";I^LT<7@$6%T2#S-DG@K@LJ46)C>A`.T!2P@[Z5T;"DY
+MVE@B9%<XV6"_YO/7%[]"9(-%:-V<-X*GGSJ4?1I72PTMM#X?:XQY)=$QZ2+P
+MQ!HPVXKOE?PXR)A?:+D59>DHX=,"ER*),3<Y?2C-9V<"$L_LO+*'K;E"L0E.
+MQ*C/H*H>-%];VC5,B-`,WNYTNOA[U"LZQ4Q`Y(!"J2SO6JA4>?8[`$P<Z62+
+M+QJ0GOE,=K+N6XOJR8`=][O+>N"E`@URA/B&/),005H.O-.^?T;PF])\WV?/
+M%K*51XKZU_[D_56VA6$UO(-5R<B=M'*\)7\;=`9H0B=#:7EZ/)V_8HPW)]ZY
+M[HXW8KW`]Q`^K;I@0F)@G..KI]]2X6)B<X;X@7Y$:0^V!F#W]GI23)9*?<:G
+MBCNO8DM<']_6[^R%8#]I>6'0T/$S]`("I-`+&!&2>Z-*%PO"D_Q.E:G7<7=[
+MI<^0VIH=CZH9$9^5"W?CGNJ0Y<%R^I(R-M5;9#,.B4;R8['I*P^0%-3("7H(
+M2-#V.4!`(<0=EP,>0S*H?-O[N6'JE`,U`V\<<;=F6L4RZW#1$[,1Z5/-28A?
+M0/ATG:"NW/_TZ('?]7E=9D`5WR`OZN4>7-%DR,5[;$^A,E7QE#[U]F*VZR_H
+M*XX<X1!K_*LESD2GZ2>#+B;Z9*0M(\<#->VZV)%.6&`@!."\7,,/[8,WDDMU
+M2*@5[=A":;?D^<$^*U.UN^B%7M*2^A@`.N)^7"-?@!V9$W$_4[\R"WJ*,Z-$
+M8=9[;;447S.)EED+*4FGT[<U^,V+(J&MAE*0+=7Y!90Y%U\]'JH!^VLMYL0/
+M$@W#!E*A@&A$0[:<8WR8Q%1:OEENQ=.01-<IQD\P`+]0>045[*=AI%;U(1L8
+M\[-R4%15\D,""]:=;;OVAJK.TY\J8A)G&J<JH:2H%!?=XE!+`P0*``````#A
+M@&9!````````````````!0`<`&9I;&4P550)``,6MYA0=SN\4'5X"P`!!/4!
+M```$%````%!+`P0*``````"\>V9!ZECJ?1<````7````"``<`&)U:6QD+G-H
+M550)``-CKIA0=SN\4'5X"P`!!/4!```$%````",A+V)I;B]S:`IE8VAO(")T
+M97-T+B(*4$L!`AX#"@``````X8!F00````````````````4`&```````````
+M`*2!`````&9I;&4P550%``,6MYA0=7@+``$$]0$```04````4$L!`AX#"@``
+M````O'MF0>I8ZGT7````%P````@`&````````0```.V!/P```&)U:6QD+G-H
+M550%``-CKIA0=7@+``$$]0$```04````4$L%!@`````"``(`F0```)@````D
+E`%1H:7,@:7,@82!S86UP;&4@9FEL92!F;W(@:7-S=64@,C4W+@``
+`
+end