Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
c4de710
Migrate to Apache Commons IO 2.21.0-SNAPSHOT
garydgregory Oct 1, 2025
ae08cb6
Avoid redirects for snapshots in this branch
garydgregory Oct 2, 2025
9e446ae
Use `IOUtils.checkIndexFromSize` for argument validation (#716)
ppkarwasz Oct 2, 2025
54e7aa4
Set commons-parent to 88
garydgregory Oct 5, 2025
29794ce
remove: make `TarUtils` final and clean up internal methods (#712)
ppkarwasz Oct 6, 2025
3840465
Add `AbstractArchiveBuilder` for unified archiver support (#721)
ppkarwasz Oct 6, 2025
268c451
Disable JDK 26-ea tests (#724)
ppkarwasz Oct 7, 2025
a7a749f
Bump org.apache.commons:commons-parent from 88 to 89
garydgregory Oct 8, 2025
befbfe0
[COMPRESS-711] Fix incorrect CPIO checksum verification (#725)
ppkarwasz Oct 10, 2025
ffed37c
Sort members and remove test clutter
garydgregory Oct 10, 2025
45a791e
Move action to fix section
garydgregory Oct 10, 2025
4758954
Fix Javadoc
garydgregory Oct 10, 2025
740bd9c
Add `ArchiveFile` abstraction for file-based archives (#709)
ppkarwasz Oct 11, 2025
d558dcb
Sort members
garydgregory Oct 11, 2025
ddd9c32
Javadoc
garydgregory Oct 11, 2025
0bc2c93
Narrow test exception typing
garydgregory Oct 11, 2025
01f422e
Use final
garydgregory Oct 11, 2025
77ffe52
Add configurable maximum entry name length (#710)
ppkarwasz Oct 15, 2025
f14dd4d
Restrict visibility of unintentionally exposed APIs (#730)
ppkarwasz Oct 15, 2025
592ad68
Post merge clean ups
garydgregory Oct 15, 2025
72d18c2
Declare `IOException` on archive `InputStream` constructors (#731)
ppkarwasz Oct 16, 2025
ac17e97
Javadoc
garydgregory Oct 16, 2025
a00bf87
Rename private instance variable
garydgregory Oct 16, 2025
54baf27
7z: enforce reference limits on `Folder` parsing (#729)
ppkarwasz Oct 16, 2025
ad8b0a0
Improve sparse file handling performance (#715)
ppkarwasz Oct 17, 2025
d25f722
Simplify writing ustart trailer
garydgregory Oct 17, 2025
2e84319
ARJ: correct byte accounting and truncation errors (#723)
ppkarwasz Oct 17, 2025
f1b1805
Refactor common test pattern
garydgregory Oct 17, 2025
4420a9d
ARJ: strict header validation and selfExtracting option (#728)
ppkarwasz Oct 18, 2025
dc57654
Javadoc
garydgregory Oct 18, 2025
f1830f9
7z: unsigned number parsing and improved header validation (#734)
ppkarwasz Oct 18, 2025
ca4662d
Normalize some error messages
garydgregory Oct 18, 2025
040b945
Simplify `PackingUtils` using `IOUtils` (#737)
ppkarwasz Oct 19, 2025
6bf5ee3
Fix grammar
garydgregory Oct 19, 2025
971718a
7z: optimize header loading (#735)
ppkarwasz Oct 19, 2025
13c2d7b
Deprecate `IOUtils.readFully` and `IOUtils.skip` (#736)
ppkarwasz Oct 19, 2025
86e7021
Use `consume` instead of `skip` (#738)
ppkarwasz Oct 20, 2025
eef0abd
Use HTTPS in URL
garydgregory Nov 2, 2025
520a574
Test with `commons-io` 2.21.0 RC1
ppkarwasz Nov 4, 2025
fac0d66
fix: remove staging repository
ppkarwasz Nov 7, 2025
0eff92f
Merge remote-tracking branch 'apache/master' into commons_io_2_21_0
ppkarwasz Nov 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ Before you push a pull request, review this list:
- [ ] Read the [ASF Generative Tooling Guidance](https://www.apache.org/legal/generative-tooling.html) if you use Artificial Intelligence (AI).
- [ ] I used AI to create any part of, or all of, this pull request.
- [ ] Run a successful build using the default [Maven](https://maven.apache.org/) goal with `mvn`; that's `mvn` on the command line by itself.
- [ ] Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied. This may not always be possible, but it is a best-practice.
- [ ] Write unit tests that match behavioral changes, where the tests fail if the changes to the runtime are not applied. This may not always be possible, but it is a best practice.
- [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
- [ ] Each commit in the pull request should have a meaningful subject line and body. Note that a maintainer may squash commits during the merge process.
17 changes: 1 addition & 16 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj.
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.20.0</version>
<version>2.21.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
Expand Down Expand Up @@ -289,21 +289,6 @@ Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj.
<artifactId>maven-bundle-plugin</artifactId>
<version>${commons.felix.version}</version>
</plugin>
<plugin>
<groupId>com.github.siom79.japicmp</groupId>
<artifactId>japicmp-maven-plugin</artifactId>
<configuration>
<parameter>
<excludes>
<!-- Compress 1.21 -> 1.22 updates ASM from 3.2 to 9.2 for pack200 implementation. -->
<exclude>org.apache.commons.compress.harmony.pack200.Segment</exclude>
<exclude>org.apache.commons.compress.harmony.pack200.SegmentMethodVisitor</exclude>
<exclude>org.apache.commons.compress.harmony.pack200.SegmentAnnotationVisitor</exclude>
<exclude>org.apache.commons.compress.harmony.pack200.SegmentFieldVisitor</exclude>
</excludes>
</parameter>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
Expand Down
27 changes: 20 additions & 7 deletions src/changes/changes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,39 +56,46 @@ The <action> type attribute can be add,update,fix,remove.
<action type="fix" dev="ggregory" due-to="Gary Gregory">AES256SHA256Decoder now enforces the CPP source k_NumCyclesPower_Supported_MAX = 24 limit.</action>
<action type="fix" dev="ggregory" due-to="Gary Gregory">Don't loose precision while reading folders from a SevenZFile.</action>
<action type="fix" dev="ggregory" due-to="Roel van Dijk, Gary Gregory">Improve some exception messages in TarUtils and TarArchiveEntry.</action>
<!-- FIX bzip2 -->
<action type="fix" dev="pkarwasz" due-to="Piotr P. Karwasz">SevenZFile now enforces the same folder and coder limits as the CPP implementation.</action>
<action type="fix" dev="pkarwasz" due-to="Piotr P. Karwasz">Refactor unsigned number parsing and header validation in SevenZFile.</action>
<!-- FIX bzip2 -->
<action type="fix" dev="ggregory" due-to="Tyler Nighswander, Gary Gregory">BZip2CompressorInputStream now throw CompressorException (a subclass of IOException) for invalid or corrupted data, providing more specific error reporting.</action>
<action type="fix" dev="pkarwasz" due-to="Tyler Nighswander, Piotr P. Karwasz">BZip2 input streams treat Huffman codes longer than 20 bits as corrupted data, matching the behavior of the reference implementation.</action>
<!-- FIX dump -->
<action type="fix" dev="pkarwasz" due-to="Tyler Nighswander">Align DUMP archive block size with Linux `dump` utility.</action>
<action type="fix" dev="ggregory" due-to="Tyler Nighswander, Gary Gregory">DumpArchiveInputStream.getNextEntry() throws an ArchiveException instead of ArrayIndexOutOfBoundsException.</action>
<action type="fix" dev="pkarwasz" due-to="Piotr P. Karwasz">Fix DumpArchiveInputStream to correctly handle file names up to 255 bytes #711.</action>
<!-- FIX zip -->
<!-- FIX zip -->
<action type="fix" dev="ggregory" due-to="Dominik Stadler, Gary Gregory" issue="COMPRESS-598">ZipArchiveInputStream.read(byte[], int, int) now throws an IOException instead of a NullPointerException.</action>
<action type="fix" dev="ggregory" due-to="Tyler Nighswander, Gary Gregory">ZipFile.createBoundedInputStream(long, long) now throws an ArchiveException instead of IllegalArgumentException.</action>
<action type="fix" dev="ggregory" due-to="Tyler Nighswander, Gary Gregory">ZipFile.getContentBeforeFirstLocalFileHeader() now throws an ArchiveException instead of IllegalArgumentException.</action>
<action type="fix" dev="ggregory" due-to="Gary Gregory">ExplodingInputStream now throws ArchiveException instead of ArithmeticException.</action>
<action type="fix" dev="ggregory" due-to="Tyler Nighswander, Gary Gregory">ZipArchiveInputStream.read() now throws an IOException instead of java.lang.ArrayIndexOutOfBoundsException.</action>
<action type="fix" dev="ggregory" due-to="Stanislav Fort, Gary Gregory">ZipArchiveInputStream now throws an MemoryLimitException instead of ArchiveException, or OutOfMemoryError when running with low memory settings set on the command line.</action>
<action type="fix" dev="ggregory" due-to="YuWeiBoy, Gary Gregory" issue="COMPRESS-708">ZstdCompressorInputStream closes the InputStream held by ZipArchiveInputStream garbage collection.</action>
<!-- FIX tar -->
<!-- FIX tar -->
<action type="fix" dev="pkarwasz" due-to="Tyler Nighswander, Piotr P. Karwasz, Gary Gregory">>Uniform handling of special tar records in TarFile and TarArchiveInputStream.</action>
<action type="fix" dev="ggregory" due-to="Gary Gregory, Stanislav Fort">TarArchiveOutputStream now throws a IllegalArgumentException instead of an OutOfMemoryError.</action>
<action type="fix" dev="ggregory" issue="COMPRESS-707" due-to="Gary Gregory, Roel van Dijk">TarUtils.verifyCheckSum() throws an Exception when checksum could not be parsed.</action>
<!-- FIX ar -->
<action type="fix" dev="ggregory" due-to="Gary Gregory">ArArchiveInputStream.readGNUStringTable(byte[], int, int) now provides a better exception message, wrapping the underlying exception.</action>
<action type="fix" dev="ggregory" due-to="Gary Gregory">ArArchiveInputStream.read(byte[], int, int) now throws ArchiveException instead of ArithmeticException.</action>
<action type="fix" dev="pkarwasz" due-to="Tyler Nighswander">Simplify handling of special AR records in ArArchiveInputStream.</action>
<!-- FIX unpack200 -->
<!-- FIX arj -->
<action type="fix" dev="pkarwasz" due-to="Piotr P. Karwasz">Correct byte accounting and truncation errors in ARJ input stream.</action>
<action type="fix" dev="pkarwasz" due-to="Piotr P. Karwasz">Add strict header validation in ARJ input stream and `selfExtracting` option.</action>
<!-- FIX unpack200 -->
<action type="fix" dev="ggregory" due-to="Gary Gregory, Stanislav Fort">org.apache.commons.compress.harmony.unpack200 now throws Pack200Exception, IllegalArgumentException, and IllegalStateException instead of other runtime exceptions and Error.</action>
<!-- FIX pack200 -->
<action type="fix" dev="ggregory" due-to="Gary Gregory, Igor Morgenstern">org.apache.commons.compress.harmony.pack200 now throws Pack200Exception, IllegalArgumentException, IllegalStateException, instead of other runtime exceptions and Error.</action>
<action type="fix" dev="ppkarwasz" due-to="Raeps">Extract duplicate code in org.apache.commons.compress.harmony.pack200.IntList.</action>
<!-- FIX cpio -->
<action type="fix" dev="pkarwasz" due-to="Piotr P. Karwasz">Simplify `PackingUtils` by leveraging Commons IO.</action>
<!-- FIX cpio -->
<action type="fix" dev="ggregory" due-to="Stan, Gary Gregory">CpioArchiveEntry now throws ArchiveException instead of Arithmetic exception.</action>
<action type="fix" dev="ggregory" due-to="Stan, Gary Gregory">CpioArchiveInputStream.getNextEntry() now throws a MemoryLimitException instead of OutOfMemoryError when it can't process input greater than available memory.</action>
<action type="fix" dev="ggregory" due-to="Gary Gregory">CpioArchiveInputStream.readOldAsciiEntry(boolean) now throws ArchiveException instead of Arithmetic exception.</action>
<action type="fix" dev="ggregory" due-to="Gary Gregory">CpioArchiveInputStream.readOldBinaryEntry(boolean) now throws ArchiveException instead of Arithmetic exception.</action>
<action type="fix" issue="COMPRESS-711" dev="pkarwasz" due-to="Piotr P. Karwasz">Fix checksum calculation in CpioArchiveInputStream when reading with a non-zero offset.</action>
<!-- FIX gzip -->
<action type="fix" dev="ggregory" due-to="Gary Gregory">GzipParameters.setOperatingSystem(int) now throws CompressorException on illegal input.</action>
<action type="fix" issue="COMPRESS-705" dev="ggregory" due-to="Mario Fredenhagen, Gary Gregory">GZip IOException: Extra subfield length exceeds remaining bytes in extra field; use new option GzipCompressorInputStream.Builder.setIgnoreExtraField(boolean).</action>
Expand All @@ -104,6 +111,8 @@ The <action> type attribute can be add,update,fix,remove.
<action type="fix" dev="ggregory" due-to="Gary Gregory">SeekableInMemoryByteChannel.SeekableInMemoryByteChannel() internal buffer now defaults to IOUtils.DEFAULT_BUFFER_SIZE.</action>
<action type="fix" dev="ggregory" due-to="Gary Gregory">SeekableInMemoryByteChannel.position(), size(), and truncate() now comply with the SeekableByteChannel contract and throw ClosedChannelException.</action>
<action type="fix" dev="ggregory" due-to="Gary Gregory">SeekableInMemoryByteChannel.position(long) now throws IllegalArgumentException instead of IOException when the position request is negative, complying with the SeekableByteChannel.position(long) contract.</action>
<action type="fix" dev="pkarwasz" due-to="Piotr P. Karwasz">Makes TarUtils final and cleans up protected methods #712.</action>
<action type="fix" dev="pkarwasz" due-to="Piotr P. Karwasz">All archive input stream constructors now throw IOException.</action>
<!-- ADD -->
<action type="add" dev="ggregory" due-to="Gary Gregory">Add MemoryLimitException.MemoryLimitException(long, long).</action>
<action type="add" dev="ggregory" due-to="Gary Gregory">Add CompressException.CompressException(String, Object...).</action>
Expand All @@ -121,15 +130,19 @@ The <action> type attribute can be add,update,fix,remove.
<action type="add" dev="ggregory" due-to="Gary Gregory">Add Pack200Exception.addExact(int, long).</action>
<action type="add" issue="COMPRESS-705" dev="ggregory" due-to="Gary Gregory">Add GzipCompressorInputStream.Builder.setIgnoreExtraField(boolean).</action>
<action type="add" dev="ggregory" due-to="Gary Gregory">Add SnappyCompressorInputStream.getUncompressedSize() and deprecate getSize().</action>
<action type="add" dev="ggregory" due-to="Gary Gregory">Add ArchiveInputStream.ArchiveInputStream(InputStream, Charset) as a public constructor, it was private.</action>
<action type="add" dev="ggregory" due-to="Gary Gregory, Piotr P. Karwasz">Introduce builders for all ArchiveInputStream implementations and deprecate some constructors.</action>
<action type="add" dev="ggregory" due-to="Gary Gregory">TarFile now implements IOIterable&lt;TarArchiveEntry&gt;.</action>
<action type="add" dev="ggregory" due-to="Gary Gregory">Add a builder for the TarFile class and deprecate some constructors.</action>
<action type="add" dev="pkarwasz" due-to="Piotr Karwasz">SevenZFile, TarFile, and ZipFile now always close underlying resources when builder or constructor fails.</action>
<action type="add" dev="pkarwasz" due-to="Piotr P. Karwasz">Introduce an ArchiveFile abstraction to unify the APIs of SevenZFile, TarFile, and ZipFile.</action>
<action type="add" dev="pkarwasz" due-to="Piotr P. Karwasz">Add a configurable maxEntryNameLength option to all archivers.</action>
<!-- UPDATE -->
<action type="update" dev="ggregory" due-to="Gary Gregory">Bump org.apache.commons:commons-parent from 85 to 89 #707.</action>
<action type="update" dev="ggregory" due-to="Gary Gregory">Bump org.apache.commons:commons-lang3 from 3.18.0 to 3.19.0.</action>
<action type="update" dev="ggregory" due-to="Gary Gregory, Dependabot">Bump com.github.luben:zstd-jni from 1.5.7-4 to 1.5.7-6 #717, #740.</action>
<action type="update" dev="ggregory" due-to="Dependabot, Piotr P. Karwasz, Gary Gregory">Bump com.github.marschall:memoryfilesystem from 2.8.1 to 2.8.2 #727.</action>
<action type="update" dev="ggregory" due-to="Dependabot, Gary Gregory">Bump com.github.marschall:memoryfilesystem from 2.8.1 to 2.8.2 #727.</action>
<!-- REMOVE -->
<action type="remove" dev="pkarwasz" due-to="Piotr P. Karwasz">Deprecate IOUtils.readFully and IOUtils.skip.</action>
</release>
<release version="1.28.0" date="2025-07-26" description="This is a feature and maintenance release. Java 8 or later is required.">
<!-- FIX -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.commons.compress.archivers;

import org.apache.commons.io.build.AbstractStreamBuilder;

/**
* Base class for builder pattern implementations of all archive readers.
*
* <p>Ensures that all {@code ArchiveInputStream} implementations and other
* archive handlers expose a consistent set of configuration options.</p>
*
* @param <T> The type of archive stream or file to build.
* @param <B> The type of the concrete builder subclass.
* @since 1.29.0
*/
public abstract class AbstractArchiveBuilder<T, B extends AbstractArchiveBuilder<T, B>>
extends AbstractStreamBuilder<T, B> {

private int maxEntryNameLength = Short.MAX_VALUE;

/**
* Constructs a new instance.
*/
protected AbstractArchiveBuilder() {
// empty
}

/**
* Gets the maximum length of an archive entry name.
*
* @return The maximum length of an archive entry name.
*/
public int getMaxEntryNameLength() {
return maxEntryNameLength;
}

/**
* Sets the maximum length, in bytes, of an archive entry name.
*
* <p>Most operating systems and file systems impose relatively small limits on
* file name or path length, which are sufficient for everyday use. By contrast,
* many archive formats permit much longer names: for example, TAR can encode
* names of several gigabytes, while ZIP allows up to 64&nbsp;KiB.</p>
*
* <p>This setting applies an upper bound on entry name length after encoding
* with the {@link #setCharset configured charset}. If an entry name exceeds this
* limit, an {@link ArchiveException} will be thrown during reading.</p>
*
* <p>The default is {@link Short#MAX_VALUE}, which already exceeds the limits
* of most operating systems.</p>
*
* @param maxEntryNameLength The maximum entry name length in bytes; must be positive
* @return {@code this} instance.
* @throws IllegalArgumentException If {@code maxEntryNameLength} is not positive.
*/
public B setMaxEntryNameLength(final int maxEntryNameLength) {
if (maxEntryNameLength <= 0) {
throw new IllegalArgumentException("maxEntryNameLength must be positive");
}
this.maxEntryNameLength = maxEntryNameLength;
return asThis();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,24 +33,6 @@ public class ArchiveException extends CompressException {
/** Serial. */
private static final long serialVersionUID = 2772690708123267100L;

/**
* Delegates to {@link Math#addExact(int, int)} wrapping its {@link ArithmeticException} in our {@link ArchiveException}.
*
* @param x the first value.
* @param y the second value.
* @return the result.
* @throws ArchiveException if the result overflows an {@code int}.
* @see Math#addExact(int, int)
* @since 1.29.0
*/
public static int addExact(final int x, final int y) throws ArchiveException {
try {
return Math.addExact(x, y);
} catch (final ArithmeticException e) {
throw new ArchiveException(e);
}
}

/**
* Delegates to {@link Math#addExact(int, int)} wrapping its {@link ArithmeticException} in our {@link ArchiveException}.
*
Expand Down
Loading
Loading