aboutsummaryrefslogtreecommitdiff
path: root/archival
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
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')
-rw-r--r--archival/Config.src2
-rw-r--r--archival/ar.c16
-rw-r--r--archival/bbunzip.c23
-rw-r--r--archival/gzip.c1
-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
-rw-r--r--archival/lzop.c14
-rw-r--r--archival/tar.c89
9 files changed, 209 insertions, 91 deletions
diff --git a/archival/Config.src b/archival/Config.src
index 76635ba78..a9afaea5b 100644
--- a/archival/Config.src
+++ b/archival/Config.src
@@ -31,7 +31,7 @@ config FEATURE_SEAMLESS_GZ
31 31
32config FEATURE_SEAMLESS_Z 32config FEATURE_SEAMLESS_Z
33 bool "tar, rpm, modprobe etc understand .Z data" 33 bool "tar, rpm, modprobe etc understand .Z data"
34 default n 34 default n # it is ancient
35 help 35 help
36 Make tar, rpm, modprobe etc understand .Z data. 36 Make tar, rpm, modprobe etc understand .Z data.
37 37
diff --git a/archival/ar.c b/archival/ar.c
index 89e6a1207..a850868f6 100644
--- a/archival/ar.c
+++ b/archival/ar.c
@@ -22,23 +22,13 @@
22//config: default n # needs to be improved to be able to replace binutils ar 22//config: default n # needs to be improved to be able to replace binutils ar
23//config: help 23//config: help
24//config: ar is an archival utility program used to create, modify, and 24//config: ar is an archival utility program used to create, modify, and
25//config: extract contents from archives. An archive is a single file holding 25//config: extract contents from archives. In practice, it is used exclusively
26//config: a collection of other files in a structure that makes it possible to 26//config: for object module archives used by compilers.
27//config: retrieve the original individual files (called archive members).
28//config: The original files' contents, mode (permissions), timestamp, owner,
29//config: and group are preserved in the archive, and can be restored on
30//config: extraction.
31//config: 27//config:
32//config: The stored filename is limited to 15 characters. (for more information
33//config: see long filename support).
34//config: ar has 60 bytes of overheads for every stored file.
35//config:
36//config: This implementation of ar can extract archives, it cannot create or
37//config: modify them.
38//config: On an x86 system, the ar applet adds about 1K. 28//config: On an x86 system, the ar applet adds about 1K.
39//config: 29//config:
40//config: Unless you have a specific application which requires ar, you should 30//config: Unless you have a specific application which requires ar, you should
41//config: probably say N here. 31//config: probably say N here: most compilers come with their own ar utility.
42//config: 32//config:
43//config:config FEATURE_AR_LONG_FILENAMES 33//config:config FEATURE_AR_LONG_FILENAMES
44//config: bool "Support for long filenames (not needed for debs)" 34//config: bool "Support for long filenames (not needed for debs)"
diff --git a/archival/bbunzip.c b/archival/bbunzip.c
index a859ef201..aaaf67e03 100644
--- a/archival/bbunzip.c
+++ b/archival/bbunzip.c
@@ -222,7 +222,7 @@ char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext)
222 222
223//config:config UNCOMPRESS 223//config:config UNCOMPRESS
224//config: bool "uncompress" 224//config: bool "uncompress"
225//config: default n 225//config: default n # ancient
226//config: help 226//config: help
227//config: uncompress is used to decompress archives created by compress. 227//config: uncompress is used to decompress archives created by compress.
228//config: Not much used anymore, replaced by gzip/gunzip. 228//config: Not much used anymore, replaced by gzip/gunzip.
@@ -292,6 +292,13 @@ int uncompress_main(int argc UNUSED_PARAM, char **argv)
292//config: gunzip is used to decompress archives created by gzip. 292//config: gunzip is used to decompress archives created by gzip.
293//config: You can use the `-t' option to test the integrity of 293//config: You can use the `-t' option to test the integrity of
294//config: an archive, without decompressing it. 294//config: an archive, without decompressing it.
295//config:
296//config:config FEATURE_GUNZIP_LONG_OPTIONS
297//config: bool "Enable long options"
298//config: default y
299//config: depends on GUNZIP && LONG_OPTS
300//config: help
301//config: Enable use of long options.
295 302
296//applet:IF_GUNZIP(APPLET(gunzip, BB_DIR_BIN, BB_SUID_DROP)) 303//applet:IF_GUNZIP(APPLET(gunzip, BB_DIR_BIN, BB_SUID_DROP))
297//applet:IF_GUNZIP(APPLET_ODDNAME(zcat, gunzip, BB_DIR_BIN, BB_SUID_DROP, zcat)) 304//applet:IF_GUNZIP(APPLET_ODDNAME(zcat, gunzip, BB_DIR_BIN, BB_SUID_DROP, zcat))
@@ -323,6 +330,17 @@ char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UN
323 } 330 }
324 return filename; 331 return filename;
325} 332}
333
334#if ENABLE_FEATURE_GUNZIP_LONG_OPTIONS
335static const char gunzip_longopts[] ALIGN1 =
336 "stdout\0" No_argument "c"
337 "to-stdout\0" No_argument "c"
338 "force\0" No_argument "f"
339 "test\0" No_argument "t"
340 "no-name\0" No_argument "n"
341 ;
342#endif
343
326/* 344/*
327 * Linux kernel build uses gzip -d -n. We accept and ignore it. 345 * Linux kernel build uses gzip -d -n. We accept and ignore it.
328 * Man page says: 346 * Man page says:
@@ -339,6 +357,9 @@ char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UN
339int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 357int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
340int gunzip_main(int argc UNUSED_PARAM, char **argv) 358int gunzip_main(int argc UNUSED_PARAM, char **argv)
341{ 359{
360#if ENABLE_FEATURE_GUNZIP_LONG_OPTIONS
361 applet_long_options = gunzip_longopts;
362#endif
342 getopt32(argv, "cfvqdtn"); 363 getopt32(argv, "cfvqdtn");
343 argv += optind; 364 argv += optind;
344 365
diff --git a/archival/gzip.c b/archival/gzip.c
index c9171304a..f9bb3c742 100644
--- a/archival/gzip.c
+++ b/archival/gzip.c
@@ -2160,6 +2160,7 @@ static const char gzip_longopts[] ALIGN1 =
2160 "quiet\0" No_argument "q" 2160 "quiet\0" No_argument "q"
2161 "fast\0" No_argument "1" 2161 "fast\0" No_argument "1"
2162 "best\0" No_argument "9" 2162 "best\0" No_argument "9"
2163 "no-name\0" No_argument "n"
2163 ; 2164 ;
2164#endif 2165#endif
2165 2166
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 */
diff --git a/archival/lzop.c b/archival/lzop.c
index 73d11a705..a5fc01941 100644
--- a/archival/lzop.c
+++ b/archival/lzop.c
@@ -640,7 +640,7 @@ static int lzo_get_method(header_t *h)
640/**********************************************************************/ 640/**********************************************************************/
641// compress a file 641// compress a file
642/**********************************************************************/ 642/**********************************************************************/
643static NOINLINE smallint lzo_compress(const header_t *h) 643static NOINLINE int lzo_compress(const header_t *h)
644{ 644{
645 unsigned block_size = LZO_BLOCK_SIZE; 645 unsigned block_size = LZO_BLOCK_SIZE;
646 int r = 0; /* LZO_E_OK */ 646 int r = 0; /* LZO_E_OK */
@@ -650,7 +650,6 @@ static NOINLINE smallint lzo_compress(const header_t *h)
650 uint32_t d_adler32 = ADLER32_INIT_VALUE; 650 uint32_t d_adler32 = ADLER32_INIT_VALUE;
651 uint32_t d_crc32 = CRC32_INIT_VALUE; 651 uint32_t d_crc32 = CRC32_INIT_VALUE;
652 int l; 652 int l;
653 smallint ok = 1;
654 uint8_t *wrk_mem = NULL; 653 uint8_t *wrk_mem = NULL;
655 654
656 if (h->method == M_LZO1X_1) 655 if (h->method == M_LZO1X_1)
@@ -732,7 +731,7 @@ static NOINLINE smallint lzo_compress(const header_t *h)
732 free(wrk_mem); 731 free(wrk_mem);
733 free(b1); 732 free(b1);
734 free(b2); 733 free(b2);
735 return ok; 734 return 1;
736} 735}
737 736
738static FAST_FUNC void lzo_check( 737static FAST_FUNC void lzo_check(
@@ -753,7 +752,7 @@ static FAST_FUNC void lzo_check(
753/**********************************************************************/ 752/**********************************************************************/
754// decompress a file 753// decompress a file
755/**********************************************************************/ 754/**********************************************************************/
756static NOINLINE smallint lzo_decompress(const header_t *h) 755static NOINLINE int lzo_decompress(const header_t *h)
757{ 756{
758 unsigned block_size = LZO_BLOCK_SIZE; 757 unsigned block_size = LZO_BLOCK_SIZE;
759 int r; 758 int r;
@@ -761,7 +760,6 @@ static NOINLINE smallint lzo_decompress(const header_t *h)
761 uint32_t c_adler32 = ADLER32_INIT_VALUE; 760 uint32_t c_adler32 = ADLER32_INIT_VALUE;
762 uint32_t d_adler32 = ADLER32_INIT_VALUE; 761 uint32_t d_adler32 = ADLER32_INIT_VALUE;
763 uint32_t c_crc32 = CRC32_INIT_VALUE, d_crc32 = CRC32_INIT_VALUE; 762 uint32_t c_crc32 = CRC32_INIT_VALUE, d_crc32 = CRC32_INIT_VALUE;
764 smallint ok = 1;
765 uint8_t *b1; 763 uint8_t *b1;
766 uint32_t mcs_block_size = MAX_COMPRESSED_SIZE(block_size); 764 uint32_t mcs_block_size = MAX_COMPRESSED_SIZE(block_size);
767 uint8_t *b2 = NULL; 765 uint8_t *b2 = NULL;
@@ -865,7 +863,7 @@ static NOINLINE smallint lzo_decompress(const header_t *h)
865 } 863 }
866 864
867 free(b2); 865 free(b2);
868 return ok; 866 return 1;
869} 867}
870 868
871/**********************************************************************/ 869/**********************************************************************/
@@ -1050,7 +1048,7 @@ static void lzo_set_method(header_t *h)
1050 h->level = level; 1048 h->level = level;
1051} 1049}
1052 1050
1053static smallint do_lzo_compress(void) 1051static int do_lzo_compress(void)
1054{ 1052{
1055 header_t header; 1053 header_t header;
1056 1054
@@ -1078,7 +1076,7 @@ static smallint do_lzo_compress(void)
1078/**********************************************************************/ 1076/**********************************************************************/
1079// decompress 1077// decompress
1080/**********************************************************************/ 1078/**********************************************************************/
1081static smallint do_lzo_decompress(void) 1079static int do_lzo_decompress(void)
1082{ 1080{
1083 header_t header; 1081 header_t header;
1084 1082
diff --git a/archival/tar.c b/archival/tar.c
index 0dd675f64..adb0b934f 100644
--- a/archival/tar.c
+++ b/archival/tar.c
@@ -152,9 +152,12 @@
152# define FNM_LEADING_DIR 0 152# define FNM_LEADING_DIR 0
153#endif 153#endif
154 154
155 155#if 0
156//#define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__) 156# define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__)
157#define DBG(...) ((void)0) 157#else
158# define DBG(...) ((void)0)
159#endif
160#define DBG_OPTION_PARSING 0
158 161
159 162
160#define block_buf bb_common_bufsiz1 163#define block_buf bb_common_bufsiz1
@@ -884,6 +887,7 @@ enum {
884 IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) 887 IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,)
885 IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,) 888 IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,)
886#if ENABLE_FEATURE_TAR_LONG_OPTIONS 889#if ENABLE_FEATURE_TAR_LONG_OPTIONS
890 OPTBIT_STRIP_COMPONENTS,
887 OPTBIT_NORECURSION, 891 OPTBIT_NORECURSION,
888 IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,) 892 IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,)
889 OPTBIT_NUMERIC_OWNER, 893 OPTBIT_NUMERIC_OWNER,
@@ -908,12 +912,13 @@ enum {
908 OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z 912 OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z
909 OPT_XZ = IF_FEATURE_SEAMLESS_XZ( (1 << OPTBIT_XZ )) + 0, // J 913 OPT_XZ = IF_FEATURE_SEAMLESS_XZ( (1 << OPTBIT_XZ )) + 0, // J
910 OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z 914 OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z
911 OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m 915 OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m
912 OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion 916 OPT_STRIP_COMPONENTS = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_STRIP_COMPONENTS)) + 0, // strip-components
913 OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command 917 OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion
914 OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner 918 OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command
915 OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions 919 OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner
916 OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite 920 OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions
921 OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite
917 922
918 OPT_ANY_COMPRESS = (OPT_BZIP2 | OPT_LZMA | OPT_GZIP | OPT_XZ | OPT_COMPRESS), 923 OPT_ANY_COMPRESS = (OPT_BZIP2 | OPT_LZMA | OPT_GZIP | OPT_XZ | OPT_COMPRESS),
919}; 924};
@@ -957,6 +962,7 @@ static const char tar_longopts[] ALIGN1 =
957# if ENABLE_FEATURE_TAR_NOPRESERVE_TIME 962# if ENABLE_FEATURE_TAR_NOPRESERVE_TIME
958 "touch\0" No_argument "m" 963 "touch\0" No_argument "m"
959# endif 964# endif
965 "strip-components\0" Required_argument "\xf9"
960 "no-recursion\0" No_argument "\xfa" 966 "no-recursion\0" No_argument "\xfa"
961# if ENABLE_FEATURE_TAR_TO_COMMAND 967# if ENABLE_FEATURE_TAR_TO_COMMAND
962 "to-command\0" Required_argument "\xfb" 968 "to-command\0" Required_argument "\xfb"
@@ -1002,15 +1008,28 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
1002 "tt:vv:" // count -t,-v 1008 "tt:vv:" // count -t,-v
1003 IF_FEATURE_TAR_FROM("X::T::") // cumulative lists 1009 IF_FEATURE_TAR_FROM("X::T::") // cumulative lists
1004#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM 1010#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM
1005 "\xff::" // cumulative lists for --exclude 1011 "\xff::" // --exclude=PATTERN is a list
1006#endif 1012#endif
1007 IF_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd 1013 IF_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd
1008 IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive 1014 IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive
1009 IF_NOT_FEATURE_TAR_CREATE("t--x:x--t"); // mutually exclusive 1015 IF_NOT_FEATURE_TAR_CREATE("t--x:x--t") // mutually exclusive
1016#if ENABLE_FEATURE_TAR_LONG_OPTIONS
1017 ":\xf9+" // --strip-components=NUM
1018#endif
1019 ;
1010#if ENABLE_FEATURE_TAR_LONG_OPTIONS 1020#if ENABLE_FEATURE_TAR_LONG_OPTIONS
1011 applet_long_options = tar_longopts; 1021 applet_long_options = tar_longopts;
1012#endif 1022#endif
1013#if ENABLE_DESKTOP 1023#if ENABLE_DESKTOP
1024 /* Lie to buildroot when it starts asking stupid questions. */
1025 if (argv[1] && strcmp(argv[1], "--version") == 0) {
1026 // Output of 'tar --version' examples:
1027 // tar (GNU tar) 1.15.1
1028 // tar (GNU tar) 1.25
1029 // bsdtar 2.8.3 - libarchive 2.8.3
1030 puts("tar (busybox) " BB_VER);
1031 return 0;
1032 }
1014 if (argv[1] && argv[1][0] != '-') { 1033 if (argv[1] && argv[1][0] != '-') {
1015 /* Compat: 1034 /* Compat:
1016 * 1st argument without dash handles options with parameters 1035 * 1st argument without dash handles options with parameters
@@ -1047,10 +1066,14 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
1047 IF_FEATURE_SEAMLESS_XZ( "J" ) 1066 IF_FEATURE_SEAMLESS_XZ( "J" )
1048 IF_FEATURE_SEAMLESS_Z( "Z" ) 1067 IF_FEATURE_SEAMLESS_Z( "Z" )
1049 IF_FEATURE_TAR_NOPRESERVE_TIME("m") 1068 IF_FEATURE_TAR_NOPRESERVE_TIME("m")
1069 IF_FEATURE_TAR_LONG_OPTIONS("\xf9:") // --strip-components
1050 , &base_dir // -C dir 1070 , &base_dir // -C dir
1051 , &tar_filename // -f filename 1071 , &tar_filename // -f filename
1052 IF_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T 1072 IF_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T
1053 IF_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X 1073 IF_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X
1074#if ENABLE_FEATURE_TAR_LONG_OPTIONS
1075 , &tar_handle->tar__strip_components // --strip-components
1076#endif
1054 IF_FEATURE_TAR_TO_COMMAND(, &(tar_handle->tar__to_command)) // --to-command 1077 IF_FEATURE_TAR_TO_COMMAND(, &(tar_handle->tar__to_command)) // --to-command
1055#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM 1078#if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM
1056 , &excludes // --exclude 1079 , &excludes // --exclude
@@ -1058,11 +1081,49 @@ int tar_main(int argc UNUSED_PARAM, char **argv)
1058 , &verboseFlag // combined count for -t and -v 1081 , &verboseFlag // combined count for -t and -v
1059 , &verboseFlag // combined count for -t and -v 1082 , &verboseFlag // combined count for -t and -v
1060 ); 1083 );
1061 //bb_error_msg("opt:%08x", opt); 1084#if DBG_OPTION_PARSING
1085 bb_error_msg("opt: 0x%08x", opt);
1086# define showopt(o) bb_error_msg("opt & %s(%x): %x", #o, o, opt & o);
1087 showopt(OPT_TEST );
1088 showopt(OPT_EXTRACT );
1089 showopt(OPT_BASEDIR );
1090 showopt(OPT_TARNAME );
1091 showopt(OPT_2STDOUT );
1092 showopt(OPT_NOPRESERVE_OWNER);
1093 showopt(OPT_P );
1094 showopt(OPT_VERBOSE );
1095 showopt(OPT_KEEP_OLD );
1096 showopt(OPT_CREATE );
1097 showopt(OPT_DEREFERENCE );
1098 showopt(OPT_BZIP2 );
1099 showopt(OPT_LZMA );
1100 showopt(OPT_INCLUDE_FROM );
1101 showopt(OPT_EXCLUDE_FROM );
1102 showopt(OPT_GZIP );
1103 showopt(OPT_XZ );
1104 showopt(OPT_COMPRESS );
1105 showopt(OPT_NOPRESERVE_TIME );
1106 showopt(OPT_STRIP_COMPONENTS);
1107 showopt(OPT_NORECURSION );
1108 showopt(OPT_2COMMAND );
1109 showopt(OPT_NUMERIC_OWNER );
1110 showopt(OPT_NOPRESERVE_PERM );
1111 showopt(OPT_OVERWRITE );
1112 showopt(OPT_ANY_COMPRESS );
1113 bb_error_msg("base_dir:'%s'", base_dir);
1114 bb_error_msg("tar_filename:'%s'", tar_filename);
1115 bb_error_msg("verboseFlag:%d", verboseFlag);
1116 bb_error_msg("tar_handle->tar__to_command:'%s'", tar_handle->tar__to_command);
1117 bb_error_msg("tar_handle->tar__strip_components:%u", tar_handle->tar__strip_components);
1118 return 0;
1119# undef showopt
1120#endif
1062 argv += optind; 1121 argv += optind;
1063 1122
1064 if (verboseFlag) tar_handle->action_header = header_verbose_list; 1123 if (verboseFlag)
1065 if (verboseFlag == 1) tar_handle->action_header = header_list; 1124 tar_handle->action_header = header_verbose_list;
1125 if (verboseFlag == 1)
1126 tar_handle->action_header = header_list;
1066 1127
1067 if (opt & OPT_EXTRACT) 1128 if (opt & OPT_EXTRACT)
1068 tar_handle->action_data = data_extract_all; 1129 tar_handle->action_data = data_extract_all;