throws IOException { String t; ConstantPool cp = c.getConstantPool(); int[] v = new int[cp.getLength() + 1]; out.write(linkPath(t = c.getSourceFileName())); defs.add(t); refs.add(t); out.write(linkDef(t = c.getPackageName())); defs.add(t); refs.add(t); fout.write(SPACE); sig = m.getSignature(); msig=Utility.methodSignatureReturnType(sig, false); out.write(msig); for (int i = 0; i < v.length - 1; i++) { if (v[i] != 1) { Constant constant = cp.getConstant(i); if (constant != null) { full.add(constantToString(constant, cp, v));
calledMethods = new HashSet<>(); calledMethodNames = new HashSet<>(); className = classContext.getJavaClass().getClassName(); String[] parts = className.split("[$+.]"); String simpleClassName = parts[parts.length - 1]; ConstantPool cp = classContext.getJavaClass().getConstantPool(); for(Constant constant : cp.getConstantPool()) { if(constant instanceof ConstantMethodHandle) { int kind = ((ConstantMethodHandle) constant).getReferenceKind(); if(kind >= 5 && kind <= 9) { Constant ref = cp.getConstant(((ConstantMethodHandle)constant).getReferenceIndex()); if(ref instanceof ConstantCP) { String className = cp.getConstantString(((ConstantCP) ref).getClassIndex(), Const.CONSTANT_Class); ConstantNameAndType nameAndType = (ConstantNameAndType) cp.getConstant(((ConstantCP) ref).getNameAndTypeIndex()); String name = ((ConstantUtf8)cp.getConstant(nameAndType.getNameIndex())).getBytes(); String signature = ((ConstantUtf8)cp.getConstant(nameAndType.getSignatureIndex())).getBytes(); MethodAnnotation called = new MethodAnnotation(ClassName.toDottedClassName(className), name, signature, kind==6 /* invokestatic */); calledMethods.add(called); priority = NORMAL_PRIORITY; BugInstance bugInstance = new BugInstance(this, "UPM_UNCALLED_PRIVATE_METHOD", priority).addClass(this).addMethod(m); bugReporter.reportBug(bugInstance);
@Override public void visitJavaClass(JavaClass obj) { setupVisitorForClass(obj); getConstantPool().accept(this); doVisitMethod(targetMethod); }
public static boolean hasInterestingClass(ConstantPool cp, Collection<String> classes) { for(Constant c : cp.getConstantPool()) { if(c instanceof ConstantClass) { String className = ((ConstantUtf8)cp.getConstant(((ConstantClass)c).getNameIndex())).getBytes(); if(classes.contains(className)) { return true; } } } return false; }
private void init(JavaClass jclass) { ConstantPool cp = jclass.getConstantPool(); int numConstants = cp.getLength(); for (int i = 0; i < numConstants; ++i) { try { Constant c = cp.getConstant(i); if (c instanceof ConstantMethodref) { ConstantMethodref cmr = (ConstantMethodref) c; ConstantNameAndType cnat = (ConstantNameAndType) cp.getConstant(cmr.getNameAndTypeIndex(), Const.CONSTANT_NameAndType); String methodName = ((ConstantUtf8) cp.getConstant(cnat.getNameIndex(), Const.CONSTANT_Utf8)).getBytes(); String className = cp.getConstantString(cmr.getClassIndex(), Const.CONSTANT_Class).replace('/', '.'); String methodSig = ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex(), Const.CONSTANT_Utf8)).getBytes();
@Override public void visitClassContext(ClassContext classContext) { JavaClass jclass = classContext.getJavaClass(); // We can ignore classes that were compiled for anything // less than JDK 1.5. This should avoid lots of unnecessary work // when analyzing code for older VM targets. if (BCELUtil.preTiger(jclass)) { return; } boolean sawUtilConcurrentLocks = false; for (Constant c : jclass.getConstantPool().getConstantPool()) { if (c instanceof ConstantMethodref) { ConstantMethodref m = (ConstantMethodref) c; ConstantClass cl = (ConstantClass) jclass.getConstantPool().getConstant(m.getClassIndex()); ConstantUtf8 name = (ConstantUtf8) jclass.getConstantPool().getConstant(cl.getNameIndex()); String nameAsString = name.getBytes(); if (nameAsString.startsWith("java/util/concurrent/locks")) { sawUtilConcurrentLocks = true; } } } if (sawUtilConcurrentLocks) { super.visitClassContext(classContext); } }
@Override public void visit(JavaClass obj) { compute(); ConstantPool cp = obj.getConstantPool(); Constant[] constants = cp.getConstantPool(); checkConstant: for (int i = 0; i < constants.length; i++) { Constant co = constants[i]; String ref = getClassName(obj, i); if ((ref.startsWith("java") || ref.startsWith("org.w3c.dom")) && !defined.contains(ref)) { bugReporter.reportBug(new BugInstance(this, "VR_UNRESOLVABLE_REFERENCE", NORMAL_PRIORITY).addClass(obj) .addString(ref)); if (className.equals(obj.getClassName()) || !defined.contains(className)) { ConstantNameAndType nt = (ConstantNameAndType) cp.getConstant(co2.getNameAndTypeIndex()); String name = ((ConstantUtf8) obj.getConstantPool().getConstant(nt.getNameIndex(), Const.CONSTANT_Utf8)).getBytes(); String signature = ((ConstantUtf8) obj.getConstantPool().getConstant(nt.getSignatureIndex(), Const.CONSTANT_Utf8)) .getBytes();
/** * implements the visitor to look for classes that reference com.sun.xxx, or org.apache.xerces.xxx classes by looking for class constants in the constant * pool * * @param context * the context object of the currently parsed class */ @Override public void visitClassContext(ClassContext context) { JavaClass cls = context.getJavaClass(); if (!isInternal(cls.getClassName())) { ConstantPool pool = cls.getConstantPool(); int numItems = pool.getLength(); for (int i = 0; i < numItems; i++) { Constant c = pool.getConstant(i); if (c instanceof ConstantClass) { String clsName = ((ConstantClass) c).getBytes(pool); if (isInternal(clsName)) { bugReporter.reportBug( new BugInstance(this, BugType.IICU_INCORRECT_INTERNAL_CLASS_USE.name(), NORMAL_PRIORITY).addClass(cls).addString(clsName)); } } } } }
UnconditionalValueDerefDataflow dataflow = classContext.getUnconditionalValueDerefDataflow(method); SignatureParser parser = new SignatureParser(method.getSignature()); int paramLocalOffset = method.isStatic() ? 0 : 1; .getEffectiveTypeQualifierAnnotation(xmethod, i, nonnullTypeQualifierValue); boolean implicitNullCheckForEquals = false; if (directTypeQualifierAnnotation == null && "equals".equals(method.getName()) && "(Ljava/lang/Object;)Z".equals(method.getSignature()) && !method.isStatic()) { implicitNullCheckForEquals = true; Code code = method.getCode(); ConstantPool cp = jclass.getConstantPool(); byte codeBytes[] = code.getCode(); for (CodeException e : code.getExceptionTable()) { ConstantClass cl = (ConstantClass) cp.getConstant(e.getCatchType()); int endPC = e.getEndPC(); int startPC = e.getStartPC(); || jclass.isFinal()) { priority--; reportBug(new BugInstance(this, bugPattern, priority).addClassAndMethod(jclass, method).add( LocalVariableAnnotation.getParameterLocalVariableAnnotation(method, paramLocal)));
/** * 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; }
public void visitJavaClass(JavaClass clazz) { stack.push(clazz); clazz.accept(visitor); Field[] fields = clazz.getFields(); for(int i=0; i < fields.length; i++) fields[i].accept(this); Method[] methods = clazz.getMethods(); for(int i=0; i < methods.length; i++) methods[i].accept(this); Attribute[] attributes = clazz.getAttributes(); for(int i=0; i < attributes.length; i++) attributes[i].accept(this); clazz.getConstantPool().accept(this); stack.pop(); }
JavaClass javaClass = classContext.getJavaClass(); boolean skip = false; ConstantPool constantPool = javaClass.getConstantPool(); for(Constant c : constantPool.getConstantPool() ) { if (c instanceof ConstantMethodref || c instanceof ConstantInterfaceMethodref) { ConstantCP m = (ConstantCP) c; @DottedClassName String clazz = m.getClass(constantPool); ConstantNameAndType nt = (ConstantNameAndType) constantPool.getConstant(m.getNameAndTypeIndex(), Const.CONSTANT_NameAndType); String name = nt.getName(constantPool); if ("setAttribute".equals(name) && "javax.servlet.http.HttpSession".equals(clazz) || ("writeObject".equals(name) && ("java.io.ObjectOutput".equals(clazz) System.out.println(this.getClass().getSimpleName() + " Checking " + javaClass.getClassName()); Method[] methodList = javaClass.getMethods(); if (method.getCode() == null) { continue;
for (Constant c : javaClass.getConstantPool().getConstantPool()) { if (c instanceof ConstantUtf8) { ConstantUtf8 utf8 = (ConstantUtf8) c; String constantValue = String.valueOf(utf8.getBytes()); for (Method m : javaClass.getMethods()) { if (!customReadObjectMethod && READ_DESERIALIZATION_METHODS.contains(m.getName())) { try { customReadObjectMethod = hasCustomReadObject(m, classContext, classesToIgnoreInReadObjectMethod); AnalysisContext.logError("Cannot check custom read object", e); } else if (!customInvokeMethod && "invoke".equals(m.getName())) { try { customInvokeMethod = hasCustomReadObject(m, classContext, classesToIgnoreInReadObjectMethod); for (Field f : javaClass.getFields()) { if ((f.getName().toLowerCase().contains("method") && f.getType().equals(new ObjectType("java.lang.String"))) || f.getType().equals(new ObjectType("java.reflect.Method"))) { bugReporter.reportBug(new BugInstance(this, DESERIALIZATION_GADGET_TYPE, priority) // .addClass(javaClass)); } else if (isSerializable && hasMethodField && useDangerousApis) { bugReporter.reportBug(new BugInstance(this, DESERIALIZATION_GADGET_TYPE, Priorities.LOW_PRIORITY) // .addClass(javaClass));
ConstantPool cp = getConstantPool(); int nameAndTypeIdx = fieldRef.getNameAndTypeIndex(); ConstantNameAndType ntc = (ConstantNameAndType) cp.getConstant(nameAndTypeIdx); int nameIdx = ntc.getNameIndex(); Field[] flds = getClassContext().getJavaClass().getFields(); ConstantUtf8 nameCons = (ConstantUtf8) cp.getConstant(nameIdx); ConstantUtf8 typeCons = (ConstantUtf8) cp.getConstant(ntc.getSignatureIndex()); if (alreadyReported.contains(nameCons.getBytes())) { return; alreadyReported.add(nameCons.getBytes()); bugReporter.reportBug(new BugInstance(this, STRUTS_ACTION_NAME.equals(mtClassName) ? "MTIA_SUSPECT_STRUTS_INSTANCE_FIELD" : "MTIA_SUSPECT_SERVLET_INSTANCE_FIELD", LOW_PRIORITY) .addField( new FieldAnnotation(getDottedClassName(), nameCons.getBytes(), typeCons.getBytes(), false)).addClass(this).addSourceLine(this));
Map<String, Set<String>> constraintInfo = new HashMap<>(); Set<String> exs = new HashSet<>(); ExceptionTable et = m.getExceptionTable(); if (et != null) { int[] indexTable = et.getExceptionIndexTable(); ConstantPool pool = cls.getConstantPool(); for (int index : indexTable) { if (index != 0) { ConstantClass ccls = (ConstantClass) pool.getConstant(index); String exName = ccls.getBytes(pool); JavaClass exClass = Repository.lookupClass(exName); if (!exClass.instanceOf(runtimeClass)) { exs.add(ccls.getBytes(pool)); constraintInfo.put(cls.getClassName(), exs); return constraintInfo;
@Override public void visitClassContext(ClassContext classContext) { JavaClass javaClass = classContext.getJavaClass(); if (!javaClass.getPackageName().contains(".pages")) { return; } //The package contains ".pages" and has some references to tapestry // then it must be an endpoint. //The constants pool contains all references that are reused in the bytecode // including full class name and interface name. if (javaClass.getPackageName().contains(".pages")) { ConstantPool constants = javaClass.getConstantPool(); for (Constant c : constants.getConstantPool()) { if (c instanceof ConstantUtf8) { ConstantUtf8 utf8 = (ConstantUtf8) c; String constantValue = String.valueOf(utf8.getBytes()); if (constantValue.startsWith("Lorg/apache/tapestry5/annotations")) { bugReporter.reportBug(new BugInstance(this, TAPESTRY_ENDPOINT_TYPE, Priorities.LOW_PRIORITY) // .addClass(javaClass)); return; } } } } }
ConstantPool pool = javaClass.getConstantPool(); boolean found = false; for (Constant constantEntry : pool.getConstantPool()) { if (constantEntry instanceof ConstantNameAndType) { ConstantNameAndType nt = (ConstantNameAndType) constantEntry; if ("putIfAbsent".equals(nt.getName(pool))) { found = true; break; Method[] methodList = javaClass.getMethods(); analyzeMethod(classContext, method); } catch (DataflowAnalysisException e) { bugReporter.logError("Error analyzing " + method.toString(), e); } catch (CFGBuilderException e) { bugReporter.logError("Error analyzing " + method.toString(), e);
public void setupVisitorForClass(JavaClass obj) { constantPool = obj.getConstantPool(); thisClass = obj; ConstantClass c = (ConstantClass) constantPool.getConstant(obj.getClassNameIndex()); className = getStringFromIndex(c.getNameIndex()); dottedClassName = className.replace('/', '.'); packageName = obj.getPackageName(); sourceFile = obj.getSourceFileName(); dottedSuperclassName = obj.getSuperclassName(); superclassName = dottedSuperclassName.replace('.', '/'); ClassDescriptor cDesc = DescriptorFactory.createClassDescriptor(className); if (!FindBugs.isNoAnalysis()) { try { thisClassInfo = (ClassInfo) Global.getAnalysisCache().getClassAnalysis(XClass.class, cDesc); } catch (CheckedAnalysisException e) { throw new AssertionError("Can't find ClassInfo for " + cDesc); } } super.visitJavaClass(obj); }
/** This method casually visits ConstantClass references. */ public void visitConstantClass(ConstantClass obj){ Constant c = cp.getConstant(obj.getNameIndex()); if (c instanceof ConstantUtf8){ //Ignore the case where it's not a ConstantUtf8 here, we'll find out later. String classname = ((ConstantUtf8) c).getBytes(); if (classname.startsWith(jc.getClassName().replace('.','/')+"$")){ hasInnerClass = true; } } } }
@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