summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>2011-12-30 14:04:14 -0500
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>2011-12-30 14:04:14 -0500
commitb4a4200f204080b2442523059ce84ee794c31173 (patch)
tree1b41c974368cbec7901951ab50cd49f331e0e5f3
parentf80e9537a2a2bf965e71b1be34dea35710a3ef20 (diff)
downloadlibarchive-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.am2
-rw-r--r--tar/test/CMakeLists.txt1
-rw-r--r--tar/test/test_print_longpath.c54
-rw-r--r--tar/test/test_print_longpath.tar.Z.uu24
-rw-r--r--tar/util.c18
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
diff --git a/tar/util.c b/tar/util.c
index 95d0db5d..7e705c2b 100644
--- a/tar/util.c
+++ b/tar/util.c
@@ -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;
}
}