You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2022/11/21 15:03:22 UTC

[commons-bcel] branch master updated: Code ctor should validate u4, not u2. for code length per JVM spec's "u4 code_length"

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-bcel.git


The following commit(s) were added to refs/heads/master by this push:
     new 5bb1c3f5 Code ctor should validate u4, not u2. for code length per JVM spec's "u4 code_length"
5bb1c3f5 is described below

commit 5bb1c3f5b83b8e678dc4655201ea5d419ecc0817
Author: Gary David Gregory (Code signing key) <gg...@apache.org>
AuthorDate: Mon Nov 21 10:02:39 2022 -0500

    Code ctor should validate u4, not u2. for code length per JVM spec's "u4
    code_length"
---
 src/main/java/org/apache/bcel/classfile/Code.java | 21 +++++++++++++++-
 src/main/java/org/apache/bcel/util/Args.java      | 30 +++++++++++++++++------
 2 files changed, 43 insertions(+), 8 deletions(-)

diff --git a/src/main/java/org/apache/bcel/classfile/Code.java b/src/main/java/org/apache/bcel/classfile/Code.java
index c29fcd39..5718f2d2 100644
--- a/src/main/java/org/apache/bcel/classfile/Code.java
+++ b/src/main/java/org/apache/bcel/classfile/Code.java
@@ -33,6 +33,25 @@ import org.apache.commons.lang3.ArrayUtils;
  * This attribute has attributes itself, namely <em>LineNumberTable</em> which is used for debugging purposes and
  * <em>LocalVariableTable</em> which contains information about the local variables.
  *
+ * <pre>
+ * Code_attribute {
+ *   u2 attribute_name_index;
+ *   u4 attribute_length;
+ *   u2 max_stack;
+ *   u2 max_locals;
+ *   u4 code_length;
+ *   u1 code[code_length];
+ *   u2 exception_table_length;
+ *   {
+ *     u2 start_pc;
+ *     u2 end_pc;
+ *     u2 handler_pc;
+ *     u2 catch_type;
+ *   } exception_table[exception_table_length];
+ *   u2 attributes_count;
+ *   attribute_info attributes[attributes_count];
+ * }
+ * </pre>
  * @see Attribute
  * @see CodeException
  * @see LineNumberTable
@@ -66,7 +85,7 @@ public final class Code extends Attribute {
     Code(final int nameIndex, final int length, final DataInput file, final ConstantPool constantPool) throws IOException {
         // Initialize with some default values which will be overwritten later
         this(nameIndex, length, file.readUnsignedShort(), file.readUnsignedShort(), (byte[]) null, (CodeException[]) null, (Attribute[]) null, constantPool);
-        final int codeLength = Args.requireU2(file.readInt(), 1, "Code length attribute");
+        final int codeLength = Args.requireU4(file.readInt(), 1, "Code length attribute");
         code = new byte[codeLength]; // Read byte code
         file.readFully(code);
         /*
diff --git a/src/main/java/org/apache/bcel/util/Args.java b/src/main/java/org/apache/bcel/util/Args.java
index 0ff13f96..be385606 100644
--- a/src/main/java/org/apache/bcel/util/Args.java
+++ b/src/main/java/org/apache/bcel/util/Args.java
@@ -78,10 +78,10 @@ public class Args {
      */
     public static int requireU2(final int value, final int min, final int max, final String message) {
         if (max > Const.MAX_SHORT) {
-            throw new IllegalArgumentException(String.format("Programming error: %,d > %,d", max, Const.MAX_SHORT));
+            throw new IllegalArgumentException(String.format("Programming error: max %,d > %,d", max, Const.MAX_SHORT));
         }
         if (min < 0) {
-            throw new IllegalArgumentException(String.format("Programming error: %,d < 0", min));
+            throw new IllegalArgumentException(String.format("Programming error: min %,d < 0", min));
         }
         if (value < min || value > max) {
             throw new ClassFormatException(String.format("%s [Value out of range (%,d - %,d) for type u2: %,d]", message, min, Const.MAX_SHORT, value));
@@ -98,7 +98,7 @@ public class Args {
      * @return The value to test.
      */
     public static int requireU2(final int value, final int min, final String message) {
-        return requireU2(value, 0, Const.MAX_SHORT, message);
+        return requireU2(value, min, Const.MAX_SHORT, message);
     }
 
     /**
@@ -113,16 +113,32 @@ public class Args {
     }
 
     /**
-     * Requires a u4 value.
+     * Requires a u4 value of at least {@code min}.
      *
      * @param value   The value to test.
+     * @param min     The minimum required value.
      * @param message The message prefix
      * @return The value to test.
      */
-    public static int requireU4(final int value, final String message) {
-        if (value < 0) {
-            throw new ClassFormatException(String.format("%s [Value out of range (0 - %,d) for type u4: %,d]", message, Integer.MAX_VALUE, value & 0xFFFFFFFFL));
+    public static int requireU4(final int value, final int min, final String message) {
+        if (min < 0) {
+            throw new IllegalArgumentException(String.format("Programming error: min %,d < 0", min));
+        }
+        if (value < min) {
+            throw new ClassFormatException(
+                    String.format("%s [Value out of range (%,d - %,d) for type u2: %,d]", message, min, Integer.MAX_VALUE, value & 0xFFFFFFFFL));
         }
         return value;
     }
+
+    /**
+     * Requires a u4 value.
+     *
+     * @param value   The value to test.
+     * @param message The message prefix
+     * @return The value to test.
+     */
+    public static int requireU4(final int value, final String message) {
+        return requireU4(value, 0, message);
+    }
 }