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) };

Reply via email to