Search in sources :

Example 16 with Constant

use of org.apache.bcel.classfile.Constant in project jop by jop-devel.

the class ClassInfo method setConstantInfo.

/**
 * Replace a constant with a new constant value in the constant pool.
 * Be aware that this does not check for duplicate entries, and may create additional
 * new entries in the constant pool.
 *
 * @see #addConstantInfo(ConstantInfo)
 * @param i the index of the constant to replace.
 * @param constant the new value.
 */
public void setConstantInfo(int i, ConstantInfo constant) {
    Constant c = constant.createConstant(cpg);
    cpg.setConstant(i, c);
}
Also used : Constant(org.apache.bcel.classfile.Constant)

Example 17 with Constant

use of org.apache.bcel.classfile.Constant in project jop by jop-devel.

the class FindUsedConstants method find.

private void find(Method method) {
    MethodGen mg = new MethodGen(method, clazz.getClassName(), cpool);
    InstructionList il = mg.getInstructionList();
    InstructionFinder f = new InstructionFinder(il);
    // find instructions that access the constant pool
    // collect all indices to constants in ClassInfo
    String cpInstr = "CPInstruction";
    for (Iterator it = f.search(cpInstr); it.hasNext(); ) {
        InstructionHandle[] match = (InstructionHandle[]) it.next();
        InstructionHandle first = match[0];
        CPInstruction ii = (CPInstruction) first.getInstruction();
        int idx = ii.getIndex();
        Constant co = cpool.getConstant(idx);
        int len = 1;
        switch(co.getTag()) {
            case Constants.CONSTANT_Long:
            case Constants.CONSTANT_Double:
                len = 2;
                break;
        }
        // we don't need the field references in the cpool anymore
        if (co.getTag() != Constants.CONSTANT_Fieldref) {
            getCli().addUsedConst(idx, len);
        }
    // also modify the index!
    // Constant cnst = cpool.getConstant(ii.getIndex());
    // int newIndex = addConstant(cnst);
    // System.out.println(ii+" -> "+newIndex);
    // ii.setIndex(newIndex);
    }
    il.dispose();
    CodeExceptionGen[] et = mg.getExceptionHandlers();
    for (int i = 0; i < et.length; i++) {
        ObjectType ctype = et[i].getCatchType();
        if (ctype != null) {
            getCli().addUsedConst(cpool.lookupClass(ctype.getClassName()), 1);
        }
    }
}
Also used : InstructionList(org.apache.bcel.generic.InstructionList) Constant(org.apache.bcel.classfile.Constant) InstructionFinder(org.apache.bcel.util.InstructionFinder) MethodGen(org.apache.bcel.generic.MethodGen) InstructionHandle(org.apache.bcel.generic.InstructionHandle) CPInstruction(org.apache.bcel.generic.CPInstruction) ObjectType(org.apache.bcel.generic.ObjectType) Iterator(java.util.Iterator) CodeExceptionGen(org.apache.bcel.generic.CodeExceptionGen)

Example 18 with Constant

use of org.apache.bcel.classfile.Constant in project fb-contrib by mebigfatguy.

the class SloppyClassReflection method sawOpcode.

/**
 * overrides the visitor to find class loading that is non obfuscation proof
 *
 * @param seen
 *            the opcode that is being visited
 */
