This is an automated email from the ASF dual-hosted git repository.

garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-bcel.git

commit e2fb2ab23ebf182577754ec2a4aff8d2c2dd8528
Author: Gary Gregory <[email protected]>
AuthorDate: Thu Sep 17 09:12:26 2026 -0700

    Add and use ClassFormatException.ClassFormatException(String,
    Object...).
---
 src/changes/changes.xml                            |  3 ++-
 src/examples/ClassDumper.java                      |  4 ++--
 .../bcel/classfile/AnnotationElementValue.java     |  2 +-
 .../apache/bcel/classfile/ArrayElementValue.java   |  2 +-
 .../java/org/apache/bcel/classfile/Attribute.java  |  5 +++--
 .../bcel/classfile/ClassFormatException.java       | 11 +++++++++++
 .../org/apache/bcel/classfile/ClassParser.java     |  4 ++--
 .../java/org/apache/bcel/classfile/Constant.java   |  2 +-
 .../org/apache/bcel/classfile/ConstantPool.java    | 20 ++++++++++----------
 .../org/apache/bcel/classfile/ElementValue.java    |  5 ++---
 .../apache/bcel/classfile/EnumElementValue.java    |  2 +-
 .../apache/bcel/classfile/SimpleElementValue.java  |  2 +-
 .../org/apache/bcel/classfile/StackMapEntry.java   |  4 ++--
 .../org/apache/bcel/classfile/StackMapType.java    |  2 +-
 .../java/org/apache/bcel/classfile/Utility.java    | 22 +++++++++++-----------
 .../java/org/apache/bcel/generic/LOOKUPSWITCH.java |  2 +-
 .../java/org/apache/bcel/generic/TABLESWITCH.java  |  3 +--
 src/main/java/org/apache/bcel/generic/Type.java    |  2 +-
 src/main/java/org/apache/bcel/util/Args.java       |  9 ++++-----
 src/main/java/org/apache/bcel/util/CodeHTML.java   |  4 ++--
 .../java/org/apache/bcel/data/ConstantPoolX.java   |  6 +++---
 21 files changed, 63 insertions(+), 53 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index ba3cee3b..47f7aabf 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -59,9 +59,10 @@ The <action> type attribute can be add,update,fix,remove.
   Defining changes.version allows one to create the RN without first removing 
the SNAPSHOT suffix.
    -->
   <body>
-    <release version="6.13.1" date="YYYY-MM-DD" description="This is a feature 
and maintenance release. Java 8 or later is required.">
+    <release version="6.14.0" date="YYYY-MM-DD" description="This is a feature 
and maintenance release. Java 8 or later is required.">
       <!-- FIX -->
       <!-- ADD -->
+      <action                  type="add" dev="ggregory" due-to="Gary 
Gregory">Add and use ClassFormatException.ClassFormatException(String, 
Object...).</action>
       <!-- UPDATE -->
     </release>
     <release version="6.13.0" date="2026-09-06" description="This is a feature 
