From 53197a52a2b1c5c9540f3c66d00161034880549b Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Thu, 25 Sep 2025 12:59:51 +0200 Subject: [PATCH 01/11] remove: make `TarUtils` final and clean up internal methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `TarUtils` already had a private constructor and was only used within the `o.a.c.compress.archivers.tar` package. This PR makes the class explicitly final and simplifies its internal API: * Mark `TarUtils` as `final`. * Change `protected` methods to package-private (they were never usable outside the package due to the private constructor). * Remove deprecated non-`public` methods. * Simplify `parsePaxHeaders`: * Require a non-negative `headerSize`. The special value `-1` (“unlimited”) was only used in tests. * Update tests to supply a valid `headerSize`. * Standardize error handling for invalid PAX 0.0 sparse records: all parsing errors now throw `ArchiveException` (previously one case threw `IOException`). A changelog entry is included even though these are internal changes, to give users a reference point in case any unintended side effects arise. --- pom.xml | 6 ++ src/changes/changes.xml | 2 + .../compress/archivers/tar/TarUtils.java | 89 +++++------------- .../compress/archivers/tar/TarUtilsTest.java | 94 ++++++++++--------- 4 files changed, 80 insertions(+), 111 deletions(-) diff --git a/pom.xml b/pom.xml index 498a0d52dea..dfeca11976e 100644 --- a/pom.xml +++ b/pom.xml @@ -300,6 +300,12 @@ Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj. org.apache.commons.compress.harmony.pack200.SegmentMethodVisitor org.apache.commons.compress.harmony.pack200.SegmentAnnotationVisitor org.apache.commons.compress.harmony.pack200.SegmentFieldVisitor + + org.apache.commons.compress.archivers.tar.TarUtils#parseFromPAX01SparseHeaders(java.lang.String) + org.apache.commons.compress.archivers.tar.TarUtils#parsePAX01SparseHeaders(java.lang.String) + org.apache.commons.compress.archivers.tar.TarUtils#parsePAX1XSparseHeaders(java.io.InputStream,int) + org.apache.commons.compress.archivers.tar.TarUtils#parsePaxHeaders(java.io.InputStream,java.util.List,java.util.Map) + org.apache.commons.compress.archivers.tar.TarUtils#parsePaxHeaders(java.io.InputStream,java.util.List,java.util.Map,long) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index b23dc64dc05..f3547e265a8 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -127,6 +127,8 @@ The type attribute can be add,update,fix,remove. Bump org.apache.commons:commons-parent from 85 to 88 #707. Bump org.apache.commons:commons-lang3 from 3.18.0 to 3.19.0. + + Makes TarUtils final and cleans up protected methods. 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 3938ce2f3ba..e1d1c5fe6c0 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 @@ -461,7 +461,7 @@ public static boolean parseBoolean(final byte[] buffer, final int offset) { * @throws IOException Corrupted TAR archive. * @since 1.21 */ - protected static List parseFromPAX01SparseHeaders(final String sparseMap) throws IOException { + static List parseFromPAX01SparseHeaders(final String sparseMap) throws IOException { final List sparseHeaders = new ArrayList<>(); final String[] sparseHeaderStrings = HEADER_STRINGS_PATTERN.split(sparseMap); if (sparseHeaderStrings.length % 2 == 1) { @@ -614,30 +614,6 @@ public static long parseOctalOrBinary(final byte[] buffer, final int offset, fin return parseBinaryBigInteger(buffer, offset, length, negative); } - /** - * For PAX Format 0.1, the sparse headers are stored in a single variable : GNU.sparse.map - * - *

- * GNU.sparse.map: Map of non-null data chunks. It is a string consisting of comma-separated values "offset,size[,offset-1,size-1...]" - *

- *

