You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by bo...@apache.org on 2021/05/01 11:48:14 UTC
[commons-compress] branch master updated: COMPRESS-575 harden
parser for PAX 1.0 sparse struct blocks
This is an automated email from the ASF dual-hosted git repository.
bodewig 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 2887391 COMPRESS-575 harden parser for PAX 1.0 sparse struct blocks
2887391 is described below
commit 2887391296216e5196921f04bea8cd834843cfe2
Author: Stefan Bodewig <bo...@apache.org>
AuthorDate: Sat May 1 13:47:25 2021 +0200
COMPRESS-575 harden parser for PAX 1.0 sparse struct blocks
---
.../commons/compress/archivers/tar/TarUtils.java | 19 +++-
.../compress/archivers/tar/TarUtilsTest.java | 119 +++++++++++++++++++++
2 files changed, 136 insertions(+), 2 deletions(-)
diff --git a/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java b/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java
index eee894e..3ba7a1b 100644
--- a/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java
+++ b/src/main/java/org/apache/commons/compress/archivers/tar/TarUtils.java
@@ -882,14 +882,26 @@ public class TarUtils {
long[] readResult = readLineOfNumberForPax1X(inputStream);
long sparseHeadersCount = readResult[0];
+ if (sparseHeadersCount < 0) {
+ // overflow while reading number?
+ throw new IOException("Corrupted TAR archive. Negative value in sparse headers block");
+ }
bytesRead += readResult[1];
while (sparseHeadersCount-- > 0) {
readResult = readLineOfNumberForPax1X(inputStream);
- long sparseOffset = readResult[0];
+ final long sparseOffset = readResult[0];
+ if (sparseOffset < 0) {
+ throw new IOException("Corrupted TAR archive."
+ + " Sparse header block offset contains negative value");
+ }
bytesRead += readResult[1];
readResult = readLineOfNumberForPax1X(inputStream);
- long sparseNumbytes = readResult[0];
+ final long sparseNumbytes = readResult[0];
+ if (sparseNumbytes < 0) {
+ throw new IOException("Corrupted TAR archive."
+ + " Sparse header block numbytes contains negative value");
+ }
bytesRead += readResult[1];
sparseHeaders.add(new TarArchiveStructSparse(sparseOffset, sparseNumbytes));
}
@@ -918,6 +930,9 @@ public class TarUtils {
if (number == -1) {
throw new IOException("Unexpected EOF when reading parse information of 1.X PAX format");
}
+ if (number < '0' || number > '9') {
+ throw new IOException("Corrupted TAR archive. Non-numeric value in sparse headers block");
+ }
result = result * 10 + (number - '0');
}
bytesRead += 1;
diff --git a/src/test/java/org/apache/commons/compress/archivers/tar/TarUtilsTest.java b/src/test/java/org/apache/commons/compress/archivers/tar/TarUtilsTest.java
index 0bca2f0..adb2408 100644
--- a/src/test/java/org/apache/commons/compress/archivers/tar/TarUtilsTest.java
+++ b/src/test/java/org/apache/commons/compress/archivers/tar/TarUtilsTest.java
@@ -672,4 +672,123 @@ public class TarUtilsTest {
TarUtils.parsePAX01SparseHeaders(map);
}
+ @Test
+ public void parsePAX1XSparseHeaders() throws Exception {
+ final byte[] header = ("1\n"
+ + "0\n"
+ + "20\n")
+ .getBytes();
+ final byte[] block = new byte[512];
+ System.arraycopy(header, 0, block, 0, header.length);
+ try (ByteArrayInputStream in = new ByteArrayInputStream(block)) {
+ final List<TarArchiveStructSparse> sparse = TarUtils.parsePAX1XSparseHeaders(in, 512);
+ assertEquals(1, sparse.size());
+ assertEquals(0, sparse.get(0).getOffset());
+ assertEquals(20, sparse.get(0).getNumbytes());
+ assertEquals(-1, in.read());
+ }
+ }
+
+ @Test
+ public void parsePAX1XSparseHeadersRejectsIncompleteLastLine() throws Exception {
+ thrown.expect(IOException.class);
+ thrown.expectMessage(startsWith("Unexpected EOF"));
+ final byte[] header = ("1\n"
+ + "0\n"
+ + "20")
+ .getBytes();
+ try (ByteArrayInputStream in = new ByteArrayInputStream(header)) {
+ TarUtils.parsePAX1XSparseHeaders(in, 512);
+ }
+ }
+
+ @Test
+ public void parsePAX1XSparseHeadersRejectsNonNumericNumberOfEntries() throws Exception {
+ thrown.expect(IOException.class);
+ thrown.expectMessage(startsWith("Corrupted TAR archive."));
+ final byte[] header = ("x\n"
+ + "0\n"
+ + "20\n")
+ .getBytes();
+ final byte[] block = new byte[512];
+ System.arraycopy(header, 0, block, 0, header.length);
+ try (ByteArrayInputStream in = new ByteArrayInputStream(block)) {
+ TarUtils.parsePAX1XSparseHeaders(in, 512);
+ }
+ }
+
+ @Test
+ public void parsePAX1XSparseHeadersRejectsNonNumericOffset() throws Exception {
+ thrown.expect(IOException.class);
+ thrown.expectMessage(startsWith("Corrupted TAR archive."));
+ final byte[] header = ("1\n"
+ + "x\n"
+ + "20\n")
+ .getBytes();
+ final byte[] block = new byte[512];
+ System.arraycopy(header, 0, block, 0, header.length);
+ try (ByteArrayInputStream in = new ByteArrayInputStream(block)) {
+ TarUtils.parsePAX1XSparseHeaders(in, 512);
+ }
+ }
+
+ @Test
+ public void parsePAX1XSparseHeadersRejectsNonNumericNumbytes() throws Exception {
+ thrown.expect(IOException.class);
+ thrown.expectMessage(startsWith("Corrupted TAR archive."));
+ final byte[] header = ("1\n"
+ + "0\n"
+ + "2x\n")
+ .getBytes();
+ final byte[] block = new byte[512];
+ System.arraycopy(header, 0, block, 0, header.length);
+ try (ByteArrayInputStream in = new ByteArrayInputStream(block)) {
+ TarUtils.parsePAX1XSparseHeaders(in, 512);
+ }
+ }
+ @Test
+ public void parsePAX1XSparseHeadersRejectsNegativeNumberOfEntries() throws Exception {
+ thrown.expect(IOException.class);
+ thrown.expectMessage(startsWith("Corrupted TAR archive."));
+ final byte[] header = ("111111111111111111111111111111111111111111111111111111111111111\n"
+ + "0\n"
+ + "20\n")
+ .getBytes();
+ final byte[] block = new byte[512];
+ System.arraycopy(header, 0, block, 0, header.length);
+ try (ByteArrayInputStream in = new ByteArrayInputStream(block)) {
+ TarUtils.parsePAX1XSparseHeaders(in, 512);
+ }
+ }
+
+ @Test
+ public void parsePAX1XSparseHeadersRejectsNegativeOffset() throws Exception {
+ thrown.expect(IOException.class);
+ thrown.expectMessage(startsWith("Corrupted TAR archive."));
+ final byte[] header = ("1\n"
+ + "111111111111111111111111111111111111111111111111111111111111111\n"
+ + "20\n")
+ .getBytes();
+ final byte[] block = new byte[512];
+ System.arraycopy(header, 0, block, 0, header.length);
+ try (ByteArrayInputStream in = new ByteArrayInputStream(block)) {
+ TarUtils.parsePAX1XSparseHeaders(in, 512);
+ }
+ }
+
+ @Test
+ public void parsePAX1XSparseHeadersRejectsNegativeNumbytes() throws Exception {
+ thrown.expect(IOException.class);
+ thrown.expectMessage(startsWith("Corrupted TAR archive."));
+ final byte[] header = ("1\n"
+ + "0\n"
+ + "111111111111111111111111111111111111111111111111111111111111111\n")
+ .getBytes();
+ final byte[] block = new byte[512];
+ System.arraycopy(header, 0, block, 0, header.length);
+ try (ByteArrayInputStream in = new ByteArrayInputStream(block)) {
+ TarUtils.parsePAX1XSparseHeaders(in, 512);
+ }
+ }
+
}