/** * overrides the visitor to initialize and tear down the opcode stack * * @param classContext the context object of the currently parsed class */ @Override public void visitClassContext(ClassContext classContext) { try { String clsName = classContext.getJavaClass().getClassName(); isInnerClass = clsName.contains("$"); clsSignature = SignatureUtils.classToSignature(clsName); stack = new OpcodeStack(); localSpecialObjects = new HashMap<>(); fieldSpecialObjects = new HashMap<>(); super.visitClassContext(classContext); if (!isInnerClass && !fieldSpecialObjects.isEmpty()) { for (Map.Entry<String, String> entry : fieldSpecialObjects.entrySet()) { String fieldName = entry.getKey(); String signature = entry.getValue(); bugReporter.reportBug( makeFieldBugInstance().addClass(this).addField(clsName, fieldName, signature, false)); } } } finally { stack = null; localSpecialObjects = null; fieldSpecialObjects = null; } }
/** * Checks to see if any of the locals or fields that we are tracking are passed into another * method. If they are, we clear out our tracking of them, because we can't easily track their * progress into the method. * * <p>This can be overridden to check for exceptions to this rule, for example, being logged to * the console not counting. */ protected void processMethodParms() { String sig = getSigConstantOperand(); int numParms = SignatureUtils.getNumParameters(sig); if ((numParms > 0) && (stack.getStackDepth() >= numParms)) { for (int i = 0; i < numParms; i++) { clearUserValue(stack.getStackItem(i)); } } }
private void sawInvokeInterfaceVirtual() { String sig = getSigConstantOperand(); int numParms = SignatureUtils.getNumParameters(sig); if (stack.getStackDepth() > numParms) { OpcodeStack.Item item = stack.getStackItem(numParms); Object uo = item.getUserValue(); if (uo != null) { String name = getNameConstantOperand(); if (isMethodThatShouldBeCalled(name)) { clearUserValue(item); } else if (!"clone".equals(name)) { if ((!Values.SIG_VOID.equals(SignatureUtils.getReturnSignature(sig))) && !nextOpIsPop()) { clearUserValue(item); } } } } processMethodParms(); }
@Override public void visitField(Field obj) { if (!isInnerClass && obj.isPrivate() && !obj.isSynthetic()) { String sig = obj.getSignature(); if (sig.startsWith(Values.SIG_QUALIFIED_CLASS_PREFIX)) { String type = SignatureUtils.stripSignature(sig); if (doesObjectNeedToBeWatched(type)) { fieldSpecialObjects.put(obj.getName(), obj.getSignature()); } } } }