diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-11-11 17:56:45 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-11-11 17:56:45 +0100 |
commit | 9655f95d0f501b03b33c7896b7b0c23d090aff81 (patch) | |
tree | 66ea6ffe5d8a5791b7bb8fcb8b7eebaceea5d96e | |
parent | 87e039d0160be16a9a242f74af2e90cdb9f97e12 (diff) | |
download | busybox-w32-9655f95d0f501b03b33c7896b7b0c23d090aff81.tar.gz busybox-w32-9655f95d0f501b03b33c7896b7b0c23d090aff81.tar.bz2 busybox-w32-9655f95d0f501b03b33c7896b7b0c23d090aff81.zip |
tar: handle pax-encoded utf8 filenames and link names. Closes 9406
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/libarchive/get_header_tar.c | 32 | ||||
-rwxr-xr-x | testsuite/tar.tests | 20 | ||||
-rw-r--r-- | testsuite/tar.utf8.tar.bz2 | bin | 0 -> 519 bytes |
3 files changed, 45 insertions, 7 deletions
diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index ea91a883e..c7e3bc16e 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c | |||
@@ -113,11 +113,19 @@ static void process_pax_hdr(archive_handle_t *archive_handle, unsigned sz, int g | |||
113 | value = end + 1; | 113 | value = end + 1; |
114 | 114 | ||
115 | # if ENABLE_FEATURE_TAR_GNU_EXTENSIONS | 115 | # if ENABLE_FEATURE_TAR_GNU_EXTENSIONS |
116 | if (!global && is_prefixed_with(value, "path=")) { | 116 | if (!global) { |
117 | value += sizeof("path=") - 1; | 117 | if (is_prefixed_with(value, "path=")) { |
118 | free(archive_handle->tar__longname); | 118 | value += sizeof("path=") - 1; |
119 | archive_handle->tar__longname = xstrdup(value); | 119 | free(archive_handle->tar__longname); |
120 | continue; | 120 | archive_handle->tar__longname = xstrdup(value); |
121 | continue; | ||
122 | } | ||
123 | if (is_prefixed_with(value, "linkpath=")) { | ||
124 | value += sizeof("linkpath=") - 1; | ||
125 | free(archive_handle->tar__linkname); | ||
126 | archive_handle->tar__linkname = xstrdup(value); | ||
127 | continue; | ||
128 | } | ||
121 | } | 129 | } |
122 | # endif | 130 | # endif |
123 | 131 | ||
@@ -179,7 +187,13 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
179 | * the message and we don't check whether we indeed | 187 | * the message and we don't check whether we indeed |
180 | * saw zero block directly before this. */ | 188 | * saw zero block directly before this. */ |
181 | if (i == 0) { | 189 | if (i == 0) { |
182 | bb_error_msg("short read"); | 190 | /* GNU tar 1.29 will be silent if tar archive ends abruptly |
191 | * (if there are no zero blocks at all, and last read returns zero, | ||
192 | * not short read 0 < len < 512). Complain only if | ||
193 | * the very first read fails. Grrr. | ||
194 | */ | ||
195 | if (archive_handle->offset == 0) | ||
196 | bb_error_msg("short read"); | ||
183 | /* this merely signals end of archive, not exit(1): */ | 197 | /* this merely signals end of archive, not exit(1): */ |
184 | return EXIT_FAILURE; | 198 | return EXIT_FAILURE; |
185 | } | 199 | } |
@@ -195,7 +209,11 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) | |||
195 | archive_handle->offset += i; | 209 | archive_handle->offset += i; |
196 | 210 | ||
197 | /* If there is no filename its an empty header */ | 211 | /* If there is no filename its an empty header */ |
198 | if (tar.name[0] == 0 && tar.prefix[0] == 0) { | 212 | if (tar.name[0] == 0 && tar.prefix[0] == 0 |
213 | /* Have seen a tar archive with pax 'x' header supplying UTF8 filename, | ||
214 | * with actual file having all name fields NUL-filled. Check this: */ | ||
215 | && !p_longname | ||
216 | ) { | ||
199 | if (archive_handle->tar__end) { | 217 | if (archive_handle->tar__end) { |
200 | /* Second consecutive empty header - end of archive. | 218 | /* Second consecutive empty header - end of archive. |
201 | * Read until the end to empty the pipe from gz or bz2 | 219 | * Read until the end to empty the pipe from gz or bz2 |
diff --git a/testsuite/tar.tests b/testsuite/tar.tests index c44b7ad07..ffcbe9ba9 100755 --- a/testsuite/tar.tests +++ b/testsuite/tar.tests | |||
@@ -299,6 +299,26 @@ l4/V8LDoe90yiWJhOJvIypgEfxdyRThQkBVn/bI= | |||
299 | " | 299 | " |
300 | SKIP= | 300 | SKIP= |
301 | 301 | ||
302 | optional UNICODE_SUPPORT | ||
303 | testing "Pax-encoded UTF8 names and symlinks" '\ | ||
304 | tar xvf ../tar.utf8.tar.bz2 2>&1; echo $? | ||
305 | export LANG=en_US.UTF-8 | ||
306 | ls -l etc/ssl/certs/* | sed "s:.*etc/:etc/:" | ||
307 | unset LANG | ||
308 | rm -rf etc usr | ||
309 | ' "\ | ||
310 | etc/ssl/certs/3b2716e5.0 | ||
311 | etc/ssl/certs/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem | ||
312 | etc/ssl/certs/f80cc7f6.0 | ||
313 | usr/share/ca-certificates/mozilla/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.crt | ||
314 | 0 | ||
315 | etc/ssl/certs/3b2716e5.0 -> EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem | ||
316 | etc/ssl/certs/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem -> /usr/share/ca-certificates/mozilla/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.crt | ||
317 | etc/ssl/certs/f80cc7f6.0 -> EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem | ||
318 | " \ | ||
319 | "" "" | ||
320 | SKIP= | ||
321 | |||
302 | 322 | ||
303 | cd .. && rm -rf tar.tempdir || exit 1 | 323 | cd .. && rm -rf tar.tempdir || exit 1 |
304 | 324 | ||
diff --git a/testsuite/tar.utf8.tar.bz2 b/testsuite/tar.utf8.tar.bz2 new file mode 100644 index 000000000..0398e1aea --- /dev/null +++ b/testsuite/tar.utf8.tar.bz2 | |||
Binary files differ | |||