- * Will internally invoke {@link #parseFromPAX01SparseHeaders} and map IOExceptions to a RzuntimeException, You should use - * {@link #parseFromPAX01SparseHeaders} directly instead. - *

- * - * @param sparseMap the sparse map string consisting of comma-separated values "offset,size[,offset-1,size-1...]". - * @return sparse headers parsed from sparse map. - * @deprecated use #parseFromPAX01SparseHeaders instead. - */ - @Deprecated - protected static List parsePAX01SparseHeaders(final String sparseMap) { - try { - return parseFromPAX01SparseHeaders(sparseMap); - } catch (final IOException ex) { - throw new UncheckedIOException(ex.getMessage(), ex); - } - } - /** * For PAX Format 1.X: The sparse map itself is stored in the file data block, preceding the actual file data. It consists of a series of decimal numbers * delimited by newlines. The map is padded with nulls to the nearest block boundary. The first number gives the number of entries in the map. Following are @@ -648,7 +624,7 @@ protected static List parsePAX01SparseHeaders(final Stri * @return sparse headers. * @throws IOException if an I/O error occurs. */ - protected static List parsePAX1XSparseHeaders(final InputStream inputStream, final int recordSize) throws IOException { + static List parsePAX1XSparseHeaders(final InputStream inputStream, final int recordSize) throws IOException { // for 1.X PAX Headers final List sparseHeaders = new ArrayList<>(); long bytesRead = 0; @@ -681,37 +657,6 @@ protected static List parsePAX1XSparseHeaders(final Inpu return sparseHeaders; } - /** - * For PAX Format 0.0, the sparse headers(GNU.sparse.offset and GNU.sparse.numbytes) may appear multi times, and they look like: - * - *
-     * GNU.sparse.size=size
-     * GNU.sparse.numblocks=numblocks
-     * repeat numblocks times
-     *   GNU.sparse.offset=offset
-     *   GNU.sparse.numbytes=numbytes
-     * end repeat
-     * 
- *

- * For PAX Format 0.1, the sparse headers are stored in a single variable: GNU.sparse.map - *

- *

- * GNU.sparse.map: Map of non-null data chunks. It is a string consisting of comma-separated values "offset,size[,offset-1,size-1...]" - *

- * - * @param inputStream input stream to read keys and values. - * @param sparseHeaders used in PAX Format 0.0 & 0.1, as it may appear multiple times, the sparse headers need to be stored in an array, not a map. - * @param globalPaxHeaders global PAX headers of the tar archive. - * @return map of PAX headers values found inside the current (local or global) PAX headers tar entry. - * @throws IOException if an I/O error occurs. - * @deprecated use the four-arg version instead. - */ - @Deprecated - protected static Map parsePaxHeaders(final InputStream inputStream, final List sparseHeaders, - final Map globalPaxHeaders) throws IOException { - return parsePaxHeaders(inputStream, sparseHeaders, globalPaxHeaders, -1); - } - /** * For PAX Format 0.0, the sparse headers(GNU.sparse.offset and GNU.sparse.numbytes) may appear multi times, and they look like: * @@ -733,13 +678,17 @@ protected static Map parsePaxHeaders(final InputStream inputStre * @param inputStream input stream to read keys and values * @param sparseHeaders used in PAX Format 0.0 & 0.1, as it may appear multiple times, the sparse headers need to be stored in an array, not a map * @param globalPaxHeaders global PAX headers of the tar archive - * @param headerSize total size of the PAX header, will be ignored if negative + * @param headerSize total size of the PAX header * @return map of PAX headers values found inside the current (local or global) PAX headers tar entry. * @throws IOException if an I/O error occurs. * @since 1.21 */ - protected static Map parsePaxHeaders(final InputStream inputStream, final List sparseHeaders, - final Map globalPaxHeaders, final long headerSize) throws IOException { + static Map parsePaxHeaders( + final InputStream inputStream, + final List sparseHeaders, + final Map globalPaxHeaders, + final long headerSize) + throws IOException { final Map headers = new HashMap<>(globalPaxHeaders); Long offset = null; // Format is "length keyword=value\n"; @@ -760,7 +709,7 @@ protected static Map parsePaxHeaders(final InputStream inputStre while ((ch = inputStream.read()) != -1) { read++; totalRead++; - if (totalRead < 0 || headerSize >= 0 && totalRead >= headerSize) { + if (totalRead < 0 || totalRead >= headerSize) { break; } if (ch == '=') { // end of keyword @@ -769,7 +718,7 @@ protected static Map parsePaxHeaders(final InputStream inputStre final int restLen = len - read; if (restLen <= 1) { // only NL headers.remove(keyword); - } else if (headerSize >= 0 && restLen > headerSize - totalRead) { + } else if (restLen > headerSize - totalRead) { throw new ArchiveException("PAX header value size %,d exceeds size of header record.", restLen); } else { final byte[] rest = IOUtils.readRange(inputStream, restLen); @@ -791,9 +740,10 @@ protected static Map parsePaxHeaders(final InputStream inputStre sparseHeaders.add(new TarArchiveStructSparse(offset, 0)); } try { - offset = Long.valueOf(value); - } catch (final NumberFormatException ex) { - throw new ArchiveException("Failed to read PAX header: Offset %s contains a non-numeric value.", + offset = ParsingUtils.parseLongValue(value); + } catch (final IOException ex) { + throw new ArchiveException( + "Failed to read PAX header: Offset %s contains a non-numeric value.", TarGnuSparseKeys.OFFSET); } if (offset < 0) { @@ -806,7 +756,14 @@ protected static Map parsePaxHeaders(final InputStream inputStre throw new ArchiveException("Failed to read PAX header: %s is expected before GNU.sparse.numbytes shows up.", TarGnuSparseKeys.OFFSET); } - final long numbytes = ParsingUtils.parseLongValue(value); + final long numbytes; + try { + numbytes = ParsingUtils.parseLongValue(value); + } catch (final IOException ex) { + throw new ArchiveException( + "Failed to read PAX header: Numbytes %s contains a non-numeric value.", + TarGnuSparseKeys.NUMBYTES); + } if (numbytes < 0) { throw new ArchiveException("Failed to read PAX header: %s contains negative value.", TarGnuSparseKeys.NUMBYTES); } 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 c9375513616..42e30e266f4 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 @@ -20,6 +20,8 @@ package org.apache.commons.compress.archivers.tar; import static java.nio.charset.StandardCharsets.UTF_8; +import static java.util.Collections.emptyList; +import static java.util.Collections.emptyMap; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -29,12 +31,9 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; -import java.io.UncheckedIOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Stream; @@ -291,7 +290,7 @@ void testParseOctalInvalid() { @Test void testParsePAX01SparseHeadersRejectsOddNumberOfEntries() { final String map = "0,10,20,0,20"; - assertThrows(UncheckedIOException.class, () -> TarUtils.parsePAX01SparseHeaders(map)); + assertThrows(ArchiveException.class, () -> TarUtils.parseFromPAX01SparseHeaders(map)); } @Test @@ -399,7 +398,9 @@ void testParseTarWithSpecialPaxHeaders() throws IOException { @Test void testPaxHeaderEntryWithEmptyValueRemovesKey() throws Exception { - final Map headers = TarUtils.parsePaxHeaders(new ByteArrayInputStream("11 foo=bar\n7 foo=\n".getBytes(UTF_8)), null, new HashMap<>()); + final byte[] bytes = "11 foo=bar\n7 foo=\n".getBytes(UTF_8); + final Map headers = + TarUtils.parsePaxHeaders(new ByteArrayInputStream(bytes), emptyList(), emptyMap(), bytes.length); assertEquals(0, headers.size()); } @@ -459,17 +460,19 @@ void testReadNegativeBinary8Byte() { void testReadNonAsciiPaxHeader() throws Exception { final String ae = "\u00e4"; final String line = "11 path=" + ae + "\n"; - assertEquals(11, line.getBytes(UTF_8).length); - final Map headers = TarUtils.parsePaxHeaders(new ByteArrayInputStream(line.getBytes(UTF_8)), null, new HashMap<>()); + final byte[] bytes = line.getBytes(UTF_8); + assertEquals(11, bytes.length); + final Map headers = + TarUtils.parsePaxHeaders(new ByteArrayInputStream(bytes), emptyList(), emptyMap(), 11); assertEquals(1, headers.size()); assertEquals(ae, headers.get("path")); } @Test void testReadPax00SparseHeader() throws Exception { - final String header = "23 GNU.sparse.offset=0\n26 GNU.sparse.numbytes=10\n"; + final byte[] header = "23 GNU.sparse.offset=0\n26 GNU.sparse.numbytes=10\n".getBytes(UTF_8); final List sparseHeaders = new ArrayList<>(); - TarUtils.parsePaxHeaders(new ByteArrayInputStream(header.getBytes(UTF_8)), sparseHeaders, Collections.emptyMap()); + TarUtils.parsePaxHeaders(new ByteArrayInputStream(header), sparseHeaders, emptyMap(), header.length); assertEquals(1, sparseHeaders.size()); assertEquals(0, sparseHeaders.get(0).getOffset()); assertEquals(10, sparseHeaders.get(0).getNumbytes()); @@ -477,9 +480,9 @@ void testReadPax00SparseHeader() throws Exception { @Test void testReadPax00SparseHeaderMakesNumbytesOptional() throws Exception { - final String header = "23 GNU.sparse.offset=0\n24 GNU.sparse.offset=10\n"; + final byte[] header = "23 GNU.sparse.offset=0\n24 GNU.sparse.offset=10\n".getBytes(UTF_8); final List sparseHeaders = new ArrayList<>(); - TarUtils.parsePaxHeaders(new ByteArrayInputStream(header.getBytes(UTF_8)), sparseHeaders, Collections.emptyMap()); + TarUtils.parsePaxHeaders(new ByteArrayInputStream(header), sparseHeaders, emptyMap(), header.length); assertEquals(2, sparseHeaders.size()); assertEquals(0, sparseHeaders.get(0).getOffset()); assertEquals(0, sparseHeaders.get(0).getNumbytes()); @@ -487,48 +490,46 @@ void testReadPax00SparseHeaderMakesNumbytesOptional() throws Exception { assertEquals(0, sparseHeaders.get(1).getNumbytes()); } - @Test - void testReadPax00SparseHeaderRejectsNegativeNumbytes() throws Exception { - final String header = "23 GNU.sparse.offset=0\n26 GNU.sparse.numbytes=-1\n"; - assertThrows(ArchiveException.class, () -> TarUtils.parsePaxHeaders(new ByteArrayInputStream(header.getBytes(UTF_8)), null, Collections.emptyMap())); - } - - @Test - void testReadPax00SparseHeaderRejectsNegativeOffset() throws Exception { - final String header = "24 GNU.sparse.offset=-1\n26 GNU.sparse.numbytes=10\n"; - assertThrows(ArchiveException.class, () -> TarUtils.parsePaxHeaders(new ByteArrayInputStream(header.getBytes(UTF_8)), null, Collections.emptyMap())); - } - - @Test - void testReadPax00SparseHeaderRejectsNonNumericNumbytes() throws Exception { - final String header = "23 GNU.sparse.offset=0\n26 GNU.sparse.numbytes=1a\n"; - assertThrows(IOException.class, () -> TarUtils.parsePaxHeaders(new ByteArrayInputStream(header.getBytes(UTF_8)), null, Collections.emptyMap())); - } - - @Test - void testReadPax00SparseHeaderRejectsNonNumericOffset() throws Exception { - final String header = "23 GNU.sparse.offset=a\n26 GNU.sparse.numbytes=10\n"; - assertThrows(ArchiveException.class, () -> TarUtils.parsePaxHeaders(new ByteArrayInputStream(header.getBytes(UTF_8)), null, Collections.emptyMap())); + static Stream testReadPaxHeaderInvalidCases() { + return Stream.of( + Arguments.of( + "Negative numbytes in PAX 00 sparse header", + "23 GNU.sparse.offset=0\n26 GNU.sparse.numbytes=-1\n"), + Arguments.of( + "Negative offset in PAX 00 sparse header", + "24 GNU.sparse.offset=-1\n26 GNU.sparse.numbytes=10\n"), + Arguments.of( + "Non-numeric numbytes in PAX 00 sparse header", + "23 GNU.sparse.offset=0\n26 GNU.sparse.numbytes=1a\n"), + Arguments.of( + "Non-numeric offset in PAX 00 sparse header", + "23 GNU.sparse.offset=a\n26 GNU.sparse.numbytes=10\n"), + Arguments.of("Missing trailing newline in PAX header", "30 atime=1321711775.9720594634")); + } + + @ParameterizedTest(name = "{0}") + @MethodSource + void testReadPaxHeaderInvalidCases(final String description, final String header) { + final byte[] bytes = header.getBytes(UTF_8); + assertThrows( + ArchiveException.class, + () -> TarUtils.parsePaxHeaders(new ByteArrayInputStream(bytes), emptyList(), emptyMap(), bytes.length)); } @Test void testReadPaxHeaderWithEmbeddedNewline() throws Exception { - final Map headers = TarUtils.parsePaxHeaders(new ByteArrayInputStream("28 comment=line1\nline2\nand3\n".getBytes(UTF_8)), null, - new HashMap<>()); + final byte[] header = "28 comment=line1\nline2\nand3\n".getBytes(UTF_8); + final Map headers = + TarUtils.parsePaxHeaders(new ByteArrayInputStream(header), emptyList(), emptyMap(), header.length); assertEquals(1, headers.size()); assertEquals("line1\nline2\nand3", headers.get("comment")); } - @Test - void testReadPaxHeaderWithoutTrailingNewline() throws Exception { - assertThrows(ArchiveException.class, - () -> TarUtils.parsePaxHeaders(new ByteArrayInputStream("30 atime=1321711775.9720594634".getBytes(UTF_8)), null, Collections.emptyMap())); - } - @Test void testReadSimplePaxHeader() throws Exception { - final Map headers = TarUtils.parsePaxHeaders(new ByteArrayInputStream("30 atime=1321711775.972059463\n".getBytes(UTF_8)), null, - new HashMap<>()); + final byte[] header = "30 atime=1321711775.972059463\n".getBytes(UTF_8); + final Map headers = + TarUtils.parsePaxHeaders(new ByteArrayInputStream(header), emptyList(), emptyMap(), header.length); assertEquals(1, headers.size()); assertEquals("1321711775.972059463", headers.get("atime")); } @@ -643,8 +644,11 @@ void testRoundTripOctalOrBinary8_ValueTooBigForBinary() { @Test void testSecondEntryWinsWhenPaxHeaderContainsDuplicateKey() throws Exception { - final Map headers = TarUtils.parsePaxHeaders(new ByteArrayInputStream("11 foo=bar\n11 foo=baz\n".getBytes(UTF_8)), null, - new HashMap<>()); + final Map headers = TarUtils.parsePaxHeaders( + new ByteArrayInputStream("11 foo=bar\n11 foo=baz\n".getBytes(UTF_8)), + emptyList(), + emptyMap(), + Integer.MAX_VALUE); assertEquals(1, headers.size()); assertEquals("baz", headers.get("foo")); } From e4619b2886d6d9c00016db7be30f3e56d2e4d50a Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Thu, 25 Sep 2025 13:11:56 +0200 Subject: [PATCH 02/11] fix: make `TarUtils` final This change actually makes `TarUtils` final and introduces a JapiCmp configuration that ignores all `CLASS_NOW_FINAL` changes. --- pom.xml | 13 +++++++++++++ src/changes/changes.xml | 2 +- .../commons/compress/archivers/tar/TarUtils.java | 3 +-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index dfeca11976e..b0c0e8c4c3f 100644 --- a/pom.xml +++ b/pom.xml @@ -307,6 +307,19 @@ Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj. org.apache.commons.compress.archivers.tar.TarUtils#parsePaxHeaders(java.io.InputStream,java.util.List,java.util.Map) org.apache.commons.compress.archivers.tar.TarUtils#parsePaxHeaders(java.io.InputStream,java.util.List,java.util.Map,long) + + + + CLASS_NOW_FINAL + true + true + + diff --git a/src/changes/changes.xml b/src/changes/changes.xml index f3547e265a8..6576e1a11d6 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -128,7 +128,7 @@ The type attribute can be add,update,fix,remove. Bump org.apache.commons:commons-parent from 85 to 88 #707. Bump org.apache.commons:commons-lang3 from 3.18.0 to 3.19.0. - Makes TarUtils final and cleans up protected methods. + Makes TarUtils final and cleans up protected methods #712.
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 e1d1c5fe6c0..75738de370f 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 @@ -48,8 +48,7 @@ * * @Immutable */ -// CheckStyle:HideUtilityClassConstructorCheck OFF (bc) -public class TarUtils { +public final class TarUtils { private static final Pattern HEADER_STRINGS_PATTERN = Pattern.compile(","); From 803f78dfb0ae00c2b4ca63acba815c545da84474 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Thu, 25 Sep 2025 13:25:19 +0200 Subject: [PATCH 03/11] fix: don't call tests with `Integer.MAX_VALUE` --- .../commons/compress/archivers/tar/TarUtilsTest.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) 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 42e30e266f4..acfa4b3b25d 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 @@ -504,6 +504,10 @@ static Stream testReadPaxHeaderInvalidCases() { Arguments.of( "Non-numeric offset in PAX 00 sparse header", "23 GNU.sparse.offset=a\n26 GNU.sparse.numbytes=10\n"), + Arguments.of( + "Numbytes in PAX 00 sparse header without offset", + "26 GNU.sparse.numbytes=10\n" + ), Arguments.of("Missing trailing newline in PAX header", "30 atime=1321711775.9720594634")); } @@ -644,11 +648,9 @@ void testRoundTripOctalOrBinary8_ValueTooBigForBinary() { @Test void testSecondEntryWinsWhenPaxHeaderContainsDuplicateKey() throws Exception { - final Map headers = TarUtils.parsePaxHeaders( - new ByteArrayInputStream("11 foo=bar\n11 foo=baz\n".getBytes(UTF_8)), - emptyList(), - emptyMap(), - Integer.MAX_VALUE); + final byte[] header = "11 foo=bar\n11 foo=baz\n".getBytes(UTF_8); + final Map headers = + TarUtils.parsePaxHeaders(new ByteArrayInputStream(header), emptyList(), emptyMap(), header.length); assertEquals(1, headers.size()); assertEquals("baz", headers.get("foo")); } From efea6fa53e281980568db7d79b9ab99046eb54a7 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Fri, 3 Oct 2025 20:57:05 +0200 Subject: [PATCH 04/11] fix: bump `japicmp` to version `0.24.0` This bumps `japicmp` to the new version `0.24.0`, which ignores changes to protected method in non-extensible classes such as `TarUtils`. --- pom.xml | 42 ++++++------------------------------------ 1 file changed, 6 insertions(+), 36 deletions(-) diff --git a/pom.xml b/pom.xml index b0c0e8c4c3f..73a353d9d05 100644 --- a/pom.xml +++ b/pom.xml @@ -74,8 +74,6 @@ Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj. 2.0.16 2025-07-29T22:23:16Z - - 0.5.5 true 0.96 @@ -89,6 +87,12 @@ Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj. ${basedir}/src/conf/checkstyle/checkstyle.xml ${basedir}/src/conf/checkstyle/checkstyle-suppressions.xml LICENSE.txt, NOTICE.txt, **/maven-archiver/pom.properties + + + 0.5.5 + 0.24.0 jira @@ -289,40 +293,6 @@ Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj. maven-bundle-plugin ${commons.felix.version} - - com.github.siom79.japicmp - japicmp-maven-plugin - - - - - org.apache.commons.compress.harmony.pack200.Segment - org.apache.commons.compress.harmony.pack200.SegmentMethodVisitor - org.apache.commons.compress.harmony.pack200.SegmentAnnotationVisitor - org.apache.commons.compress.harmony.pack200.SegmentFieldVisitor - - org.apache.commons.compress.archivers.tar.TarUtils#parseFromPAX01SparseHeaders(java.lang.String) - org.apache.commons.compress.archivers.tar.TarUtils#parsePAX01SparseHeaders(java.lang.String) - org.apache.commons.compress.archivers.tar.TarUtils#parsePAX1XSparseHeaders(java.io.InputStream,int) - org.apache.commons.compress.archivers.tar.TarUtils#parsePaxHeaders(java.io.InputStream,java.util.List,java.util.Map) - org.apache.commons.compress.archivers.tar.TarUtils#parsePaxHeaders(java.io.InputStream,java.util.List,java.util.Map,long) - - - - - CLASS_NOW_FINAL - true - true - - - - - org.apache.maven.plugins maven-checkstyle-plugin From ab6111ab6559ffedea42f0aff9339213b357d4bd Mon Sep 17 00:00:00 2001 From: Gary Gregory Date: Sun, 5 Oct 2025 06:43:25 -0400 Subject: [PATCH 05/11] Update japicmp version from 0.24.0 to 0.24.1 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 73a353d9d05..290742a1a9e 100644 --- a/pom.xml +++ b/pom.xml @@ -92,7 +92,7 @@ Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj. --> 0.5.5 - 0.24.0 + 0.24.1 jira From adcb46b6e785fac63153f3bb604c831d9f0bb37e Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Mon, 6 Oct 2025 08:30:27 +0200 Subject: [PATCH 06/11] fix: clean up POM --- pom.xml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 290742a1a9e..2b105a1fec3 100644 --- a/pom.xml +++ b/pom.xml @@ -74,6 +74,8 @@ Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj. 2.0.16 2025-07-29T22:23:16Z + + 0.5.5 true 0.96 @@ -87,11 +89,7 @@ Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj. ${basedir}/src/conf/checkstyle/checkstyle.xml ${basedir}/src/conf/checkstyle/checkstyle-suppressions.xml LICENSE.txt, NOTICE.txt, **/maven-archiver/pom.properties - - - 0.5.5 + 0.24.1 From 333e11f8db47161efe69fdd56e385c9ae761dc6d Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Mon, 6 Oct 2025 08:31:20 +0200 Subject: [PATCH 07/11] fix: enforcer rule to clean up temporary override --- pom.xml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/pom.xml b/pom.xml index 2b105a1fec3..2adf4629439 100644 --- a/pom.xml +++ b/pom.xml @@ -404,6 +404,28 @@ Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj. org.apache.maven.plugins maven-checkstyle-plugin + + + org.apache.maven.plugins + maven-enforcer-plugin + + + cleanup-parent-upgrade + + enforce + + + + + project.parent.version + 88 + Please remove the override of the `commons.japicmp.version` property in the pom.xml. + + + + + + From 8b7fe86e573cec84b5778f6967c8771bb03216e1 Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Mon, 6 Oct 2025 08:51:56 +0200 Subject: [PATCH 08/11] Test `project.parent.version` resolution on CI --- pom.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2adf4629439..9b645a9863c 100644 --- a/pom.xml +++ b/pom.xml @@ -418,8 +418,6 @@ Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj. project.parent.version - 88 - Please remove the override of the `commons.japicmp.version` property in the pom.xml. From a73d9689fe937713f72490e31b09c2c22ae017cc Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Mon, 6 Oct 2025 08:59:14 +0200 Subject: [PATCH 09/11] Try ignoring white space --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index 9b645a9863c..f139ac70979 100644 --- a/pom.xml +++ b/pom.xml @@ -418,6 +418,8 @@ Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj. project.parent.version + \s*88\s* + Please remove `commons.japicmp.version` override. From 4617029bf0c0bfad0093282f3bb04db095c5898a Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Mon, 6 Oct 2025 09:04:05 +0200 Subject: [PATCH 10/11] Try newest Enforcer version --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f139ac70979..700bc02342f 100644 --- a/pom.xml +++ b/pom.xml @@ -408,6 +408,7 @@ Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj. org.apache.maven.plugins maven-enforcer-plugin + 3.6.2 cleanup-parent-upgrade @@ -418,7 +419,7 @@ Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj. project.parent.version - \s*88\s* + 88 Please remove `commons.japicmp.version` override. From 854affde56ca12830a7a7353ce46108439e7c11b Mon Sep 17 00:00:00 2001 From: "Piotr P. Karwasz" Date: Mon, 6 Oct 2025 09:13:15 +0200 Subject: [PATCH 11/11] Remove enforcer rule --- pom.xml | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/pom.xml b/pom.xml index 700bc02342f..2b105a1fec3 100644 --- a/pom.xml +++ b/pom.xml @@ -404,29 +404,6 @@ Brotli, Zstandard and ar, cpio, jar, tar, zip, dump, 7z, arj. org.apache.maven.plugins maven-checkstyle-plugin - - - org.apache.maven.plugins - maven-enforcer-plugin - 3.6.2 - - - cleanup-parent-upgrade - - enforce - - - - - project.parent.version - 88 - Please remove `commons.japicmp.version` override. - - - - - -