From eb469760c544f92e63107d43a7012f86d8760fd4 Mon Sep 17 00:00:00 2001 From: aclement Date: Thu, 10 Sep 2009 15:35:03 +0000 Subject: refactoring --- .../bcel/verifier/statics/Pass2Verifier.java | 1349 +++++++++++--------- .../bcel/verifier/statics/Pass3aVerifier.java | 18 +- 2 files changed, 746 insertions(+), 621 deletions(-) (limited to 'bcel-builder/verifier-src') diff --git a/bcel-builder/verifier-src/org/aspectj/apache/bcel/verifier/statics/Pass2Verifier.java b/bcel-builder/verifier-src/org/aspectj/apache/bcel/verifier/statics/Pass2Verifier.java index f6b15dbb1..b02c35128 100644 --- a/bcel-builder/verifier-src/org/aspectj/apache/bcel/verifier/statics/Pass2Verifier.java +++ b/bcel-builder/verifier-src/org/aspectj/apache/bcel/verifier/statics/Pass2Verifier.java @@ -105,199 +105,176 @@ import org.aspectj.apache.bcel.verifier.exc.ClassConstraintException; import org.aspectj.apache.bcel.verifier.exc.LocalVariableInfoInconsistentException; /** - * This PassVerifier verifies a class file according to - * pass 2 as described in The Java Virtual Machine - * Specification, 2nd edition. - * More detailed information is to be found at the do_verify() - * method's documentation. - * - * @version $Id: Pass2Verifier.java,v 1.4 2009/09/09 19:56:20 aclement Exp $ + * This PassVerifier verifies a class file according to pass 2 as described in The Java Virtual Machine Specification, 2nd edition. + * More detailed information is to be found at the do_verify() method's documentation. + * + * @version $Id: Pass2Verifier.java,v 1.5 2009/09/10 15:35:05 aclement Exp $ * @author Enver Haase * @see #do_verify() */ -public final class Pass2Verifier extends PassVerifier implements Constants{ +public final class Pass2Verifier extends PassVerifier implements Constants { /** - * The LocalVariableInfo instances used by Pass3bVerifier. - * localVariablesInfos[i] denotes the information for the - * local variables of method number i in the - * JavaClass this verifier operates on. + * The LocalVariableInfo instances used by Pass3bVerifier. localVariablesInfos[i] denotes the information for the local + * variables of method number i in the JavaClass this verifier operates on. */ private LocalVariablesInfo[] localVariablesInfos; - + /** The Verifier that created this. */ private Verifier myOwner; /** * Should only be instantiated by a Verifier. - * + * * @see Verifier */ - public Pass2Verifier(Verifier owner){ + public Pass2Verifier(Verifier owner) { myOwner = owner; } /** - * Returns a LocalVariablesInfo object containing information - * about the usage of the local variables in the Code attribute - * of the said method or null if the class file this - * Pass2Verifier operates on could not be pass-2-verified correctly. - * The method number method_nr is the method you get using - * Repository.lookupClass(myOwner.getClassname()).getMethods()[method_nr];. - * You should not add own information. Leave that to JustIce. + * Returns a LocalVariablesInfo object containing information about the usage of the local variables in the Code attribute of + * the said method or null if the class file this Pass2Verifier operates on could not be pass-2-verified correctly. The + * method number method_nr is the method you get using + * Repository.lookupClass(myOwner.getClassname()).getMethods()[method_nr];. You should not add own information. Leave + * that to JustIce. */ - public LocalVariablesInfo getLocalVariablesInfo(int method_nr){ - if (this.verify() != VerificationResult.VR_OK) return null; // It's cached, don't worry. - if (method_nr < 0 || method_nr >= localVariablesInfos.length){ + public LocalVariablesInfo getLocalVariablesInfo(int method_nr) { + if (this.verify() != VerificationResult.VR_OK) + return null; // It's cached, don't worry. + if (method_nr < 0 || method_nr >= localVariablesInfos.length) { throw new AssertionViolatedException("Method number out of range."); } return localVariablesInfos[method_nr]; } - + /** - * Pass 2 is the pass where static properties of the - * class file are checked without looking into "Code" - * arrays of methods. - * This verification pass is usually invoked when - * a class is resolved; and it may be possible that - * this verification pass has to load in other classes - * such as superclasses or implemented interfaces. - * Therefore, Pass 1 is run on them.
- * Note that most referenced classes are not loaded - * in for verification or for an existance check by this - * pass; only the syntactical correctness of their names - * and descriptors (a.k.a. signatures) is checked.
- * Very few checks that conceptually belong here - * are delayed until pass 3a in JustIce. JustIce does - * not only check for syntactical correctness but also - * for semantical sanity - therefore it needs access to - * the "Code" array of methods in a few cases. Please - * see the pass 3a documentation, too. - * + * Pass 2 is the pass where static properties of the class file are checked without looking into "Code" arrays of methods. This + * verification pass is usually invoked when a class is resolved; and it may be possible that this verification pass has to load + * in other classes such as superclasses or implemented interfaces. Therefore, Pass 1 is run on them.
+ * Note that most referenced classes are not loaded in for verification or for an existance check by this pass; only the + * syntactical correctness of their names and descriptors (a.k.a. signatures) is checked.
+ * Very few checks that conceptually belong here are delayed until pass 3a in JustIce. JustIce does not only check for + * syntactical correctness but also for semantical sanity - therefore it needs access to the "Code" array of methods in a few + * cases. Please see the pass 3a documentation, too. + * * @see org.aspectj.apache.bcel.verifier.statics.Pass3aVerifier */ - public VerificationResult do_verify(){ + @Override + public VerificationResult do_verify() { VerificationResult vr1 = myOwner.doPass1(); - if (vr1.equals(VerificationResult.VR_OK)){ - + if (vr1.equals(VerificationResult.VR_OK)) { + // For every method, we could have information about the local variables out of LocalVariableTable attributes of // the Code attributes. localVariablesInfos = new LocalVariablesInfo[Repository.lookupClass(myOwner.getClassName()).getMethods().length]; VerificationResult vr = VerificationResult.VR_OK; // default. - try{ + try { constant_pool_entries_satisfy_static_constraints(); field_and_method_refs_are_valid(); every_class_has_an_accessible_superclass(); final_methods_are_not_overridden(); - } - catch (ClassConstraintException cce){ + } catch (ClassConstraintException cce) { vr = new VerificationResult(VerificationResult.VERIFIED_REJECTED, cce.getMessage()); } return vr; - } - else + } else return VerificationResult.VR_NOTYET; } /** - * Ensures that every class has a super class and that - * final classes are not subclassed. - * This means, the class this Pass2Verifier operates - * on has proper super classes (transitively) up to - * java.lang.Object. - * The reason for really loading (and Pass1-verifying) - * all of those classes here is that we need them in - * Pass2 anyway to verify no final methods are overridden + * Ensures that every class has a super class and that final classes are not subclassed. This means, the class this + * Pass2Verifier operates on has proper super classes (transitively) up to java.lang.Object. The reason for really loading (and + * Pass1-verifying) all of those classes here is that we need them in Pass2 anyway to verify no final methods are overridden * (that could be declared anywhere in the ancestor hierarchy). - * + * * @throws ClassConstraintException otherwise. */ - private void every_class_has_an_accessible_superclass(){ + private void every_class_has_an_accessible_superclass() { HashSet hs = new HashSet(); // save class names to detect circular inheritance JavaClass jc = Repository.lookupClass(myOwner.getClassName()); int supidx = -1; - while (supidx != 0){ + while (supidx != 0) { supidx = jc.getSuperclassNameIndex(); - - if (supidx == 0){ - if (jc != Repository.lookupClass(Type.OBJECT.getClassName())){ - throw new ClassConstraintException("Superclass of '"+jc.getClassName()+"' missing but not "+Type.OBJECT.getClassName()+" itself!"); + + if (supidx == 0) { + if (jc != Repository.lookupClass(Type.OBJECT.getClassName())) { + throw new ClassConstraintException("Superclass of '" + jc.getClassName() + "' missing but not " + + Type.OBJECT.getClassName() + " itself!"); } - } - else{ + } else { String supername = jc.getSuperclassName(); - if (! hs.add(supername)){ // If supername already is in the list + if (!hs.add(supername)) { // If supername already is in the list throw new ClassConstraintException("Circular superclass hierarchy detected."); } Verifier v = VerifierFactory.getVerifier(supername); VerificationResult vr = v.doPass1(); - if (vr != VerificationResult.VR_OK){ - throw new ClassConstraintException("Could not load in ancestor class '"+supername+"'."); + if (vr != VerificationResult.VR_OK) { + throw new ClassConstraintException("Could not load in ancestor class '" + supername + "'."); } jc = Repository.lookupClass(supername); - if (jc.isFinal()){ - throw new ClassConstraintException("Ancestor class '"+supername+"' has the FINAL access modifier and must therefore not be subclassed."); + if (jc.isFinal()) { + throw new ClassConstraintException("Ancestor class '" + supername + + "' has the FINAL access modifier and must therefore not be subclassed."); } } } } /** - * Ensures that final methods are not overridden. - * Precondition to run this method: - * constant_pool_entries_satisfy_static_constraints() and - * every_class_has_an_accessible_superclass() have to be invoked before + * Ensures that final methods are not overridden. Precondition to run this method: + * constant_pool_entries_satisfy_static_constraints() and every_class_has_an_accessible_superclass() have to be invoked before * (in that order). - * + * * @throws ClassConstraintException otherwise. * @see #constant_pool_entries_satisfy_static_constraints() * @see #every_class_has_an_accessible_superclass() */ - private void final_methods_are_not_overridden(){ + private void final_methods_are_not_overridden() { HashMap hashmap = new HashMap(); JavaClass jc = Repository.lookupClass(myOwner.getClassName()); - + int supidx = -1; - while (supidx != 0){ + while (supidx != 0) { supidx = jc.getSuperclassNameIndex(); Method[] methods = jc.getMethods(); - for (int i=0; i CONST_String; private Class CONST_Integer; private Class CONST_Float; @@ -336,17 +310,17 @@ public final class Pass2Verifier extends PassVerifier implements Constants{ private HashSet field_names_and_desc = new HashSet(); private HashSet method_names_and_desc = new HashSet(); - private CPESSC_Visitor(JavaClass _jc){ + private CPESSC_Visitor(JavaClass _jc) { jc = _jc; cp = _jc.getConstantPool(); cplen = cp.getLength(); CONST_Class = org.aspectj.apache.bcel.classfile.ConstantClass.class; /* - CONST_Fieldref = org.aspectj.apache.bcel.classfile.ConstantFieldref.class; - CONST_Methodref = org.aspectj.apache.bcel.classfile.ConstantMethodref.class; - CONST_InterfaceMethodref = org.aspectj.apache.bcel.classfile.ConstantInterfaceMethodref.class; - */ + * CONST_Fieldref = org.aspectj.apache.bcel.classfile.ConstantFieldref.class; CONST_Methodref = + * org.aspectj.apache.bcel.classfile.ConstantMethodref.class; CONST_InterfaceMethodref = + * org.aspectj.apache.bcel.classfile.ConstantInterfaceMethodref.class; + */ CONST_String = org.aspectj.apache.bcel.classfile.ConstantString.class; CONST_Integer = org.aspectj.apache.bcel.classfile.ConstantInteger.class; CONST_Float = org.aspectj.apache.bcel.classfile.ConstantFloat.class; @@ -359,20 +333,23 @@ public final class Pass2Verifier extends PassVerifier implements Constants{ carrier.visit(); } - private void checkIndex(Node referrer, int index, Class shouldbe){ - if ((index < 0) || (index >= cplen)){ - throw new ClassConstraintException("Invalid index '"+index+"' used by '"+tostring(referrer)+"'."); + private void checkIndex(Node referrer, int index, Class shouldbe) { + if ((index < 0) || (index >= cplen)) { + throw new ClassConstraintException("Invalid index '" + index + "' used by '" + tostring(referrer) + "'."); } Constant c = cp.getConstant(index); - if (! shouldbe.isInstance(c)){ + if (!shouldbe.isInstance(c)) { /* String isnot = shouldbe.toString().substring(shouldbe.toString().lastIndexOf(".")+1); //Cut all before last "." */ - throw new ClassCastException("Illegal constant '"+tostring(c)+"' at index '"+index+"'. '"+tostring(referrer)+"' expects a '"+shouldbe+"'."); + throw new ClassCastException("Illegal constant '" + tostring(c) + "' at index '" + index + "'. '" + + tostring(referrer) + "' expects a '" + shouldbe + "'."); } } - /////////////////////////////////////// + + // ///////////////////////////////////// // ClassFile structure (vmspec2 4.1) // - /////////////////////////////////////// - public void visitJavaClass(JavaClass obj){ + // ///////////////////////////////////// + @Override + public void visitJavaClass(JavaClass obj) { Attribute[] atts = obj.getAttributes(); boolean foundSourceFile = false; boolean foundInnerClasses = false; @@ -381,521 +358,631 @@ public final class Pass2Verifier extends PassVerifier implements Constants{ // This is a costly check; existing verifiers don't do it! boolean hasInnerClass = new InnerClassDetector(jc).innerClassReferenced(); - for (int i=0; i 1){ - throw new ClassConstraintException("Field '"+tostring(obj)+"' must only have at most one of its ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC modifiers set."); + // //////////////////////// + @Override + public void visitField(Field obj) { + + if (jc.isClass()) { + int maxone = 0; + if (obj.isPrivate()) + maxone++; + if (obj.isProtected()) + maxone++; + if (obj.isPublic()) + maxone++; + if (maxone > 1) { + throw new ClassConstraintException("Field '" + tostring(obj) + + "' must only have at most one of its ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC modifiers set."); } - if (obj.isFinal() && obj.isVolatile()){ - throw new ClassConstraintException("Field '"+tostring(obj)+"' must only have at most one of its ACC_FINAL, ACC_VOLATILE modifiers set."); + if (obj.isFinal() && obj.isVolatile()) { + throw new ClassConstraintException("Field '" + tostring(obj) + + "' must only have at most one of its ACC_FINAL, ACC_VOLATILE modifiers set."); } - } - else{ // isInterface! - if (!obj.isPublic()){ - throw new ClassConstraintException("Interface field '"+tostring(obj)+"' must have the ACC_PUBLIC modifier set but hasn't!"); + } else { // isInterface! + if (!obj.isPublic()) { + throw new ClassConstraintException("Interface field '" + tostring(obj) + + "' must have the ACC_PUBLIC modifier set but hasn't!"); } - if (!obj.isStatic()){ - throw new ClassConstraintException("Interface field '"+tostring(obj)+"' must have the ACC_STATIC modifier set but hasn't!"); + if (!obj.isStatic()) { + throw new ClassConstraintException("Interface field '" + tostring(obj) + + "' must have the ACC_STATIC modifier set but hasn't!"); } - if (!obj.isFinal()){ - throw new ClassConstraintException("Interface field '"+tostring(obj)+"' must have the ACC_FINAL modifier set but hasn't!"); + if (!obj.isFinal()) { + throw new ClassConstraintException("Interface field '" + tostring(obj) + + "' must have the ACC_FINAL modifier set but hasn't!"); } } - if ((obj.getModifiers() & ~(ACC_PUBLIC|ACC_PRIVATE|ACC_PROTECTED|ACC_STATIC|ACC_FINAL|ACC_VOLATILE|ACC_TRANSIENT)) > 0){ - addMessage("Field '"+tostring(obj)+"' has access flag(s) other than ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_VOLATILE, ACC_TRANSIENT set (ignored)."); + if ((obj.getModifiers() & ~(ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL | ACC_VOLATILE | ACC_TRANSIENT)) > 0) { + addMessage("Field '" + + tostring(obj) + + "' has access flag(s) other than ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_VOLATILE, ACC_TRANSIENT set (ignored)."); } checkIndex(obj, obj.getNameIndex(), CONST_Utf8); String name = obj.getName(); - if (! validFieldName(name)){ - throw new ClassConstraintException("Field '"+tostring(obj)+"' has illegal name '"+obj.getName()+"'."); + if (!validFieldName(name)) { + throw new ClassConstraintException("Field '" + tostring(obj) + "' has illegal name '" + obj.getName() + "'."); } // A descriptor is often named signature in BCEL checkIndex(obj, obj.getSignatureIndex(), CONST_Utf8); - String sig = ((ConstantUtf8) (cp.getConstant(obj.getSignatureIndex()))).getBytes(); // Field or Method signature(=descriptor) + String sig = ((ConstantUtf8) (cp.getConstant(obj.getSignatureIndex()))).getValue(); // Field or Method + // signature(=descriptor) - try{ - Type.getType(sig); /* Don't need the return value */ - } - catch (ClassFormatError cfe){ // sometimes BCEL is a little harsh describing exceptional situations. - throw new ClassConstraintException("Illegal descriptor (==signature) '"+sig+"' used by '"+tostring(obj)+"'."); + try { + Type.getType(sig); /* Don't need the return value */ + } catch (ClassFormatError cfe) { // sometimes BCEL is a little harsh describing exceptional situations. + throw new ClassConstraintException("Illegal descriptor (==signature) '" + sig + "' used by '" + tostring(obj) + + "'."); } - String nameanddesc = (name+sig); - if (field_names_and_desc.contains(nameanddesc)){ - throw new ClassConstraintException("No two fields (like '"+tostring(obj)+"') are allowed have same names and descriptors!"); + String nameanddesc = (name + sig); + if (field_names_and_desc.contains(nameanddesc)) { + throw new ClassConstraintException("No two fields (like '" + tostring(obj) + + "') are allowed have same names and descriptors!"); } - if (field_names.contains(name)){ - addMessage("More than one field of name '"+name+"' detected (but with different type descriptors). This is very unusual."); + if (field_names.contains(name)) { + addMessage("More than one field of name '" + name + + "' detected (but with different type descriptors). This is very unusual."); } field_names_and_desc.add(nameanddesc); field_names.add(name); Attribute[] atts = obj.getAttributes(); - for (int i=0; i 1){ - throw new ClassConstraintException("Method '"+tostring(obj)+"' must only have at most one of its ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC modifiers set."); + // Nearly forgot this! Funny return values are allowed, but a non-empty arguments list makes a different method out of + // it! + if (name.equals(STATIC_INITIALIZER_NAME) && (ts.length != 0)) { + throw new ClassConstraintException( + "Method '" + + tostring(obj) + + "' has illegal name '" + + name + + "'. It's name resembles the class or interface initialization method which it isn't because of its arguments (==descriptor)."); + } + + if (jc.isClass()) { + int maxone = 0; + if (obj.isPrivate()) + maxone++; + if (obj.isProtected()) + maxone++; + if (obj.isPublic()) + maxone++; + if (maxone > 1) { + throw new ClassConstraintException("Method '" + tostring(obj) + + "' must only have at most one of its ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC modifiers set."); } - if (obj.isAbstract()){ - if (obj.isFinal()) throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_FINAL modifier set."); - if (obj.isNative()) throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_NATIVE modifier set."); - if (obj.isPrivate()) throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_PRIVATE modifier set."); - if (obj.isStatic()) throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_STATIC modifier set."); - if (obj.isStrictfp()) throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_STRICT modifier set."); - if (obj.isSynchronized()) throw new ClassConstraintException("Abstract method '"+tostring(obj)+"' must not have the ACC_SYNCHRONIZED modifier set."); + if (obj.isAbstract()) { + if (obj.isFinal()) + throw new ClassConstraintException("Abstract method '" + tostring(obj) + + "' must not have the ACC_FINAL modifier set."); + if (obj.isNative()) + throw new ClassConstraintException("Abstract method '" + tostring(obj) + + "' must not have the ACC_NATIVE modifier set."); + if (obj.isPrivate()) + throw new ClassConstraintException("Abstract method '" + tostring(obj) + + "' must not have the ACC_PRIVATE modifier set."); + if (obj.isStatic()) + throw new ClassConstraintException("Abstract method '" + tostring(obj) + + "' must not have the ACC_STATIC modifier set."); + if (obj.isStrictfp()) + throw new ClassConstraintException("Abstract method '" + tostring(obj) + + "' must not have the ACC_STRICT modifier set."); + if (obj.isSynchronized()) + throw new ClassConstraintException("Abstract method '" + tostring(obj) + + "' must not have the ACC_SYNCHRONIZED modifier set."); } - } - else{ // isInterface! - if (!name.equals(STATIC_INITIALIZER_NAME)){//vmspec2, p.116, 2nd paragraph - if (!obj.isPublic()){ - throw new ClassConstraintException("Interface method '"+tostring(obj)+"' must have the ACC_PUBLIC modifier set but hasn't!"); + } else { // isInterface! + if (!name.equals(STATIC_INITIALIZER_NAME)) {// vmspec2, p.116, 2nd paragraph + if (!obj.isPublic()) { + throw new ClassConstraintException("Interface method '" + tostring(obj) + + "' must have the ACC_PUBLIC modifier set but hasn't!"); } - if (!obj.isAbstract()){ - throw new ClassConstraintException("Interface method '"+tostring(obj)+"' must have the ACC_STATIC modifier set but hasn't!"); + if (!obj.isAbstract()) { + throw new ClassConstraintException("Interface method '" + tostring(obj) + + "' must have the ACC_STATIC modifier set but hasn't!"); } - if ( obj.isPrivate() || - obj.isProtected() || - obj.isStatic() || - obj.isFinal() || - obj.isSynchronized() || - obj.isNative() || - obj.isStrictfp() ){ - throw new ClassConstraintException("Interface method '"+tostring(obj)+"' must not have any of the ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT modifiers set."); + if (obj.isPrivate() || obj.isProtected() || obj.isStatic() || obj.isFinal() || obj.isSynchronized() + || obj.isNative() || obj.isStrictfp()) { + throw new ClassConstraintException( + "Interface method '" + + tostring(obj) + + "' must not have any of the ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT modifiers set."); } } } // A specific instance initialization method... (vmspec2,Page 116). - if (name.equals(CONSTRUCTOR_NAME)){ - //..may have at most one of ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC set: is checked above. - //..may also have ACC_STRICT set, but none of the other flags in table 4.5 (vmspec2, page 115) - if ( obj.isStatic() || - obj.isFinal() || - obj.isSynchronized() || - obj.isNative() || - obj.isAbstract() ){ - throw new ClassConstraintException("Instance initialization method '"+tostring(obj)+"' must not have any of the ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT modifiers set."); + if (name.equals(CONSTRUCTOR_NAME)) { + // ..may have at most one of ACC_PRIVATE, ACC_PROTECTED, ACC_PUBLIC set: is checked above. + // ..may also have ACC_STRICT set, but none of the other flags in table 4.5 (vmspec2, page 115) + if (obj.isStatic() || obj.isFinal() || obj.isSynchronized() || obj.isNative() || obj.isAbstract()) { + throw new ClassConstraintException( + "Instance initialization method '" + + tostring(obj) + + "' must not have any of the ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT modifiers set."); } } // Class and interface initialization methods... - if (name.equals(STATIC_INITIALIZER_NAME)){ - if ((obj.getModifiers() & (~ACC_STRICT)) > 0){ - addMessage("Class or interface initialization method '"+tostring(obj)+"' has superfluous access modifier(s) set: everything but ACC_STRICT is ignored."); + if (name.equals(STATIC_INITIALIZER_NAME)) { + if ((obj.getModifiers() & (~ACC_STRICT)) > 0) { + addMessage("Class or interface initialization method '" + tostring(obj) + + "' has superfluous access modifier(s) set: everything but ACC_STRICT is ignored."); } - if (obj.isAbstract()){ - throw new ClassConstraintException("Class or interface initialization method '"+tostring(obj)+"' must not be abstract. This contradicts the Java Language Specification, Second Edition (which omits this constraint) but is common practice of existing verifiers."); + if (obj.isAbstract()) { + throw new ClassConstraintException( + "Class or interface initialization method '" + + tostring(obj) + + "' must not be abstract. This contradicts the Java Language Specification, Second Edition (which omits this constraint) but is common practice of existing verifiers."); } } - if ((obj.getModifiers() & ~(ACC_PUBLIC|ACC_PRIVATE|ACC_PROTECTED|ACC_STATIC|ACC_FINAL|ACC_SYNCHRONIZED|ACC_NATIVE|ACC_ABSTRACT|ACC_STRICT)) > 0){ - addMessage("Method '"+tostring(obj)+"' has access flag(s) other than ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT set (ignored)."); + if ((obj.getModifiers() & ~(ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED + | ACC_NATIVE | ACC_ABSTRACT | ACC_STRICT)) > 0) { + addMessage("Method '" + + tostring(obj) + + "' has access flag(s) other than ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SYNCHRONIZED, ACC_NATIVE, ACC_ABSTRACT, ACC_STRICT set (ignored)."); } - String nameanddesc = (name+sig); - if (method_names_and_desc.contains(nameanddesc)){ - throw new ClassConstraintException("No two methods (like '"+tostring(obj)+"') are allowed have same names and desciptors!"); + String nameanddesc = (name + sig); + if (method_names_and_desc.contains(nameanddesc)) { + throw new ClassConstraintException("No two methods (like '" + tostring(obj) + + "') are allowed have same names and desciptors!"); } method_names_and_desc.add(nameanddesc); Attribute[] atts = obj.getAttributes(); int num_code_atts = 0; - for (int i=0; i= cplen)){ - throw new ClassConstraintException("Invalid index '"+index+"' used by '"+tostring(obj)+"'."); + if ((index < 0) || (index >= cplen)) { + throw new ClassConstraintException("Invalid index '" + index + "' used by '" + tostring(obj) + "'."); } Constant c = cp.getConstant(index); - if (CONST_Long.isInstance(c) && field_type.equals(Type.LONG)){ + if (CONST_Long.isInstance(c) && field_type.equals(Type.LONG)) { return; } - if (CONST_Float.isInstance(c) && field_type.equals(Type.FLOAT)){ + if (CONST_Float.isInstance(c) && field_type.equals(Type.FLOAT)) { return; } - if (CONST_Double.isInstance(c) && field_type.equals(Type.DOUBLE)){ + if (CONST_Double.isInstance(c) && field_type.equals(Type.DOUBLE)) { return; } - if (CONST_Integer.isInstance(c) && (field_type.equals(Type.INT) || field_type.equals(Type.SHORT) || field_type.equals(Type.CHAR) || field_type.equals(Type.BYTE) || field_type.equals(Type.BOOLEAN))){ + if (CONST_Integer.isInstance(c) + && (field_type.equals(Type.INT) || field_type.equals(Type.SHORT) || field_type.equals(Type.CHAR) + || field_type.equals(Type.BYTE) || field_type.equals(Type.BOOLEAN))) { return; } - if (CONST_String.isInstance(c) && field_type.equals(Type.STRING)){ + if (CONST_String.isInstance(c) && field_type.equals(Type.STRING)) { return; } - throw new ClassConstraintException("Illegal type of ConstantValue '"+obj+"' embedding Constant '"+c+"'. It is referenced by field '"+tostring(f)+"' expecting a different type: '"+field_type+"'."); + throw new ClassConstraintException("Illegal type of ConstantValue '" + obj + "' embedding Constant '" + c + + "'. It is referenced by field '" + tostring(f) + "' expecting a different type: '" + field_type + "'."); } } + // SYNTHETIC: see above // DEPRECATED: see above - ///////////////////////////////////////////////////////// + // /////////////////////////////////////////////////////// // method_info-structure-ATTRIBUTES (vmspec2 4.6, 4.7) // - ///////////////////////////////////////////////////////// - public void visitCode(Code obj){//vmspec2 4.7.3 + // /////////////////////////////////////////////////////// + public void visitCode(Code obj) {// vmspec2 4.7.3 // No code attribute allowed for native or abstract methods: see visitMethod(Method). // Code array constraints are checked in Pass3 (3a and 3b). checkIndex(obj, obj.getNameIndex(), CONST_Utf8); - String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes(); - if (! name.equals("Code")){ - throw new ClassConstraintException("The Code attribute '"+tostring(obj)+"' is not correctly named 'Code' but '"+name+"'."); + String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getValue(); + if (!name.equals("Code")) { + throw new ClassConstraintException("The Code attribute '" + tostring(obj) + "' is not correctly named 'Code' but '" + + name + "'."); } Method m = null; // satisfy compiler - if (!(carrier.predecessor() instanceof Method)){ - addMessage("Code attribute '"+tostring(obj)+"' is not declared in a method_info structure but in '"+carrier.predecessor()+"'. Ignored."); + if (!(carrier.predecessor() instanceof Method)) { + addMessage("Code attribute '" + tostring(obj) + "' is not declared in a method_info structure but in '" + + carrier.predecessor() + "'. Ignored."); return; - } - else{ - m = (Method) carrier.predecessor(); // we can assume this method was visited before; - // i.e. the data consistency was verified. + } else { + m = (Method) carrier.predecessor(); // we can assume this method was visited before; + // i.e. the data consistency was verified. } - if (obj.getCode().length == 0){ - throw new ClassConstraintException("Code array of Code attribute '"+tostring(obj)+"' (method '"+m+"') must not be empty."); + if (obj.getCode().length == 0) { + throw new ClassConstraintException("Code array of Code attribute '" + tostring(obj) + "' (method '" + m + + "') must not be empty."); } - //In JustIce, the check for correct offsets into the code array is delayed to Pass 3a. + // In JustIce, the check for correct offsets into the code array is delayed to Pass 3a. CodeException[] exc_table = obj.getExceptionTable(); - for (int i=0; i= code.getMaxLocals()){ - throw new ClassConstraintException("LocalVariableTable attribute '"+tostring(lvt)+"' references a LocalVariable '"+tostring(localvariables[i])+"' with an index that exceeds the surrounding Code attribute's max_locals value of '"+code.getMaxLocals()+"'."); + if (((t == Type.LONG || t == Type.DOUBLE) ? localindex + 1 : localindex) >= code.getMaxLocals()) { + throw new ClassConstraintException("LocalVariableTable attribute '" + tostring(lvt) + + "' references a LocalVariable '" + tostring(localvariables[i]) + + "' with an index that exceeds the surrounding Code attribute's max_locals value of '" + + code.getMaxLocals() + "'."); } - try{ - localVariablesInfos[method_number].add(localindex, localname, localvariables[i].getStartPC(), localvariables[i].getLength(), t); - } - catch(LocalVariableInfoInconsistentException lviie){ - throw new ClassConstraintException("Conflicting information in LocalVariableTable '"+tostring(lvt)+"' found in Code attribute '"+tostring(obj)+"' (method '"+tostring(m)+"'). "+lviie.getMessage()); + try { + localVariablesInfos[method_number].add(localindex, localname, localvariables[i].getStartPC(), + localvariables[i].getLength(), t); + } catch (LocalVariableInfoInconsistentException lviie) { + throw new ClassConstraintException("Conflicting information in LocalVariableTable '" + tostring(lvt) + + "' found in Code attribute '" + tostring(obj) + "' (method '" + tostring(m) + "'). " + + lviie.getMessage()); } }// for all local variables localvariables[i] in the LocalVariableTable attribute atts[a] END num_of_lvt_attribs++; - if (num_of_lvt_attribs > obj.getMaxLocals()){ - throw new ClassConstraintException("Number of LocalVariableTable attributes of Code attribute '"+tostring(obj)+"' (method '"+tostring(m)+"') exceeds number of local variable slots '"+obj.getMaxLocals()+"' ('There may be no more than one LocalVariableTable attribute per local variable in the Code attribute.')."); + if (num_of_lvt_attribs > obj.getMaxLocals()) { + throw new ClassConstraintException( + "Number of LocalVariableTable attributes of Code attribute '" + + tostring(obj) + + "' (method '" + + tostring(m) + + "') exceeds number of local variable slots '" + + obj.getMaxLocals() + + "' ('There may be no more than one LocalVariableTable attribute per local variable in the Code attribute.')."); } }// if atts[a] instanceof LocalVariableTable END }// for all attributes atts[a] END }// visitCode(Code) END - public void visitExceptionTable(ExceptionTable obj){//vmspec2 4.7.4 + public void visitExceptionTable(ExceptionTable obj) {// vmspec2 4.7.4 // incorrectly named, it's the Exceptions attribute (vmspec2 4.7.4) checkIndex(obj, obj.getNameIndex(), CONST_Utf8); - String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes(); - if (! name.equals("Exceptions")){ - throw new ClassConstraintException("The Exceptions attribute '"+tostring(obj)+"' is not correctly named 'Exceptions' but '"+name+"'."); + String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getValue(); + if (!name.equals("Exceptions")) { + throw new ClassConstraintException("The Exceptions attribute '" + tostring(obj) + + "' is not correctly named 'Exceptions' but '" + name + "'."); } int[] exc_indices = obj.getExceptionIndexTable(); - for (int i=0; iPrecondition: index-style cross referencing in the constant - * pool must be valid. Simply invoke constant_pool_entries_satisfy_static_constraints() - * before. - * + * Ensures that the ConstantCP-subclassed entries of the constant pool are valid. According to + * "Yellin: Low Level Security in Java", this method does not verify the existence of referenced entities (such as classes) but + * only the formal correctness (such as well-formed signatures). The visitXXX() methods throw ClassConstraintException instances + * otherwise. Precondition: index-style cross referencing in the constant pool must be valid. Simply invoke + * constant_pool_entries_satisfy_static_constraints() before. + * * @throws ClassConstraintException otherwise. * @see #constant_pool_entries_satisfy_static_constraints() */ - private void field_and_method_refs_are_valid(){ + private void field_and_method_refs_are_valid() { JavaClass jc = Repository.lookupClass(myOwner.getClassName()); DescendingVisitor v = new DescendingVisitor(jc, new FAMRAV_Visitor(jc)); v.visit(); } /** - * A Visitor class that ensures the ConstantCP-subclassed entries - * of the constant pool are valid. - * Precondition: index-style cross referencing in the constant - * pool must be valid. - * - * @see #constant_pool_entries_satisfy_static_constraints() + * A Visitor class that ensures the ConstantCP-subclassed entries of the constant pool are valid. Precondition: index-style + * cross referencing in the constant pool must be valid. + * + * @see #constant_pool_entries_satisfy_static_constraints() * @see org.aspectj.apache.bcel.classfile.ConstantCP */ - private class FAMRAV_Visitor extends EmptyClassVisitor{ + private class FAMRAV_Visitor extends EmptyClassVisitor { private final ConstantPool cp; // ==jc.getConstantPool() -- only here to save typing work. - private FAMRAV_Visitor(JavaClass _jc){ + + private FAMRAV_Visitor(JavaClass _jc) { cp = _jc.getConstantPool(); } - - public void visitConstantFieldref(ConstantFieldref obj){ - if (obj.getTag() != Constants.CONSTANT_Fieldref){ - throw new ClassConstraintException("ConstantFieldref '"+tostring(obj)+"' has wrong tag!"); + + public void visitConstantFieldref(ConstantFieldref obj) { + if (obj.getTag() != Constants.CONSTANT_Fieldref) { + throw new ClassConstraintException("ConstantFieldref '" + tostring(obj) + "' has wrong tag!"); } int name_and_type_index = obj.getNameAndTypeIndex(); ConstantNameAndType cnat = (ConstantNameAndType) (cp.getConstant(name_and_type_index)); - String name = ((ConstantUtf8) (cp.getConstant(cnat.getNameIndex()))).getBytes(); // Field or Method name - if (!validFieldName(name)){ - throw new ClassConstraintException("Invalid field name '"+name+"' referenced by '"+tostring(obj)+"'."); + String name = ((ConstantUtf8) (cp.getConstant(cnat.getNameIndex()))).getValue(); // Field or Method name + if (!validFieldName(name)) { + throw new ClassConstraintException("Invalid field name '" + name + "' referenced by '" + tostring(obj) + "'."); } - + int class_index = obj.getClassIndex(); ConstantClass cc = (ConstantClass) (cp.getConstant(class_index)); - String className = ((ConstantUtf8) (cp.getConstant(cc.getNameIndex()))).getBytes(); // Class Name in internal form - if (! validClassName(className)){ - throw new ClassConstraintException("Illegal class name '"+className+"' used by '"+tostring(obj)+"'."); + String className = ((ConstantUtf8) (cp.getConstant(cc.getNameIndex()))).getValue(); // Class Name in internal form + if (!validClassName(className)) { + throw new ClassConstraintException("Illegal class name '" + className + "' used by '" + tostring(obj) + "'."); } - String sig = ((ConstantUtf8) (cp.getConstant(cnat.getSignatureIndex()))).getBytes(); // Field or Method signature(=descriptor) - - try{ + String sig = ((ConstantUtf8) (cp.getConstant(cnat.getSignatureIndex()))).getValue(); // Field or Method + // signature(=descriptor) + + try { Type.getType(sig); /* Don't need the return value */ - } - catch (ClassFormatError cfe){ + } catch (ClassFormatError cfe) { // Well, BCEL sometimes is a little harsh describing exceptional situations. - throw new ClassConstraintException("Illegal descriptor (==signature) '"+sig+"' used by '"+tostring(obj)+"'."); + throw new ClassConstraintException("Illegal descriptor (==signature) '" + sig + "' used by '" + tostring(obj) + + "'."); } } - public void visitConstantMethodref(ConstantMethodref obj){ - if (obj.getTag() != Constants.CONSTANT_Methodref){ - throw new ClassConstraintException("ConstantMethodref '"+tostring(obj)+"' has wrong tag!"); + public void visitConstantMethodref(ConstantMethodref obj) { + if (obj.getTag() != Constants.CONSTANT_Methodref) { + throw new ClassConstraintException("ConstantMethodref '" + tostring(obj) + "' has wrong tag!"); } int name_and_type_index = obj.getNameAndTypeIndex(); ConstantNameAndType cnat = (ConstantNameAndType) (cp.getConstant(name_and_type_index)); - String name = ((ConstantUtf8) (cp.getConstant(cnat.getNameIndex()))).getBytes(); // Field or Method name - if (!validClassMethodName(name)){ - throw new ClassConstraintException("Invalid (non-interface) method name '"+name+"' referenced by '"+tostring(obj)+"'."); + String name = ((ConstantUtf8) (cp.getConstant(cnat.getNameIndex()))).getValue(); // Field or Method name + if (!validClassMethodName(name)) { + throw new ClassConstraintException("Invalid (non-interface) method name '" + name + "' referenced by '" + + tostring(obj) + "'."); } int class_index = obj.getClassIndex(); ConstantClass cc = (ConstantClass) (cp.getConstant(class_index)); - String className = ((ConstantUtf8) (cp.getConstant(cc.getNameIndex()))).getBytes(); // Class Name in internal form - if (! validClassName(className)){ - throw new ClassConstraintException("Illegal class name '"+className+"' used by '"+tostring(obj)+"'."); + String className = ((ConstantUtf8) (cp.getConstant(cc.getNameIndex()))).getValue(); // Class Name in internal form + if (!validClassName(className)) { + throw new ClassConstraintException("Illegal class name '" + className + "' used by '" + tostring(obj) + "'."); } - String sig = ((ConstantUtf8) (cp.getConstant(cnat.getSignatureIndex()))).getBytes(); // Field or Method signature(=descriptor) - - try{ - Type t = Type.getReturnType(sig); - if ( name.equals(CONSTRUCTOR_NAME) && (t != Type.VOID) ){ + String sig = ((ConstantUtf8) (cp.getConstant(cnat.getSignatureIndex()))).getValue(); // Field or Method + // signature(=descriptor) + + try { + Type t = Type.getReturnType(sig); + if (name.equals(CONSTRUCTOR_NAME) && (t != Type.VOID)) { throw new ClassConstraintException("Instance initialization method must have VOID return type."); } - } - catch (ClassFormatError cfe){ + } catch (ClassFormatError cfe) { // Well, BCEL sometimes is a little harsh describing exceptional situations. - throw new ClassConstraintException("Illegal descriptor (==signature) '"+sig+"' used by '"+tostring(obj)+"'."); + throw new ClassConstraintException("Illegal descriptor (==signature) '" + sig + "' used by '" + tostring(obj) + + "'."); } } - public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj){ - if (obj.getTag() != Constants.CONSTANT_InterfaceMethodref){ - throw new ClassConstraintException("ConstantInterfaceMethodref '"+tostring(obj)+"' has wrong tag!"); + public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj) { + if (obj.getTag() != Constants.CONSTANT_InterfaceMethodref) { + throw new ClassConstraintException("ConstantInterfaceMethodref '" + tostring(obj) + "' has wrong tag!"); } int name_and_type_index = obj.getNameAndTypeIndex(); ConstantNameAndType cnat = (ConstantNameAndType) (cp.getConstant(name_and_type_index)); - String name = ((ConstantUtf8) (cp.getConstant(cnat.getNameIndex()))).getBytes(); // Field or Method name - if (!validInterfaceMethodName(name)){ - throw new ClassConstraintException("Invalid (interface) method name '"+name+"' referenced by '"+tostring(obj)+"'."); + String name = ((ConstantUtf8) (cp.getConstant(cnat.getNameIndex()))).getValue(); // Field or Method name + if (!validInterfaceMethodName(name)) { + throw new ClassConstraintException("Invalid (interface) method name '" + name + "' referenced by '" + tostring(obj) + + "'."); } int class_index = obj.getClassIndex(); ConstantClass cc = (ConstantClass) (cp.getConstant(class_index)); - String className = ((ConstantUtf8) (cp.getConstant(cc.getNameIndex()))).getBytes(); // Class Name in internal form - if (! validClassName(className)){ - throw new ClassConstraintException("Illegal class name '"+className+"' used by '"+tostring(obj)+"'."); + String className = ((ConstantUtf8) (cp.getConstant(cc.getNameIndex()))).getValue(); // Class Name in internal form + if (!validClassName(className)) { + throw new ClassConstraintException("Illegal class name '" + className + "' used by '" + tostring(obj) + "'."); } - String sig = ((ConstantUtf8) (cp.getConstant(cnat.getSignatureIndex()))).getBytes(); // Field or Method signature(=descriptor) - - try{ - Type t = Type.getReturnType(sig); - if ( name.equals(STATIC_INITIALIZER_NAME) && (t != Type.VOID) ){ - addMessage("Class or interface initialization method '"+STATIC_INITIALIZER_NAME+"' usually has VOID return type instead of '"+t+"'. Note this is really not a requirement of The Java Virtual Machine Specification, Second Edition."); + String sig = ((ConstantUtf8) (cp.getConstant(cnat.getSignatureIndex()))).getValue(); // Field or Method + // signature(=descriptor) + + try { + Type t = Type.getReturnType(sig); + if (name.equals(STATIC_INITIALIZER_NAME) && (t != Type.VOID)) { + addMessage("Class or interface initialization method '" + STATIC_INITIALIZER_NAME + + "' usually has VOID return type instead of '" + t + + "'. Note this is really not a requirement of The Java Virtual Machine Specification, Second Edition."); } - } - catch (ClassFormatError cfe){ + } catch (ClassFormatError cfe) { // Well, BCEL sometimes is a little harsh describing exceptional situations. - throw new ClassConstraintException("Illegal descriptor (==signature) '"+sig+"' used by '"+tostring(obj)+"'."); + throw new ClassConstraintException("Illegal descriptor (==signature) '" + sig + "' used by '" + tostring(obj) + + "'."); } } - + } /** - * This method returns true if and only if the supplied String - * represents a valid Java class name. + * This method returns true if and only if the supplied String represents a valid Java class name. */ - private static final boolean validClassName(String name){ - /* - * TODO: implement. - * Are there any restrictions? - */ + private static final boolean validClassName(String name) { + /* + * TODO: implement. Are there any restrictions? + */ return true; } + /** - * This method returns true if and only if the supplied String - * represents a valid method name. - * This is basically the same as a valid identifier name in the - * Java programming language, but the special name for - * the instance initialization method is allowed and the special name - * for the class/interface initialization method may be allowed. + * This method returns true if and only if the supplied String represents a valid method name. This is basically the same as a + * valid identifier name in the Java programming language, but the special name for the instance initialization method is + * allowed and the special name for the class/interface initialization method may be allowed. */ - private static boolean validMethodName(String name, boolean allowStaticInit){ - if (validJavaLangMethodName(name)) return true; - - if (allowStaticInit){ + private static boolean validMethodName(String name, boolean allowStaticInit) { + if (validJavaLangMethodName(name)) + return true; + + if (allowStaticInit) { return (name.equals(CONSTRUCTOR_NAME) || name.equals(STATIC_INITIALIZER_NAME)); - } - else{ + } else { return name.equals(CONSTRUCTOR_NAME); } } /** - * This method returns true if and only if the supplied String - * represents a valid method name that may be referenced by + * This method returns true if and only if the supplied String represents a valid method name that may be referenced by * ConstantMethodref objects. */ - private static boolean validClassMethodName(String name){ + private static boolean validClassMethodName(String name) { return validMethodName(name, false); } /** - * This method returns true if and only if the supplied String - * represents a valid Java programming language method name stored as a simple - * (non-qualified) name. - * Conforming to: The Java Virtual Machine Specification, Second Edition, §2.7, §2.7.1, §2.2. + * This method returns true if and only if the supplied String represents a valid Java programming language method name stored + * as a simple (non-qualified) name. Conforming to: The Java Virtual Machine Specification, Second Edition, §2.7, §2.7.1, §2.2. */ - private static boolean validJavaLangMethodName(String name){ - if (!Character.isJavaIdentifierStart(name.charAt(0))) return false; - - for (int i=1; iEnver Haase * @see #do_verify() */ @@ -151,6 +151,7 @@ public final class Pass3aVerifier extends PassVerifier { * * @throws InvalidMethodException if the method to verify does not exist. */ + @Override public VerificationResult do_verify() { if (myOwner.doPass2().equals(VerificationResult.VR_OK)) { // Okay, class file was loaded correctly by Pass 1 @@ -482,6 +483,7 @@ public final class Pass3aVerifier extends PassVerifier { /** * Assures the generic preconditions of a LoadClass instance. The referenced class is loaded and pass2-verified. */ + @Override public void visitLoadClass(Instruction o) { ObjectType t = o.getLoadClassType(cpg); if (t != null) {// null means "no class is loaded" @@ -503,6 +505,7 @@ public final class Pass3aVerifier extends PassVerifier { /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ // LDC and LDC_W (LDC_W is a subclass of LDC in BCEL's model) + @Override public void visitLDC(Instruction o) { indexValid(o, o.getIndex()); Constant c = cpg.getConstant(o.getIndex()); @@ -515,6 +518,7 @@ public final class Pass3aVerifier extends PassVerifier { /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ // LDC2_W + @Override public void visitLDC2_W(Instruction o) { indexValid(o, o.getIndex()); Constant c = cpg.getConstant(o.getIndex()); @@ -571,6 +575,7 @@ public final class Pass3aVerifier extends PassVerifier { } /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ + @Override public void visitInvokeInstruction(InvokeInstruction o) { indexValid(o, o.getIndex()); if (o.getOpcode() == Constants.INVOKEVIRTUAL || o.getOpcode() == Constants.INVOKESPECIAL @@ -582,10 +587,10 @@ public final class Pass3aVerifier extends PassVerifier { // Constants are okay due to pass2. ConstantNameAndType cnat = (ConstantNameAndType) cpg.getConstant(((ConstantMethodref) c).getNameAndTypeIndex()); ConstantUtf8 cutf8 = (ConstantUtf8) cpg.getConstant(cnat.getNameIndex()); - if (cutf8.getBytes().equals(Constants.CONSTRUCTOR_NAME) && !(o.getOpcode() == Constants.INVOKESPECIAL)) { + if (cutf8.getValue().equals(Constants.CONSTRUCTOR_NAME) && !(o.getOpcode() == Constants.INVOKESPECIAL)) { constraintViolated(o, "Only INVOKESPECIAL is allowed to invoke instance initialization methods."); } - if (!cutf8.getBytes().equals(Constants.CONSTRUCTOR_NAME) && cutf8.getBytes().startsWith("<")) { + if (!cutf8.getValue().equals(Constants.CONSTRUCTOR_NAME) && cutf8.getValue().startsWith("<")) { constraintViolated( o, "No method with a name beginning with '<' other than the instance initialization methods may be called by the method invocation instructions."); @@ -604,7 +609,7 @@ public final class Pass3aVerifier extends PassVerifier { // Invoked method must not be or ConstantNameAndType cnat = (ConstantNameAndType) cpg.getConstant(((ConstantInterfaceMethodref) c) .getNameAndTypeIndex()); - String name = ((ConstantUtf8) cpg.getConstant(cnat.getNameIndex())).getBytes(); + String name = ((ConstantUtf8) cpg.getConstant(cnat.getNameIndex())).getValue(); if (name.equals(Constants.CONSTRUCTOR_NAME)) { constraintViolated(o, "Method to invoke must not be '" + Constants.CONSTRUCTOR_NAME + "'."); } @@ -647,6 +652,7 @@ public final class Pass3aVerifier extends PassVerifier { } /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ + @Override public void visitINSTANCEOF(Instruction o) { indexValid(o, o.getIndex()); Constant c = cpg.getConstant(o.getIndex()); @@ -656,6 +662,7 @@ public final class Pass3aVerifier extends PassVerifier { } /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ + @Override public void visitCHECKCAST(Instruction o) { indexValid(o, o.getIndex()); Constant c = cpg.getConstant(o.getIndex()); @@ -665,6 +672,7 @@ public final class Pass3aVerifier extends PassVerifier { } /** Checks if the constraints of operands of the said instruction(s) are satisfied. */ + @Override public void visitNEW(Instruction o) { indexValid(o, o.getIndex()); Constant c = cpg.getConstant(o.getIndex()); @@ -672,7 +680,7 @@ public final class Pass3aVerifier extends PassVerifier { constraintViolated(o, "Expecting a CONSTANT_Class operand, but found a '" + c + "'."); } else { ConstantUtf8 cutf8 = (ConstantUtf8) cpg.getConstant(((ConstantClass) c).getNameIndex()); - Type t = Type.getType("L" + cutf8.getBytes() + ";"); + Type t = Type.getType("L" + cutf8.getValue() + ";"); if (t instanceof ArrayType) { constraintViolated(o, "NEW must not be used to create an array."); } -- cgit v1.2.3