/** * Add an annotation about a parameter * * @param index parameter index, starting from 0 * * @param role the role used to describe the parameter */ @Nonnull public BugInstance addParameterAnnotation(int index, String role) { return addInt(index + 1).describe(role); }
public BugInstance addOptionalAnnotation(@CheckForNull BugAnnotation annotation, String role) { if (annotation == null) { return this; } return add(annotation).describe(role); }
@Nonnull public BugInstance addCalledMethod(XMethod m) { return addMethod(m).describe(MethodAnnotation.METHOD_CALLED); }
@Nonnull public BugInstance addEqualsMethodUsed(@CheckForNull Collection<XMethod> equalsMethods) { if (equalsMethods == null) { return this; } if (equalsMethods.size() < 5) { for (XMethod m : equalsMethods) { addMethod(m).describe(MethodAnnotation.METHOD_EQUALS_USED); } } else { addMethod(equalsMethods.iterator().next()).describe(MethodAnnotation.METHOD_EQUALS_USED); } return this; }
private void annotateWarningWithTypeQualifier(BugInstance warning, TypeQualifierValue<?> typeQualifierValue) { if (TypeQualifierValue.hasMultipleVariants(typeQualifierValue)) { StringBuilder buf = new StringBuilder(); buf.append("@"); buf.append(typeQualifierValue.typeQualifier.getDottedClassName()); // When there are multiple variants, qualify the type // qualifier with the value indicating which variant. buf.append("("); buf.append(typeQualifierValue.value); buf.append(")"); warning.addString(buf.toString()).describe(StringAnnotation.TYPE_QUALIFIER_ROLE); } else { warning.addClass(typeQualifierValue.typeQualifier).describe(ClassAnnotation.TYPE_QUALIFIER_ROLE); } }
/** * Add a method annotation for the method which has been called by the * method currently being visited by given visitor. Assumes that the visitor * has just looked at an invoke instruction of some kind. * * @param visitor * the DismantleBytecode object * @return this object */ @Nonnull public BugInstance addCalledMethod(DismantleBytecode visitor) { return addMethod(MethodAnnotation.fromCalledMethod(visitor)).describe(MethodAnnotation.METHOD_CALLED); }
/** * Add a method annotation. * * @param className * name of class containing called method * @param methodName * name of called method * @param methodSig * signature of called method * @param isStatic * true if called method is static, false if not * @return this object */ @Nonnull public BugInstance addCalledMethod(String className, String methodName, String methodSig, boolean isStatic) { return addMethod(MethodAnnotation.fromCalledMethod(className, methodName, methodSig, isStatic)).describe( MethodAnnotation.METHOD_CALLED); }
public void reportBug(BugInstance bug, Data d) { bug.setPriority(d.priority); bug.addSourceLine(d.primarySource); HashSet<Integer> lines = new HashSet<>(); lines.add(d.primarySource.getStartLine()); d.allSource.remove(d.primarySource); for (SourceLineAnnotation source : d.allSource) { if (lines.add(source.getStartLine())) { bug.addSourceLine(source); bug.describe(SourceLineAnnotation.ROLE_ANOTHER_INSTANCE); } /* else if (false && SystemProperties.ASSERTIONS_ENABLED) { AnalysisContext.logError("Skipping duplicated source warning for " + bug.getInstanceHash() + " " + bug.getMessage()); }*/ } reporter.reportBug(bug); }
@Override public void report() { for (Map.Entry<String, SortedSet<String>> e : map.entrySet()) { Set<String> occursIn = e.getValue(); if (occursIn.size() == 1) { continue; } XField field = definition.get(e.getKey()); if (field == null) { continue; } Integer length = stringSize.get(e.getKey()); int overhead = length * (occursIn.size() - 1); if (overhead < 3 * SIZE_OF_HUGE_CONSTANT) { continue; } String className = field.getClassName(); BugInstance bug = new BugInstance(this, "HSC_HUGE_SHARED_STRING_CONSTANT", overhead > 20 * SIZE_OF_HUGE_CONSTANT ? HIGH_PRIORITY : (overhead > 8 * SIZE_OF_HUGE_CONSTANT ? NORMAL_PRIORITY : LOW_PRIORITY)).addClass(className) .addField(field).addInt(length).addInt(occursIn.size()).describe(IntAnnotation.INT_OCCURRENCES); for (String c : occursIn) { if (!c.equals(className)) { bug.addClass(c); } } bugReporter.reportBug(bug); } }
@Override public void visit(Code obj) { found.clear(); priority = LOW_PRIORITY; state = SAW_NOTHING; super.visit(obj); bugAccumulator.reportAccumulatedBugs(); if (!found.isEmpty()) { BugInstance bug = new BugInstance(this, "FE_FLOATING_POINT_EQUALITY", priority).addClassAndMethod(this); boolean first = true; for (SourceLineAnnotation s : found) { bug.add(s); if (first) { first = false; } else { bug.describe(SourceLineAnnotation.ROLE_ANOTHER_INSTANCE); } } bugReporter.reportBug(bug); found.clear(); } }
private void checkStackValue(int arg) { Item item = getStack().getStackItem(arg); if(item.getXField() == currentDoubleCheckField) { bugReporter.reportBug(new BugInstance(this, "DC_PARTIALLY_CONSTRUCTED", NORMAL_PRIORITY).addClassAndMethod(this) .addField(currentDoubleCheckField).describe("FIELD_ON").addSourceLine(this).addSourceLine(this, assignPC) .describe("SOURCE_LINE_STORED")); stage++; } } }
/** * Add a method annotation for the method which is called by given * instruction. * * @param cpg * the constant pool for the method containing the call * @param inv * the InvokeInstruction * @return this object */ @Nonnull public BugInstance addCalledMethod(ConstantPoolGen cpg, InvokeInstruction inv) { String className = inv.getClassName(cpg); String methodName = inv.getMethodName(cpg); String methodSig = inv.getSignature(cpg); addMethod(className, methodName, methodSig, inv.getOpcode() == Const.INVOKESTATIC); describe(MethodAnnotation.METHOD_CALLED); return this; }
private void annotateAndReport(BugInstance bug, OpcodeStack.Item item) { assert item.isServletParameterTainted(); String s = item.getHttpParameterName(); int pc = item.getInjectionPC(); if (s != null && xmlSafe.matcher(s).matches()) { bug.addString(s).describe(StringAnnotation.PARAMETER_NAME_ROLE); } SourceLineAnnotation thisLine = SourceLineAnnotation.fromVisitedInstruction(this); if (pc >= 0) { SourceLineAnnotation source = SourceLineAnnotation.fromVisitedInstruction(this, pc); if (thisLine.getStartLine() != source.getStartLine()) { bug.add(source).describe(SourceLineAnnotation.ROLE_GENERATED_AT); } } bug.addOptionalLocalVariable(this, item); accumulator.accumulateBug(bug, this); }
@Override public void sawOpcode(int seen) { if (seen == Const.INVOKEVIRTUAL && stack.getStackDepth() > 0 && "java/lang/String".equals(getClassConstantOperand())) { boolean lastIndexOf = "lastIndexOf".equals(getNameConstantOperand()); if (lastIndexOf || "indexOf".equals(getNameConstantOperand())) { int stackOff = -1; if ("(Ljava/lang/String;)I".equals(getSigConstantOperand())) { // sig: String stackOff = 0; } else if ("(Ljava/lang/String;I)I".equals(getSigConstantOperand())) { // sig: String, int stackOff = 1; } if (stackOff > -1) { OpcodeStack.Item item = stack.getStackItem(stackOff); Object o = item.getConstant(); if (o != null && ((String) o).length() == 1) { bugReporter.reportBug(new BugInstance(this, lastIndexOf ? "IIO_INEFFICIENT_LAST_INDEX_OF" : "IIO_INEFFICIENT_INDEX_OF", LOW_PRIORITY).addClassAndMethod(this) .describe(StringAnnotation.STRING_MESSAGE).addCalledMethod(this).addSourceLine(this)); } } } } }
private void reportNullDeref(WarningPropertySet<WarningProperty> propertySet, Location location, String type, int priority, @CheckForNull BugAnnotation variable) { BugInstance bugInstance = new BugInstance(this, type, priority).addClassAndMethod(classContext.getJavaClass(), method); if (variable != null) { bugInstance.add(variable); } else { bugInstance.add(new LocalVariableAnnotation("?", -1, -1)); } bugInstance.addSourceLine(classContext, method, location).describe("SOURCE_LINE_DEREF"); if (FindBugsAnalysisFeatures.isRelaxedMode()) { WarningPropertyUtil.addPropertiesForDataMining(propertySet, classContext, method, location); } addPropertiesForDereferenceLocations(propertySet, Collections.singleton(location), false); propertySet.decorateBugInstance(bugInstance); bugReporter.reportBug(bugInstance); }
private void checkForCompatibleLongComparison(OpcodeStack.Item left, OpcodeStack.Item right) { if (left.getSpecialKind() == Item.RESULT_OF_I2L && right.getConstant() != null) { long value = ((Number) right.getConstant()).longValue(); if ( (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE)) { int priority = Priorities.HIGH_PRIORITY; if (value == Integer.MAX_VALUE+1L || value == Integer.MIN_VALUE-1L) { priority = Priorities.NORMAL_PRIORITY; } String stringValue = IntAnnotation.getShortInteger(value)+"L"; if (value == 0xffffffffL) { stringValue = "0xffffffffL"; } else if (value == 0x80000000L) { stringValue = "0x80000000L"; } accumulator.accumulateBug(new BugInstance(this, "INT_BAD_COMPARISON_WITH_INT_VALUE", priority ).addClassAndMethod(this) .addString(stringValue).describe(StringAnnotation.STRING_NONSTRING_CONSTANT_ROLE) .addValueSource(left, this) , this); } } }
private void reportNullDeref(WarningPropertySet<WarningProperty> propertySet, Location location, String type, int priority, BugAnnotation cause, @CheckForNull BugAnnotation variable) { BugInstance bugInstance = new BugInstance(this, type, priority).addClassAndMethod(classContext.getJavaClass(), method); bugInstance.add(cause); if (variable != null) { bugInstance.add(variable); } else { bugInstance.add(new LocalVariableAnnotation("?", -1, -1)); } bugInstance.addSourceLine(classContext, method, location).describe("SOURCE_LINE_DEREF"); if (FindBugsAnalysisFeatures.isRelaxedMode()) { WarningPropertyUtil.addPropertiesForDataMining(propertySet, classContext, method, location); } addPropertiesForDereferenceLocations(propertySet, Collections.singleton(location)); propertySet.decorateBugInstance(bugInstance); bugReporter.reportBug(bugInstance); }
@Override public void visit(Code obj) { if (!directChildOfTestCase && (getMethodName().equals("setUp") || getMethodName().equals("tearDown")) && !getMethod().isPrivate() && getMethodSig().equals("()V")) { sawSuperCall = false; super.visit(obj); if (sawSuperCall) { return; } JavaClass we = Lookup.findSuperImplementor(getThisClass(), getMethodName(), "()V", bugReporter); if (we != null && !we.getClassName().equals("junit.framework.TestCase")) { // OK, got a bug int offset = 0; if (getMethodName().equals("tearDown")) { offset = obj.getCode().length - 1; } Method superMethod = Lookup.findImplementation(we, getMethodName(), "()V"); Code superCode = superMethod.getCode(); if (superCode != null && superCode.getCode().length > 3) { bugReporter.reportBug(new BugInstance(this, getMethodName().equals("setUp") ? "IJU_SETUP_NO_SUPER" : "IJU_TEARDOWN_NO_SUPER", NORMAL_PRIORITY).addClassAndMethod(this).addMethod(we, superMethod) .describe(MethodAnnotation.METHOD_OVERRIDDEN).addSourceLine(this, offset)); } } } }
@Override public void sawOpcode(int seen) { if (seen == Const.INVOKEVIRTUAL && "start".equals(getNameConstantOperand()) && "()V".equals(getSigConstantOperand())) { try { if (Hierarchy.isSubtype(getDottedClassConstantOperand(), "java.lang.Thread")) { int priority = Priorities.NORMAL_PRIORITY; if (getPC() + 4 >= getCode().getCode().length) { priority = Priorities.LOW_PRIORITY; } BugInstance bug = new BugInstance(this, "SC_START_IN_CTOR", priority).addClassAndMethod(this) .addCalledMethod(this); Subtypes2 subtypes2 = AnalysisContext.currentAnalysisContext().getSubtypes2(); Set<ClassDescriptor> directSubtypes = subtypes2.getDirectSubtypes(getClassDescriptor()); if (!directSubtypes.isEmpty()) { for (ClassDescriptor sub : directSubtypes) { bug.addClass(sub).describe(ClassAnnotation.SUBCLASS_ROLE); } bug.setPriority(Priorities.HIGH_PRIORITY); } bugAccumulator.accumulateBug(bug, this); } } catch (ClassNotFoundException e) { bugReporter.reportMissingClass(e); } } } }
@Override public void visit(Field field) { ConstantValue value = field.getConstantValue(); if (value == null) { return; } Constant c = getConstantPool().getConstant(value.getConstantValueIndex()); if (testingEnabled && c instanceof ConstantLong && ((ConstantLong)c).getBytes() == MICROS_PER_DAY_OVERFLOWED_AS_INT) { bugReporter.reportBug( new BugInstance(this, "TESTING", HIGH_PRIORITY).addClass(this).addField(this) .addString("Did you mean MICROS_PER_DAY") .addInt(MICROS_PER_DAY_OVERFLOWED_AS_INT) .describe(IntAnnotation.INT_VALUE)); } } @Override