From a34cde9885d95f7c27c3fa887fdd9768fad6d956 Mon Sep 17 00:00:00 2001 From: Martin Matuska Date: Fri, 3 May 2019 10:48:28 +0200 Subject: [PATCH] RAR5: extract files and directories from Windows archives with correct mode Unrar assumes mode 0755 for directories, 0644 for files and 0444 for read-only files. --- libarchive/archive_read_support_format_rar5.c | 26 +++- libarchive/test/test_read_format_rar5.c | 12 ++ .../test/test_read_format_rar5_win32.rar.uu | 131 +++++++++--------- 3 files changed, 98 insertions(+), 71 deletions(-) diff --git a/libarchive/archive_read_support_format_rar5.c b/libarchive/archive_read_support_format_rar5.c index e3c3b62d1..e05bf2645 100644 --- a/libarchive/archive_read_support_format_rar5.c +++ b/libarchive/archive_read_support_format_rar5.c @@ -1572,6 +1572,11 @@ static int process_head_file(struct archive_read* a, struct rar5* rar, UNKNOWN_UNPACKED_SIZE = 0x0008, }; + enum FILE_ATTRS { + ATTR_READONLY = 0x1, ATTR_HIDDEN = 0x2, ATTR_SYSTEM = 0x4, + ATTR_DIRECTORY = 0x10, + }; + enum COMP_INFO_FLAGS { SOLID = 0x0040, }; @@ -1629,17 +1634,26 @@ static int process_head_file(struct archive_read* a, struct rar5* rar, if(host_os == HOST_WINDOWS) { /* Host OS is Windows */ - unsigned short mode = 0660; + __LA_MODE_T mode; - if(is_dir) - mode |= AE_IFDIR; - else - mode |= AE_IFREG; + if(file_attr & ATTR_DIRECTORY) { + mode = 0755 | AE_IFDIR; + } else { + if (file_attr & ATTR_READONLY) + mode = 0444 | AE_IFREG; + else + mode = 0644 | AE_IFREG; + } archive_entry_set_mode(entry, mode); + + /* + * TODO: implement attribute support (READONLY, HIDDEN, SYSTEM) + * This requires a platform-independent extended attribute handling + */ } else if(host_os == HOST_UNIX) { /* Host OS is Unix */ - archive_entry_set_mode(entry, (unsigned short) file_attr); + archive_entry_set_mode(entry, (__LA_MODE_T) file_attr); } else { /* Unknown host OS */ archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT, diff --git a/libarchive/test/test_read_format_rar5.c b/libarchive/test/test_read_format_rar5.c index cc1c4b896..c52422744 100644 --- a/libarchive/test/test_read_format_rar5.c +++ b/libarchive/test/test_read_format_rar5.c @@ -771,25 +771,37 @@ DEFINE_TEST(test_read_format_rar5_extract_win32) { PROLOGUE("test_read_format_rar5_win32.rar"); assertA(0 == archive_read_next_header(a, &ae)); + assertEqualString("testdir", archive_entry_pathname(ae)); + assertEqualInt(archive_entry_mode(ae), AE_IFDIR | 0755); + assertA(0 == extract_one(a, ae, 0)); + assertA(0 == archive_read_next_header(a, &ae)); assertEqualString("test.bin", archive_entry_pathname(ae)); + assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); assertA(0 == extract_one(a, ae, 0x7CCA70CD)); assertA(0 == archive_read_next_header(a, &ae)); assertEqualString("test1.bin", archive_entry_pathname(ae)); + assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); assertA(0 == extract_one(a, ae, 0x7E13B2C6)); assertA(0 == archive_read_next_header(a, &ae)); + /* Read only file */ assertEqualString("test2.bin", archive_entry_pathname(ae)); + assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0444); assertA(0 == extract_one(a, ae, 0xF166AFCB)); assertA(0 == archive_read_next_header(a, &ae)); assertEqualString("test3.bin", archive_entry_pathname(ae)); + assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); assertA(0 == extract_one(a, ae, 0x9FB123D9)); assertA(0 == archive_read_next_header(a, &ae)); assertEqualString("test4.bin", archive_entry_pathname(ae)); + assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); assertA(0 == extract_one(a, ae, 0x10C43ED4)); assertA(0 == archive_read_next_header(a, &ae)); assertEqualString("test5.bin", archive_entry_pathname(ae)); + assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); assertA(0 == extract_one(a, ae, 0xB9D155F2)); assertA(0 == archive_read_next_header(a, &ae)); assertEqualString("test6.bin", archive_entry_pathname(ae)); + assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0644); assertA(0 == extract_one(a, ae, 0x36A448FF)); EPILOGUE(); } diff --git a/libarchive/test/test_read_format_rar5_win32.rar.uu b/libarchive/test/test_read_format_rar5_win32.rar.uu index 59920490e..16d9fce1d 100644 --- a/libarchive/test/test_read_format_rar5_win32.rar.uu +++ b/libarchive/test/test_read_format_rar5_win32.rar.uu @@ -1,68 +1,69 @@ begin 644 test_read_format_rar5_win32.rar -M4F%R(1H'`0#SX8+K"P$%!P`&`0&`@(``/^"F5B0"`POI`@2P"2#-<,I\@`4` -M"'1E#?W= -MS:V=?6U=33TM#/SA0'XZ,BHF'.G#9J&A(*`?GQ[>GAV='-R<6]M:V -MEG96-A7UU;65=54R$W]?R/T"4^B4Y_A$ET6*,&>6%VHX*:8IE!?F0M%VG48R -MPSC`J$?_H)3&:0I?95"L5E8+BP&1:#; -MAX.`8'(/KF$3H*9V&`\#;>A[O8=7T(W\6$"-&#'G"AY-"8-B^.#F.APB!*GA -MA18[8T/Y\5"`;"$-"(32,9R0+R4`8B?AZB4"`POG`@2`("#&LA-^@`4`"71E -M_MZ^GGY>/AW -M]W;V=?5T]'/SEHZ&?G9N9EY63D8^-BXF'A -M8.!?WU[>7=UFYH!9@!;-"-LC0$.A"U@6`X1-8__0K^QS*_>TU/6 -MRJ_(8IKGE-.XIH6GK_HGV@`)6BG`)0(#"^8"!(`@(,NO9O&`!0`)=&5S=#(N -M8FEN"@,"A/;"@`U:U`'/]F(!$&1%9B]7!7]2222222222222222222222222 -M2222222222222222222222222222222222223[\^1N9V\]KM]OI+K^[M;N^9 -MT9N[T[_28S,,Z?,.-S?,\X<_BN=OR`"`"`&IAXZ<-OCW]O7T\_+Q\._N[>SK -MZNGHY^;EY./BX>#?WMWFI:2CHJ&@GYZ=G)N:F9B7EI64DY*1 -MD(^.C8R+BHF(AX:%A(."@8!_?GWWO8^T*7"EJ^DJ%`9V,`+9H1O$:`AT(6L" -MP'")[=I:<$/3LT`LP`MFA&Z1H"'0A:P+`<(GMREIP0].30"S`"V:$;A&@(=" -M%K`L!PB>VZ6G!#TW-`+,`+9H1MD:`AT(6L"P'")K'_Z%?V.97[VFIZV57Y#% -M-<\IIW%-"T]?]$^TVMWAVR4"`POT`@2`("#9([&?@`4`"71EO+LEY]]M9^&\\, -MWO7CO^DQF89X_9MAKF??:-?Q7/7Y`!`!`#848765^/?V]?3S\O'P[^[M[.OJ -MZ>CGYN7DX^+AX-_>W=S;VMG8U];5U-/2T=#/SLW,R\K)R,?&Q<3#PL'`O[Z] -MO+NZN;BWMK6TL[*QL*^NK:RKJJFHIZ:EI*.BH:"?GIV6E923DI&0 -MCXZ-C(N*B8B'AH6$@X*!@']^??=]3[8AOPALOH4&#J;"`FDX$V"95@TP3;@P -MF6DRPI=O")0\&G@!T,0$TG`FN3*KFER;<&$RTF6%+MV1*'@T[`.AB`FDX$UB -M958T/&FX`#:3+"EVZ(E#P:=`'0Q`32<":I,JJ:'C3<`!M)EA2^4__8C^QK(_ -M>\:'K=J/R*(O+ -MLEY]]M9^&\\,WO7CO^DQF89X_9MAKF??:-?Q7/7Y`!`!`#7=,+*J?'O[>OIY -M^7CX=_=V]G7U=/1S\W+R5DY&/C -M8N)AX6#@7]]>WEW=7-Q;VUK:6=E8V%?75M95U5344]-2TE'14-!/ST[.3#2X!T,0$TG`FL3*K&EB;<&$RTF6%+MX1*'@T -M\`.AB`FDX$U2954T/&FX`#:3+"EV[(E#P:=@'0Q`32<":A,JH:'C3<`!M)EA -M2^=?_L1_8UD?O>-#UNU'Y%$.=/..;N7KV[)>??;>LS[/'-[UX[_28S,,\?L,TUS/OM&_Q7/7Y`!`!`#6<+ -MK*J?'O[>OIY^7CX=_=V]G7U=/1S\W+R5DY&/C8N)AX6#@7]]>WEW=7-Q;VUK:6=E8V%?75M95U5344]-2TE'14 -M-!/ST[.3MVH_(HAYUR'CV(>#4]?^@ -M_:`_"MBZ)0(#"_P"!(`@(/](I#:`!0`)=&5S=#8N8FEN"@,"%79G@0U:U`'- -M[G@!$&1552]U;J2222222222222222222222222222222222222222222222 -M222222222222222<[SO.\W&:UX\XYNY>O;LEY]]MZS/L\CGYN7DX^+AX- -M_>W=S;VMG8U];5U-/2T=#/SLW,R\K)R,?&Q<3#PL'`O[Z]O+NZN;BWMK6TL[ -M*QL*^NK:RKJJFHIZ:EI*.BH:"?GIV6E923DI&0CXZ-C(N*B8B'AH -M6$@X*!@']^??=]Q]N(3A"3;)!`K]0<,EK)2D<7#&%%S2X:>$#;38!T>W8(A: -MV3LP5-G#):R4I'%@QA18TL&GA`VTV`='MT"(6MDZ,%39PR6LE*1Q4,845-*A -MIX0-M-@'1[<@B%K9.3!4V<,EK)2D<4#&%%#2@:>$#;38!T?./_W$?V-9'[WC -;0];M1^11#SKD/'L0\&IZ_]!^T!UW5E$#!00` +M4F%R(1H'`0#SX8+K"P$%!P`&`0&`@(``EV&"+"$"`PL`!0`0`````(````=T +M97-T9&ER"@,"5NNI_W0?[W +MVO?=>:\Z7^@`0`$`R""?GX]O7T\O'O[NSKZNGHY^7DX^+AX-_=W-K9U];5U- +M/2T,_-S,K)R,?&Q<3#P;^]O+NYN+>VM;2SLK&OKJVKJJFGI:2CHJ&@GYV'9T$&P`\Q!(R">9A6-`NFH9;8-YN'@X!@<@^N +M81.@IG88#P-MZ'N]AU?0C?Q80(T8,><*'DT)@V+XX.8Z'"($J>&%%CMC0_GQ +M4(!L(0T(A-(QG)`O)0`QGD%J)0(#"^L"!(`@(,:R$WZ``P`)=&5S=#$N8FEN +M"@,"$I6A@`U:U`'-\6<7#G7SNUN[YG1F[ +MO3O]%F,,Z?#,/6YOF>>GO;]_`_=OV`"`"`&PPZ<-FGU\_'O[>OIY^7CX=_=V +M]G7U=/1S\W+R5DY&/C8N)AX6#@ +M7]]>WEW=7-Q;VUK:6=E8V%?75M95U5344]-2TE'14-!/ST[.3FYH!9@!;-"-LC0$.A +M"U@6`X1/;5+3@AZ:F@%F`%LT(VB-`0Z$+6!8#A$UA]Z%,?GS*>SVE?X8*>=C +M4\-BG=.J=HXIZ?]R?M!(:PP')0(#"^L"!(`@(<7#G7SNUN[YG1F[ +MO3O]%F,,Z?#,/6YOF>>GO;]_`_=OV`"`"`&IATX;-/KY^/?V]?3S\O'P[^[M +M[.OJZ>CGYN7DX^+AX-_>W=S;VMG8U];5U-/2T=#/SLW,R\K)R,?&Q<3#PL'` +MO[Z]O+NZN;BWMK6TL[*QL*^NK:RKJJFHIZ:EI*.BH:"?GIV6E923 +MDI&0CXZ-C(N*B8B'AH6$@X*!@'_WO8_D*7"EJ_4J%`9V,`+9H1ND:`AT(6L" +MP'")[\[SO-RUK/'AS>Z]>]72\[VUGX; +MSPS6]^._Z+,89X_&9MAOF??:->O/X'?K\@`@`@!LK,L+N/CW]O7T\_+Q\._N +M[>SKZNGHY^;EY./BX>#?WMWFI:2CHJ&@GYZ=G)N:F9B7EI64 +MDY*1D(^.C8R+BHF(AX:%A(."@8!_?O_[[UOQB$^$)+[%!@ZJP@)I6!-DF59- +M,DTP85+::84MW9$H?1AV`=#$!-*P)L$RK!I@FF#"I;33"ENZ(E#Z,.@#H8@) +MI6!-UH>G1#RK4/$L0^/_<7F@SHER0)0(#"_<"!(`@(-0^Q!"` +M`P`)=&5S=#0N8FEN"@,"`HP9@0U:U`'/YW,!$&1552]7!7XDDDDDDDDDDDDD +MDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDG.\[SG-RUK/' +MASFZ]>]72\[VUGX;SPS6]^._Z+,89X_&9MAOF??:->O/X'?K\@`@`@!L*,KK +M*_'O[>OIY^7CX=_=V]G7U=/1S\W+R5DY&/C8N)AX6#@7]]>WEW=7-Q;VUK:6=E8V%?75M95U5344]-2TE'14-! +M/ST[.3$.%]B +M@P=380$TG`FR3*LFF2;D&$RVFF%+=@B4/HPP`=#$!-)P)KDRJYI<SKZNGHY^;EY./BX>#?WMWFI:2CHJ&@GYZ=G)N:F9B7EI64DY*1D(^.C8R+BHF(AX:%A(."@8!_? +MO_[[W'XXA.D)1LT$"OW!PR6LE*QQ<,847-+AIH@;:C`.CV[!$+6S=F"ILX9+ +M62E8XL&,*+&E@TT0-M1@'1[=`B%K9NC!4V<,EK)2L<5#&%%32H::(&VHP#H] +MN01"ULW)@J;.&2UDI6.*!C"BAI0--$#;48!T?G'][B''U_9#Z?:1^AHA[VM# +MT\$/*RH>)D0^/_<?EX^'?W= +MO9U]73T<_-R\G'QUL[&OK:NIIZ6CH9^=FYF7E9.1CXV+B8>%@X +M%_?7MY=W5S<6]M:VEG96-A7UU;65=54U%/34M)1T5#03\].SDW-3,Q+RTK*2 +MW((A:V;DP5-G#):R4K'%`QA10TH&FB!M +KJ,`Z/SC^]Q#CZ_LA]/M(_0T0][6AZ>"'E94/$R(?'_N'S0`==U91`P4$```` ` end -- 2.47.2