]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Fix ISO9660 hardlink handling and fix the parsing of
authorTim Kientzle <kientzle@gmail.com>
Sat, 25 Jul 2009 06:18:47 +0000 (02:18 -0400)
committerTim Kientzle <kientzle@gmail.com>
Sat, 25 Jul 2009 06:18:47 +0000 (02:18 -0400)
Rockridge symlinks.  Update tests to verify the correct
behavior here.

SVN-Revision: 1275

libarchive/archive_read_support_format_iso9660.c
libarchive/test/test_read_format_isojoliet_bz2.c
libarchive/test/test_read_format_isorr_bz2.c
libarchive/test/test_read_format_isorr_bz2.iso.bz2.uu

index 1921c580953920ca2ed28008a70bb88b6e695df1..6ec46ad11efa5436c546b289366acd79c7b55e8f 100644 (file)
@@ -579,6 +579,7 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
            && file->size > 0) {
                archive_entry_set_hardlink(entry,
                    iso9660->previous_pathname.s);
+               archive_entry_unset_size(entry);
                iso9660->entry_bytes_remaining = 0;
                iso9660->entry_sparse_offset = 0;
                release_file(iso9660, file);
@@ -1174,12 +1175,12 @@ static void
 parse_rockridge_SL1(struct file_info *file, const unsigned char *data,
     int data_length)
 {
-       int component_continues = 1;
+       const char *separator = "";
 
-       if (!file->symlink_continues)
+       if (!file->symlink_continues || file->symlink.length < 1)
                archive_string_empty(&file->symlink);
-       else
-               archive_strcat(&file->symlink, "/");
+       else if (file->symlink.s[file->symlink.length - 1] != '/')
+               separator = "/";
        file->symlink_continues = 0;
 
        /*
@@ -1216,9 +1217,8 @@ parse_rockridge_SL1(struct file_info *file, const unsigned char *data,
                unsigned char nlen = *data++;
                data_length -= 2;
 
-               if (!component_continues)
-                       archive_strcat(&file->symlink, "/");
-               component_continues = 0;
+               archive_strcat(&file->symlink, separator);
+               separator = "/";
 
                switch(flag) {
                case 0: /* Usual case, this is text. */
@@ -1232,7 +1232,7 @@ parse_rockridge_SL1(struct file_info *file, const unsigned char *data,
                                return;
                        archive_strncat(&file->symlink,
                            (const char *)data, nlen);
-                       component_continues = 1;
+                       separator = "";
                        break;
                case 0x02: /* Current dir. */
                        archive_strcat(&file->symlink, ".");
@@ -1243,6 +1243,7 @@ parse_rockridge_SL1(struct file_info *file, const unsigned char *data,
                case 0x08: /* Root of filesystem. */
                        archive_string_empty(&file->symlink);
                        archive_strcat(&file->symlink, "/");
+                       separator = "";
                        break;
                case 0x10: /* Undefined (historically "volume root" */
                        archive_string_empty(&file->symlink);
index d84d9d8df7f1d91819f0b49927652438383fb4d2..2d5ea3145fefb60d4e9c453b0cca3f88e2b1c681 100644 (file)
@@ -108,14 +108,10 @@ joliettest(int withrr)
                assertEqualInt(2, archive_entry_gid(ae));
        }
 
-       /* A hardlink to the regular file. */
+       /* A regular file with a hardlink. */
        assertEqualInt(0, archive_read_next_header(a, &ae));
        assertEqualString("hardlink", archive_entry_pathname(ae));
        assert(S_ISREG(archive_entry_stat(ae)->st_mode));
-       if (withrr) {
-               assertEqualString("long-joliet-file-name.textfile",
-                   archive_entry_hardlink(ae));
-       }
        assertEqualInt(6, archive_entry_size(ae));
        assertEqualInt(0, archive_read_data_block(a, &p, &size, &offset));
        assertEqualInt(6, (int)size);
@@ -129,11 +125,11 @@ joliettest(int withrr)
                assertEqualInt(2, archive_entry_gid(ae));
        }
 
-       /* A regular file. */
+       /* Another link to the regular file. */
        assertEqualInt(0, archive_read_next_header(a, &ae));
        assertEqualString("long-joliet-file-name.textfile", archive_entry_pathname(ae));
        assert(S_ISREG(archive_entry_stat(ae)->st_mode));
-       assertEqualInt(6, archive_entry_size(ae));
+       assertEqualInt(0, archive_entry_size(ae));
        if (withrr) {
                assertEqualInt(86401, archive_entry_mtime(ae));
                assertEqualInt(86401, archive_entry_atime(ae));
index 2dfc2ae73548e4dcce924577e62a6bdf1dbe38af..d01057419fce76c48f6a4f8257aa15fdad480bff 100644 (file)
@@ -33,9 +33,12 @@ rm -rf /tmp/iso
 mkdir /tmp/iso
 mkdir /tmp/iso/dir
 echo "hello" >/tmp/iso/file
-dd if=/dev/zero bs=1 count=12345678 >>/tmp/iso/file
+dd if=/dev/zero count=1 bs=12345678 >>/tmp/iso/file
 ln /tmp/iso/file /tmp/iso/hardlink
 (cd /tmp/iso; ln -s file symlink)
+(cd /tmp/iso; ln -s /tmp/ symlink2)
+(cd /tmp/iso; ln -s /tmp/../ symlink3)
+(cd /tmp/iso; ln -s .././../tmp/ symlink4)
 TZ=utc touch -afhm -t 197001020000.01 /tmp/iso /tmp/iso/file /tmp/iso/dir
 TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink
 mkhybrid -R -uid 1 -gid 2 /tmp/iso | bzip2 > test_read_format_isorr_bz2.iso.bz2
@@ -52,6 +55,7 @@ DEFINE_TEST(test_read_format_isorr_bz2)
        const void *p;
        size_t size;
        off_t offset;
+       int i;
        int r;
 
        extract_reference_file(refname);
@@ -67,68 +71,104 @@ DEFINE_TEST(test_read_format_isorr_bz2)
        assertEqualInt(ARCHIVE_OK,
            archive_read_open_filename(a, refname, 10240));
 
-       /* First entry is '.' root directory. */
-       assertEqualInt(0, archive_read_next_header(a, &ae));
-       assertEqualString(".", archive_entry_pathname(ae));
-       assert(S_ISDIR(archive_entry_stat(ae)->st_mode));
-       assertEqualInt(2048, archive_entry_size(ae));
-       assertEqualInt(86401, archive_entry_mtime(ae));
-       assertEqualInt(0, archive_entry_mtime_nsec(ae));
-       assertEqualInt(86401, archive_entry_ctime(ae));
-       assertEqualInt(0, archive_entry_stat(ae)->st_nlink);
-       assertEqualInt(0, archive_entry_uid(ae));
-       assertEqualIntA(a, ARCHIVE_EOF,
-           archive_read_data_block(a, &p, &size, &offset));
-       assertEqualInt((int)size, 0);
+       /* Retrieve each of the 8 files on the ISO image and
+        * verify that each one is what we expect. */
+       for (i = 0; i < 8; ++i) {
+               assertEqualInt(0, archive_read_next_header(a, &ae));
 
-       /* A directory. */
-       assertEqualInt(0, archive_read_next_header(a, &ae));
-       assertEqualString("dir", archive_entry_pathname(ae));
-       assert(S_ISDIR(archive_entry_stat(ae)->st_mode));
-       assertEqualInt(2048, archive_entry_size(ae));
-       assertEqualInt(86401, archive_entry_mtime(ae));
-       assertEqualInt(86401, archive_entry_atime(ae));
-       assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
-       assertEqualInt(1, archive_entry_uid(ae));
-       assertEqualInt(2, archive_entry_gid(ae));
-
-       /* A regular file. */
-       assertEqualInt(0, archive_read_next_header(a, &ae));
-       assertEqualString("file", archive_entry_pathname(ae));
-       assert(S_ISREG(archive_entry_stat(ae)->st_mode));
-       assertEqualInt(12345684, archive_entry_size(ae));
-       assertEqualInt(0, archive_read_data_block(a, &p, &size, &offset));
-       assertEqualInt(0, offset);
-       assertEqualMem(p, "hello\n", 6);
-       assertEqualInt(86401, archive_entry_mtime(ae));
-       assertEqualInt(86401, archive_entry_atime(ae));
-       assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
-       assertEqualInt(1, archive_entry_uid(ae));
-       assertEqualInt(2, archive_entry_gid(ae));
-
-       /* A hardlink to the regular file. */
-       assertEqualInt(0, archive_read_next_header(a, &ae));
-       assertEqualString("hardlink", archive_entry_pathname(ae));
-       assert(S_ISREG(archive_entry_stat(ae)->st_mode));
-       assertEqualString("file", archive_entry_hardlink(ae));
-       assertEqualInt(12345684, archive_entry_size(ae));
-       assertEqualInt(86401, archive_entry_mtime(ae));
-       assertEqualInt(86401, archive_entry_atime(ae));
-       assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
-       assertEqualInt(1, archive_entry_uid(ae));
-       assertEqualInt(2, archive_entry_gid(ae));
-
-       /* A symlink to the regular file. */
-       assertEqualInt(0, archive_read_next_header(a, &ae));
-       assertEqualString("symlink", archive_entry_pathname(ae));
-       assert(S_ISLNK(archive_entry_stat(ae)->st_mode));
-       assertEqualString("file", archive_entry_symlink(ae));
-       assertEqualInt(0, archive_entry_size(ae));
-       assertEqualInt(172802, archive_entry_mtime(ae));
-       assertEqualInt(172802, archive_entry_atime(ae));
-       assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
-       assertEqualInt(1, archive_entry_uid(ae));
-       assertEqualInt(2, archive_entry_gid(ae));
+               if (strcmp(".", archive_entry_pathname(ae)) == 0) {
+                       /* '.' root directory. */
+                       assert(S_ISDIR(archive_entry_stat(ae)->st_mode));
+                       assertEqualInt(2048, archive_entry_size(ae));
+                       assertEqualInt(86401, archive_entry_mtime(ae));
+                       assertEqualInt(0, archive_entry_mtime_nsec(ae));
+                       assertEqualInt(86401, archive_entry_ctime(ae));
+                       assertEqualInt(0, archive_entry_stat(ae)->st_nlink);
+                       assertEqualInt(0, archive_entry_uid(ae));
+                       assertEqualIntA(a, ARCHIVE_EOF,
+                           archive_read_data_block(a, &p, &size, &offset));
+                       assertEqualInt((int)size, 0);
+               } else if (strcmp("dir", archive_entry_pathname(ae)) == 0) {
+                       /* A directory. */
+                       assertEqualString("dir", archive_entry_pathname(ae));
+                       assert(S_ISDIR(archive_entry_stat(ae)->st_mode));
+                       assertEqualInt(2048, archive_entry_size(ae));
+                       assertEqualInt(86401, archive_entry_mtime(ae));
+                       assertEqualInt(86401, archive_entry_atime(ae));
+                       assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
+                       assertEqualInt(1, archive_entry_uid(ae));
+                       assertEqualInt(2, archive_entry_gid(ae));
+               } else if (strcmp("file", archive_entry_pathname(ae)) == 0) {
+                       /* A regular file. */
+                       assertEqualString("file", archive_entry_pathname(ae));
+                       assert(S_ISREG(archive_entry_stat(ae)->st_mode));
+                       assertEqualInt(12345684, archive_entry_size(ae));
+                       assertEqualInt(0,
+                           archive_read_data_block(a, &p, &size, &offset));
+                       assertEqualInt(0, offset);
+                       assertEqualMem(p, "hello\n", 6);
+                       assertEqualInt(86401, archive_entry_mtime(ae));
+                       assertEqualInt(86401, archive_entry_atime(ae));
+                       assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
+                       assertEqualInt(1, archive_entry_uid(ae));
+                       assertEqualInt(2, archive_entry_gid(ae));
+               } else if (strcmp("hardlink", archive_entry_pathname(ae)) == 0) {
+                       /* A hardlink to the regular file. */
+                       /* Note: If "hardlink" gets returned before "file",
+                        * then "hardlink" will get returned as a regular file
+                        * and "file" will get returned as the hardlink.
+                        * This test should tolerate that, since it's a
+                        * perfectly permissible thing for libarchive to do. */
+                       assertEqualString("hardlink", archive_entry_pathname(ae));
+                       assert(S_ISREG(archive_entry_stat(ae)->st_mode));
+                       assertEqualString("file", archive_entry_hardlink(ae));
+                       assertEqualInt(0, archive_entry_size_is_set(ae));
+                       assertEqualInt(0, archive_entry_size(ae));
+                       assertEqualInt(86401, archive_entry_mtime(ae));
+                       assertEqualInt(86401, archive_entry_atime(ae));
+                       assertEqualInt(2, archive_entry_stat(ae)->st_nlink);
+                       assertEqualInt(1, archive_entry_uid(ae));
+                       assertEqualInt(2, archive_entry_gid(ae));
+               } else if (strcmp("symlink", archive_entry_pathname(ae)) == 0) {
+                       /* A symlink to the regular file. */
+                       assert(S_ISLNK(archive_entry_stat(ae)->st_mode));
+                       assertEqualString("file", archive_entry_symlink(ae));
+                       assertEqualInt(0, archive_entry_size(ae));
+                       assertEqualInt(172802, archive_entry_mtime(ae));
+                       assertEqualInt(172802, archive_entry_atime(ae));
+                       assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+                       assertEqualInt(1, archive_entry_uid(ae));
+                       assertEqualInt(2, archive_entry_gid(ae));
+               } else if (strcmp("symlink2", archive_entry_pathname(ae)) == 0) {
+                       /* A symlink to /tmp (an absolute path) */
+                       assert(S_ISLNK(archive_entry_stat(ae)->st_mode));
+                       assertEqualString("/tmp", archive_entry_symlink(ae));
+                       assertEqualInt(0, archive_entry_size(ae));
+                       assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+                       assertEqualInt(1, archive_entry_uid(ae));
+                       assertEqualInt(2, archive_entry_gid(ae));
+               } else if (strcmp("symlink3", archive_entry_pathname(ae)) == 0) {
+                       /* A symlink to /tmp/.. (with a ".." component) */
+                       assert(S_ISLNK(archive_entry_stat(ae)->st_mode));
+                       assertEqualString("/tmp/..", archive_entry_symlink(ae));
+                       assertEqualInt(0, archive_entry_size(ae));
+                       assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+                       assertEqualInt(1, archive_entry_uid(ae));
+                       assertEqualInt(2, archive_entry_gid(ae));
+               } else if (strcmp("symlink4", archive_entry_pathname(ae)) == 0) {
+                       /* A symlink to a path with ".." and "." components */
+                       assert(S_ISLNK(archive_entry_stat(ae)->st_mode));
+                       assertEqualString(".././../tmp",
+                           archive_entry_symlink(ae));
+                       assertEqualInt(0, archive_entry_size(ae));
+                       assertEqualInt(1, archive_entry_stat(ae)->st_nlink);
+                       assertEqualInt(1, archive_entry_uid(ae));
+                       assertEqualInt(2, archive_entry_gid(ae));
+               } else {
+                       failure("Saw a file that shouldn't have been there");
+                       assertEqualString(archive_entry_pathname(ae), "");
+               }
+       }
 
        /* End of archive. */
        assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae));
@@ -139,11 +179,7 @@ DEFINE_TEST(test_read_format_isorr_bz2)
 
        /* Close the archive. */
        assertEqualInt(0, archive_read_close(a));
-#if ARCHIVE_VERSION_NUMBER < 2000000
-       archive_read_finish(a);
-#else
        assertEqualInt(0, archive_read_finish(a));
-#endif
 }
 
 
