String sourceFile = jclass.getSourceFileName(); if (lhsType_.getType() == T_TOP || lhsType_.getType() == T_BOTTOM || rhsType_.getType() == T_TOP || rhsType_.getType() == T_BOTTOM) { return; if (rhsType_.getType() == T_NULL) { } else if (lhsType_.getType() == T_NULL) { addEqualsCheck(lhsType_.getSignature(), handle.getPosition()); addEqualsCheck(rhsType_.getSignature(), handle.getPosition()); String lhsSig = lhsType_.getSignature(); String rhsSig = rhsType_.getSignature(); boolean allOk = checkForWeirdEquals(lhsSig, rhsSig, new HashSet<XMethod>()); if (allOk) { SourceLineAnnotation.fromVisitedInstruction(this.classContext, methodGen, sourceFile, location.getHandle())); } else if (result == IncompatibleTypes.INCOMPATIBLE_CLASSES) { String lhsSig = lhsType_.getSignature(); String rhsSig = rhsType_.getSignature(); boolean core = lhsSig.startsWith("Ljava") && rhsSig.startsWith("Ljava"); if (core) { .addEqualsMethodUsed(DescriptorFactory.createClassDescriptorFromSignature(lhsType_.getSignature())) .addEqualsMethodUsed(DescriptorFactory.createClassDescriptorFromSignature(lhsType_.getSignature()))
Method method, Location location) { try { Instruction ins = location.getHandle().getInstruction(); if (!receiverObjectInstructionSet.get(ins.getOpcode())) { return; Type type = frame.getInstance(ins, classContext.getConstantPoolGen()); if (type instanceof ReferenceType) { propertySet.setProperty(GeneralWarningProperty.RECEIVER_OBJECT_TYPE, type.toString());
@SuppressWarnings("unchecked") @Override public void visitMethod(Method obj) { argNums = null; Type[] argumentTypes = obj.getArgumentTypes(); if(argumentTypes.length == 0) { return; } int lvNum = obj.isStatic() ? 0 : 1; nArgs = argumentTypes.length; int argCount = lvNum; for(Type type : argumentTypes) { argCount+=type.getSize(); } for(int i=0; i<nArgs; i++) { if(argumentTypes[i].getSignature().equals("Ljava/lang/String;")) { if(argNums == null) { argNums = new int[argCount]; Arrays.fill(argNums, -1); } argNums[lvNum] = i; } lvNum+=argumentTypes[i].getSize(); } if(argNums != null) { passedParameters = new List[nArgs]; } super.visitMethod(obj); }
private static IncompatibleTypes getPriorityForAssumingCompatibleWithArray(Type rhsType) { if (rhsType.equals(Type.OBJECT)) { return ARRAY_AND_OBJECT; } String sig = rhsType.getSignature(); if ("Ljava/io/Serializable;".equals(sig) || "Ljava/lang/Cloneable;".equals(sig)) { return SEEMS_OK; } return ARRAY_AND_NON_ARRAY; }
private static Map<Integer, Value> getParameterTypes(MethodDescriptor descriptor) { Type[] argumentTypes = Type.getArgumentTypes(descriptor.getSignature()); int j = 0; Map<Integer, Value> result = new HashMap<>(); if(!descriptor.isStatic()) { result.put(j++, new Value("this", null, "L"+descriptor.getSlashedClassName()+";")); } for (int i = 0; i < argumentTypes.length; i++) { result.put(j, new Value("arg"+i, null, argumentTypes[i].getSignature())); j += argumentTypes[i].getSize(); } return result; }
System.out.println(" Analyzing method " + classContext.getJavaClass().getClassName() + "." + method.getName()); Dataflow<BitSet, LiveLocalStoreAnalysis> llsaDataflow = classContext.getLiveLocalStoreDataflow(method); int pc = handle.getPosition(); IndexedInstruction ins = (IndexedInstruction) location.getHandle().getInstruction(); SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFileName, location.getHandle()); System.out.println(" Store at " + sourceLineAnnotation.getStartLine() + "@" + location.getHandle().getPosition() + " is " + (storeLive ? "live" : "dead")); if (storeLive && sourceLineAnnotation.getStartLine() > 0) { for (Field f : javaClass.getFields()) { priority--; LDC ldc = (LDC) prevIns; Type t = ldc.getType(methodGen.getConstantPool()); if ("Ljava/lang/Class;".equals(t.getSignature())) { Object value = ldc.getValue(methodGen.getConstantPool()); if (value instanceof ConstantClass) { String signatureOfValue = typeOfValue.getSignature(); if ((signatureOfValue.startsWith("Ljava/sql/") || signatureOfValue.startsWith("Ljavax/sql/")) && !signatureOfValue.endsWith("Exception")) {
String sourceFile = classContext.getJavaClass().getSourceFileName(); if (DEBUG) { System.out.println("Checking " + methodName); Location location = i.next(); InstructionHandle handle = location.getHandle(); Instruction ins = handle.getInstruction(); int pc = handle.getPosition(); Instruction ins = handle.getInstruction(); if (operandType.equals(TopType.instance())) { String castSig = castType.getSignature(); if (operandType.equals(NullType.instance()) || operandNullness.isDefinitelyNull()) { SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFile, handle); assert castSig.length() > 1; if (!isCast) { accumulator.accumulateBug(new BugInstance(this, "NP_NULL_INSTANCEOF", split ? LOW_PRIORITY : NORMAL_PRIORITY) .addClassAndMethod(methodGen, sourceFile).addType(castSig), sourceLineAnnotation); SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFile, handle);
@Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof InjectionSink)) { return false; } final InjectionSink other = (InjectionSink) obj; // include only attributes that cannot change after object construction return this.bugType.equals(other.bugType) && this.originalPriority == other.originalPriority && this.classContext.getClassDescriptor().equals(other.classContext.getClassDescriptor()) && this.method.getName().equals(other.method.getName()) && this.method.getSignature().equals(other.method.getSignature()) && this.method.getReturnType().equals(other.method.getReturnType()) && this.instructionHandle.getInstruction().getOpcode() == other.instructionHandle.getInstruction().getOpcode() && this.instructionHandle.getPosition() == other.instructionHandle.getPosition(); }
private void analyzeMethod(ClassContext classContext, Method method) throws CheckedAnalysisException { LocalVariableTable lvt = method.getLocalVariableTable(); UselessValuesContext context = new UselessValuesContext(classContext, method); context.initObservedValues(); if(++iteration > MAX_ITERATIONS) { AnalysisContext.logError("FindUselessObjects: " + classContext.getClassDescriptor().getDottedClassName() + "." + method.getName() + method.getSignature() + ": cannot converge after " + MAX_ITERATIONS + " iterations; method is skipped"); return; Instruction inst = location.getHandle().getInstruction(); ValueNumberFrame before = location.frameBefore(); if (!before.isValid()) { int nconsumed = inst.consumeStack(context.cpg); if(nconsumed > 0) { ValueNumber[] vns = new ValueNumber[nconsumed]; .getAnalysisCache() .getClassAnalysis(XClass.class, DescriptorFactory.createClassDescriptorFromSignature(type.getSignature())) .findMatchingMethod(m); } catch (CheckedAnalysisException e) {
private Method findSuperclassMethod(@DottedClassName String superclassName, Method subclassMethod) throws ClassNotFoundException { String methodName = subclassMethod.getName(); Type[] subArgs = null; JavaClass superClass = Repository.lookupClass(superclassName); Method[] methods = superClass.getMethods(); outer: for (Method m : methods) { if (m.getName().equals(methodName)) { if (subArgs == null) { subArgs = Type.getArgumentTypes(subclassMethod.getSignature()); } Type[] superArgs = Type.getArgumentTypes(m.getSignature()); if (subArgs.length == superArgs.length) { for (int j = 0; j < subArgs.length; j++) { if (!superArgs[j].equals(subArgs[j])) { continue outer; } } return m; } } } if (!"Object".equals(superclassName)) { @DottedClassName String superSuperClassName = superClass.getSuperclassName(); if (superSuperClassName.equals(superclassName)) { throw new ClassNotFoundException("superclass of " + superclassName + " is itself"); } return findSuperclassMethod(superSuperClassName, subclassMethod); } return null; }
String sourceFile = classContext.getJavaClass().getSourceFileName(); if (DEBUG) { System.out.println("\n" + fullMethodName); if (operandType.equals(TopType.instance())) { if (operandType.equals(NullType.instance())) { InstructionHandle next = handle.getNext(); vnFrame, "INVOKED_ON")), SourceLineAnnotation.fromVisitedInstruction( classContext, methodGen, sourceFile, handle)); boolean parmIsObject = "Ljava/lang/Object;".equals(expectedType.getSignature()); boolean selfOperation = !allMethod && operand.equals(actualType) && !parmIsObject; if (!allMethod && !parmIsObject && actualType instanceof GenericObjectType) { SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFile, handle); .createClassOrObjectDescriptorFromSignature(expectedType.getSignature()); ClassDescriptor actualClassDescriptor = DescriptorFactory.createClassOrObjectDescriptorFromSignature(equalsType .getSignature()); ClassSummary classSummary = AnalysisContext.currentAnalysisContext().getClassSummary(); Set<XMethod> targets = null;
try { Method m = getMethod(); if (m.isPublic() && !m.isSynthetic() && "clone".equals(m.getName()) && (m.getArgumentTypes().length == 0)) { String returnClsName = m.getReturnType().getSignature(); returnClsName = SignatureUtils.stripSignature(returnClsName); if (!clsName.equals(returnClsName)) { if (Values.DOTTED_JAVA_LANG_OBJECT.equals(returnClsName)) { bugReporter.reportBug( new BugInstance(this, BugType.CU_CLONE_USABILITY_OBJECT_RETURN.name(), NORMAL_PRIORITY).addClass(this).addMethod(this)); } else { JavaClass clonedClass = Repository.lookupClass(returnClsName); if (!cls.instanceOf(clonedClass)) { bugReporter.reportBug( new BugInstance(this, BugType.CU_CLONE_USABILITY_MISMATCHED_RETURN.name(), HIGH_PRIORITY).addClass(this).addMethod(this));
IncompatibleTypes result = IncompatibleTypes.getPriorityForAssumingCompatible(lhsType, rhsType, true); if (result != IncompatibleTypes.SEEMS_OK && result != IncompatibleTypes.UNCHECKED) { String sourceFile = jclass.getSourceFileName(); boolean isAssertSame = handle.getInstruction() instanceof INVOKESTATIC; if (isAssertSame) { if(testingEnabled) { bugAccumulator.accumulateBug( new BugInstance(this, "TESTING", result.getPriority()) .addClassAndMethod(methodGen, sourceFile) .addString("Calling assertSame with two distinct objects") .addFoundAndExpectedType(rhsType, lhsType) .addSomeSourceForTopTwoStackValues(classContext, method, location), SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFile, handle)); .addClassAndMethod(methodGen, sourceFile).addFoundAndExpectedType(rhsType, lhsType) .addSomeSourceForTopTwoStackValues(classContext, method, location), SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFile, handle)); if (lhsType.equals(Type.OBJECT) && rhsType.equals(Type.OBJECT)) { return; String lhs = SignatureConverter.convert(lhsType.getSignature()); String rhs = SignatureConverter.convert(rhsType.getSignature());
ConstantPoolGen cpg = classContext.getConstantPoolGen(); String sourceFile = classContext.getJavaClass().getSourceFileName(); if (DEBUG) { String methodName = methodGen.getClassName() + "." + methodGen.getName(); Location location = i.next(); InstructionHandle handle = location.getHandle(); Instruction ins = handle.getInstruction(); if (operandType.equals(TopType.instance())) { SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFile, handle); ReferenceType problem = DeepSubtypeAnalysis.getLeastSerializableTypeComponent(refType); bugAccumulator.accumulateBug(new BugInstance(this, "J2EE_STORE_OF_NON_SERIALIZABLE_OBJECT_INTO_SESSION", isSerializable < 0.15 ? HIGH_PRIORITY : isSerializable > 0.5 ? LOW_PRIORITY : NORMAL_PRIORITY) .addClassAndMethod(methodGen, sourceFile).addType(problem).describe(TypeAnnotation.FOUND_ROLE), sourceLineAnnotation);
private void analyzeMethod(ClassContext classContext, Method method) throws DataflowAnalysisException, CFGBuilderException { if (BCELUtil.isSynthetic(method) || (method.getAccessFlags() & Const.ACC_BRIDGE) == Const.ACC_BRIDGE) { return; TypeDataflow typeDataflow = classContext.getTypeDataflow(method); String sourceFileName = javaClass.getSourceFileName(); Instruction ins = handle.getInstruction(); TypeFrame typeFrame = typeDataflow.getFactAtLocation(location); Type objType = typeFrame.getStackValue(2); if(extendsConcurrentMap(ClassName.toDottedClassName(ClassName.fromFieldSignature(objType.getSignature())))) { InstructionHandle next = handle.getNext(); boolean isIgnored = next != null && next.getInstruction() instanceof POP; Type type = typeFrame.getTopValue(); int priority = getPriorityForBeingMutable(type); BugInstance bugInstance = new BugInstance(this, pattern, priority) .addClassAndMethod(methodGen, sourceFileName).addCalledMethod(methodGen, invoke) .add(new TypeAnnotation(type)).add(ba); SourceLineAnnotation where = SourceLineAnnotation.fromVisitedInstruction(classContext, method, location); accumulator.accumulateBug(bugInstance, where);
int resetForMethodEntry0(@SlashedClassName String className, Method m) { methodName = m.getName(); String signature = m.getSignature(); stack.clear(); lvValues.clear(); seenTransferOfControl = false; exceptionHandlers.clear(); Code code = m.getCode(); if (code != null) { CodeException[] exceptionTable = code.getExceptionTable(); System.out.println(" --- " + className + " " + m.getName() + " " + signature); Type[] argTypes = Type.getArgumentTypes(signature); int reg = 0; if (!m.isStatic()) { Item it = Item.initialArgument(argType.getSignature(), reg); setLVValue(reg, it); reg += it.getSize();
int outlineChunkStartOffset = first.getPosition(); int outlineChunkEndOffset = last.getPosition() + last.getInstruction().getLength(); Instruction c = inst.copy(); // Use clone for shallow copy null); int newLocalVarIndex = newLVG.getIndex(); String varSignature = varType.getSignature();
/** * Get LocalVariable object. * * This relies on that the instruction list has already been dumped to byte code or * or that the `setPositions' methods has been called for the instruction list. * * Note that due to the conversion from byte code offset to InstructionHandle, * it is impossible to tell the difference between a live range that ends BEFORE * the last insturction of the method or a live range that ends AFTER the last * instruction of the method. Hence the live_to_end flag to differentiate * between these two cases. * * @param cp constant pool */ public LocalVariable getLocalVariable( final ConstantPoolGen cp ) { int start_pc = 0; int length = 0; if ((start != null) && (end != null)) { start_pc = start.getPosition(); length = end.getPosition() - start_pc; if ((end.getNext() == null) && live_to_end) { length += end.getInstruction().getLength(); } } final int name_index = cp.addUtf8(name); final int signature_index = cp.addUtf8(type.getSignature()); return new LocalVariable(start_pc, length, name_index, signature_index, index, cp .getConstantPool(), orig_index); }
Instruction ins = handle.getInstruction(); if (ins.getOpcode() == Const.INVOKEVIRTUAL) { INVOKEVIRTUAL iv = (INVOKEVIRTUAL) ins; .getSignature()); if (classDescriptor.equals(classContext.getClassDescriptor())) { continue; bugReporter.reportBug(new BugInstance(this, "JML_JSR166_CALLING_WAIT_RATHER_THAN_AWAIT", priority) .addClassAndMethod(classContext.getJavaClass(), method).addCalledMethod(cpg, iv).addMethod(m) .describe(MethodAnnotation.METHOD_ALTERNATIVE_TARGET).addType(classDescriptor) .describe(TypeAnnotation.FOUND_ROLE).addSourceLine(classContext, method, location)); if (ins.getOpcode() != Const.MONITORENTER) { continue; bugReporter.reportMissingClass(e); String sig = type.getSignature(); boolean isUtilConcurrentSig = sig.startsWith(UTIL_CONCURRRENT_SIG_PREFIX);
Type[] parameterTypeList = Type.getArgumentTypes(methodGen.getSignature()); Location firstLocation = new Location(cfg.getEntry().getFirstInstruction(), cfg.getEntry()); Stream paramStream = new Stream(firstLocation, objectType.getClassName(), streamBase.getClassName()); paramStream.setIsOpenOnCreation(true); paramStream.setOpenLocation(firstLocation); switch (type.getType()) { case Const.T_LONG: case Const.T_DOUBLE: String sourceFile = javaClass.getSourceFileName(); String leakClass = stream.getStreamBase(); if (isMainMethod(method) && (leakClass.contains("InputStream") || leakClass.contains("Reader"))) { bugAccumulator.accumulateBug(new BugInstance(this, pos.bugType, pos.priority) .addClassAndMethod(methodGen, sourceFile).addTypeOfNamedClass(leakClass) .describe(TypeAnnotation.CLOSEIT_ROLE), SourceLineAnnotation.fromVisitedInstruction(classContext, methodGen, sourceFile, stream.getLocation().getHandle()));