This is an automated email from the ASF dual-hosted git repository. ggregory pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-compress.git
commit b778b64d01811046ae5c69c94012508dde1c58b3 Author: Gary Gregory <garydgreg...@gmail.com> AuthorDate: Sat Feb 17 14:35:32 2024 -0500 Internal refactoring --- .../commons/compress/harmony/pack200/Codec.java | 25 ++++++++- .../compress/harmony/pack200/PopulationCodec.java | 2 +- .../commons/compress/harmony/pack200/RunCodec.java | 2 +- .../compress/harmony/unpack200/Archive.java | 60 ++++++++++++--------- .../harmony/unpack200/Pack200UnpackerAdapter.java | 16 ++++++ .../compress/harmony/unpack200/Segment.java | 6 +-- .../commons/compress/utils/BoundedInputStream.java | 6 +++ .../harmony/pack200/tests/RunCodecTest.java | 30 +++++++++++ .../harmony/unpack200/tests/ArchiveTest.java | 34 ++++++++++++ .../harmony/unpack200/tests/SegmentTest.java | 35 ++++++++++++ .../apache/commons/compress/pack/bandint_oom.pack | Bin 0 -> 88 bytes .../apache/commons/compress/pack/cpfloat_oom.pack | Bin 0 -> 178 bytes .../apache/commons/compress/pack/cputf8_oom.pack | Bin 0 -> 427 bytes .../apache/commons/compress/pack/favoured_oom.pack | Bin 0 -> 84 bytes .../apache/commons/compress/pack/filebits_oom.pack | Bin 0 -> 309 bytes .../apache/commons/compress/pack/flags_oom.pack | Bin 0 -> 1624 bytes .../commons/compress/pack/references_oom.pack | Bin 0 -> 66 bytes .../commons/compress/pack/segment_header_oom.pack | Bin 0 -> 41 bytes .../commons/compress/pack/signatures_oom.pack | Bin 0 -> 121 bytes 19 files changed, 183 insertions(+), 33 deletions(-) diff --git a/src/main/java/org/apache/commons/compress/harmony/pack200/Codec.java b/src/main/java/org/apache/commons/compress/harmony/pack200/Codec.java index a3f4d43f8..a575558ba 100644 --- a/src/main/java/org/apache/commons/compress/harmony/pack200/Codec.java +++ b/src/main/java/org/apache/commons/compress/harmony/pack200/Codec.java @@ -19,6 +19,8 @@ package org.apache.commons.compress.harmony.pack200; import java.io.IOException; import java.io.InputStream; +import org.apache.commons.io.input.BoundedInputStream; + /** * A Codec allows a sequence of bytes to be decoded into integer values (or vice versa). * <p> @@ -123,7 +125,7 @@ public abstract class Codec { */ public int[] decodeInts(final int n, final InputStream in) throws IOException, Pack200Exception { lastBandLength = 0; - final int[] result = new int[n]; + final int[] result = new int[check(n, in)]; int last = 0; for (int i = 0; i < n; i++) { result[i] = last = decode(in, last); @@ -142,7 +144,7 @@ public abstract class Codec { * @throws Pack200Exception if there is a problem decoding the value or that the value is invalid */ public int[] decodeInts(final int n, final InputStream in, final int firstValue) throws IOException, Pack200Exception { - final int[] result = new int[n + 1]; + final int[] result = new int[check(n + 1, in)]; result[0] = firstValue; int last = firstValue; for (int i = 1; i < n + 1; i++) { @@ -151,6 +153,25 @@ public abstract class Codec { return result; } + int check(final int n, final InputStream in) throws Pack200Exception { + if (in instanceof BoundedInputStream) { + final BoundedInputStream bin = (BoundedInputStream) in; + final long count = bin.getCount(); + final long maxLength = bin.getMaxLength(); + if (maxLength > -1) { + final long remaining = maxLength - count; + final String format = "Can't read beyond end of stream (n = %,d, count = %,d, maxLength = %,d, remaining = %,d)"; + if (count < -1) { + throw new Pack200Exception(String.format(format, n, count, maxLength, remaining)); + } + if (n > remaining) { + throw new Pack200Exception(String.format(format, n, count, maxLength, remaining)); + } + } + } + return n; + } + /** * Encodes a single value into a sequence of bytes. Note that this method can only be used for non-delta encodings. * diff --git a/src/main/java/org/apache/commons/compress/harmony/pack200/PopulationCodec.java b/src/main/java/org/apache/commons/compress/harmony/pack200/PopulationCodec.java index 1ac615995..d32c55701 100644 --- a/src/main/java/org/apache/commons/compress/harmony/pack200/PopulationCodec.java +++ b/src/main/java/org/apache/commons/compress/harmony/pack200/PopulationCodec.java @@ -60,7 +60,7 @@ public class PopulationCodec extends Codec { @Override public int[] decodeInts(final int n, final InputStream in) throws IOException, Pack200Exception { lastBandLength = 0; - favoured = new int[n]; // there must be <= n values, but probably a lot + favoured = new int[check(n, in)]; // there must be <= n values, but probably a lot // less int[] result; // read table of favorites first diff --git a/src/main/java/org/apache/commons/compress/harmony/pack200/RunCodec.java b/src/main/java/org/apache/commons/compress/harmony/pack200/RunCodec.java index 1d0902b85..883a3095e 100644 --- a/src/main/java/org/apache/commons/compress/harmony/pack200/RunCodec.java +++ b/src/main/java/org/apache/commons/compress/harmony/pack200/RunCodec.java @@ -67,7 +67,7 @@ public class RunCodec extends Codec { normalise(aValues, aCodec); final int[] bValues = bCodec.decodeInts(n - k, in); normalise(bValues, bCodec); - final int[] band = new int[n]; + final int[] band = new int[check(n, in)]; System.arraycopy(aValues, 0, band, 0, k); System.arraycopy(bValues, 0, band, k, n - k); lastBandLength = aCodec.lastBandLength + bCodec.lastBandLength; diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/Archive.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/Archive.java index 6b41eff9e..f70c56ca9 100644 --- a/src/main/java/org/apache/commons/compress/harmony/unpack200/Archive.java +++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/Archive.java @@ -18,13 +18,16 @@ package org.apache.commons.compress.harmony.unpack200; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; -import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; import java.util.jar.JarOutputStream; @@ -32,6 +35,7 @@ import java.util.zip.GZIPInputStream; import org.apache.commons.compress.harmony.pack200.Pack200Exception; import org.apache.commons.io.IOUtils; +import org.apache.commons.io.input.BoundedInputStream; /** * Archive is the main entry point to unpack200. An archive is constructed with either two file names, a pack file and an output file name or an input stream @@ -39,7 +43,7 @@ import org.apache.commons.io.IOUtils; */ public class Archive { - private InputStream inputStream; + private BoundedInputStream inputStream; private final JarOutputStream outputStream; @@ -53,10 +57,14 @@ public class Archive { private boolean deflateHint; - private String inputFileName; + private final Path inputPath; + + private final long inputSize; private String outputFileName; + private static final int[] MAGIC = { 0xCA, 0xFE, 0xD0, 0x0D }; + /** * Creates an Archive with streams for the input and output files. Note: If you use this method then calling {@link #setRemovePackFile(boolean)} will have * no effect. @@ -65,8 +73,18 @@ public class Archive { * @param outputStream TODO */ public Archive(final InputStream inputStream, final JarOutputStream outputStream) { - this.inputStream = inputStream; + this.inputStream = inputStream instanceof BoundedInputStream ? (BoundedInputStream) inputStream : new BoundedInputStream(inputStream); this.outputStream = outputStream; + if (inputStream instanceof FileInputStream) { + try { + inputPath = Paths.get(((FileInputStream) inputStream).getFD().toString()); + } catch (final IOException e) { + throw new UncheckedIOException(e); + } + } else { + inputPath = null; + } + this.inputSize = -1; } /** @@ -79,9 +97,10 @@ public class Archive { * @throws IOException TODO */ public Archive(final String inputFileName, final String outputFileName) throws FileNotFoundException, IOException { - this.inputFileName = inputFileName; + this.inputPath = Paths.get(inputFileName); this.outputFileName = outputFileName; - this.inputStream = new FileInputStream(inputFileName); + this.inputSize = Files.size(this.inputPath); + this.inputStream = new BoundedInputStream(Files.newInputStream(inputPath), inputSize); this.outputStream = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(outputFileName))); } @@ -138,7 +157,7 @@ public class Archive { outputStream.setComment("PACK200"); try { if (!inputStream.markSupported()) { - inputStream = new BufferedInputStream(inputStream); + inputStream = new BoundedInputStream(new BufferedInputStream(inputStream)); if (!inputStream.markSupported()) { throw new IllegalStateException(); } @@ -146,20 +165,19 @@ public class Archive { inputStream.mark(2); if ((inputStream.read() & 0xFF | (inputStream.read() & 0xFF) << 8) == GZIPInputStream.GZIP_MAGIC) { inputStream.reset(); - inputStream = new BufferedInputStream(new GZIPInputStream(inputStream)); + inputStream = new BoundedInputStream(new BufferedInputStream(new GZIPInputStream(inputStream))); } else { inputStream.reset(); } - inputStream.mark(4); - final int[] magic = { 0xCA, 0xFE, 0xD0, 0x0D }; // Magic word for + inputStream.mark(MAGIC.length); // pack200 - final int[] word = new int[4]; + final int[] word = new int[MAGIC.length]; for (int i = 0; i < word.length; i++) { word[i] = inputStream.read(); } boolean compressedWithE0 = false; - for (int m = 0; m < magic.length; m++) { - if (word[m] != magic[m]) { + for (int m = 0; m < MAGIC.length; m++) { + if (word[m] != MAGIC[m]) { compressedWithE0 = true; } } @@ -188,7 +206,7 @@ public class Archive { segment.setPreRead(false); if (i == 1) { - segment.log(Segment.LOG_LEVEL_VERBOSE, "Unpacking from " + inputFileName + " to " + outputFileName); + segment.log(Segment.LOG_LEVEL_VERBOSE, "Unpacking from " + inputPath + " to " + outputFileName); } segment.log(Segment.LOG_LEVEL_VERBOSE, "Reading segment " + i); if (overrideDeflateHint) { @@ -196,10 +214,6 @@ public class Archive { } segment.unpack(inputStream, outputStream); outputStream.flush(); - - if (inputStream instanceof FileInputStream) { - inputFileName = ((FileInputStream) inputStream).getFD().toString(); - } } } } finally { @@ -207,14 +221,8 @@ public class Archive { IOUtils.closeQuietly(outputStream); IOUtils.closeQuietly(logFile); } - if (removePackFile) { - boolean deleted = false; - if (inputFileName != null) { - deleted = new File(inputFileName).delete(); - } - if (!deleted) { - throw new Pack200Exception("Failed to delete the input file."); - } + if (removePackFile && inputPath != null) { + Files.delete(inputPath); } } diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/Pack200UnpackerAdapter.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/Pack200UnpackerAdapter.java index 2c725fee2..f8038ba71 100644 --- a/src/main/java/org/apache/commons/compress/harmony/unpack200/Pack200UnpackerAdapter.java +++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/Pack200UnpackerAdapter.java @@ -21,17 +21,33 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.jar.JarOutputStream; import org.apache.commons.compress.harmony.pack200.Pack200Adapter; import org.apache.commons.compress.harmony.pack200.Pack200Exception; import org.apache.commons.compress.java.util.jar.Pack200.Unpacker; +import org.apache.commons.io.input.BoundedInputStream; /** * This class provides the binding between the standard Pack200 interface and the internal interface for (un)packing. */ public class Pack200UnpackerAdapter extends Pack200Adapter implements Unpacker { + static BoundedInputStream newBoundedInputStream(final File file) throws IOException { + return newBoundedInputStream(file.toPath()); + } + + @SuppressWarnings("resource") + static BoundedInputStream newBoundedInputStream(final Path inputPath) throws IOException { + return new BoundedInputStream(new BufferedInputStream(Files.newInputStream(inputPath)), Files.size(inputPath)); + } + + static BoundedInputStream newBoundedInputStream(final String first, final String... more) throws IOException { + return newBoundedInputStream(Paths.get(first, more)); + } + @Override public void unpack(final File file, final JarOutputStream out) throws IOException { if (file == null || out == null) { diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/Segment.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/Segment.java index 014db4938..576fead75 100644 --- a/src/main/java/org/apache/commons/compress/harmony/unpack200/Segment.java +++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/Segment.java @@ -462,13 +462,13 @@ public class Segment { /** * Unpacks a packed stream (either .pack. or .pack.gz) into a corresponding JarOuputStream. * - * @param in a packed stream. + * @param inputStream a packed input stream. * @param out output stream. * @throws Pack200Exception if there is a problem unpacking * @throws IOException if there is a problem with I/O during unpacking */ - public void unpack(final InputStream in, final JarOutputStream out) throws IOException, Pack200Exception { - unpackRead(in); + public void unpack(final InputStream inputStream, final JarOutputStream out) throws IOException, Pack200Exception { + unpackRead(inputStream); unpackProcess(); unpackWrite(out); } diff --git a/src/main/java/org/apache/commons/compress/utils/BoundedInputStream.java b/src/main/java/org/apache/commons/compress/utils/BoundedInputStream.java index 8da853372..b4622c8b3 100644 --- a/src/main/java/org/apache/commons/compress/utils/BoundedInputStream.java +++ b/src/main/java/org/apache/commons/compress/utils/BoundedInputStream.java @@ -49,4 +49,10 @@ public class BoundedInputStream extends org.apache.commons.io.input.BoundedInput return getMaxLength() - getCount(); } +// @Override +// protected void onMaxLength(long maxLength, long count) throws IOException { +// if (count > maxLength) { +// throw new IOException("Can't read past EOF."); +// } +// } } diff --git a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/RunCodecTest.java b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/RunCodecTest.java index 0cb488fdd..cc86a288d 100644 --- a/src/test/java/org/apache/commons/compress/harmony/pack200/tests/RunCodecTest.java +++ b/src/test/java/org/apache/commons/compress/harmony/pack200/tests/RunCodecTest.java @@ -20,12 +20,14 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import java.io.ByteArrayInputStream; +import java.io.IOException; import java.util.stream.Stream; import org.apache.commons.compress.harmony.pack200.Codec; import org.apache.commons.compress.harmony.pack200.Pack200Exception; import org.apache.commons.compress.harmony.pack200.PopulationCodec; import org.apache.commons.compress.harmony.pack200.RunCodec; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -76,6 +78,21 @@ public class RunCodecTest { } } + @Disabled + @Test + public void testRunCodecDecodeIntsOverflow() throws Exception { + final byte[] bytes1 = Codec.DELTA5.encode(new int[] { 1, -2, -3, 1000, 55 }); + final byte[] bytes2 = Codec.UNSIGNED5.encode(new int[] { 5, 10, 20 }); + final byte[] bandEncoded = new byte[bytes1.length + bytes2.length]; + System.arraycopy(bytes1, 0, bandEncoded, 0, bytes1.length); + System.arraycopy(bytes2, 0, bandEncoded, bytes1.length, bytes2.length); + final RunCodec runCodec = new RunCodec(5, Codec.DELTA5, Codec.UNSIGNED5); + + // Should only throw an IOException and not an OutOfMemoryError + assertThrows(IOException.class, () -> runCodec.decodeInts(Integer.MAX_VALUE - 1, new ByteArrayInputStream(bandEncoded))); + assertThrows(IOException.class, () -> runCodec.decodeInts(Integer.MAX_VALUE - 1, new ByteArrayInputStream(bandEncoded), 1)); + } + @Test public void testEncodeSingleValue() { assertThrows(Pack200Exception.class, () -> new RunCodec(10, Codec.SIGNED5, Codec.UDELTA5).encode(5), @@ -104,6 +121,19 @@ public class RunCodecTest { } } + @Disabled + @Test + public void testPopulationCodecDecodeIntsOverflow() throws Exception { + final byte[] bytes1 = Codec.DELTA5.encode(new int[] { 11, 12, 33, 4000, -555 }); + final PopulationCodec popCodec = new PopulationCodec(Codec.UNSIGNED5, Codec.BYTE1, Codec.UNSIGNED5); + final byte[] bytes2 = popCodec.encode(new int[] { 10, 20 }, new int[] { 0, 1, 2, 1, 0, 2, 2, 2, 1, 1, 0, 2, 0, 1, 1, 0, 0 }, + new int[] { 5, 3, 999, 789, 355, 12345 }); + final byte[] bandEncoded = new byte[bytes1.length + bytes2.length]; + + // Should only throw an IOException and not an OutOfMemoryError + assertThrows(IOException.class, () -> popCodec.decodeInts(Integer.MAX_VALUE - 1, new ByteArrayInputStream(bandEncoded))); + } + @Test public void testNestedRunCodec() throws Exception { final int[] band = { 1, 2, 3, 10, 20, 30, 100, 200, 300 }; diff --git a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/ArchiveTest.java b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/ArchiveTest.java index f169af182..98e1b1cd4 100644 --- a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/ArchiveTest.java +++ b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/ArchiveTest.java @@ -16,6 +16,7 @@ */ package org.apache.commons.compress.harmony.unpack200.tests; +import static org.junit.Assert.assertThrows; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -31,6 +32,10 @@ import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -39,8 +44,13 @@ import java.util.zip.ZipEntry; import org.apache.commons.compress.AbstractTempDirTest; import org.apache.commons.compress.harmony.unpack200.Archive; +import org.apache.commons.compress.harmony.unpack200.Segment; +import org.apache.commons.io.input.BoundedInputStream; +import org.apache.commons.io.output.NullOutputStream; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; /** * Tests for org.apache.commons.compress.harmony.unpack200.Archive, which is the main class for unpack200. @@ -176,6 +186,30 @@ public class ArchiveTest extends AbstractTempDirTest { } } + @ParameterizedTest + @ValueSource(strings = { + // @formatter:off + "bandint_oom.pack", + "cpfloat_oom.pack", + "cputf8_oom.pack", + "favoured_oom.pack", + "filebits_oom.pack", + "flags_oom.pack", + "references_oom.pack", + "segment_header_oom.pack", + "signatures_oom.pack" + // @formatter:on + }) + // Tests of various files that can cause out of memory errors + public void testParsingOOM(final String testFileName) throws Exception { + final URL url = Segment.class.getResource("/org/apache/commons/compress/pack/" + testFileName); + final Path path = Paths.get(url.toURI()); + try (InputStream in = new BoundedInputStream(new BufferedInputStream(Files.newInputStream(path)), Files.size(path)); + JarOutputStream out = new JarOutputStream(NullOutputStream.INSTANCE)) { + assertThrows(IOException.class, () -> new Archive(in, out).unpack()); + } + } + @Test public void testRemovePackFile() throws Exception { final File original = new File(Archive.class.getResource("/pack200/sql.pack.gz").toURI()); diff --git a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/SegmentTest.java b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/SegmentTest.java index d3dd7f338..76c2dc81b 100644 --- a/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/SegmentTest.java +++ b/src/test/java/org/apache/commons/compress/harmony/unpack200/tests/SegmentTest.java @@ -16,21 +16,32 @@ */ package org.apache.commons.compress.harmony.unpack200.tests; +import static org.junit.Assert.assertThrows; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarOutputStream; import org.apache.commons.compress.AbstractTempDirTest; import org.apache.commons.compress.harmony.unpack200.Segment; +import org.apache.commons.io.input.BoundedInputStream; +import org.apache.commons.io.output.NullOutputStream; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; /** * Tests for org.apache.commons.compress.harmony.unpack200.Segment. @@ -88,4 +99,28 @@ public class SegmentTest extends AbstractTempDirTest { } } + @ParameterizedTest + @ValueSource(strings = { + // @formatter:off + "bandint_oom.pack", + "cpfloat_oom.pack", + "cputf8_oom.pack", + "favoured_oom.pack", + "filebits_oom.pack", + "flags_oom.pack", + "references_oom.pack", + "segment_header_oom.pack", + "signatures_oom.pack" + // @formatter:on + }) + // Tests of various files that can cause out of memory errors + public void testParsingOOM(final String testFileName) throws Exception { + final URL url = Segment.class.getResource("/org/apache/commons/compress/pack/" + testFileName); + final Path path = Paths.get(url.toURI()); + try (InputStream in = new BoundedInputStream(new BufferedInputStream(Files.newInputStream(path)), Files.size(path)); + JarOutputStream out = new JarOutputStream(NullOutputStream.INSTANCE)) { + assertThrows(IOException.class, () -> new Segment().unpack(in, out)); + } + } + } diff --git a/src/test/resources/org/apache/commons/compress/pack/bandint_oom.pack b/src/test/resources/org/apache/commons/compress/pack/bandint_oom.pack new file mode 100644 index 000000000..ad011e5f2 Binary files /dev/null and b/src/test/resources/org/apache/commons/compress/pack/bandint_oom.pack differ diff --git a/src/test/resources/org/apache/commons/compress/pack/cpfloat_oom.pack b/src/test/resources/org/apache/commons/compress/pack/cpfloat_oom.pack new file mode 100644 index 000000000..29255d14f Binary files /dev/null and b/src/test/resources/org/apache/commons/compress/pack/cpfloat_oom.pack differ diff --git a/src/test/resources/org/apache/commons/compress/pack/cputf8_oom.pack b/src/test/resources/org/apache/commons/compress/pack/cputf8_oom.pack new file mode 100644 index 000000000..88632cb9c Binary files /dev/null and b/src/test/resources/org/apache/commons/compress/pack/cputf8_oom.pack differ diff --git a/src/test/resources/org/apache/commons/compress/pack/favoured_oom.pack b/src/test/resources/org/apache/commons/compress/pack/favoured_oom.pack new file mode 100644 index 000000000..658be7f5f Binary files /dev/null and b/src/test/resources/org/apache/commons/compress/pack/favoured_oom.pack differ diff --git a/src/test/resources/org/apache/commons/compress/pack/filebits_oom.pack b/src/test/resources/org/apache/commons/compress/pack/filebits_oom.pack new file mode 100644 index 000000000..282967e47 Binary files /dev/null and b/src/test/resources/org/apache/commons/compress/pack/filebits_oom.pack differ diff --git a/src/test/resources/org/apache/commons/compress/pack/flags_oom.pack b/src/test/resources/org/apache/commons/compress/pack/flags_oom.pack new file mode 100644 index 000000000..2608ee02d Binary files /dev/null and b/src/test/resources/org/apache/commons/compress/pack/flags_oom.pack differ diff --git a/src/test/resources/org/apache/commons/compress/pack/references_oom.pack b/src/test/resources/org/apache/commons/compress/pack/references_oom.pack new file mode 100644 index 000000000..b613eaa4d Binary files /dev/null and b/src/test/resources/org/apache/commons/compress/pack/references_oom.pack differ diff --git a/src/test/resources/org/apache/commons/compress/pack/segment_header_oom.pack b/src/test/resources/org/apache/commons/compress/pack/segment_header_oom.pack new file mode 100644 index 000000000..033967067 Binary files /dev/null and b/src/test/resources/org/apache/commons/compress/pack/segment_header_oom.pack differ diff --git a/src/test/resources/org/apache/commons/compress/pack/signatures_oom.pack b/src/test/resources/org/apache/commons/compress/pack/signatures_oom.pack new file mode 100644 index 000000000..aa4b2fc79 Binary files /dev/null and b/src/test/resources/org/apache/commons/compress/pack/signatures_oom.pack differ