diff options
author | Michihiro NAKAJIMA <ggcueroad@gmail.com> | 2011-12-30 14:04:14 -0500 |
---|---|---|
committer | Michihiro NAKAJIMA <ggcueroad@gmail.com> | 2011-12-30 14:04:14 -0500 |
commit | b4a4200f204080b2442523059ce84ee794c31173 (patch) | |
tree | 1b41c974368cbec7901951ab50cd49f331e0e5f3 | |
parent | f80e9537a2a2bf965e71b1be34dea35710a3ef20 (diff) | |
download | libarchive-b4a4200f204080b2442523059ce84ee794c31173.tar.gz |
Issue 216: bsdtar output truncated.
Properly treat the long path that the return code of snprintf function is -1.
SVN-Revision: 4042
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | tar/test/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tar/test/test_print_longpath.c | 54 | ||||
-rw-r--r-- | tar/test/test_print_longpath.tar.Z.uu | 24 | ||||
-rw-r--r-- | tar/util.c | 18 |
5 files changed, 97 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am index 6d9165e6..026fd53f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -665,6 +665,7 @@ bsdtar_test_SOURCES= \ tar/test/test_option_s.c \ tar/test/test_option_uid_uname.c \ tar/test/test_patterns.c \ + tar/test/test_print_longpath.c \ tar/test/test_stdio.c \ tar/test/test_strip_components.c \ tar/test/test_symlink_dir.c \ @@ -694,6 +695,7 @@ bsdtar_test_EXTRA_DIST= \ tar/test/test_patterns_2.tar.uu \ tar/test/test_patterns_3.tar.uu \ tar/test/test_patterns_4.tar.uu \ + tar/test/test_print_longpath.tar.Z.uu \ tar/test/CMakeLists.txt diff --git a/tar/test/CMakeLists.txt b/tar/test/CMakeLists.txt index f30a0dd3..3329ff11 100644 --- a/tar/test/CMakeLists.txt +++ b/tar/test/CMakeLists.txt @@ -33,6 +33,7 @@ IF(ENABLE_TAR AND ENABLE_TEST) test_option_s.c test_option_uid_uname.c test_patterns.c + test_print_longpath.c test_stdio.c test_strip_components.c test_symlink_dir.c diff --git a/tar/test/test_print_longpath.c b/tar/test/test_print_longpath.c new file mode 100644 index 00000000..4bac1679 --- /dev/null +++ b/tar/test/test_print_longpath.c @@ -0,0 +1,54 @@ +/*- + * Copyright (c) 2011 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$"); + +DEFINE_TEST(test_print_longpath) +{ + const char *reffile = "test_print_longpath.tar.Z"; + char buff[2048]; + int i, j, k; + + /* Reference file has one entry "file" with a very old timestamp. */ + extract_reference_file(reffile); + + /* Build long path pattern. */ + memset(buff, 0, sizeof(buff)); + for (k = 0; k < 4; k++) { + for (j = 0; j < k+1; j++) { + for (i = 0; i < 10; i++) + strncat(buff, "0123456789", + sizeof(buff) - strlen(buff) -1); + strncat(buff, "/", sizeof(buff) - strlen(buff) -1); + } + strncat(buff, "\n", sizeof(buff) - strlen(buff) -1); + } + buff[sizeof(buff)-1] = '\0'; + + assertEqualInt(0, + systemf("%s -tf %s >test.out 2>test.err", testprog, reffile)); + assertTextFileContents(buff, "test.out"); + assertEmptyFile("test.err"); +} diff --git a/tar/test/test_print_longpath.tar.Z.uu b/tar/test/test_print_longpath.tar.Z.uu new file mode 100644 index 00000000..05658ffc --- /dev/null +++ b/tar/test/test_print_longpath.tar.Z.uu @@ -0,0 +1,24 @@ +begin 644 test_print_longpath.tar.Z +M'YV04,+@05(F#)DR<E[`B"%C!HT:-F[@R+&PX<.($RLZA"B1(L.-&#U:Y)CQ +MX\6.&D^6'!DR)4<``&#(O%&C!HB8"VG&N"DSADZ>,H/*E$$31(P8$6_0"$H4 +M!`R+-&@``($'IM6K6+-JW<JUJ]>O8+O6F4,GC!R<8^J4"<LV[5JV8(7*!"KT +M)MR[>//JW<NWK]>C.^&$H8.FA\N6)DF*!(DR,6*6C2&O9#Q9Y6++ASN^4"`# +M!H@Q=-*T*=,CQ@P9-638\%B#L^?!HDF;1JV:M8(9.$`P22(DB)0A2))8*>)B +MC)R"H=^X"3VZ].G4-B;FP*'`K_7KV+-KW\Z]N_?O5S-75BS^,GG'D2F;?ZR^ +M?.87.&'0M(G39XV=]7_&EQO4*-(;2C%U@U,RH`;15#6`IZ!V8Y5UEDQN:1=A +M=OS1U=^"&&:H85@!#53000FYA]YX[&$VXGKIF2@9BC`%-1]0]N'7DW[\R125 +M#/XEM91,-3DU`T0TS#!551L6"5>#9J&EEH1+4BB7A7/%=**(*U+9WI185IFE +M>D;Z)0-#(`A&F&%;JGBEEFB>J::9;"JF4)GGI=EFB7&N6>><FKGV&7.R/5<; +M##/<H"=LS<T&'44U4(>;;KSY!IQPQ!F'7!K*\>D<;:M55%V7G';J:896XDEB +MBG>62N>II$8$GXL]YG<?C#36V-]1.@;5(Z`TW&!##`A^ZJM52#X(PX38$7M= +MA?M%&:JIJ38[ZK,H0EO>KW=U2)!!"+TI)[/2PHEJMY"U.%.K,[[JJHPUVB!? +MC@#N&$-J/@(I%574^AJLDF\5VR1VR/;KK;/1!KSLMP*?6"];,Y@6YF"%#0RP +MP^#:27!YVDK\\+\1BUKPBA5K#/'&%F?,;0Z;=;9G;)<>"L-T@UIJZ)\RY'!; +M;KOU]EMPPQ5W'&R5HOQRIC%O>O#07WUL-,8@>XS>JN/25RZZ,4)9(:WM]@0O +MKC3=T"O17=X+X;[7&6M=OT]*N>W$2!]]-L!<>V7MA]FJ'7+2(SLLKGSDYF3N +MTU+/!(,-[`:X4)#QVA#5D&T;Z?6P8%LGME]DUV7VW'(KO;;((27.%0TQT+#P +MF)77G?;HEY,<.MJEGPYPQZ*G3CKE2+...NRNUSYWR9Z!YK.?F>800\N[8TJ1 +M[T(3K3KF%]N.)]-X.ZTWU+'*ZAG5@G<^@X^YUJ`U"`EJKN'BC_<5/E^17W@\ +:W;-;/K?W[+?O_OOPQR___/37;__]^.>OOU<` +` +end @@ -115,8 +115,21 @@ safe_fprintf(FILE *f, const char *fmt, ...) va_end(ap); /* If the result was too large, allocate a buffer on the heap. */ - if (length >= fmtbuff_length) { - fmtbuff_length = length+1; + while (length < 0 || length >= fmtbuff_length) { + if (length >= fmtbuff_length) + fmtbuff_length = length+1; + else if (fmtbuff_length < 8192) + fmtbuff_length *= 2; + else { + int old_length = fmtbuff_length; + fmtbuff_length += fmtbuff_length / 4; + if (old_length > fmtbuff_length) { + length = old_length; + fmtbuff_heap[length-1] = '\0'; + break; + } + } + free(fmtbuff_heap); fmtbuff_heap = malloc(fmtbuff_length); /* Reformat the result into the heap buffer if we can. */ @@ -129,6 +142,7 @@ safe_fprintf(FILE *f, const char *fmt, ...) /* Leave fmtbuff pointing to the truncated * string in fmtbuff_stack. */ length = sizeof(fmtbuff_stack) - 1; + break; } } |