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