aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2016-11-11 17:56:45 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2016-11-11 17:56:45 +0100
commit9655f95d0f501b03b33c7896b7b0c23d090aff81 (patch)
tree66ea6ffe5d8a5791b7bb8fcb8b7eebaceea5d96e
parent87e039d0160be16a9a242f74af2e90cdb9f97e12 (diff)
downloadbusybox-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.c32
-rwxr-xr-xtestsuite/tar.tests20
-rw-r--r--testsuite/tar.utf8.tar.bz2bin0 -> 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"
300SKIP= 300SKIP=
301 301
302optional UNICODE_SUPPORT
303testing "Pax-encoded UTF8 names and symlinks" '\
304tar xvf ../tar.utf8.tar.bz2 2>&1; echo $?
305export LANG=en_US.UTF-8
306ls -l etc/ssl/certs/* | sed "s:.*etc/:etc/:"
307unset LANG
308rm -rf etc usr
309' "\
310etc/ssl/certs/3b2716e5.0
311etc/ssl/certs/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem
312etc/ssl/certs/f80cc7f6.0
313usr/share/ca-certificates/mozilla/EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.crt
3140
315etc/ssl/certs/3b2716e5.0 -> EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem
316etc/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
317etc/ssl/certs/f80cc7f6.0 -> EBG_Elektronik_Sertifika_Hizmet_Sağlayıcısı.pem
318" \
319"" ""
320SKIP=
321
302 322
303cd .. && rm -rf tar.tempdir || exit 1 323cd .. && 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