diff --git a/pom.xml b/pom.xml index 8ed7db1da49..53f493b5c29 100644 --- a/pom.xml +++ b/pom.xml @@ -594,11 +594,36 @@ Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj. org.apache.maven.plugins maven-surefire-plugin - - - ${argLine} --add-opens java.base/java.io=ALL-UNNAMED - - + + + + default-test + + + ${argLine} --add-opens java.base/java.io=ALL-UNNAMED + + + **/harmony/unpack200/** + + **/SevenZReadSubStreamsInfoTest.java + + + + + pack200-tests + + test + + + ${argLine} + + **/harmony/unpack200/** + + + + 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 024a9bfc8ea..4ebc30fde1d 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 @@ -81,7 +81,8 @@ public Archive(final InputStream inputStream, final JarOutputStream outputStream this.inputStream = Pack200UnpackerAdapter.newBoundedInputStream(inputStream); this.outputStream = outputStream; if (inputStream instanceof FileInputStream) { - inputPath = Paths.get(Pack200UnpackerAdapter.readPathString((FileInputStream) inputStream)); + final String pathString = Pack200UnpackerAdapter.readPathString((FileInputStream) inputStream); + inputPath = pathString != null ? Paths.get(pathString) : null; } else { inputPath = null; } 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 cbde81642b4..87ca69df29f 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 @@ -59,8 +59,26 @@ static BoundedInputStream newBoundedInputStream(final File file) throws IOExcept return newBoundedInputStream(file.toPath()); } + @SuppressWarnings("resource") // Caller closes. private static BoundedInputStream newBoundedInputStream(final FileInputStream fileInputStream) throws IOException { - return newBoundedInputStream(readPathString(fileInputStream)); + final String pathString = readPathString(fileInputStream); + if (pathString != null) { + return newBoundedInputStream(pathString); + } + // Reflection failed (e.g., Java 17+ strong encapsulation), fall back to channel size. + try { + final long size = fileInputStream.getChannel().size(); + // @formatter:off + return BoundedInputStream.builder() + .setInputStream(new BufferedInputStream(fileInputStream)) + .setMaxCount(size) + .setPropagateClose(false) + .get(); + // @formatter:on + } catch (final IOException e) { + // No limit + return BoundedInputStream.builder().setInputStream(new BufferedInputStream(fileInputStream)).get(); + } } @SuppressWarnings("resource") // Caller closes. @@ -74,7 +92,10 @@ static BoundedInputStream newBoundedInputStream(final InputStream inputStream) t return newBoundedInputStream(BoundedInputStream.builder().setInputStream(inputStream).get()); } if (inputStream instanceof FilterInputStream) { - return newBoundedInputStream(unwrap((FilterInputStream) inputStream)); + final InputStream unwrapped = unwrap((FilterInputStream) inputStream); + if (unwrapped != null) { + return newBoundedInputStream(unwrapped); + } } if (inputStream instanceof FileInputStream) { return newBoundedInputStream((FileInputStream) inputStream); @@ -140,6 +161,13 @@ private static T readField(final Object object, final String fieldName) { return (T) FieldUtils.readField(object, fieldName, true); } catch (final IllegalAccessException e) { return null; + } catch (final RuntimeException e) { + // InaccessibleObjectException (Java 9+) extends RuntimeException, not IllegalAccessException. + // Thrown when Java 17+ strong encapsulation blocks setAccessible on JDK internal fields. + if ("java.lang.reflect.InaccessibleObjectException".equals(e.getClass().getName())) { + return null; + } + throw e; } }