aboutsummaryrefslogtreecommitdiff
path: root/archival/libarchive
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2015-10-31 17:13:47 +0000
committerRon Yorston <rmy@pobox.com>2015-10-31 17:13:47 +0000
commit4432dbba6559d3d88e18ecf2c33d9e5a39e82074 (patch)
treef6db886523a04e0b45926336223ff8c32761dc43 /archival/libarchive
parentbc09f29f78547856e2152dc47051aeed548f28e8 (diff)
parent6bd3fff51aa74e2ee2d87887b12182a3b09792ef (diff)
downloadbusybox-w32-4432dbba6559d3d88e18ecf2c33d9e5a39e82074.tar.gz
busybox-w32-4432dbba6559d3d88e18ecf2c33d9e5a39e82074.tar.bz2
busybox-w32-4432dbba6559d3d88e18ecf2c33d9e5a39e82074.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'archival/libarchive')
-rw-r--r--archival/libarchive/data_extract_all.c118
-rw-r--r--archival/libarchive/decompress_gunzip.c36
-rw-r--r--archival/libarchive/get_header_tar.c1
3 files changed, 101 insertions, 54 deletions
diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c
index 45776dcbe..bd034afdc 100644
--- a/archival/libarchive/data_extract_all.c
+++ b/archival/libarchive/data_extract_all.c
@@ -11,6 +11,12 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
11 file_header_t *file_header = archive_handle->file_header; 11 file_header_t *file_header = archive_handle->file_header;
12 int dst_fd; 12 int dst_fd;
13 int res; 13 int res;
14 char *hard_link;
15#if ENABLE_FEATURE_TAR_LONG_OPTIONS
16 char *dst_name;
17#else
18# define dst_name (file_header->name)
19#endif
14 20
15#if ENABLE_FEATURE_TAR_SELINUX 21#if ENABLE_FEATURE_TAR_SELINUX
16 char *sctx = archive_handle->tar__sctx[PAX_NEXT_FILE]; 22 char *sctx = archive_handle->tar__sctx[PAX_NEXT_FILE];
@@ -23,11 +29,49 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
23 } 29 }
24#endif 30#endif
25 31
32 /* Hard links are encoded as regular files of size 0
33 * with a nonempty link field */
34 hard_link = NULL;
35 if (S_ISREG(file_header->mode) && file_header->size == 0)
36 hard_link = file_header->link_target;
37
38#if ENABLE_FEATURE_TAR_LONG_OPTIONS
39 dst_name = file_header->name;
40 if (archive_handle->tar__strip_components) {
41 unsigned n = archive_handle->tar__strip_components;
42 do {
43 dst_name = strchr(dst_name, '/');
44 if (!dst_name || dst_name[1] == '\0') {
45 data_skip(archive_handle);
46 goto ret;
47 }
48 dst_name++;
49 /*
50 * Link target is shortened only for hardlinks:
51 * softlinks restored unchanged.
52 */
53 if (hard_link) {
54// GNU tar 1.26 does not check that we reached end of link name:
55// if "dir/hardlink" is hardlinked to "file",
56// tar xvf a.tar --strip-components=1 says:
57// tar: hardlink: Cannot hard link to '': No such file or directory
58// and continues processing. We silently skip such entries.
59 hard_link = strchr(hard_link, '/');
60 if (!hard_link || hard_link[1] == '\0') {
61 data_skip(archive_handle);
62 goto ret;
63 }
64 hard_link++;
65 }
66 } while (--n != 0);
67 }
68#endif
69
26 if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) { 70 if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) {
27 char *slash = strrchr(file_header->name, '/'); 71 char *slash = strrchr(dst_name, '/');
28 if (slash) { 72 if (slash) {
29 *slash = '\0'; 73 *slash = '\0';
30 bb_make_directory(file_header->name, -1, FILEUTILS_RECUR); 74 bb_make_directory(dst_name, -1, FILEUTILS_RECUR);
31 *slash = '/'; 75 *slash = '/';
32 } 76 }
33 } 77 }
@@ -35,12 +79,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
35 if (archive_handle->ah_flags & ARCHIVE_UNLINK_OLD) { 79 if (archive_handle->ah_flags & ARCHIVE_UNLINK_OLD) {
36 /* Remove the entry if it exists */ 80 /* Remove the entry if it exists */
37 if (!S_ISDIR(file_header->mode)) { 81 if (!S_ISDIR(file_header->mode)) {
38 /* Is it hardlink? 82 if (hard_link) {
39 * We encode hard links as regular files of size 0 with a symlink */
40 if (S_ISREG(file_header->mode)
41 && file_header->link_target
42 && file_header->size == 0
43 ) {
44 /* Ugly special case: 83 /* Ugly special case:
45 * tar cf t.tar hardlink1 hardlink2 hardlink1 84 * tar cf t.tar hardlink1 hardlink2 hardlink1
46 * results in this tarball structure: 85 * results in this tarball structure:
@@ -48,22 +87,22 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
48 * hardlink2 -> hardlink1 87 * hardlink2 -> hardlink1
49 * hardlink1 -> hardlink1 <== !!! 88 * hardlink1 -> hardlink1 <== !!!
50 */ 89 */
51 if (strcmp(file_header->link_target, file_header->name) == 0) 90 if (strcmp(hard_link, dst_name) == 0)
52 goto ret; 91 goto ret;
53 } 92 }
54 /* Proceed with deleting */ 93 /* Proceed with deleting */
55 if (unlink(file_header->name) == -1 94 if (unlink(dst_name) == -1
56 && errno != ENOENT 95 && errno != ENOENT
57 ) { 96 ) {
58 bb_perror_msg_and_die("can't remove old file %s", 97 bb_perror_msg_and_die("can't remove old file %s",
59 file_header->name); 98 dst_name);
60 } 99 }
61 } 100 }
62 } 101 }
63 else if (archive_handle->ah_flags & ARCHIVE_EXTRACT_NEWER) { 102 else if (archive_handle->ah_flags & ARCHIVE_EXTRACT_NEWER) {
64 /* Remove the existing entry if its older than the extracted entry */ 103 /* Remove the existing entry if its older than the extracted entry */
65 struct stat existing_sb; 104 struct stat existing_sb;
66 if (lstat(file_header->name, &existing_sb) == -1) { 105 if (lstat(dst_name, &existing_sb) == -1) {
67 if (errno != ENOENT) { 106 if (errno != ENOENT) {
68 bb_perror_msg_and_die("can't stat old file"); 107 bb_perror_msg_and_die("can't stat old file");
69 } 108 }
@@ -73,30 +112,25 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
73 && !S_ISDIR(file_header->mode) 112 && !S_ISDIR(file_header->mode)
74 ) { 113 ) {
75 bb_error_msg("%s not created: newer or " 114 bb_error_msg("%s not created: newer or "
76 "same age file exists", file_header->name); 115 "same age file exists", dst_name);
77 } 116 }
78 data_skip(archive_handle); 117 data_skip(archive_handle);
79 goto ret; 118 goto ret;
80 } 119 }
81 else if ((unlink(file_header->name) == -1) && (errno != EISDIR)) { 120 else if ((unlink(dst_name) == -1) && (errno != EISDIR)) {
82 bb_perror_msg_and_die("can't remove old file %s", 121 bb_perror_msg_and_die("can't remove old file %s",
83 file_header->name); 122 dst_name);
84 } 123 }
85 } 124 }
86 125
87 /* Handle hard links separately 126 /* Handle hard links separately */
88 * We encode hard links as regular files of size 0 with a symlink */ 127 if (hard_link) {
89 if (S_ISREG(file_header->mode) 128 res = link(hard_link, dst_name);
90 && file_header->link_target 129 if (res != 0 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) {
91 && file_header->size == 0
92 ) {
93 /* hard link */
94 res = link(file_header->link_target, file_header->name);
95 if ((res == -1) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) {
96 bb_perror_msg("can't create %slink " 130 bb_perror_msg("can't create %slink "
97 "from %s to %s", "hard", 131 "from %s to %s", "hard",
98 file_header->name, 132 dst_name,
99 file_header->link_target); 133 hard_link);
100 } 134 }
101 /* Hardlinks have no separate mode/ownership, skip chown/chmod */ 135 /* Hardlinks have no separate mode/ownership, skip chown/chmod */
102 goto ret; 136 goto ret;
@@ -106,17 +140,17 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
106 switch (file_header->mode & S_IFMT) { 140 switch (file_header->mode & S_IFMT) {
107 case S_IFREG: { 141 case S_IFREG: {
108 /* Regular file */ 142 /* Regular file */
109 char *dst_name; 143 char *dst_nameN;
110 int flags = O_WRONLY | O_CREAT | O_EXCL; 144 int flags = O_WRONLY | O_CREAT | O_EXCL;
111 if (archive_handle->ah_flags & ARCHIVE_O_TRUNC) 145 if (archive_handle->ah_flags & ARCHIVE_O_TRUNC)
112 flags = O_WRONLY | O_CREAT | O_TRUNC; 146 flags = O_WRONLY | O_CREAT | O_TRUNC;
113 dst_name = file_header->name; 147 dst_nameN = dst_name;
114#ifdef ARCHIVE_REPLACE_VIA_RENAME 148#ifdef ARCHIVE_REPLACE_VIA_RENAME
115 if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) 149 if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME)
116 /* rpm-style temp file name */ 150 /* rpm-style temp file name */
117 dst_name = xasprintf("%s;%x", dst_name, (int)getpid()); 151 dst_nameN = xasprintf("%s;%x", dst_name, (int)getpid());
118#endif 152#endif
119 dst_fd = xopen3(dst_name, 153 dst_fd = xopen3(dst_nameN,
120 flags, 154 flags,
121 file_header->mode 155 file_header->mode
122 ); 156 );
@@ -124,32 +158,32 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
124 close(dst_fd); 158 close(dst_fd);
125#ifdef ARCHIVE_REPLACE_VIA_RENAME 159#ifdef ARCHIVE_REPLACE_VIA_RENAME
126 if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) { 160 if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) {
127 xrename(dst_name, file_header->name); 161 xrename(dst_nameN, dst_name);
128 free(dst_name); 162 free(dst_nameN);
129 } 163 }
130#endif 164#endif
131 break; 165 break;
132 } 166 }
133 case S_IFDIR: 167 case S_IFDIR:
134 res = mkdir(file_header->name, file_header->mode); 168 res = mkdir(dst_name, file_header->mode);
135 if ((res == -1) 169 if ((res == -1)
136 && (errno != EISDIR) /* btw, Linux doesn't return this */ 170 && (errno != EISDIR) /* btw, Linux doesn't return this */
137 && (errno != EEXIST) 171 && (errno != EEXIST)
138 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) 172 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
139 ) { 173 ) {
140 bb_perror_msg("can't make dir %s", file_header->name); 174 bb_perror_msg("can't make dir %s", dst_name);
141 } 175 }
142 break; 176 break;
143 case S_IFLNK: 177 case S_IFLNK:
144 /* Symlink */ 178 /* Symlink */
145//TODO: what if file_header->link_target == NULL (say, corrupted tarball?) 179//TODO: what if file_header->link_target == NULL (say, corrupted tarball?)
146 res = symlink(file_header->link_target, file_header->name); 180 res = symlink(file_header->link_target, dst_name);
147 if ((res == -1) 181 if (res != 0
148 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) 182 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
149 ) { 183 ) {
150 bb_perror_msg("can't create %slink " 184 bb_perror_msg("can't create %slink "
151 "from %s to %s", "sym", 185 "from %s to %s", "sym",
152 file_header->name, 186 dst_name,
153 file_header->link_target); 187 file_header->link_target);
154 } 188 }
155 break; 189 break;
@@ -157,11 +191,11 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
157 case S_IFBLK: 191 case S_IFBLK:
158 case S_IFCHR: 192 case S_IFCHR:
159 case S_IFIFO: 193 case S_IFIFO:
160 res = mknod(file_header->name, file_header->mode, file_header->device); 194 res = mknod(dst_name, file_header->mode, file_header->device);
161 if ((res == -1) 195 if ((res == -1)
162 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) 196 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
163 ) { 197 ) {
164 bb_perror_msg("can't create node %s", file_header->name); 198 bb_perror_msg("can't create node %s", dst_name);
165 } 199 }
166 break; 200 break;
167 default: 201 default:
@@ -186,20 +220,20 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
186 } 220 }
187#endif 221#endif
188 /* GNU tar 1.15.1 uses chown, not lchown */ 222 /* GNU tar 1.15.1 uses chown, not lchown */
189 chown(file_header->name, uid, gid); 223 chown(dst_name, uid, gid);
190 } 224 }
191 /* uclibc has no lchmod, glibc is even stranger - 225 /* uclibc has no lchmod, glibc is even stranger -
192 * it has lchmod which seems to do nothing! 226 * it has lchmod which seems to do nothing!
193 * so we use chmod... */ 227 * so we use chmod... */
194 if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_PERM)) { 228 if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_PERM)) {
195 chmod(file_header->name, file_header->mode); 229 chmod(dst_name, file_header->mode);
196 } 230 }
197 if (archive_handle->ah_flags & ARCHIVE_RESTORE_DATE) { 231 if (archive_handle->ah_flags & ARCHIVE_RESTORE_DATE) {
198 struct timeval t[2]; 232 struct timeval t[2];
199 233
200 t[1].tv_sec = t[0].tv_sec = file_header->mtime; 234 t[1].tv_sec = t[0].tv_sec = file_header->mtime;
201 t[1].tv_usec = t[0].tv_usec = 0; 235 t[1].tv_usec = t[0].tv_usec = 0;
202 utimes(file_header->name, t); 236 utimes(dst_name, t);
203 } 237 }
204 } 238 }
205 239
diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c
index b6ae7f738..eb64645ae 100644
--- a/archival/libarchive/decompress_gunzip.c
+++ b/archival/libarchive/decompress_gunzip.c
@@ -308,11 +308,11 @@ static int huft_build(const unsigned *b, const unsigned n,
308 unsigned i; /* counter, current code */ 308 unsigned i; /* counter, current code */
309 unsigned j; /* counter */ 309 unsigned j; /* counter */
310 int k; /* number of bits in current code */ 310 int k; /* number of bits in current code */
311 unsigned *p; /* pointer into c[], b[], or v[] */ 311 const unsigned *p; /* pointer into c[], b[], or v[] */
312 huft_t *q; /* points to current table */ 312 huft_t *q; /* points to current table */
313 huft_t r; /* table entry for structure assignment */ 313 huft_t r; /* table entry for structure assignment */
314 huft_t *u[BMAX]; /* table stack */ 314 huft_t *u[BMAX]; /* table stack */
315 unsigned v[N_MAX]; /* values in order of bit length */ 315 unsigned v[N_MAX + 1]; /* values in order of bit length. last v[] is never used */
316 int ws[BMAX + 1]; /* bits decoded stack */ 316 int ws[BMAX + 1]; /* bits decoded stack */
317 int w; /* bits decoded */ 317 int w; /* bits decoded */
318 unsigned x[BMAX + 1]; /* bit offsets, then code stack */ 318 unsigned x[BMAX + 1]; /* bit offsets, then code stack */
@@ -327,7 +327,7 @@ static int huft_build(const unsigned *b, const unsigned n,
327 327
328 /* Generate counts for each bit length */ 328 /* Generate counts for each bit length */
329 memset(c, 0, sizeof(c)); 329 memset(c, 0, sizeof(c));
330 p = (unsigned *) b; /* cast allows us to reuse p for pointing to b */ 330 p = b;
331 i = n; 331 i = n;
332 do { 332 do {
333 c[*p]++; /* assume all entries <= BMAX */ 333 c[*p]++; /* assume all entries <= BMAX */
@@ -367,8 +367,12 @@ static int huft_build(const unsigned *b, const unsigned n,
367 *xp++ = j; 367 *xp++ = j;
368 } 368 }
369 369
370 /* Make a table of values in order of bit lengths */ 370 /* Make a table of values in order of bit lengths.
371 p = (unsigned *) b; 371 * To detect bad input, unused v[i]'s are set to invalid value UINT_MAX.
372 * In particular, last v[i] is never filled and must not be accessed.
373 */
374 memset(v, 0xff, sizeof(v));
375 p = b;
372 i = 0; 376 i = 0;
373 do { 377 do {
374 j = *p++; 378 j = *p++;
@@ -435,7 +439,9 @@ static int huft_build(const unsigned *b, const unsigned n,
435 439
436 /* set up table entry in r */ 440 /* set up table entry in r */
437 r.b = (unsigned char) (k - w); 441 r.b = (unsigned char) (k - w);
438 if (p >= v + n) { 442 if (/*p >= v + n || -- redundant, caught by the second check: */
443 *p == UINT_MAX /* do we access uninited v[i]? (see memset(v))*/
444 ) {
439 r.e = 99; /* out of values--invalid code */ 445 r.e = 99; /* out of values--invalid code */
440 } else if (*p < s) { 446 } else if (*p < s) {
441 r.e = (unsigned char) (*p < 256 ? 16 : 15); /* 256 is EOB code */ 447 r.e = (unsigned char) (*p < 256 ? 16 : 15); /* 256 is EOB code */
@@ -520,8 +526,9 @@ static NOINLINE int inflate_codes(STATE_PARAM_ONLY)
520 e = t->e; 526 e = t->e;
521 if (e > 16) 527 if (e > 16)
522 do { 528 do {
523 if (e == 99) 529 if (e == 99) {
524 abort_unzip(PASS_STATE_ONLY);; 530 abort_unzip(PASS_STATE_ONLY);
531 }
525 bb >>= t->b; 532 bb >>= t->b;
526 k -= t->b; 533 k -= t->b;
527 e -= 16; 534 e -= 16;
@@ -557,8 +564,9 @@ static NOINLINE int inflate_codes(STATE_PARAM_ONLY)
557 e = t->e; 564 e = t->e;
558 if (e > 16) 565 if (e > 16)
559 do { 566 do {
560 if (e == 99) 567 if (e == 99) {
561 abort_unzip(PASS_STATE_ONLY); 568 abort_unzip(PASS_STATE_ONLY);
569 }
562 bb >>= t->b; 570 bb >>= t->b;
563 k -= t->b; 571 k -= t->b;
564 e -= 16; 572 e -= 16;
@@ -824,8 +832,9 @@ static int inflate_block(STATE_PARAM smallint *e)
824 832
825 b_dynamic >>= 4; 833 b_dynamic >>= 4;
826 k_dynamic -= 4; 834 k_dynamic -= 4;
827 if (nl > 286 || nd > 30) 835 if (nl > 286 || nd > 30) {
828 abort_unzip(PASS_STATE_ONLY); /* bad lengths */ 836 abort_unzip(PASS_STATE_ONLY); /* bad lengths */
837 }
829 838
830 /* read in bit-length-code lengths */ 839 /* read in bit-length-code lengths */
831 for (j = 0; j < nb; j++) { 840 for (j = 0; j < nb; j++) {
@@ -906,12 +915,14 @@ static int inflate_block(STATE_PARAM smallint *e)
906 bl = lbits; 915 bl = lbits;
907 916
908 i = huft_build(ll, nl, 257, cplens, cplext, &inflate_codes_tl, &bl); 917 i = huft_build(ll, nl, 257, cplens, cplext, &inflate_codes_tl, &bl);
909 if (i != 0) 918 if (i != 0) {
910 abort_unzip(PASS_STATE_ONLY); 919 abort_unzip(PASS_STATE_ONLY);
920 }
911 bd = dbits; 921 bd = dbits;
912 i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &inflate_codes_td, &bd); 922 i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &inflate_codes_td, &bd);
913 if (i != 0) 923 if (i != 0) {
914 abort_unzip(PASS_STATE_ONLY); 924 abort_unzip(PASS_STATE_ONLY);
925 }
915 926
916 /* set up data for inflate_codes() */ 927 /* set up data for inflate_codes() */
917 inflate_codes_setup(PASS_STATE bl, bd); 928 inflate_codes_setup(PASS_STATE bl, bd);
@@ -999,6 +1010,7 @@ inflate_unzip_internal(STATE_PARAM transformer_state_t *xstate)
999 error_msg = "corrupted data"; 1010 error_msg = "corrupted data";
1000 if (setjmp(error_jmp)) { 1011 if (setjmp(error_jmp)) {
1001 /* Error from deep inside zip machinery */ 1012 /* Error from deep inside zip machinery */
1013 bb_error_msg(error_msg);
1002 n = -1; 1014 n = -1;
1003 goto ret; 1015 goto ret;
1004 } 1016 }
diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c
index fb68673b9..ac2be726f 100644
--- a/archival/libarchive/get_header_tar.c
+++ b/archival/libarchive/get_header_tar.c
@@ -418,6 +418,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle)
418 418
419 /* Everything up to and including last ".." component is stripped */ 419 /* Everything up to and including last ".." component is stripped */
420 overlapping_strcpy(file_header->name, strip_unsafe_prefix(file_header->name)); 420 overlapping_strcpy(file_header->name, strip_unsafe_prefix(file_header->name));
421//TODO: do the same for file_header->link_target?
421 422
422 /* Strip trailing '/' in directories */ 423 /* Strip trailing '/' in directories */
423 /* Must be done after mode is set as '/' is used to check if it's a directory */ 424 /* Must be done after mode is set as '/' is used to check if it's a directory */