/** * Checks that the given string is a valid type descriptor. * * @param desc * the string to be checked. * @param canBeVoid * <tt>true</tt> if <tt>V</tt> can be considered valid. */ static void checkDesc(final String desc, final boolean canBeVoid) { int end = checkDesc(desc, 0, canBeVoid); if (end != desc.length()) { throw new IllegalArgumentException("Invalid descriptor: " + desc); } }
/** * Checks that the given string is a valid internal class name. * * @param name * the string to be checked. * @param msg * a message to be used in case of error. */ static void checkInternalName(final String name, final String msg) { if (name == null || name.length() == 0) { throw new IllegalArgumentException("Invalid " + msg + " (must not be null or empty)"); } if (name.charAt(0) == '[') { checkDesc(name, false); } else { checkInternalName(name, 0, -1, msg); } }
/** * Checks that the given string is a valid method descriptor. * * @param desc * the string to be checked. */ static void checkMethodDesc(final String desc) { if (desc == null || desc.length() == 0) { throw new IllegalArgumentException( "Invalid method descriptor (must not be null or empty)"); } if (desc.charAt(0) != '(' || desc.length() < 3) { throw new IllegalArgumentException("Invalid descriptor: " + desc); } int start = 1; if (desc.charAt(start) != ')') { do { if (desc.charAt(start) == 'V') { throw new IllegalArgumentException("Invalid descriptor: " + desc); } start = checkDesc(desc, start, false); } while (start < desc.length() && desc.charAt(start) != ')'); } start = checkDesc(desc, start + 1, true); if (start != desc.length()) { throw new IllegalArgumentException("Invalid descriptor: " + desc); } }
@Override public void visitMultiANewArrayInsn(final String desc, final int dims) { checkStartCode(); checkEndCode(); checkDesc(desc, false); if (desc.charAt(0) != '[') { throw new IllegalArgumentException( "Invalid descriptor (must be an array type descriptor): " + desc); } if (dims < 1) { throw new IllegalArgumentException( "Invalid dimensions (must be greater than 0): " + dims); } if (dims > desc.lastIndexOf('[') + 1) { throw new IllegalArgumentException( "Invalid dimensions (must not be greater than dims(desc)): " + dims); } super.visitMultiANewArrayInsn(desc, dims); ++insnCount; }
@Override public void visitEnum(final String name, final String desc, final String value) { checkEnd(); checkName(name); CheckMethodAdapter.checkDesc(desc, false); if (value == null) { throw new IllegalArgumentException("Invalid enum value"); } if (av != null) { av.visitEnum(name, desc, value); } }
return checkDesc(desc, index, false); } else { throw new IllegalArgumentException("Invalid descriptor: "
@Override public AnnotationVisitor visitTypeAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible) { checkEnd(); int sort = typeRef >>> 24; if (sort != TypeReference.FIELD) { throw new IllegalArgumentException("Invalid type reference sort 0x" + Integer.toHexString(sort)); } CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath); CheckMethodAdapter.checkDesc(desc, false); return new CheckAnnotationAdapter(super.visitTypeAnnotation(typeRef, typePath, desc, visible)); }
@Override public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { checkEnd(); CheckMethodAdapter.checkDesc(desc, false); return new CheckAnnotationAdapter(super.visitAnnotation(desc, visible)); }
@Override public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { checkEndMethod(); checkDesc(desc, false); return new CheckAnnotationAdapter(super.visitAnnotation(desc, visible)); }
@Override public AnnotationVisitor visitParameterAnnotation(final int parameter, final String desc, final boolean visible) { checkEndMethod(); checkDesc(desc, false); return new CheckAnnotationAdapter(super.visitParameterAnnotation( parameter, desc, visible)); }
@Override public AnnotationVisitor visitAnnotation(final String desc, final boolean visible) { checkState(); CheckMethodAdapter.checkDesc(desc, false); return new CheckAnnotationAdapter(super.visitAnnotation(desc, visible)); }
@Override public AnnotationVisitor visitTypeAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible) { checkState(); int sort = typeRef >>> 24; if (sort != TypeReference.CLASS_TYPE_PARAMETER && sort != TypeReference.CLASS_TYPE_PARAMETER_BOUND && sort != TypeReference.CLASS_EXTENDS) { throw new IllegalArgumentException("Invalid type reference sort 0x" + Integer.toHexString(sort)); } checkTypeRefAndPath(typeRef, typePath); CheckMethodAdapter.checkDesc(desc, false); return new CheckAnnotationAdapter(super.visitTypeAnnotation(typeRef, typePath, desc, visible)); }
@Override public AnnotationVisitor visitTypeAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible) { checkEndMethod(); int sort = typeRef >>> 24; if (sort != TypeReference.METHOD_TYPE_PARAMETER && sort != TypeReference.METHOD_TYPE_PARAMETER_BOUND && sort != TypeReference.METHOD_RETURN && sort != TypeReference.METHOD_RECEIVER && sort != TypeReference.METHOD_FORMAL_PARAMETER && sort != TypeReference.THROWS) { throw new IllegalArgumentException("Invalid type reference sort 0x" + Integer.toHexString(sort)); } CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath); CheckMethodAdapter.checkDesc(desc, false); return new CheckAnnotationAdapter(super.visitTypeAnnotation(typeRef, typePath, desc, visible)); }
@Override public AnnotationVisitor visitTryCatchAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible) { checkStartCode(); checkEndCode(); int sort = typeRef >>> 24; if (sort != TypeReference.EXCEPTION_PARAMETER) { throw new IllegalArgumentException("Invalid type reference sort 0x" + Integer.toHexString(sort)); } CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath); CheckMethodAdapter.checkDesc(desc, false); return new CheckAnnotationAdapter(super.visitTryCatchAnnotation( typeRef, typePath, desc, visible)); }
@Override public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) { checkStartCode(); checkEndCode(); checkOpcode(opcode, 4); checkInternalName(owner, "owner"); checkUnqualifiedName(version, name, "name"); checkDesc(desc, false); super.visitFieldInsn(opcode, owner, name, desc); ++insnCount; }
@Override public void visitLocalVariable(final String name, final String desc, final String signature, final Label start, final Label end, final int index) { checkStartCode(); checkEndCode(); checkUnqualifiedName(version, name, "name"); checkDesc(desc, false); checkLabel(start, true, "start label"); checkLabel(end, true, "end label"); checkUnsignedShort(index, "Invalid variable index"); int s = labels.get(start).intValue(); int e = labels.get(end).intValue(); if (e < s) { throw new IllegalArgumentException( "Invalid start and end labels (end must be greater than start)"); } super.visitLocalVariable(name, desc, signature, start, end, index); }
checkDesc(desc, false); if (start == null || end == null || index == null || end.length != start.length || index.length != start.length) {
@Override public AnnotationVisitor visitAnnotation(final String name, final String desc) { checkEnd(); checkName(name); CheckMethodAdapter.checkDesc(desc, false); return new CheckAnnotationAdapter(av == null ? null : av.visitAnnotation(name, desc)); }
@Override public AnnotationVisitor visitInsnAnnotation(final int typeRef, final TypePath typePath, final String desc, final boolean visible) { checkStartCode(); checkEndCode(); int sort = typeRef >>> 24; if (sort != TypeReference.INSTANCEOF && sort != TypeReference.NEW && sort != TypeReference.CONSTRUCTOR_REFERENCE && sort != TypeReference.METHOD_REFERENCE && sort != TypeReference.CAST && sort != TypeReference.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT && sort != TypeReference.METHOD_INVOCATION_TYPE_ARGUMENT && sort != TypeReference.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT && sort != TypeReference.METHOD_REFERENCE_TYPE_ARGUMENT) { throw new IllegalArgumentException("Invalid type reference sort 0x" + Integer.toHexString(sort)); } CheckClassAdapter.checkTypeRefAndPath(typeRef, typePath); CheckMethodAdapter.checkDesc(desc, false); return new CheckAnnotationAdapter(super.visitInsnAnnotation(typeRef, typePath, desc, visible)); }
@Override public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, final Object value) { checkState(); checkAccess(access, Opcodes.ACC_PUBLIC + Opcodes.ACC_PRIVATE + Opcodes.ACC_PROTECTED + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL + Opcodes.ACC_VOLATILE + Opcodes.ACC_TRANSIENT + Opcodes.ACC_SYNTHETIC + Opcodes.ACC_ENUM + Opcodes.ACC_DEPRECATED + 0x40000); // ClassWriter.ACC_SYNTHETIC_ATTRIBUTE CheckMethodAdapter.checkUnqualifiedName(version, name, "field name"); CheckMethodAdapter.checkDesc(desc, false); if (signature != null) { checkFieldSignature(signature); } if (value != null) { CheckMethodAdapter.checkConstant(value); } FieldVisitor av = super .visitField(access, name, desc, signature, value); return new CheckFieldAdapter(av); }