@Override
public void sawOpcode(int seen) {
    switch(state) {
        case COLLECT:
            if ((seen == INVOKESTATIC) || (seen == INVOKEVIRTUAL) || (seen == INVOKEINTERFACE) || (seen == INVOKESPECIAL)) {
                refClasses.add(getClassConstantOperand());
                String signature = getSigConstantOperand();
                Type[] argTypes = Type.getArgumentTypes(signature);
                for (Type t : argTypes) {
                    addType(t);
                }
                Type resultType = Type.getReturnType(signature);
                addType(resultType);
            }
            break;
        case SEEN_NOTHING:
            if ((seen == LDC) || (seen == LDC_W)) {
                Constant c = getConstantRefOperand();
                if (c instanceof ConstantString) {
                    clsName = ((ConstantString) c).getBytes(getConstantPool());
                    state = State.SEEN_LDC;
                }
            }
            break;
        case SEEN_LDC:
            if ((seen == INVOKESTATIC) && "forName".equals(getNameConstantOperand()) && "java/lang/Class".equals(getClassConstantOperand()) && refClasses.contains(clsName)) {
                bugReporter.reportBug(new BugInstance(this, BugType.SCR_SLOPPY_CLASS_REFLECTION.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
            }
            state = State.SEEN_NOTHING;
            break;
    }
}
Also used : BugType(com.mebigfatguy.fbcontrib.utils.BugType) Type(org.apache.bcel.generic.Type) ConstantString(org.apache.bcel.classfile.ConstantString) Constant(org.apache.bcel.classfile.Constant) BugInstance(edu.umd.cs.findbugs.BugInstance) ConstantString(org.apache.bcel.classfile.ConstantString)

Example 19 with Constant

use of org.apache.bcel.classfile.Constant in project fb-contrib by mebigfatguy.

the class ContainsBasedConditional method sawOpcode.

@edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "SF_SWITCH_FALLTHROUGH", justification = "This fall-through is deliberate and documented")
@Override
public void sawOpcode(int seen) {
    try {
        stack.precomputation(this);
        int pc = getPC();
        if ((seen == Const.LOOKUPSWITCH) || (seen == Const.TABLESWITCH)) {
            switchLocs.set(pc);
            for (int offset : getSwitchOffsets()) {
                switchLocs.set(pc + offset);
            }
            switchLocs.set(pc + getDefaultSwitchOffset());
        }
        if (switchLocs.get(pc)) {
            state = State.SAW_NOTHING;
            switchLocs.clear(pc);
        }
        switch(state) {
            case SAW_NOTHING:
                conditionCount = 0;
            // $FALL-THROUGH$
            case SAW_PATTERN:
                if (isLoad(seen)) {
                    if (conditionCount > 0) {
                        if (loadType == seen) {
                            state = State.SAW_LOAD;
                        } else {
                            state = State.SAW_NOTHING;
                        }
                    } else {
                        loadType = seen;
                        bugPC = pc;
                        state = State.SAW_LOAD;
                    }
                } else {
                    if (conditionCount >= LOW_CONDITIONAL_COUNT) {
                        bugReporter.reportBug(new BugInstance(this, BugType.CBC_CONTAINS_BASED_CONDITIONAL.name(), priority(conditionCount)).addClass(this).addMethod(this).addSourceLine(this, bugPC));
                    }
                }
                break;
            case SAW_LOAD:
                if ((seen == Const.LDC) || (seen == Const.LDC_W)) {
                    Constant c = getConstantRefOperand();
                    String currConstType = null;
                    if (c instanceof ConstantString) {
                        currConstType = Values.SLASHED_JAVA_LANG_STRING;
                    } else if (c instanceof ConstantClass) {
                        currConstType = Values.SLASHED_JAVA_LANG_CLASS;
                    }
                    if (conditionCount > 0) {
                        if ((constType != null) && constType.equals(currConstType)) {
                            state = State.SAW_CONST;
                        } else {
                            state = State.SAW_NOTHING;
                        }
                    } else if (currConstType != null) {
                        state = State.SAW_CONST;
                        constType = currConstType;
                    } else {
                        state = State.SAW_NOTHING;
                    }
                } else if (seen == Const.GETSTATIC) {
                    state = State.SAW_CONST;
                } else if ((seen >= Const.ICONST_M1) && (seen <= Const.ICONST_5)) {
                    state = State.SAW_CONST;
                } else if ((seen >= Const.LCONST_0) && (seen <= Const.LCONST_1)) {
                    state = State.SAW_CONST;
                } else {
                    state = State.SAW_NOTHING;
                }
                break;
            case SAW_CONST:
                if ((seen == Const.INVOKEVIRTUAL) && "equals".equals(getNameConstantOperand()) && SignatureBuilder.SIG_OBJECT_TO_BOOLEAN.equals(getSigConstantOperand())) {
                    state = State.SAW_EQUALS;
                } else if (seen == Const.IF_ICMPEQ) {
                    conditionCount++;
                    state = State.SAW_PATTERN;
                } else if (seen == Const.IF_ICMPNE) {
                    conditionCount++;
                    if (conditionCount >= LOW_CONDITIONAL_COUNT) {
                        bugReporter.reportBug(new BugInstance(this, BugType.CBC_CONTAINS_BASED_CONDITIONAL.name(), priority(conditionCount)).addClass(this).addMethod(this).addSourceLine(this, bugPC));
                    }
                    state = State.SAW_NOTHING;
                } else {
                    state = State.SAW_NOTHING;
                }
                break;
            case SAW_EQUALS:
                if (seen == Const.IFNE) {
                    conditionCount++;
                    state = State.SAW_PATTERN;
                } else if (seen == Const.IFEQ) {
                    conditionCount++;
                    if (conditionCount >= LOW_CONDITIONAL_COUNT) {
                        bugReporter.reportBug(new BugInstance(this, BugType.CBC_CONTAINS_BASED_CONDITIONAL.name(), priority(conditionCount)).addClass(this).addMethod(this).addSourceLine(this, bugPC));
                    }
                    state = State.SAW_NOTHING;
                } else {
                    state = State.SAW_NOTHING;
                }
                break;
            default:
                // this indicates incompatible code change
                throw new AssertionError("Unhandled state: " + state);
        }
    } finally {
        stack.sawOpcode(this, seen);
    }
}
Also used : ConstantString(org.apache.bcel.classfile.ConstantString) Constant(org.apache.bcel.classfile.Constant) BugInstance(edu.umd.cs.findbugs.BugInstance) ConstantString(org.apache.bcel.classfile.ConstantString) ConstantClass(org.apache.bcel.classfile.ConstantClass)

Example 20 with Constant

use of org.apache.bcel.classfile.Constant in project fb-contrib by mebigfatguy.

the class LoggerOddities method sawOpcode.

/**
 * implements the visitor to look for calls to Logger.getLogger with the wrong class name
 *
 * @param seen
 *            the opcode of the currently parsed instruction
 */
@Override
@SuppressWarnings("unchecked")
public void sawOpcode(int seen) {
    String ldcClassName = null;
    String seenMethodName = null;
    boolean seenToString = false;
    boolean seenFormatterLogger = false;
    int exMessageReg = -1;
    Integer arraySize = null;
    boolean simpleFormat = false;
    try {
        stack.precomputation(this);
        if ((seen == Const.LDC) || (seen == Const.LDC_W)) {
            Constant c = getConstantRefOperand();
            if (c instanceof ConstantClass) {
                ConstantPool pool = getConstantPool();
                ldcClassName = ((ConstantUtf8) pool.getConstant(((ConstantClass) c).getNameIndex())).getBytes();
            }
        } else if (seen == Const.INVOKESTATIC) {
            lookForSuspectClasses();
            String clsName = getClassConstantOperand();
            String methodName = getNameConstantOperand();
            if (Values.SLASHED_JAVA_LANG_STRING.equals(clsName) && "format".equals(methodName) && (stack.getStackDepth() >= 2)) {
                String format = (String) stack.getStackItem(1).getConstant();
                if (format != null) {
                    Matcher m = NON_SIMPLE_FORMAT.matcher(format);
                    if (!m.matches()) {
                        simpleFormat = true;
                    }
                }
            } else if ("getFormatterLogger".equals(methodName) && LOG4J2_LOGMANAGER.equals(clsName)) {
                seenFormatterLogger = true;
            }
        } else if (((seen == Const.INVOKEVIRTUAL) || (seen == Const.INVOKEINTERFACE)) && (throwableClass != null)) {
            String mthName = getNameConstantOperand();
            if ("getName".equals(mthName)) {
                if (stack.getStackDepth() >= 1) {
                    // Foo.class.getName() is being called, so we pass the
                    // name of the class to the current top of the stack
                    // (the name of the class is currently on the top of the
                    // stack, but won't be on the stack at all next opcode)
                    Item stackItem = stack.getStackItem(0);
                    LOUserValue<String> uv = (LOUserValue<String>) stackItem.getUserValue();
                    if ((uv != null) && (uv.getType() == LOUserValue.LOType.CLASS_NAME)) {
                        ldcClassName = uv.getValue();
                    }
                }
            } else if ("getMessage".equals(mthName)) {
                String callingClsName = getClassConstantOperand();
                JavaClass cls = Repository.lookupClass(callingClsName);
                if (cls.instanceOf(throwableClass) && (stack.getStackDepth() > 0)) {
                    OpcodeStack.Item exItem = stack.getStackItem(0);
                    exMessageReg = exItem.getRegisterNumber();
                }
            } else if (LOGGER_METHODS.contains(mthName)) {
                checkForProblemsWithLoggerMethods();
            } else if (Values.TOSTRING.equals(mthName) && SignatureBuilder.SIG_VOID_TO_STRING.equals(getSigConstantOperand())) {
                String callingClsName = getClassConstantOperand();
                if (SignatureUtils.isPlainStringConvertableClass(callingClsName) && (stack.getStackDepth() > 0)) {
                    OpcodeStack.Item item = stack.getStackItem(0);
                    // if the stringbuilder was previously stored, don't report it
                    if (item.getRegisterNumber() < 0) {
                        seenMethodName = mthName;
                    }
                }
                if (seenMethodName == null) {
                    seenToString = true;
                }
            }
        } else if (seen == Const.INVOKESPECIAL) {
            checkForLoggerParam();
        } else if (seen == Const.ANEWARRAY) {
            if (stack.getStackDepth() > 0) {
                OpcodeStack.Item sizeItem = stack.getStackItem(0);
                Object con = sizeItem.getConstant();
                if (con instanceof Integer) {
                    arraySize = (Integer) con;
                }
            }
        } else if (seen == Const.AASTORE) {
            if (stack.getStackDepth() >= 3) {
                OpcodeStack.Item arrayItem = stack.getStackItem(2);
                LOUserValue<Integer> uv = (LOUserValue<Integer>) arrayItem.getUserValue();
                if ((uv != null) && (uv.getType() == LOUserValue.LOType.ARRAY_SIZE)) {
                    Integer size = uv.getValue();
                    if ((size != null) && (size.intValue() > 0) && hasExceptionOnStack()) {
                        arrayItem.setUserValue(new LOUserValue<>(LOUserValue.LOType.ARRAY_SIZE, Integer.valueOf(-size.intValue())));
                    }
                }
            }
        } else if (seen == PUTSTATIC) {
            OpcodeStack.Item itm = stack.getStackItem(0);
            if (isStaticInitializer && isNonPrivateLogField(getClassConstantOperand(), getNameConstantOperand(), getSigConstantOperand())) {
                XMethod m = itm.getReturnValueOf();
                if ((m != null) && isLoggerWithClassParm(m)) {
                    bugReporter.reportBug(new BugInstance(this, BugType.LO_NON_PRIVATE_STATIC_LOGGER.name(), NORMAL_PRIORITY).addClass(this).addMethod(this).addSourceLine(this));
                }
            }
            LOUserValue<Void> loggerUV = (LOUserValue<Void>) itm.getUserValue();
            if ((loggerUV != null) && (loggerUV.getType() == LOUserValue.LOType.FORMATTER_LOGGER)) {
                formatterLoggers.add(getNameConstantOperand());
            }
        } else if (seen == GETSTATIC) {
            if (formatterLoggers.contains(getNameConstantOperand())) {
                seenFormatterLogger = true;
            }
        } else if (OpcodeUtils.isAStore(seen) && (stack.getStackDepth() > 0)) {
            OpcodeStack.Item item = stack.getStackItem(0);
            LOUserValue<String> uv = (LOUserValue<String>) item.getUserValue();
            if (uv != null) {
                if (((uv.getType() == LOUserValue.LOType.METHOD_NAME) && Values.TOSTRING.equals(uv.getValue())) || (uv.getType() == LOUserValue.LOType.SIMPLE_FORMAT) || (uv.getType() == LOUserValue.LOType.TOSTRING)) {
                    item.setUserValue(new LOUserValue<>(LOUserValue.LOType.NULL, null));
                }
            }
        }
    } catch (ClassNotFoundException cnfe) {
        bugReporter.reportMissingClass(cnfe);
    } finally {
        TernaryPatcher.pre(stack, seen);
        stack.sawOpcode(this, seen);
        TernaryPatcher.post(stack, seen);
        if (stack.getStackDepth() > 0) {
            OpcodeStack.Item item = stack.getStackItem(0);
            if (ldcClassName != null) {
                item.setUserValue(new LOUserValue<>(LOUserValue.LOType.CLASS_NAME, ldcClassName));
            } else if (seenMethodName != null) {
                item.setUserValue(new LOUserValue<>(LOUserValue.LOType.METHOD_NAME, seenMethodName));
            } else if (exMessageReg >= 0) {
                item.setUserValue(new LOUserValue<>(LOUserValue.LOType.MESSAGE_REG, Integer.valueOf(exMessageReg)));
            } else if (arraySize != null) {
                item.setUserValue(new LOUserValue<>(LOUserValue.LOType.ARRAY_SIZE, arraySize));
            } else if (simpleFormat) {
                item.setUserValue(new LOUserValue<>(LOUserValue.LOType.SIMPLE_FORMAT, Boolean.TRUE));
            } else if (seenToString) {
                item.setUserValue(new LOUserValue<>(LOUserValue.LOType.TOSTRING, null));
            } else if (seenFormatterLogger) {
                item.setUserValue(new LOUserValue<>(LOUserValue.LOType.FORMATTER_LOGGER, null));
            }
        }
    }
}
Also used : Item(edu.umd.cs.findbugs.OpcodeStack.Item) OpcodeStack(edu.umd.cs.findbugs.OpcodeStack) Matcher(java.util.regex.Matcher) Constant(org.apache.bcel.classfile.Constant) BugInstance(edu.umd.cs.findbugs.BugInstance) ToString(com.mebigfatguy.fbcontrib.utils.ToString) Item(edu.umd.cs.findbugs.OpcodeStack.Item) JavaClass(org.apache.bcel.classfile.JavaClass) ConstantPool(org.apache.bcel.classfile.ConstantPool) XMethod(edu.umd.cs.findbugs.ba.XMethod) ConstantClass(org.apache.bcel.classfile.ConstantClass)

Aggregations

Constant (org.apache.bcel.classfile.Constant)21 ConstantPool (org.apache.bcel.classfile.ConstantPool)7 ConstantString (org.apache.bcel.classfile.ConstantString)7 ConstantClass (org.apache.bcel.classfile.ConstantClass)6 BugInstance (edu.umd.cs.findbugs.BugInstance)5 ToString (com.mebigfatguy.fbcontrib.utils.ToString)4 ConstantPoolGen (org.apache.bcel.generic.ConstantPoolGen)4 OpcodeStack (edu.umd.cs.findbugs.OpcodeStack)3 ArrayList (java.util.ArrayList)3 Iterator (java.util.Iterator)3 ConstantNameAndType (org.apache.bcel.classfile.ConstantNameAndType)3 ConstantUtf8 (org.apache.bcel.classfile.ConstantUtf8)3 Method (org.apache.bcel.classfile.Method)3 CPInstruction (org.apache.bcel.generic.CPInstruction)3 InstructionHandle (org.apache.bcel.generic.InstructionHandle)3 InstructionList (org.apache.bcel.generic.InstructionList)3 InstructionFinder (org.apache.bcel.util.InstructionFinder)3 HashSet (java.util.HashSet)2 Set (java.util.Set)2 Attribute (org.apache.bcel.classfile.Attribute)2