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);
/** * 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; }
String name = ((ConstantUtf8) cp.getConstant(obj.getNameIndex())).getBytes(); if (! name.equals("Exceptions")){ throw new ClassConstraintException("The Exceptions attribute '"+tostring(obj)+"' is not correctly named 'Exceptions' but '"+name+"'."); checkIndex(obj, exc_indices[i], CONST_Class); ConstantClass cc = (ConstantClass) (cp.getConstant(exc_indices[i])); String cname = ((ConstantUtf8) cp.getConstant(cc.getNameIndex())).getBytes().replace('/','.'); //convert internal notation on-the-fly to external notation if (e == t) break; // It's a subclass of Throwable, OKAY, leave. v = VerifierFactory.getVerifier(e.getSuperclassName()); vr = v.doPass1(); if (vr != VerificationResult.VR_OK){ throw new ClassConstraintException("Exceptions attribute '"+tostring(obj)+"' references '"+cname+"' as an Exception but '"+e.getSuperclassName()+"' in the ancestor hierachy does not pass verification pass 1: "+vr); e = Repository.lookupClass(e.getSuperclassName());
Constant[] constants = cp.getConstantPool().getConstantPool(); ConstantUtf8 u8 = (ConstantUtf8)constants[s.getStringIndex()]; return addString(u8.getBytes()); ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()]; return addClass(u8.getBytes()); ConstantUtf8 u8 = (ConstantUtf8)constants[n.getNameIndex()]; ConstantUtf8 u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()]; return addNameAndType(u8.getBytes(), u8_2.getBytes()); return addUtf8(((ConstantUtf8)c).getBytes()); ConstantNameAndType n = (ConstantNameAndType)constants[m.getNameAndTypeIndex()]; ConstantUtf8 u8 = (ConstantUtf8)constants[clazz.getNameIndex()]; String class_name = u8.getBytes().replace('/', '.'); u8 = (ConstantUtf8)constants[n.getNameIndex()]; String name = u8.getBytes(); u8 = (ConstantUtf8)constants[n.getSignatureIndex()]; String signature = u8.getBytes();
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();
visitedBlocks = new BitSet(); clsContext = classContext; clsName = clsContext.getJavaClass().getClassName(); clsSig = SignatureUtils.classToSignature(clsName); JavaClass cls = classContext.getJavaClass(); Field[] fields = cls.getFields(); ConstantPool cp = classContext.getConstantPoolGen().getConstantPool(); FieldAnnotation fa = new FieldAnnotation(cls.getClassName(), f.getName(), f.getSignature(), false); boolean hasExternalAnnotation = false; for (AnnotationEntry entry : f.getAnnotationEntries()) { ConstantUtf8 cutf = (ConstantUtf8) cp.getConstant(entry.getTypeIndex()); if (!cutf.getBytes().startsWith(Values.JAVA)) { hasExternalAnnotation = true; break;
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 { 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"))) {
protected String getStringFromIndex(int i) { ConstantUtf8 name = (ConstantUtf8) constantPool.getConstant(i); return name.getBytes(); }
/** 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 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; } } } } }
/** @return signature of referenced method/field. */ public String getSignature(final ConstantPoolGen cpg) { final ConstantPool cp = cpg.getConstantPool(); final ConstantNameAndType cnat = getNameAndType(cpg); return ((ConstantUtf8) cp.getConstant(cnat.getSignatureIndex())).getBytes(); }
/** @return name of referenced method/field. */ public String getName(final ConstantPoolGen cpg) { final ConstantPool cp = cpg.getConstantPool(); final ConstantNameAndType cnat = getNameAndType(cpg); return ((ConstantUtf8) cp.getConstant(cnat.getNameIndex())).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); } }
case Constants.CONSTANT_Class: i = ((ConstantClass)c).getNameIndex(); c = getConstant(i, Constants.CONSTANT_Utf8); str = Utility.compactClassName(((ConstantUtf8)c).getBytes(), false); break; c = getConstant(i, Constants.CONSTANT_Utf8); str = "\"" + escape(((ConstantUtf8)c).getBytes()) + "\""; break; case Constants.CONSTANT_Utf8: str = ((ConstantUtf8)c).getBytes(); break; case Constants.CONSTANT_Double: str = "" + ((ConstantDouble)c).getBytes(); break; case Constants.CONSTANT_Float: str = "" + ((ConstantFloat)c).getBytes(); break; str = (constantToString(((ConstantNameAndType)c).getNameIndex(), Constants.CONSTANT_Utf8) + " " + constantToString(((ConstantNameAndType)c).getSignatureIndex(), Constants.CONSTANT_Utf8)); break;
private String getMemberName(JavaClass c, String className, int memberNameIndex, int signatureIndex) { return className + "." + ((ConstantUtf8) c.getConstantPool().getConstant(memberNameIndex, Const.CONSTANT_Utf8)).getBytes() + " : " + ((ConstantUtf8) c.getConstantPool().getConstant(signatureIndex, Const.CONSTANT_Utf8)).getBytes(); }
public void visitField(Field obj){ if (jc.isClass()){ int maxone=0; if (obj.isPrivate()) maxone++; String sig = ((ConstantUtf8) (cp.getConstant(obj.getSignatureIndex()))).getBytes(); // Field or Method signature(=descriptor)
ConstantPool cp = clazz.getConstantPool(); ConstantClass cl = (ConstantClass)cp.getConstant(clazz.getClassNameIndex(), Constants.CONSTANT_Class); ConstantUtf8 name = (ConstantUtf8)cp.getConstant(cl.getNameIndex(), Constants.CONSTANT_Utf8); name.setBytes(class_name.replace('.', '/'));
public Object getValue(ConstantPoolGen cpg) { org.apache.bcel.classfile.Constant c = cpg.getConstantPool().getConstant(index); switch(c.getTag()) { case org.apache.bcel.Constants.CONSTANT_String: int i = ((org.apache.bcel.classfile.ConstantString)c).getStringIndex(); c = cpg.getConstantPool().getConstant(i); return ((org.apache.bcel.classfile.ConstantUtf8)c).getBytes(); case org.apache.bcel.Constants.CONSTANT_Float: return new Float(((org.apache.bcel.classfile.ConstantFloat)c).getBytes()); case org.apache.bcel.Constants.CONSTANT_Integer: return new Integer(((org.apache.bcel.classfile.ConstantInteger)c).getBytes()); default: // Never reached throw new RuntimeException("Unknown or invalid constant type at " + index); } }
public final String getNameString() { // ConstantString cu8 = (ConstantString)cpool.getConstant(nameIdx); return ((ConstantUtf8) cpool.getConstant(nameIdx)).getBytes(); }
ConstantNameAndType nameAndType = (ConstantNameAndType) cp.getConstant(id.getNameAndTypeIndex()); ConstantUtf8 typeConstant = (ConstantUtf8) cp.getConstant(nameAndType.getSignatureIndex()); curCalledMethod = new FQMethod(getClassName(), "lambda$" + id.getBootstrapMethodAttrIndex(), typeConstant.getBytes()); break;