]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Add support for Info-ZIP New Unix Extra Field "ux".
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Mon, 21 Mar 2011 01:13:09 +0000 (21:13 -0400)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Mon, 21 Mar 2011 01:13:09 +0000 (21:13 -0400)
SVN-Revision: 3040

libarchive/archive_read_support_format_zip.c
libarchive/test/test_read_format_zip.c
libarchive/test/test_read_format_zip_ux.zip.uu [new file with mode: 0644]

index d9a69e74751ddfedf0e5373fdc7f3d5f63f3e42d..266800b7f2e137a8ba67abefa4706a2b058b3c90 100644 (file)
@@ -996,8 +996,35 @@ process_extra(const void* extra, struct zip* zip)
                                zip->gid = archive_le16dec(p + offset + 2);
                        break;
                case 0x7875:
+               {
                        /* Info-Zip Unix Extra Field (type 3) "ux". */
+                       int uidsize = 0, gidsize = 0;
+
+                       if (datasize >= 1 && p[offset] == 1) {/* version=1 */
+                               if (datasize >= 4) {
+                                       /* get a uid size. */
+                                       uidsize = p[offset+1];
+                                       if (uidsize == 2)
+                                               zip->uid = archive_le16dec(
+                                                    p + offset + 2);
+                                       else if (uidsize == 4 && datasize >= 6)
+                                               zip->uid = archive_le32dec(
+                                                    p + offset + 2);
+                               }
+                               if (datasize >= (2 + uidsize + 3)) {
+                                       /* get a gid size. */
+                                       gidsize = p[offset+2+uidsize];
+                                       if (gidsize == 2)
+                                               zip->gid = archive_le16dec(
+                                                   p+offset+2+uidsize+1);
+                                       else if (gidsize == 4 &&
+                                           datasize >= (2 + uidsize + 5))
+                                               zip->gid = archive_le32dec(
+                                                   p+offset+2+uidsize+1);
+                               }
+                       }
                        break;
+               }
                default:
                        break;
                }
index 5cc8e5dfc09c70845f8592203e3222c35c14711b..7c8a42f9067aa615722458d76adf87c6082f8eb6 100644 (file)
@@ -1,5 +1,6 @@
 /*-
  * Copyright (c) 2003-2007 Tim Kientzle
+ * Copyright (c) 2011 Michihiro NAKAJIMA
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,7 +32,8 @@ __FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_zip.c 189482 2009-
  *   * file2 has an invalid CRC
  */
 
-DEFINE_TEST(test_read_format_zip)
+static void
+test_basic()
 {
        const char *refname = "test_read_format_zip.zip";
        struct archive_entry *ae;
@@ -89,4 +91,55 @@ finish:
        assertEqualInt(ARCHIVE_OK, archive_read_free(a));
 }
 
+/*
+ * Read Info-ZIP New Unix Extra Field 0x7875 "ux".
+ *  Currently sotres Unix UID/GID up to 32 bits.
+ */
+static void
+test_info_zip_ux()
+{
+       const char *refname = "test_read_format_zip_ux.zip";
+       struct archive_entry *ae;
+       struct archive *a;
+       char *buff[128];
+       int r;
+
+       extract_reference_file(refname);
+       assert((a = archive_read_new()) != NULL);
+       assertA(0 == archive_read_support_compression_all(a));
+       assertA(0 == archive_read_support_format_all(a));
+       assertA(0 == archive_read_open_filename(a, refname, 10240));
+
+       assertA(0 == archive_read_next_header(a, &ae));
+       assertEqualString("file1", archive_entry_pathname(ae));
+       assertEqualInt(1300668680, archive_entry_mtime(ae));
+       assertEqualInt(18, archive_entry_size(ae));
+       failure("zip reader should read Info-ZIP New Unix Extra Field");
+       assertEqualInt(1001, archive_entry_uid(ae));
+       assertEqualInt(1001, archive_entry_gid(ae));
+       failure("archive_read_data() returns number of bytes read");
+       r = archive_read_data(a, buff, 19);
+       if (r < ARCHIVE_OK) {
+               if (strcmp(archive_error_string(a),
+                   "libarchive compiled without deflate support (no libz)") == 0) {
+                       skipping("Skipping ZIP compression check: %s",
+                           archive_error_string(a));
+                       goto finish;
+               }
+       }
+       assertEqualInt(18, r);
+       assert(0 == memcmp(buff, "hello\nhello\nhello\n", 18));
+       assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+       assertA(archive_compression(a) == ARCHIVE_COMPRESSION_NONE);
+       assertA(archive_format(a) == ARCHIVE_FORMAT_ZIP);
+       assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a));
+finish:
+       assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
 
+DEFINE_TEST(test_read_format_zip)
+{
+       test_basic();
+       test_info_zip_ux();
+}
diff --git a/libarchive/test/test_read_format_zip_ux.zip.uu b/libarchive/test/test_read_format_zip_ux.zip.uu
new file mode 100644 (file)
index 0000000..7bfe796
--- /dev/null
@@ -0,0 +1,7 @@
+begin 644 test_read_format_zip_ux.zip
+M4$L#!!0````(`&I.=3XZ-V8]"@```!(````%`!P`9FEL93%55`D``PBAADT4
+MH89-=7@+``$$Z0,```3I`P``RTC-R<GGRD`B`5!+`0(>`Q0````(`&I.=3XZ
+M-V8]"@```!(````%`!@```````$```"D@0````!F:6QE,554!0`#"*&&375X
+C"P`!!.D#```$Z0,``%!+!08``````0`!`$L```!)````````
+`
+end