aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Reimann <jreimann@redhat.com>2018-07-09 11:41:43 +0200
committerStefan Bodewig <bodewig@apache.org>2018-07-11 18:05:49 +0200
commit9e80104befc54daaa097870b857e1bc334521490 (patch)
tree1e3bd3bd420c6fa51bd6ef2292d2f6cbfceb05d5
parentf5330f7e667f5a7245c8a5f3007cda04554c5fe2 (diff)
downloadapache-commons-compress-9e80104befc54daaa097870b857e1bc334521490.tar.gz
Fix reading of multibyte name entries
This fixes COMPRESS-459 by using the name number of bytes from the field in the stream instead of relying on the assumption that each character is exactly one byte, which isn't true for UTF-8, UTF-16 or other multi-byte character encodings.
-rw-r--r--src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveEntry.java17
-rw-r--r--src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java4
-rw-r--r--src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStreamTest.java16
-rw-r--r--src/test/resources/COMPRESS-459.cpiobin0 -> 512 bytes
4 files changed, 34 insertions, 3 deletions
diff --git a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveEntry.java b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveEntry.java
index 28e58238c..3ad7c87da 100644
--- a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveEntry.java
+++ b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveEntry.java
@@ -469,10 +469,25 @@ public class CpioArchiveEntry implements CpioConstants, ArchiveEntry {
* @return the number of bytes needed to pad the header (0,1,2,3)
*/
public int getHeaderPadCount(){
+ long namesize = name != null ? name.length() : 0;
+ return getHeaderPadCount(namesize);
+ }
+
+ /**
+ * Get the number of bytes needed to pad the header to the alignment boundary.
+ *
+ * @param namesize
+ * The length of the name in bytes, as read in the stream.
+ * Without the trailing zero byte.
+ * @return the number of bytes needed to pad the header (0,1,2,3)
+ *
+ * @since 1.18
+ */
+ public int getHeaderPadCount(long namesize){
if (this.alignmentBoundary == 0) { return 0; }
int size = this.headerSize + 1; // Name has terminating null
if (name != null) {
- size += name.length();
+ size += namesize;
}
final int remain = size % this.alignmentBoundary;
if (remain > 0){
diff --git a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java
index ad8e125a9..b64d09104 100644
--- a/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java
+++ b/src/main/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStream.java
@@ -393,7 +393,7 @@ public class CpioArchiveInputStream extends ArchiveInputStream implements
+ ArchiveUtils.sanitize(name)
+ " Occured at byte: " + getBytesRead());
}
- skip(ret.getHeaderPadCount());
+ skip(ret.getHeaderPadCount(namesize-1));
return ret;
}
@@ -449,7 +449,7 @@ public class CpioArchiveInputStream extends ArchiveInputStream implements
+ ArchiveUtils.sanitize(name)
+ "Occured at byte: " + getBytesRead());
}
- skip(ret.getHeaderPadCount());
+ skip(ret.getHeaderPadCount(namesize-1));
return ret;
}
diff --git a/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStreamTest.java b/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStreamTest.java
index f1744053c..762d4648e 100644
--- a/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStreamTest.java
+++ b/src/test/java/org/apache/commons/compress/archivers/cpio/CpioArchiveInputStreamTest.java
@@ -65,4 +65,20 @@ public class CpioArchiveInputStreamTest extends AbstractTestCase {
assertEquals(count, 1);
}
+
+ @Test
+ public void testCpioUnarchiveMultibyteCharName() throws Exception {
+ final CpioArchiveInputStream in =
+ new CpioArchiveInputStream(new FileInputStream(getFile("COMPRESS-459.cpio")), "UTF-8");
+ CpioArchiveEntry entry= null;
+
+ int count = 0;
+ while ((entry = (CpioArchiveEntry) in.getNextEntry()) != null) {
+ count++;
+ assertNotNull(entry);
+ }
+ in.close();
+
+ assertEquals(2, count);
+ }
}
diff --git a/src/test/resources/COMPRESS-459.cpio b/src/test/resources/COMPRESS-459.cpio
new file mode 100644
index 000000000..8ae1662a0
--- /dev/null
+++ b/src/test/resources/COMPRESS-459.cpio
Binary files differ