Code with Finding: |
class InstConstraintVisitor { /** * Ensures the specific preconditions of the said instruction. */ @Override public void visitINVOKESPECIAL(INVOKESPECIAL o){ try { // Don't init an object twice. if ( (o.getMethodName(cpg).equals(Const.CONSTRUCTOR_NAME)) && (!(stack().peek(o.getArgumentTypes(cpg).length) instanceof UninitializedObjectType)) ){ constraintViolated(o, "Possibly initializing object twice."+ " A valid instruction sequence must not have an uninitialized object on the operand stack or in a local variable"+ " during a backwards branch, or in a local variable in code protected by an exception handler."+ " Please see The Java Virtual Machine Specification, Second Edition, 4.9.4 (pages 147 and 148) for details."); }
// the o.getClassType(cpg) type has passed pass 2; see visitLoadClass(o).
Type t = o.getType(cpg); if (t instanceof ObjectType){ String name = ((ObjectType)t).getClassName(); Verifier v = VerifierFactory.getVerifier( name ); VerificationResult vr = v.doPass2(); if (vr.getStatus() != VerificationResult.VERIFIED_OK){ constraintViolated(o, "Class '"+name+"' is referenced, but cannot be loaded and resolved: '"+vr+"'."); } }
Type[] argtypes = o.getArgumentTypes(cpg); int nargs = argtypes.length;
for (int i=nargs-1; i>=0; i--){ Type fromStack = stack().peek( (nargs-1) - i ); // 0 to nargs-1 Type fromDesc = argtypes[i]; if (fromDesc == Type.BOOLEAN || fromDesc == Type.BYTE || fromDesc == Type.CHAR || fromDesc == Type.SHORT){ fromDesc = Type.INT; } if (! fromStack.equals(fromDesc)){ if (fromStack instanceof ReferenceType && fromDesc instanceof ReferenceType){ ReferenceType rFromStack = (ReferenceType) fromStack; ReferenceType rFromDesc = (ReferenceType) fromDesc; // TODO: This can only be checked using Staerk-et-al's "set of object types", not // using a "wider cast object type". if ( ! rFromStack.isAssignmentCompatibleWith(rFromDesc) ){ constraintViolated(o, "Expecting a '"+fromDesc+"' but found a '"+fromStack+ "' on the stack (which is not assignment compatible)."); } referenceTypeIsInitialized(o, rFromStack); } else{ constraintViolated(o, "Expecting a '"+fromDesc+"' but found a '"+fromStack+"' on the stack."); } } }
Type objref = stack().peek(nargs); if (objref == Type.NULL){ return; } if (! (objref instanceof ReferenceType) ){ constraintViolated(o, "Expecting a reference type as 'objectref' on the stack, not a '"+objref+"'."); } String objref_classname = null; if ( !(o.getMethodName(cpg).equals(Const.CONSTRUCTOR_NAME))){ referenceTypeIsInitialized(o, (ReferenceType) objref); if (!(objref instanceof ObjectType)){ if (!(objref instanceof ArrayType)){ // could be a ReturnaddressType constraintViolated(o, "Expecting an ObjectType as 'objectref' on the stack, not a '"+objref+"'."); } else{ objref = GENERIC_ARRAY; } }
objref_classname = ((ObjectType) objref).getClassName(); } else{ if (!(objref instanceof UninitializedObjectType)){ constraintViolated(o, "Expecting an UninitializedObjectType as 'objectref' on the stack, not a '"+objref+ "'. Otherwise, you couldn't invoke a method since an array has no methods (not to speak of a return address)."); } objref_classname = ((UninitializedObjectType) objref).getInitialized().getClassName(); }
String theClass = o.getClassName(cpg); if ( ! Repository.instanceOf(objref_classname, theClass) ){ constraintViolated(o, "The 'objref' item '"+objref+"' does not implement '"+theClass+"' as expected."); }
} catch (ClassNotFoundException e) { // FIXME: maybe not the best way to handle this throw new AssertionViolatedException("Missing class: " + e, e); } }
}
|