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 6e15f9dc227fca17ef135192107833e8d0cf4f00 Author: Gary Gregory <garydgreg...@gmail.com> AuthorDate: Thu Apr 10 09:27:09 2025 -0400 Throw Pack200Exception instead of Error and do better range checking of index arguments. - org.apache.commons.compress.harmony.unpack200.SegmentConstantPool.getConstantPoolEntry(int, long) now throws Pack200Exception instead of Error and does better range checking of the index argument. - org.apache.commons.compress.harmony.unpack200.SegmentConstantPool.getInitMethodPoolEntry(int, long, String) now throws Pack200Exception instead of Error and does better range checking of the index argument. - Add org.apache.commons.compress.harmony.pack200.Pack200Exception.Pack200Exception(String, Throwable) --- src/changes/changes.xml | 3 + .../compress/harmony/pack200/Pack200Exception.java | 21 ++++- .../harmony/unpack200/SegmentConstantPool.java | 92 +++++++++++++--------- .../unpack200/bytecode/forms/ReferenceForm.java | 8 ++ 4 files changed, 86 insertions(+), 38 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 2cb45c529..014860871 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -71,6 +71,8 @@ The <action> type attribute can be add,update,fix,remove. <action type="fix" dev="sebb">Drop coveralls reference (no longer needed)</action> <action type="fix" dev="ggregory" due-to="Gary Gregory">Some ZIP operations won't read all data from a non-blocking file channel.</action> <action type="fix" dev="ggregory" due-to="Steve Roughley, Gary Gregory" issue="COMPRESS-696">ZipArchiveInputStream.getCompressedCount() throws NullPointerException if called before getNextEntry().</action> + <action type="fix" dev="ggregory" due-to="Gary Gregory">org.apache.commons.compress.harmony.unpack200.SegmentConstantPool.getConstantPoolEntry(int, long) now throws Pack200Exception instead of Error and does better range checking of the index argument.</action> + <action type="fix" dev="ggregory" due-to="Gary Gregory">org.apache.commons.compress.harmony.unpack200.SegmentConstantPool.getInitMethodPoolEntry(int, long, String) now throws Pack200Exception instead of Error and does better range checking of the index argument.</action> <!-- ADD --> <action type="add" dev="ggregory" due-to="Gary Gregory">Add GzipParameters.getModificationInstant().</action> <action type="add" dev="ggregory" due-to="Gary Gregory">Add GzipParameters.setModificationInstant(Instant).</action> @@ -92,6 +94,7 @@ The <action> type attribute can be add,update,fix,remove. <action type="add" issue="COMPRESS-692" dev="ggregory" due-to="Mehmet Karaman, Andrey Loskutov, Gary Gregory">Add support for zstd compression in zip archives.</action> <action type="add" dev="ggregory" due-to="Gary Gregory">Add support for XZ compression in ZIP archives.</action> <action type="add" dev="ggregory" due-to="Gary Gregory" issue="COMPRESS-695">Add ZipArchiveInputStream.createZstdInputStream(InputStream) to provide a different InputStream implementation for Zstandard (Zstd) #649.</action> + <action type="add" dev="ggregory" due-to="Gary Gregory">Add org.apache.commons.compress.harmony.pack200.Pack200Exception.Pack200Exception(String, Throwable).</action> <!-- UPDATE --> <action type="update" dev="sebb">Bump Commons Parent from 79 to 81</action> <action type="update" dev="ggregory" due-to="Dependabot, Gary Gregory">Bump org.apache.commons:commons-parent from 72 to 79 #563, #567, #574, #582, #587, #595.</action> diff --git a/src/main/java/org/apache/commons/compress/harmony/pack200/Pack200Exception.java b/src/main/java/org/apache/commons/compress/harmony/pack200/Pack200Exception.java index 5ad72b79a..6cef75df4 100644 --- a/src/main/java/org/apache/commons/compress/harmony/pack200/Pack200Exception.java +++ b/src/main/java/org/apache/commons/compress/harmony/pack200/Pack200Exception.java @@ -16,6 +16,7 @@ * specific language governing permissions and limitations * under the License. */ + package org.apache.commons.compress.harmony.pack200; import java.io.IOException; @@ -28,12 +29,28 @@ public class Pack200Exception extends IOException { private static final long serialVersionUID = 5168177401552611803L; /** - * Constructs a new Pack200 exception with the given message + * Constructs an {@code Pack200Exception} with the specified detail message. * - * @param message The detail message (which is saved for later retrieval by the {@link #getMessage()} method). + * @param message The detail message (which is saved for later retrieval by the {@link #getMessage()} method) */ public Pack200Exception(final String message) { super(message); } + /** + * Constructs an {@code Pack200Exception} with the specified detail message and cause. + * <p> + * Note that the detail message associated with {@code cause} is <i>not</i> automatically incorporated into this exception's detail message. + * </p> + * + * @param message The detail message (which is saved for later retrieval by the {@link #getMessage()} method) + * + * @param cause The cause (which is saved for later retrieval by the {@link #getCause()} method). (A null value is permitted, and indicates that the cause + * is nonexistent or unknown.) + * + * @since 1.28.0 + */ + public Pack200Exception(final String message, final Throwable cause) { + super(message, cause); + } } diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/SegmentConstantPool.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/SegmentConstantPool.java index 17fa7268b..bb0db9ebb 100644 --- a/src/main/java/org/apache/commons/compress/harmony/unpack200/SegmentConstantPool.java +++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/SegmentConstantPool.java @@ -133,7 +133,23 @@ protected static boolean regexMatches(final String regexString, final String com throw new Error("regex trying to match a pattern I don't know: " + regexString); } + static int toIndex(final long index) throws Pack200Exception { + if (index < 0) { + throw new Pack200Exception("Cannot have a negative index."); + } + return toIntExact(index); + } + + static int toIntExact(final long index) throws Pack200Exception { + try { + return Math.toIntExact(index); + } catch (final ArithmeticException e) { + throw new Pack200Exception("index", e); + } + } + private final CpBands bands; + private final SegmentConstantPoolArrayCache arrayCache = new SegmentConstantPoolArrayCache(); /** @@ -163,18 +179,16 @@ public ConstantPoolEntry getClassPoolEntry(final String name) { } /** - * Subset the constant pool of the specified type to be just that which has the specified class name. Answer the ConstantPoolEntry at the desiredIndex of - * the subsetted pool. + * Gets the subset constant pool of the specified type to be just that which has the specified class name. Answer the ConstantPoolEntry at the desiredIndex + * of the subset pool. * - * @param cp type of constant pool array to search - * @param desiredIndex index of the constant pool - * @param desiredClassName class to use to generate a subset of the pool + * @param cp type of constant pool array to search. + * @param desiredIndex index of the constant pool. + * @param desiredClassName class to use to generate a subset of the pool. * @return ConstantPoolEntry - * @throws Pack200Exception TODO + * @throws Pack200Exception if support for a type is not supported or the index not in the range [0, {@link Integer#MAX_VALUE}]. */ public ConstantPoolEntry getClassSpecificPoolEntry(final int cp, final long desiredIndex, final String desiredClassName) throws Pack200Exception { - final int index = (int) desiredIndex; - int realIndex = -1; final String[] array; switch (cp) { case CP_FIELD: @@ -189,69 +203,75 @@ public ConstantPoolEntry getClassSpecificPoolEntry(final int cp, final long desi default: throw new Error("Don't know how to handle " + cp); } - realIndex = matchSpecificPoolEntryIndex(array, desiredClassName, index); + final int index = toIndex(desiredIndex); + final int realIndex = matchSpecificPoolEntryIndex(array, desiredClassName, index); return getConstantPoolEntry(cp, realIndex); } - public ConstantPoolEntry getConstantPoolEntry(final int cp, final long value) throws Pack200Exception { - final int index = (int) value; + /** + * Gets the constant pool entry of the given type and index. + * + * @param type Constant pool type. + * @param index Index into a specific constant pool. + * @return a constant pool entry. + * @throws Pack200Exception if support for a type is not supported or the index not in the range [0, {@link Integer#MAX_VALUE}]. + */ + public ConstantPoolEntry getConstantPoolEntry(final int type, final long index) throws Pack200Exception { if (index == -1) { return null; } - if (index < 0) { - throw new Pack200Exception("Cannot have a negative range"); - } - switch (cp) { + final int actualIndex = toIndex(index); + switch (type) { case UTF_8: - return bands.cpUTF8Value(index); + return bands.cpUTF8Value(actualIndex); case CP_INT: - return bands.cpIntegerValue(index); + return bands.cpIntegerValue(actualIndex); case CP_FLOAT: - return bands.cpFloatValue(index); + return bands.cpFloatValue(actualIndex); case CP_LONG: - return bands.cpLongValue(index); + return bands.cpLongValue(actualIndex); case CP_DOUBLE: - return bands.cpDoubleValue(index); + return bands.cpDoubleValue(actualIndex); case CP_STRING: - return bands.cpStringValue(index); + return bands.cpStringValue(actualIndex); case CP_CLASS: - return bands.cpClassValue(index); + return bands.cpClassValue(actualIndex); case SIGNATURE: - throw new Error("I don't know what to do with signatures yet"); + throw new Pack200Exception("Type SIGNATURE is not supported yet: " + SIGNATURE); // return null /* new CPSignature(bands.getCpSignature()[index]) */; case CP_DESCR: - throw new Error("I don't know what to do with descriptors yet"); + throw new Pack200Exception("Type CP_DESCR is not supported yet: " + CP_DESCR); // return null /* new CPDescriptor(bands.getCpDescriptor()[index]) // */; case CP_FIELD: - return bands.cpFieldValue(index); + return bands.cpFieldValue(actualIndex); case CP_METHOD: - return bands.cpMethodValue(index); + return bands.cpMethodValue(actualIndex); case CP_IMETHOD: - return bands.cpIMethodValue(index); + return bands.cpIMethodValue(actualIndex); default: break; } // etc - throw new Error("Get value incomplete"); + throw new Pack200Exception("Type is not supported yet: " + type); } /** - * Answer the init method for the specified class. + * Gets the {@code init} method for the specified class. * - * @param cp constant pool to search (must be CP_METHOD) - * @param value index of init method - * @param desiredClassName String class name of the init method - * @return CPMethod init method - * @throws Pack200Exception TODO + * @param cp constant pool to search (must be CP_METHOD). + * @param value index of {@code init} method. + * @param desiredClassName String class name of the {@code init} method. + * @return CPMethod {@code init} method. + * @throws Pack200Exception if support for a type is not supported or the index not in the range [0, {@link Integer#MAX_VALUE}]. */ public ConstantPoolEntry getInitMethodPoolEntry(final int cp, final long value, final String desiredClassName) throws Pack200Exception { - int realIndex = -1; if (cp != CP_METHOD) { // TODO really an error? throw new Error("Nothing but CP_METHOD can be an <init>"); } - realIndex = matchSpecificPoolEntryIndex(bands.getCpMethodClass(), bands.getCpMethodDescriptor(), desiredClassName, REGEX_MATCH_INIT, (int) value); + final int realIndex = matchSpecificPoolEntryIndex(bands.getCpMethodClass(), bands.getCpMethodDescriptor(), desiredClassName, REGEX_MATCH_INIT, + toIndex(value)); return getConstantPoolEntry(cp, realIndex); } diff --git a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/forms/ReferenceForm.java b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/forms/ReferenceForm.java index 0cf63d838..7e25eeac8 100644 --- a/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/forms/ReferenceForm.java +++ b/src/main/java/org/apache/commons/compress/harmony/unpack200/bytecode/forms/ReferenceForm.java @@ -63,6 +63,14 @@ public void setByteCodeOperands(final ByteCode byteCode, final OperandManager op } } + /** + * Sets the nested entries. + * + * @param byteCode byte codes. + * @param operandManager Operand manager. + * @param offset offset. + * @throws Pack200Exception if support for a type is not supported or the offset not in the range [0, {@link Integer#MAX_VALUE}]. + */ protected void setNestedEntries(final ByteCode byteCode, final OperandManager operandManager, final int offset) throws Pack200Exception { final SegmentConstantPool globalPool = operandManager.globalConstantPool(); final ClassFileEntry[] nested = { globalPool.getConstantPoolEntry(getPoolID(), offset) };