protected UnresolvedXMethod(MethodDescriptor m) { super(m.getClassDescriptor().getDottedClassName(), m.getName(), m.getSignature(), m.isStatic() ? Const.ACC_STATIC : 0); if (XFactory.DEBUG_UNRESOLVED) { System.out.println("Unresolved xmethod: " + this); } }
/** * @param m method to check * @return array of argument numbers (0-based) which this method writes into or null if we don't know anything about this method */ private static int changedArg(MethodDescriptor m) { if(m.equals(ARRAY_COPY)) { return 2; } if(m.getName().equals("toArray") && m.getSignature().equals("([Ljava/lang/Object;)[Ljava/lang/Object;") && Subtypes2.instanceOf(m.getClassDescriptor(), "java.util.Collection")) { return 0; } if ((m.getName().equals("sort") || m.getName().equals("fill") || m.getName().equals("reverse") || m.getName().equals( "shuffle")) && (m.getSlashedClassName().equals("java/util/Arrays") || m.getSlashedClassName().equals("java/util/Collections"))) { return 0; } return -1; }
@Override public int hashCode() { int result = 1; result = PRIME * result + ((md == null) ? 0 : md.hashCode()); result = PRIME * result + parameterNumber; return result; }
/** * Create a MethodAnnotation from a MethodDescriptor. * * @param methodDescriptor * the MethodDescriptor * @return the MethodAnnotation */ public static MethodAnnotation fromMethodDescriptor(MethodDescriptor methodDescriptor) { return fromForeignMethod(methodDescriptor.getSlashedClassName(), methodDescriptor.getName(), methodDescriptor.getSignature(), methodDescriptor.isStatic()); }
@Override public XMethod findMatchingMethod(MethodDescriptor descriptor) { return findMethod(descriptor.getName(), descriptor.getSignature(), descriptor.isStatic()); }
/** * Returns true if given constant pool probably has a reference to any of supplied methods * Useful to exclude from analysis uninteresting classes * @param cp constant pool * @param methods methods collection * @return true if method is found */ public static boolean hasInterestingMethod(ConstantPool cp, Collection<MethodDescriptor> methods) { for(Constant c : cp.getConstantPool()) { if(c instanceof ConstantMethodref || c instanceof ConstantInterfaceMethodref) { ConstantCP desc = (ConstantCP)c; ConstantNameAndType nameAndType = (ConstantNameAndType) cp.getConstant(desc.getNameAndTypeIndex()); String className = cp.getConstantString(desc.getClassIndex(), Const.CONSTANT_Class); String name = ((ConstantUtf8)cp.getConstant(nameAndType.getNameIndex())).getBytes(); String signature = ((ConstantUtf8)cp.getConstant(nameAndType.getSignatureIndex())).getBytes(); // We don't know whether method is static thus cannot use equals int hash = FieldOrMethodDescriptor.getNameSigHashCode(name, signature); for(MethodDescriptor method : methods) { if (method.getNameSigHashCode() == hash && (method.getSlashedClassName().isEmpty() || method.getSlashedClassName().equals(className)) && method.getName().equals(name) && method.getSignature().equals(signature)) { return true; } } } } return false; }
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; }
/** * @param m method to check * @return true if given method is known to change its object only */ private static boolean isObjectOnlyMethod(MethodDescriptor m) { if (m.isStatic() || m.getName().equals(Const.CONSTRUCTOR_NAME) || m.getName().equals("forEach")) { return false; } String className = m.getSlashedClassName(); if(isObjectOnlyClass(className)) { return true; } if(className.startsWith("javax/xml/") && m.getName().startsWith("next")) { return true; } if ((className.startsWith("java/net/") || className.startsWith("javax/servlet")) && (m.getName().startsWith("remove") || m.getName().startsWith("add") || m.getName().startsWith("set"))) { return true; } if(OBJECT_ONLY_METHODS.contains(m)) { return true; } return false; }
/** * Convenience method for generating a method signature in human readable * form. * * @param methodDescriptor * a MethodDescriptor * @return the formatted version of that signature */ public static String convertMethodSignature(MethodDescriptor methodDescriptor) { return convertMethodSignature(methodDescriptor.getClassDescriptor().toDottedClassName(), methodDescriptor.getName(), methodDescriptor.getSignature()); }
if(m.getSlashedClassName().equals("java/lang/System") && m.getName().equals("arraycopy")) { case Const.INVOKESPECIAL: { MethodDescriptor m = getMethodDescriptorOperand(); if(m.getSlashedClassName().equals("java/lang/String")) { if((m.getName().equals("charAt") || m.getName().equals("codePointAt")) && m.getSignature().startsWith("(I)")) { checkRange(stack.getStackItem(0), 0, stack.getStackItem(1).getConstant(), "RANGE_STRING_INDEX"); if(m.getName().equals("substring") || m.getName().equals("subSequence")) { int nArgs = getNumberArguments(m.getSignature()); Item thisArg = stack.getStackItem(nArgs); Item firstArg = stack.getStackItem(nArgs-1); if ((m.getSignature().startsWith("([BII)") || m.getSignature().startsWith("([CII)") || m.getSignature().startsWith("([III)")) && (((m.getName().equals("write") || m.getName().equals("read")) && m.getSlashedClassName().startsWith( "java/io/")) || (m.getName().equals(Const.CONSTRUCTOR_NAME) && m.getSlashedClassName().equals("java/lang/String")))) { Item arrayArg = stack.getStackItem(2); Item offsetArg = stack.getStackItem(1);
/** * @param methodDescriptor */ private void sawNoSideEffectCall(MethodDescriptor methodDescriptor) { if(uselessVoidCandidate && Type.getReturnType(methodDescriptor.getSignature()) == Type.VOID && !methodDescriptor.getName().equals(Const.CONSTRUCTOR_NAME)) { /* To reduce false-positives we do not mark method as useless void if it calls * another useless void method. If that another method also in the scope of our project * then we will report it instead. If there's a cycle of no-side-effect calls, then * it's probably some delegation pattern and methods can be extended in future/derived * projects to do something useful. */ uselessVoidCandidate = false; } }
@Override public Method analyze(IAnalysisCache analysisCache, MethodDescriptor descriptor) throws CheckedAnalysisException { JavaClass jclass = analysisCache.getClassAnalysis(JavaClass.class, descriptor.getClassDescriptor()); Method[] methodList = jclass.getMethods(); Method result = null; // As a side-effect, cache all of the Methods for this JavaClass for (Method method : methodList) { MethodDescriptor methodDescriptor = DescriptorFactory.instance().getMethodDescriptor( descriptor.getSlashedClassName(), method.getName(), method.getSignature(), method.isStatic()); // Put in cache eagerly analysisCache.eagerlyPutMethodAnalysis(Method.class, methodDescriptor, method); if (methodDescriptor.equals(descriptor)) { result = method; } } return result; }
@Override protected void visitMethodCFG(MethodDescriptor methodDescriptor, CFG cfg) throws CheckedAnalysisException { if (METHOD != null && !methodDescriptor.getName().equals(METHOD)) { return; if (methodDescriptor.getName().startsWith("access$")) { return; System.out.println("CheckTypeQualifiers: checking " + methodDescriptor.toString()); } catch (CheckedAnalysisException e) { bugReporter.logError("Exception checking type qualifier " + typeQualifierValue.toString() + " on method " + methodDescriptor.toString(), e);
@Override public boolean equals(Object obj) { if (obj == null) { return false; } if (!(obj instanceof TaintLocation)) { return false; } final TaintLocation other = (TaintLocation) obj; return methodDescriptor.equals(other.methodDescriptor) && position == other.position; }
return; case Const.INVOKESPECIAL: if (inStaticInitializer && Const.CONSTRUCTOR_NAME.equals(getMethodDescriptorOperand().getName())) { ClassDescriptor classDescriptor = getClassDescriptorOperand(); if (MUTABLE_COLLECTION_CLASSES.contains(classDescriptor.getClassName())) { if (inStaticInitializer) { Map<String, AllowedParameter> methods = MUTABLE_COLLECTION_METHODS.get(getMethodDescriptorOperand() .getSlashedClassName()); if (methods != null) { String name = getMethodDescriptorOperand().getName(); AllowedParameter allowedParameter = methods.get(name); if (allowedParameter == AllowedParameter.NONE
@Override public void sawOpcode(int seen) { if (seen == Const.INVOKEINTERFACE && getClassConstantOperand().equals("java/sql/Connection") && getMethodDescriptorOperand().getName().equals("prepareStatement") && hasConstantArguments()) { matched.put(getPC(), new BugInstance(this, "IIL_PREPARE_STATEMENT_IN_LOOP", NORMAL_PRIORITY).addClassAndMethod(this) .addSourceLine(this, getPC()).addCalledMethod(this)); } else if (seen == Const.INVOKEINTERFACE && getMethodDescriptorOperand().equals(NODELIST_GET_LENGTH)) { Item item = getStack().getStackItem(0); XMethod returnValueOf = item.getReturnValueOf(); && (getMethodDescriptorOperand().equals(PATTERN_COMPILE) || getMethodDescriptorOperand() .equals(PATTERN_COMPILE_2)) && hasConstantArguments()) { String regex = getFirstArgument(); matched.put(getPC(), new BugInstance(this, "IIL_PATTERN_COMPILE_IN_LOOP", NORMAL_PRIORITY).addClassAndMethod(this)
public void setAccessMethodForMethod(String owner, String name, String sig, boolean isStatic) { accessMethodForMethod = new MethodDescriptor(owner, name, sig, isStatic); } public void setAccessMethodForField(String owner, String name, String sig, boolean isStatic) {
public void analyzeMethod() throws CheckedAnalysisException { if (DEBUG_METHOD != null && !methodDescriptor.getName().equals(DEBUG_METHOD)) { return; cpg = analysisCache.getClassAnalysis(ConstantPoolGen.class, methodDescriptor.getClassDescriptor()); typeDataflow = analysisCache.getMethodAnalysis(TypeDataflow.class, methodDescriptor); subtypes2 = Global.getAnalysisCache().getDatabase(Subtypes2.class);
@Override public String[] analyze(IAnalysisCache analysisCache, MethodDescriptor descriptor) throws CheckedAnalysisException { SignatureParser parser = new SignatureParser(descriptor.getSignature()); ArrayList<String> resultList = new ArrayList<>(); for (Iterator<String> i = parser.parameterSignatureIterator(); i.hasNext();) { resultList.add(i.next()); } return resultList.toArray(new String[resultList.size()]); } }
case INVOKEINTERFACE: case INVOKEVIRTUAL: MethodDescriptor m = new MethodDescriptor((InvokeInstruction) inst, context.cpg); XMethod xMethod = null; try { if(m.getName().equals(CONSTRUCTOR_NAME)) { if(vns[0].equals(context.thisValue)) { changed |= context.setEscape(vals);