This is an automated email from the ASF dual-hosted git repository. peterlee pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-compress.git
The following commit(s) were added to refs/heads/master by this push: new b8a0b54 COMPRESS-529 : throws IOException if non-number exists in pax header b8a0b54 is described below commit b8a0b54c59191cb8338585eab055897737730a9e Author: PeterAlfredLee <peteralfred...@gmail.com> AuthorDate: Tue May 26 21:11:54 2020 +0800 COMPRESS-529 : throws IOException if non-number exists in pax header Throws IOException with more specific info when parsing a non-number value while parsing pax headers. --- src/changes/changes.xml | 4 + .../compress/archivers/tar/TarArchiveEntry.java | 115 +++++++++++---------- .../archivers/tar/TarArchiveInputStream.java | 3 +- .../archivers/tar/TarArchiveInputStreamTest.java | 9 ++ src/test/resources/COMPRESS-529.tar | Bin 0 -> 1536 bytes 5 files changed, 78 insertions(+), 53 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index b970000..ec51a84 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -96,6 +96,10 @@ The <action> type attribute can be add,update,fix,remove. ZipFIle to make it a more specific exception. Github Pull Request #102. </action> + <action issue="COMPRESS-529" type="fix" date="2020-05-26"> + Throws IOException with more specific info when parsing a + non-number value while parsing pax headers. + </action> <action issue="COMPRESS-530" type="fix" date="2020-05-26"> Skip non-number chars while parsing pax headers. </action> diff --git a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java index f180780..87acace 100644 --- a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java +++ b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveEntry.java @@ -1063,12 +1063,14 @@ public class TarArchiveEntry implements ArchiveEntry, TarConstants { /** * add a PAX header to this entry. If the header corresponds to an existing field in the entry, * that field will be set; otherwise the header will be added to the extraPaxHeaders Map + * * @param name The full name of the header to set. * @param value value of header. + * @throws IOException if error occurs when parsing pax header * @since 1.15 */ - public void addPaxHeader(String name,String value) { - processPaxHeader(name,value); + public void addPaxHeader(String name, String value) throws IOException { + processPaxHeader(name, value); } /** @@ -1083,10 +1085,12 @@ public class TarArchiveEntry implements ArchiveEntry, TarConstants { /** * Update the entry using a map of pax headers. + * * @param headers + * @throws IOException if error occurs when parsing pax header * @since 1.15 */ - void updateEntryFromPaxHeaders(Map<String, String> headers) { + void updateEntryFromPaxHeaders(Map<String, String> headers) throws IOException { for (final Map.Entry<String, String> ent : headers.entrySet()) { final String key = ent.getKey(); final String val = ent.getValue(); @@ -1097,11 +1101,13 @@ public class TarArchiveEntry implements ArchiveEntry, TarConstants { /** * process one pax header, using the entries extraPaxHeaders map as source for extra headers * used when handling entries for sparse files. + * * @param key * @param val + * @throws IOException if error occurs when parsing pax header * @since 1.15 */ - private void processPaxHeader(String key, String val) { + private void processPaxHeader(String key, String val) throws IOException { processPaxHeader(key,val,extraPaxHeaders); } @@ -1109,12 +1115,13 @@ public class TarArchiveEntry implements ArchiveEntry, TarConstants { * Process one pax header, using the supplied map as source for extra headers to be used when handling * entries for sparse files * - * @param key the header name. - * @param val the header value. - * @param headers map of headers used for dealing with sparse file. + * @param key the header name. + * @param val the header value. + * @param headers map of headers used for dealing with sparse file. + * @throws IOException if error occurs when parsing pax header * @since 1.15 */ - private void processPaxHeader(String key, String val, Map<String, String> headers) { + private void processPaxHeader(String key, String val, Map<String, String> headers) throws IOException { /* * The following headers are defined for Pax. * atime, ctime, charset: cannot use these without changing TarArchiveEntry fields @@ -1135,50 +1142,54 @@ public class TarArchiveEntry implements ArchiveEntry, TarConstants { * * If called from addExtraPaxHeader, these additional headers must be already present . */ - switch (key) { - case "path": - setName(val); - break; - case "linkpath": - setLinkName(val); - break; - case "gid": - setGroupId(Long.parseLong(val)); - break; - case "gname": - setGroupName(val); - break; - case "uid": - setUserId(Long.parseLong(val)); - break; - case "uname": - setUserName(val); - break; - case "size": - setSize(Long.parseLong(val)); - break; - case "mtime": - setModTime((long) (Double.parseDouble(val) * 1000)); - break; - case "SCHILY.devminor": - setDevMinor(Integer.parseInt(val)); - break; - case "SCHILY.devmajor": - setDevMajor(Integer.parseInt(val)); - break; - case "GNU.sparse.size": - fillGNUSparse0xData(headers); - break; - case "GNU.sparse.realsize": - fillGNUSparse1xData(headers); - break; - case "SCHILY.filetype": - if ("sparse".equals(val)) { - fillStarSparseData(headers); - } - break; - default: - extraPaxHeaders.put(key,val); + try { + switch (key) { + case "path": + setName(val); + break; + case "linkpath": + setLinkName(val); + break; + case "gid": + setGroupId(Long.parseLong(val)); + break; + case "gname": + setGroupName(val); + break; + case "uid": + setUserId(Long.parseLong(val)); + break; + case "uname": + setUserName(val); + break; + case "size": + setSize(Long.parseLong(val)); + break; + case "mtime": + setModTime((long) (Double.parseDouble(val) * 1000)); + break; + case "SCHILY.devminor": + setDevMinor(Integer.parseInt(val)); + break; + case "SCHILY.devmajor": + setDevMajor(Integer.parseInt(val)); + break; + case "GNU.sparse.size": + fillGNUSparse0xData(headers); + break; + case "GNU.sparse.realsize": + fillGNUSparse1xData(headers); + break; + case "SCHILY.filetype": + if ("sparse".equals(val)) { + fillStarSparseData(headers); + } + break; + default: + extraPaxHeaders.put(key, val); + } + } catch (NumberFormatException e) { + throw new IOException("Error occurs when parsing " + key + " in pax header : " + val + " is not a number", e); } } diff --git a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java index 45f6b89..846a116 100644 --- a/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java +++ b/src/main/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStream.java @@ -765,7 +765,8 @@ public class TarArchiveInputStream extends ArchiveInputStream { return headers; } - private void applyPaxHeadersToCurrentEntry(final Map<String, String> headers, final List<TarArchiveStructSparse> sparseHeaders) { + private void applyPaxHeadersToCurrentEntry(final Map<String, String> headers, + final List<TarArchiveStructSparse> sparseHeaders) throws IOException { currEntry.updateEntryFromPaxHeaders(headers); currEntry.setSparseHeaders(sparseHeaders); } diff --git a/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStreamTest.java b/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStreamTest.java index 095ec2c..c3fcc01 100644 --- a/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStreamTest.java +++ b/src/test/java/org/apache/commons/compress/archivers/tar/TarArchiveInputStreamTest.java @@ -425,6 +425,15 @@ public class TarArchiveInputStreamTest extends AbstractTestCase { } @Test(expected = IOException.class) + public void testParseTarWithNonNumberPaxHeaders() throws IOException { + try (FileInputStream in = new FileInputStream(getFile("COMPRESS-529.tar")); + TarArchiveInputStream archive = new TarArchiveInputStream(in)) { + archive.getNextEntry(); + IOUtils.toByteArray(archive); + } + } + + @Test(expected = IOException.class) public void testParseTarWithSpecialPaxHeaders() throws IOException { try (FileInputStream in = new FileInputStream(getFile("COMPRESS-530.tar")); TarArchiveInputStream archive = new TarArchiveInputStream(in)) { diff --git a/src/test/resources/COMPRESS-529.tar b/src/test/resources/COMPRESS-529.tar new file mode 100644 index 0000000..351908d Binary files /dev/null and b/src/test/resources/COMPRESS-529.tar differ