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 /archival | |
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>
Diffstat (limited to 'archival')
-rw-r--r-- | archival/libarchive/get_header_tar.c | 32 |
1 files changed, 25 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 |