and maintenance release. Java 8 or later is required.">
diff --git a/src/examples/ClassDumper.java b/src/examples/ClassDumper.java
index acd9516f..ead2d07f 100644
--- a/src/examples/ClassDumper.java
+++ b/src/examples/ClassDumper.java
@@ -127,7 +127,7 @@ final class ClassDumper {
             accessFlags |= Const.ACC_ABSTRACT;
         }
         if ((accessFlags & Const.ACC_ABSTRACT) != 0 && (accessFlags & 
Const.ACC_FINAL) != 0) {
-            throw new ClassFormatException("Class " + fileName + " can't be 
both final and abstract");
+            throw new ClassFormatException("Class %s can't be both final and 
abstract", fileName);
         }
 
         System.out.printf("%nClass info:%n");
@@ -259,7 +259,7 @@ final class ClassDumper {
     private void processID() throws IOException, ClassFormatException {
         final int magic = file.readInt();
         if (magic != Const.JVM_CLASSFILE_MAGIC) {
-            throw new ClassFormatException(fileName + " is not a Java .class 
file");
+            throw new ClassFormatException("%s is not a Java .class file", 
fileName);
         }
         System.out.println("Java Class Dump");
         System.out.println("  file: " + fileName);
diff --git 
a/src/main/java/org/apache/bcel/classfile/AnnotationElementValue.java 
b/src/main/java/org/apache/bcel/classfile/AnnotationElementValue.java
index 334361f9..8c8092c2 100644
--- a/src/main/java/org/apache/bcel/classfile/AnnotationElementValue.java
+++ b/src/main/java/org/apache/bcel/classfile/AnnotationElementValue.java
@@ -40,7 +40,7 @@ public class AnnotationElementValue extends ElementValue {
     public AnnotationElementValue(final int type, final AnnotationEntry 
annotationEntry, final ConstantPool cpool) {
         super(type, cpool);
         if (type != ANNOTATION) {
-            throw new ClassFormatException("Only element values of type 
annotation can be built with this ctor - type specified: " + type);
+            throw new ClassFormatException("Only element values of type 
annotation can be built with this ctor - type specified: %s", type);
         }
         this.annotationEntry = annotationEntry;
     }
diff --git a/src/main/java/org/apache/bcel/classfile/ArrayElementValue.java 
b/src/main/java/org/apache/bcel/classfile/ArrayElementValue.java
index 5a8d3195..56ff01da 100644
--- a/src/main/java/org/apache/bcel/classfile/ArrayElementValue.java
+++ b/src/main/java/org/apache/bcel/classfile/ArrayElementValue.java
@@ -42,7 +42,7 @@ public class ArrayElementValue extends ElementValue {
     public ArrayElementValue(final int type, final ElementValue[] 
elementValues, final ConstantPool cpool) {
         super(type, cpool);
         if (type != ARRAY) {
-            throw new ClassFormatException("Only element values of type array 
can be built with this ctor - type specified: " + type);
+            throw new ClassFormatException("Only element values of type array 
can be built with this ctor - type specified: %s", type);
         }
         this.elementValues = elementValues != null ? elementValues : 
EMPTY_ARRAY;
     }
diff --git a/src/main/java/org/apache/bcel/classfile/Attribute.java 
b/src/main/java/org/apache/bcel/classfile/Attribute.java
index cc671a36..6320aed1 100644
--- a/src/main/java/org/apache/bcel/classfile/Attribute.java
+++ b/src/main/java/org/apache/bcel/classfile/Attribute.java
@@ -137,8 +137,9 @@ public abstract class Attribute implements Cloneable, Node {
         // mutually recursive Record component attributes) deeply enough to 
overflow the parser's stack (CWE-674).
         final int depth = NESTING_DEPTH.get().intValue() + 1;
         if (depth > MAX_NESTING_DEPTH) {
-            throw new ClassFormatException("Attributes are nested more than " 
+ MAX_NESTING_DEPTH + " levels deep; if this is a valid class file, raise the"
-                    + " limit with the system property " + 
Attribute.class.getCanonicalName() + ".maxNestingDepth.");
+            throw new ClassFormatException(
+                    "Attributes are nested more than %,d levels deep; if this 
is a valid class file, raise the limit with the system property 
%s.maxNestingDepth.",
+                    MAX_NESTING_DEPTH, Attribute.class.getCanonicalName());
         }
         NESTING_DEPTH.set(Integer.valueOf(depth));
         try {
diff --git a/src/main/java/org/apache/bcel/classfile/ClassFormatException.java 
b/src/main/java/org/apache/bcel/classfile/ClassFormatException.java
index 6540de6e..11c44e05 100644
--- a/src/main/java/org/apache/bcel/classfile/ClassFormatException.java
+++ b/src/main/java/org/apache/bcel/classfile/ClassFormatException.java
@@ -42,6 +42,17 @@ public class ClassFormatException extends RuntimeException {
         super(message);
     }
 
+    /**
+     * Constructs a new instance with the specified detail message formatted 
with See {@link String#format(String, Object...)}.
+     *
+     * @param format See {@link String#format(String, Object...)}.
+     * @param args   See {@link String#format(String, Object...)}.
+     * @since 6.14.0
+     */
+    public ClassFormatException(String format, Object... args) {
+        super(String.format(format, args));
+    }
+
     /**
      * Constructs a new instance with the specified detail message and cause.
      *
diff --git a/src/main/java/org/apache/bcel/classfile/ClassParser.java 
b/src/main/java/org/apache/bcel/classfile/ClassParser.java
index ecd68957..71bd03e1 100644
--- a/src/main/java/org/apache/bcel/classfile/ClassParser.java
+++ b/src/main/java/org/apache/bcel/classfile/ClassParser.java
@@ -211,7 +211,7 @@ public final class ClassParser {
             accessFlags |= Const.ACC_ABSTRACT;
         }
         if ((accessFlags & Const.ACC_ABSTRACT) != 0 && (accessFlags & 
Const.ACC_FINAL) != 0) {
-            throw new ClassFormatException("Class " + fileName + " can't be 
both final and abstract");
+            throw new ClassFormatException("Class %s can't be both final and 
abstract", fileName);
         }
         classNameIndex = dataInputStream.readUnsignedShort();
         superclassNameIndex = dataInputStream.readUnsignedShort();
@@ -249,7 +249,7 @@ public final class ClassParser {
      */
     private void readID() throws IOException, ClassFormatException {
         if (dataInputStream.readInt() != Const.JVM_CLASSFILE_MAGIC) {
-            throw new ClassFormatException(fileName + " is not a Java .class 
file");
+            throw new ClassFormatException("%s is not a Java .class file", 
fileName);
         }
     }
 
diff --git a/src/main/java/org/apache/bcel/classfile/Constant.java 
b/src/main/java/org/apache/bcel/classfile/Constant.java
index c3b1b4a8..56a3750e 100644
--- a/src/main/java/org/apache/bcel/classfile/Constant.java
+++ b/src/main/java/org/apache/bcel/classfile/Constant.java
@@ -103,7 +103,7 @@ public abstract class Constant implements Cloneable, Node {
         case Const.CONSTANT_Package:
             return new ConstantPackage(dataInput);
         default:
-            throw new ClassFormatException("Invalid byte tag in constant pool: 
" + b);
+            throw new ClassFormatException("Invalid byte tag in constant pool: 
%s", b);
         }
     }
 
diff --git a/src/main/java/org/apache/bcel/classfile/ConstantPool.java 
b/src/main/java/org/apache/bcel/classfile/ConstantPool.java
index 51ce05e2..3beef94d 100644
--- a/src/main/java/org/apache/bcel/classfile/ConstantPool.java
+++ b/src/main/java/org/apache/bcel/classfile/ConstantPool.java
@@ -172,8 +172,8 @@ public class ConstantPool implements Cloneable, Node, 
Iterable<Constant> {
             // CONSTANT_MethodHandle referencing another CONSTANT_MethodHandle 
(such as itself) would otherwise make
             // this method recurse without bound until a StackOverflowError.
             if (referenceTag != Const.CONSTANT_Fieldref && referenceTag != 
Const.CONSTANT_Methodref && referenceTag != Const.CONSTANT_InterfaceMethodref) {
-                throw new ClassFormatException(
-                        "Constant pool at index " + cmh.getReferenceIndex() + 
" has an invalid tag " + referenceTag + " for a CONSTANT_MethodHandle 
reference");
+                throw new ClassFormatException("Constant pool at index %,d has 
an invalid tag %s for a CONSTANT_MethodHandle reference",
+                        cmh.getReferenceIndex(), referenceTag);
             }
             str = Const.getMethodHandleName(cmh.getReferenceKind()) + " " + 
constantToString(cmh.getReferenceIndex(), referenceTag);
             break;
@@ -250,7 +250,7 @@ public class ConstantPool implements Cloneable, Node, 
Iterable<Constant> {
          * desynchronizes any consumer that reparses the emitted bytes (the 
CVE-2022-42920 writer-overflow shape).
          */
         if (constantPool.length > Const.MAX_CP_ENTRIES) {
-            throw new ClassFormatException("Constant pool size " + 
constantPool.length + " exceeds the u2 maximum of " + Const.MAX_CP_ENTRIES);
+            throw new ClassFormatException("Constant pool size %,d exceeds the 
u2 maximum of %,d", constantPool.length, Const.MAX_CP_ENTRIES);
         }
         file.writeShort(constantPool.length);
         for (int i = 1; i < constantPool.length; i++) {
@@ -304,7 +304,7 @@ public class ConstantPool implements Cloneable, Node, 
Iterable<Constant> {
     public <T extends Constant> T getConstant(final int index, final byte tag, 
final Class<T> castTo) throws ClassFormatException {
         final T c = getConstant(index);
         if (c == null || c.getTag() != tag) {
-            throw new ClassFormatException("Expected class '" + 
Const.getConstantName(tag) + "' at index " + index + " and got " + c);
+            throw new ClassFormatException("Expected class '%s' at index %,d 
and got %s", Const.getConstantName(tag), index, c);
         }
         return c;
     }
@@ -322,23 +322,23 @@ public class ConstantPool implements Cloneable, Node, 
Iterable<Constant> {
      */
     public <T extends Constant> T getConstant(final int index, final Class<T> 
castTo) throws ClassFormatException {
         if (index >= constantPool.length || index < 1) {
-            throw new ClassFormatException("Invalid constant pool reference 
using index: " + index + ". Constant pool size is: " + constantPool.length);
+            throw new ClassFormatException("Invalid constant pool reference 
using index: %,d. Constant pool size is: %,d", index, constantPool.length);
         }
         if (constantPool[index] != null && 
!castTo.isAssignableFrom(constantPool[index].getClass())) {
-            throw new ClassFormatException("Invalid constant pool reference at 
index: " + index +
-                    ". Expected " + castTo + " but was " + 
constantPool[index].getClass());
+            throw new ClassFormatException("Invalid constant pool reference at 
index: %,d. Expected %s but was %s", index, castTo,
+                    constantPool[index].getClass());
         }
         if (index > 1) {
             final Constant prev = constantPool[index - 1];
             if (prev != null && (prev.getTag() == Const.CONSTANT_Double || 
prev.getTag() == Const.CONSTANT_Long)) {
-                throw new ClassFormatException("Constant pool at index " + 
index + " is invalid. The index is unused due to the preceeding "
-                        + Const.getConstantName(prev.getTag()) + ".");
+                throw new ClassFormatException("Constant pool at index %,d is 
invalid. The index is unused due to the preceeding %s.", index,
+                        Const.getConstantName(prev.getTag()));
             }
         }
         // Previous check ensures this won't throw a ClassCastException
         final T c = castTo.cast(constantPool[index]);
         if (c == null) {
-            throw new ClassFormatException("Constant pool at index " + index + 
" is null.");
+            throw new ClassFormatException("Constant pool at index %,d is 
null.", index);
         }
         return c;
     }
diff --git a/src/main/java/org/apache/bcel/classfile/ElementValue.java 
b/src/main/java/org/apache/bcel/classfile/ElementValue.java
index 1a607323..ec5de5eb 100644
--- a/src/main/java/org/apache/bcel/classfile/ElementValue.java
+++ b/src/main/java/org/apache/bcel/classfile/ElementValue.java
@@ -134,8 +134,7 @@ public abstract class ElementValue {
                 // Annotation element values may legitimately nest 
(annotations whose members are annotations or arrays thereof), but a malicious 
class file
                 // can alternate annotation and array nesting to recurse 
without limit. Count both kinds of nesting against the same JVM spec 4.4.1 
bound so
                 // the depth cannot be reset by wrapping an array in an 
annotation (CWE-674).
-                throw new ClassFormatException(
-                    String.format("Annotation element values are only valid if 
they nest %,d or fewer levels.", Const.MAX_ARRAY_DIMENSIONS));
+                throw new ClassFormatException("Annotation element values are 
only valid if they nest %,d or fewer levels.", Const.MAX_ARRAY_DIMENSIONS);
             }
             return new AnnotationElementValue(ANNOTATION, 
AnnotationEntry.read(input, cpool, isRuntimeVisible, arrayNesting), cpool);
 
@@ -143,7 +142,7 @@ public abstract class ElementValue {
             arrayNesting++;
             if (arrayNesting > Const.MAX_ARRAY_DIMENSIONS) {
                 // JVM spec 4.4.1
-                throw new ClassFormatException(String.format("Arrays are only 
valid if they represent %,d or fewer dimensions.", Const.MAX_ARRAY_DIMENSIONS));
+                throw new ClassFormatException("Arrays are only valid if they 
represent %,d or fewer dimensions.", Const.MAX_ARRAY_DIMENSIONS);
             }
             final int numArrayVals = input.readUnsignedShort();
             final ElementValue[] evalues = new ElementValue[numArrayVals];
diff --git a/src/main/java/org/apache/bcel/classfile/EnumElementValue.java 
b/src/main/java/org/apache/bcel/classfile/EnumElementValue.java
index 4dde61fe..7df4bc5a 100644
--- a/src/main/java/org/apache/bcel/classfile/EnumElementValue.java
+++ b/src/main/java/org/apache/bcel/classfile/EnumElementValue.java
@@ -43,7 +43,7 @@ public class EnumElementValue extends ElementValue {
     public EnumElementValue(final int type, final int typeIdx, final int 
valueIdx, final ConstantPool cpool) {
         super(type, cpool);
         if (type != ENUM_CONSTANT) {
-            throw new ClassFormatException("Only element values of type enum 
can be built with this ctor - type specified: " + type);
+            throw new ClassFormatException("Only element values of type enum 
can be built with this ctor - type specified: %d", type);
         }
         this.typeIdx = typeIdx;
         this.valueIdx = valueIdx;
diff --git a/src/main/java/org/apache/bcel/classfile/SimpleElementValue.java 
b/src/main/java/org/apache/bcel/classfile/SimpleElementValue.java
index b674cbe5..75ad648a 100644
--- a/src/main/java/org/apache/bcel/classfile/SimpleElementValue.java
+++ b/src/main/java/org/apache/bcel/classfile/SimpleElementValue.java
@@ -60,7 +60,7 @@ public class SimpleElementValue extends ElementValue {
             dos.writeShort(getIndex());
             break;
         default:
-            throw new ClassFormatException("SimpleElementValue doesn't know 
how to write out type " + type);
+            throw new ClassFormatException("SimpleElementValue doesn't know 
how to write out type %d", type);
         }
     }
 
diff --git a/src/main/java/org/apache/bcel/classfile/StackMapEntry.java 
b/src/main/java/org/apache/bcel/classfile/StackMapEntry.java
index 93b2fed8..3057a875 100644
--- a/src/main/java/org/apache/bcel/classfile/StackMapEntry.java
+++ b/src/main/java/org/apache/bcel/classfile/StackMapEntry.java
@@ -98,7 +98,7 @@ public final class StackMapEntry implements Node, Cloneable {
             }
         } else {
             /* Can't happen */
-            throw new ClassFormatException("Invalid frame type found while 
parsing stack map table: " + frameType);
+            throw new ClassFormatException("Invalid frame type found while 
parsing stack map table: %d", frameType);
         }
     }
 
@@ -209,7 +209,7 @@ public final class StackMapEntry implements Node, Cloneable 
{
             }
         } else if (!(frameType >= Const.SAME_FRAME && frameType <= 
Const.SAME_FRAME_MAX)) {
             /* Can't happen */
-            throw new ClassFormatException("Invalid Stack map table tag: " + 
frameType);
+            throw new ClassFormatException("Invalid Stack map table tag: %d", 
frameType);
         }
     }
 
diff --git a/src/main/java/org/apache/bcel/classfile/StackMapType.java 
b/src/main/java/org/apache/bcel/classfile/StackMapType.java
index b6ab8444..defbe92b 100644
--- a/src/main/java/org/apache/bcel/classfile/StackMapType.java
+++ b/src/main/java/org/apache/bcel/classfile/StackMapType.java
@@ -84,7 +84,7 @@ public final class StackMapType implements Node, Cloneable {
 
     private byte checkType(final byte type) {
         if (type < Const.ITEM_Bogus || type > Const.ITEM_NewObject) {
-            throw new ClassFormatException("Illegal type for StackMapType: " + 
type);
+            throw new ClassFormatException("Illegal type for StackMapType: 
%d", type);
         }
         return type;
     }
diff --git a/src/main/java/org/apache/bcel/classfile/Utility.java 
b/src/main/java/org/apache/bcel/classfile/Utility.java
index e3b00655..0eee074d 100644
--- a/src/main/java/org/apache/bcel/classfile/Utility.java
+++ b/src/main/java/org/apache/bcel/classfile/Utility.java
@@ -387,7 +387,7 @@ public abstract class Utility {
             // huge allocation.
             final long jumpTableLength = (long) high - low + 1;
             if (jumpTableLength < 0 || jumpTableLength * 4 > 
bytes.available()) {
-                throw new ClassFormatException("Invalid TABLESWITCH: low = " + 
low + ", high = " + high + " but only " + bytes.available() + " bytes remain");
+                throw new ClassFormatException("Invalid TABLESWITCH: low = 
%,d, high = %,d but only %,d bytes remain", low, high, bytes.available());
             }
             buf.append("\tdefault = ").append(defaultOffset).append(", low = 
").append(low).append(", high = ").append(high).append("(");
             jumpTable = new int[(int) jumpTableLength];
@@ -408,7 +408,7 @@ public abstract class Utility {
             offset = bytes.getIndex() - 8 - noPadBytes - 1;
             // Each match-offset pair is 8 bytes, see the TABLESWITCH check 
above.
             if (npairs < 0 || (long) npairs * 8 > bytes.available()) {
-                throw new ClassFormatException("Invalid LOOKUPSWITCH: npairs = 
" + npairs + " but only " + bytes.available() + " bytes remain");
+                throw new ClassFormatException("Invalid LOOKUPSWITCH: npairs = 
%,d but only %,d bytes remain", npairs, bytes.available());
             }
             match = new int[npairs];
             jumpTable = new int[npairs];
@@ -1090,7 +1090,7 @@ public abstract class Utility {
             for (final String element : argv) {
                 str = getSignature(element);
                 if (str.endsWith("V")) {
-                    throw new ClassFormatException("Invalid type: " + element);
+                    throw new ClassFormatException("Invalid type: %s", 
element);
                 }
                 buf.append(str);
             }
@@ -1441,7 +1441,7 @@ public abstract class Utility {
     private static String typeParamTypeToString(final String signature, final 
boolean chopit) {
         int index = signature.indexOf(':');
         if (index <= 0) {
-            throw new ClassFormatException("Invalid type parameter signature: 
" + signature);
+            throw new ClassFormatException("Invalid type parameter signature: 
%s", signature);
         }
         // get the TypeParameter identifier
         final StringBuilder typeParam = new 
StringBuilder(signature.substring(0, index));
@@ -1516,7 +1516,7 @@ public abstract class Utility {
      */
     private static String typeSignatureToString(final String signature, final 
boolean chopit, final int depth) throws ClassFormatException {
         if (depth > MAX_SIGNATURE_NESTING) {
-            throw new ClassFormatException("Invalid signature: nesting depth 
exceeds " + MAX_SIGNATURE_NESTING);
+            throw new ClassFormatException("Invalid signature: nesting depth 
exceeds %,d", MAX_SIGNATURE_NESTING);
         }
         // corrected concurrent private static field acess
         wrap(CONSUMER_CHARS, 1); // This is the default, read just one char 
like 'B'
@@ -1537,7 +1537,7 @@ public abstract class Utility {
             case 'T': { // TypeVariableSignature
                 final int index = signature.indexOf(';'); // Look for closing 
';'
                 if (index < 0) {
-                    throw new ClassFormatException("Invalid type variable 
signature: " + signature);
+                    throw new ClassFormatException("Invalid type variable 
signature: %s", signature);
                 }
                 // corrected concurrent private static field acess
                 wrap(CONSUMER_CHARS, index + 1); // "Tblabla;" 'T' and ';' are 
removed
@@ -1552,12 +1552,12 @@ public abstract class Utility {
                 } else {
                     fromIndex = signature.indexOf('>', fromIndex);
                     if (fromIndex < 0) {
-                        throw new ClassFormatException("Invalid signature: " + 
signature);
+                        throw new ClassFormatException("Invalid signature: 
%s", signature);
                     }
                 }
                 final int index = signature.indexOf(';', fromIndex); // Look 
for closing ';'
                 if (index < 0) {
-                    throw new ClassFormatException("Invalid signature: " + 
signature);
+                    throw new ClassFormatException("Invalid signature: %s", 
signature);
                 }
 
                 // check to see if there are any TypeArguments
@@ -1570,7 +1570,7 @@ public abstract class Utility {
                 // but make sure we are not looking past the end of the 
current item
                 fromIndex = signature.indexOf(';');
                 if (fromIndex < 0) {
-                    throw new ClassFormatException("Invalid signature: " + 
signature);
+                    throw new ClassFormatException("Invalid signature: %s", 
signature);
                 }
                 if (fromIndex < bracketIndex) {
                     // just a class identifier
@@ -1643,7 +1643,7 @@ public abstract class Utility {
                     return type.toString();
                 }
                 if (signature.charAt(consumedChars) != ';') {
-                    throw new ClassFormatException("Invalid signature: " + 
signature);
+                    throw new ClassFormatException("Invalid signature: %s", 
signature);
                 }
                 wrap(CONSUMER_CHARS, consumedChars + 1); // remove final ";"
                 return type.toString();
@@ -1671,7 +1671,7 @@ public abstract class Utility {
             case 'V':
                 return "void";
             default:
-                throw new ClassFormatException("Invalid signature: '" + 
signature + "'");
+                throw new ClassFormatException("Invalid signature: '%s'", 
signature);
             }
         } catch (final StringIndexOutOfBoundsException e) { // Should never 
occur
             throw new ClassFormatException("Invalid signature: " + signature, 
e);
diff --git a/src/main/java/org/apache/bcel/generic/LOOKUPSWITCH.java 
b/src/main/java/org/apache/bcel/generic/LOOKUPSWITCH.java
index 67e7a20c..b02ea7e6 100644
--- a/src/main/java/org/apache/bcel/generic/LOOKUPSWITCH.java
+++ b/src/main/java/org/apache/bcel/generic/LOOKUPSWITCH.java
@@ -93,7 +93,7 @@ public class LOOKUPSWITCH extends Select {
         // Require the match table to actually fit into the remaining code 
bytes (8 bytes per match-offset pair). The npairs field is attacker-controlled 
in
         // a malicious class file and could otherwise request a multi-gigabyte 
allocation, or a negative array size, before a single pair is read.
         if (matchLength < 0 || matchLength > bytes.available() / 8) {
-            throw new ClassFormatException("Invalid lookupswitch: npairs=" + 
matchLength + ", but only " + bytes.available() + " bytes of code remain.");
+            throw new ClassFormatException("Invalid lookupswitch: npairs=%,d, 
but only %,d bytes of code remain.", matchLength, bytes.available());
         }
         setMatchLength(matchLength);
         final short fixedLength = (short) (9 + matchLength * 8);
diff --git a/src/main/java/org/apache/bcel/generic/TABLESWITCH.java 
b/src/main/java/org/apache/bcel/generic/TABLESWITCH.java
index 736fbc68..effca7d8 100644
--- a/src/main/java/org/apache/bcel/generic/TABLESWITCH.java
+++ b/src/main/java/org/apache/bcel/generic/TABLESWITCH.java
@@ -98,8 +98,7 @@ public class TABLESWITCH extends Select {
         // allocation, or a negative array size, before a single table entry 
is read.
         final long matchLengthLong = (long) high - low + 1;
         if (matchLengthLong < 0 || matchLengthLong > bytes.available() / 4) {
-            throw new ClassFormatException(
-                    "Invalid tableswitch: low=" + low + ", high=" + high + ", 
but only " + bytes.available() + " bytes of code remain.");
+            throw new ClassFormatException("Invalid tableswitch: low=%,d, 
high=%,d, but only %,d bytes of code remain.", low, high, bytes.available());
         }
         final int matchLength = (int) matchLengthLong;
         setMatchLength(matchLength);
diff --git a/src/main/java/org/apache/bcel/generic/Type.java 
b/src/main/java/org/apache/bcel/generic/Type.java
index dff2dcaf..9aee2ed3 100644
--- a/src/main/java/org/apache/bcel/generic/Type.java
+++ b/src/main/java/org/apache/bcel/generic/Type.java
@@ -315,7 +315,7 @@ public abstract class Type {
         }
         final int index = signature.indexOf(';'); // Look for closing ';'
         if (index < 0) {
-            throw new ClassFormatException("Invalid signature: " + signature);
+            throw new ClassFormatException("Invalid signature: %s", signature);
         }
         return encode(1, index + 1);
     }
diff --git a/src/main/java/org/apache/bcel/util/Args.java 
b/src/main/java/org/apache/bcel/util/Args.java
index 25d45e11..e6c79f69 100644
--- a/src/main/java/org/apache/bcel/util/Args.java
+++ b/src/main/java/org/apache/bcel/util/Args.java
@@ -39,7 +39,7 @@ public class Args {
      */
     public static int require(final int value, final int required, final 
String message) {
         if (value != required) {
-            throw new ClassFormatException(String.format("%s [Value must be 0: 
%,d]", message, value));
+            throw new ClassFormatException("%s [Value must be 0: %,d]", 
message, value);
         }
         return value;
     }
@@ -64,7 +64,7 @@ public class Args {
      */
     public static int requireU1(final int value, final String message) {
         if (value < 0 || value > Const.MAX_BYTE) {
-            throw new ClassFormatException(String.format("%s [Value out of 
range (0 - %,d) for type u1: %,d]", message, Const.MAX_BYTE, value));
+            throw new ClassFormatException("%s [Value out of range (0 - %,d) 
for type u1: %,d]", message, Const.MAX_BYTE, value);
         }
         return value;
     }
@@ -86,7 +86,7 @@ public class Args {
             throw new IllegalArgumentException(String.format("%s programming 
error: min %,d < 0", message, min));
         }
         if (value < min || value > max) {
-            throw new ClassFormatException(String.format("%s [Value out of 
range (%,d - %,d) for type u2: %,d]", message, min, max, value));
+            throw new ClassFormatException("%s [Value out of range (%,d - %,d) 
for type u2: %,d]", message, min, max, value);
         }
         return value;
     }
@@ -131,8 +131,7 @@ public class Args {
             throw new IllegalArgumentException(String.format("%s programming 
error: min %,d < 0", message, min));
         }
         if (value < min || value > max) {
-            throw new ClassFormatException(
-                    String.format("%s [Value out of range (%,d - %,d) for type 
u4: %,d]", message, min, Integer.MAX_VALUE, value & 0xFFFFFFFFL));
+            throw new ClassFormatException("%s [Value out of range (%,d - %,d) 
for type u4: %,d]", message, min, Integer.MAX_VALUE, value & 0xFFFFFFFFL);
         }
         return value;
     }
diff --git a/src/main/java/org/apache/bcel/util/CodeHTML.java 
b/src/main/java/org/apache/bcel/util/CodeHTML.java
index c23527a3..6f8597bb 100644
--- a/src/main/java/org/apache/bcel/util/CodeHTML.java
+++ b/src/main/java/org/apache/bcel/util/CodeHTML.java
@@ -115,7 +115,7 @@ final class CodeHTML {
             // huge allocation.
             final long jumpTableLength = (long) high - low + 1;
             if (jumpTableLength < 0 || jumpTableLength * 4 > 
bytes.available()) {
-                throw new ClassFormatException("Invalid TABLESWITCH: low = " + 
low + ", high = " + high + " but only " + bytes.available() + " bytes remain");
+                throw new ClassFormatException("Invalid TABLESWITCH: low = 
%,d, high = %,d but only %,d bytes remain", low, high, bytes.available());
             }
             buf.append("<TABLE BORDER=1><TR>");
             // Print switch indices in first row (and default)
@@ -140,7 +140,7 @@ final class CodeHTML {
             offset = bytes.getIndex() - 8 - noPadBytes - 1;
             // Each match-offset pair is 8 bytes, see the TABLESWITCH check 
above.
             if (npairs < 0 || (long) npairs * 8 > bytes.available()) {
-                throw new ClassFormatException("Invalid LOOKUPSWITCH: npairs = 
" + npairs + " but only " + bytes.available() + " bytes remain");
+                throw new ClassFormatException("Invalid LOOKUPSWITCH: npairs = 
%,d but only %,d bytes remain", npairs, bytes.available());
             }
             jumpTable = new int[npairs];
             defaultOffset += offset;
diff --git a/src/test/java/org/apache/bcel/data/ConstantPoolX.java 
b/src/test/java/org/apache/bcel/data/ConstantPoolX.java
index ba5cb41c..c6f88847 100644
--- a/src/test/java/org/apache/bcel/data/ConstantPoolX.java
+++ b/src/test/java/org/apache/bcel/data/ConstantPoolX.java
@@ -202,7 +202,7 @@ public abstract class ConstantPoolX implements Cloneable, 
Node {
      */
     public Constant getConstant(final int index) {
         if (index >= constantPool.length || index < 0) {
-            throw new ClassFormatException("Invalid constant pool reference: " 
+ index + ". Constant pool size is: " + constantPool.length);
+            throw new ClassFormatException("Invalid constant pool reference: 
%,d. Constant pool size is: %,d", index, constantPool.length);
         }
         return constantPool[index];
     }
@@ -219,10 +219,10 @@ public abstract class ConstantPoolX implements Cloneable, 
Node {
     public Constant getConstant(final int index, final byte tag) throws 
ClassFormatException {
         final Constant c = getConstant(index);
         if (c == null) {
-            throw new ClassFormatException("Constant pool at index " + index + 
" is null.");
+            throw new ClassFormatException("Constant pool at index %,d is 
null.", index);
         }
         if (c.getTag() != tag) {
-            throw new ClassFormatException("Expected class '" + 
Const.getConstantName(tag) + "' at index " + index + " and got " + c);
+            throw new ClassFormatException("Expected class '%s' at index %,d 
and got %s", Const.getConstantName(tag), index, c);
         }
         return c;
     }

Reply via email to