empty values mean "remove the mapping" in PAX headers
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 becb9a4..410c8ef 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
@@ -455,19 +455,23 @@
String keyword = coll.toString(CharsetNames.UTF_8);
// Get rest of entry
final int restLen = len - read;
- byte[] rest = new byte[restLen];
- int got = IOUtils.readFully(i, rest);
- if (got != restLen) {
- throw new IOException("Failed to read "
- + "Paxheader. Expected "
- + restLen
- + " bytes, read "
- + got);
+ if (restLen == 1) { // only NL
+ headers.remove(keyword);
+ } else {
+ byte[] rest = new byte[restLen];
+ int got = IOUtils.readFully(i, rest);
+ if (got != restLen) {
+ throw new IOException("Failed to read "
+ + "Paxheader. Expected "
+ + restLen
+ + " bytes, read "
+ + got);
+ }
+ // Drop trailing NL
+ String value = new String(rest, 0,
+ restLen - 1, CharsetNames.UTF_8);
+ headers.put(keyword, value);
}
- // Drop trailing NL
- String value = new String(rest, 0,
- restLen - 1, CharsetNames.UTF_8);
- headers.put(keyword, value);
break;
}
coll.write((byte) ch);
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 862e02b..b1519a2 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
@@ -58,6 +58,28 @@
}
@Test
+ public void secondEntryWinsWhenPaxHeaderContainsDuplicateKey() throws Exception {
+ final InputStream is = new ByteArrayInputStream(new byte[1]);
+ final TarArchiveInputStream tais = new TarArchiveInputStream(is);
+ Map<String, String> headers = tais
+ .parsePaxHeaders(new ByteArrayInputStream("11 foo=bar\n11 foo=baz\n"
+ .getBytes(CharsetNames.UTF_8)));
+ assertEquals(1, headers.size());
+ assertEquals("baz", headers.get("foo"));
+ tais.close();
+ }
+
+ @Test
+ public void paxHeaderEntryWithEmptyValueRemovesKey() throws Exception {
+ final InputStream is = new ByteArrayInputStream(new byte[1]);
+ final TarArchiveInputStream tais = new TarArchiveInputStream(is);
+ Map<String, String> headers = tais
+ .parsePaxHeaders(new ByteArrayInputStream("11 foo=bar\n7 foo=\n"
+ .getBytes(CharsetNames.UTF_8)));
+ assertEquals(0, headers.size());
+ }
+
+ @Test
public void readPaxHeaderWithEmbeddedNewline() throws Exception {
final InputStream is = new ByteArrayInputStream(new byte[1]);
final TarArchiveInputStream tais = new TarArchiveInputStream(is);