index d4e3fc898a97a72271395447257865d317d92121..fe2cad90679e926e0c9f5555ec464d5cd3a4f591 100644 (file)
@@ -1,23 +1,25 @@
 begin 644 test_read_format_isorr_bz2.iso.bz2
-M0EIH.3%!629363S[0-4``,?_W?__R_158__Z/__?8*?OWB8AZB2```4@`,0"
-M@0C0`SX`6UH$P:F@32FCU-D1Z@#U'J!HT>H#0`!H`T9`#U-#33(-`-3TFA#1
-MJ933TFR%#(&@`#0-````'J`T``,.-#1HT&C0-``````R````-`9``8<:&C1H
-M-&@:`````!D````:`R``P1*(1$]3U,C(--``T!H:9``````:``&F)?&F1;DY
-M&:FB?6\AB@WG9X@8AM,HTK/Q9EXPZD#E2A$D)(@;F(G^B.92GLB`=H@`+I1!
-M1$`';Y%%P_YU^!0+8BJ(@#DC&D@D4"1D4?Z1!$1`&Z`V[]0H($(!6L90;<NF
-M9^?26V%/AEU/G]J7$.#!IBC,>:>A0V<))<GYB`(B`.INK=BX9"_=9R*"<::E
-MFLK=4PYO'Q\%X>XH7BH%"KAF8!:H8<BRI_..!GF=:H4'$TR7@-X.M"X!J02@
-M$"QE&OW!J]D&9@$]-M!R8/GDX=A>\].K:4`Y`,4,!RN:#SL[!;-"!6%0F?`H
-M2_2AM@*%/%<\*!XL/C2%A1AI$8/AF(#SZ;]:>$5^/NKNO<+EH@_CS4XUI(Q*
-M123&G=9T]QQR?"=WMV(,&60`1D0:U043)E&22GWA);Z:"9R.A@,4,IL+O=L7
-M<MBZ,<:K"\_.A6THZ_!VK;Z[UT7!2MP4";.`R#RPL<*"C)0P,\'%UF#3%OPT
-MS>ACF:V5C!L"HB&,82/[./'>PAEG-"P<D-Q@ZZCIL]<TF$\Y02VP>A,D6T1+
-M2<\S]-*$,]X-XF%:_)1,W,=`,^+.N0""6@"85=H@<2FZ=HI-GDHK&)>/T74Y
-M+5>[4:S`Z`M87AHD`H6BE*8R%X=9AS$7&+Z?F%A.`<C&X,.+^:SH,(=)!_1_
-MRX-6BR.),-RP"J'7$A#:'R>AX!"XZRR@C5_?4^P".90`*]#[D(PA*&MPV7U2
-M;.]7.&/5!?P@C:J)S&T%=%,KJ@X0[""E8G!I!/I%`KSMA<#^!%C+Y*")'1](
-MJ06:CXD^5K*:`$E<L@BJ/F_'T+B"7]@ZTSH#Q4D(HV+'N)`YXIE`=KP4=YJ=
-MJF(B!L#\<;%%HG<.LJ9DRD!8A?@LI*E>`B`0$P5;&R;BF<5/Y7&(5A`<TB[M
-<.ZP#3X6R2U+IJWT5!$`<=U?^+N2*<*$@>?:!J@``
+M0EIH.3%!629364.3#=@``-+_W?__2_358_WZ/__?8*?OWB8A_B2```4@`,0"
+M@0C0`YX`)E`6H-")J&IDV2,C)H&F330``-`:&@:8@#(PAD``--1HF1HF0T3$
+MTAIH#U-'J``T``````>H#(!P``#0-#0T-,@`T``&@&AH``&0``<```T#0T-#
+M3(`-``!H!H:``!D``")1$R0GJ>ILI/1D!,)D&&)J8:`(&$&:F(9&F3TC#"EX
+MTR!;ER<Y/W/8%RN8K<Z&$,)P."?&SVA9I8QW(NI*1)"$"`'&@&U$'F4IYH@'
+MV$`!?C$%$0`>)EHN+:;W/S@4P0$!1`'?C!I(C`4DT=*4*P$/@01$1`'#%;N4
+MH7542A!ONH!@P1E2HR^G,V=@ML2GHX=3^O73`3FP:9@S)-O6IGS+"0)<AL_]
+MC]]BJ@B`.YR0O#0<^0SL%FG1'H:.GELW+M]7#4W^GJ!?B"X?P4+BJE"KC@?2
+MI:H;W'HVV'OU%/K-:U0HAF;9+E/F&W$$0"I!**0+&4>6J653D1?G4V:>6BI;
+M4#0@[$G.L/OV.O4.[7`DJ*XBG4[&MFVSJA`K"H:BI0+^G0+#@JE+*T.,1!`E
+M*.^+/,"DY36'@:(33(1@^F!.&Q/!^U"AZ5''>2`_4G?2K^#%G4,(Q?3;:K-2
+MJJ5CBN,>-M66$(\$B"$V#=,3B(">#<HTZE++^E[PZ(%>:B=F0CHU"0"HH=)/
+M9PD5$]I2SY$*J!@NFVGOWT4::?:,*TDA*L:4IJ18UE(""4D!!<'BD]#H+,HS
+M2$@1+.&<=#;P%*@D/$6G,2N):O[12QA20]EP`\,+8_`,?HL3C/US`W:M^L8#
+MYF%%M`JPN>8]-D[#'&#C$!6OT40;E-T)XT["%`6H@@*=@@9Y8HJHD;.]/6,"
+MZ_/='):KW:K4N.F%H0O#14`H6>3)&BI!C#@++V4C$:'R*:`LT40Y$;<O8-KD
+M@.F0AU3$'['])1P:L]E&!E[$LP50[$2&&T/J>PYB%PUE)R-[P]K[@,X^?BP2
+ME$%ZW\$,0AE+6X+^I78V+U<X9,P+\X84;3/$T:0*X6;9U(<)NL`P261N8PS1
+MO$DUTQU1E!_(DB:GA%-;P16<'H%:"ZEL@'%-V&\(A"8!$,*MCYDC?$*5#GA&
+M+UYB:'/*53>_?UZF<GBU>?M)YK\A1P3)?C[)"'6AKL*,('(VP[[FI3?'#?DO
+M)SA=J#1"3.*-1;`<8RJ-(!07(M(LC6:`)(`@:Y4_@*AOB%80'5C(&)M@>%A]
+>`03A;8?5JI>F&!NYJB@B`.1W?_%W)%.%"00Y,-V`
 `
 end