⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 constructorcallsoverridablemethodrule.java

📁 检查Java程序漏洞
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
     *     * @todo investigate limiting the number of passes through config.     */    private boolean evaluateDangerOfMethods(Map classMethodMap) {        //check each method if it calls overridable method        boolean found = false;        for (Iterator methodsIter = classMethodMap.keySet().iterator(); methodsIter.hasNext();) {            MethodHolder h = (MethodHolder) methodsIter.next();            List calledMeths = (List) classMethodMap.get(h);            for (Iterator calledMethsIter = calledMeths.iterator(); calledMethsIter.hasNext() && (h.isDangerous() == false);) {                //if this method matches one of our dangerous methods, mark it dangerous                MethodInvocation meth = (MethodInvocation) calledMethsIter.next();                //System.out.println("Called meth is " + meth);                for (Iterator innerMethsIter = classMethodMap.keySet().iterator(); innerMethsIter.hasNext();) { //need to skip self here h == h3                    MethodHolder h3 = (MethodHolder) innerMethsIter.next();                    if (h3.isDangerous()) {                        String matchMethodName = h3.getASTMethodDeclarator().getImage();                        int matchMethodParamCount = h3.getASTMethodDeclarator().getParameterCount();                        //System.out.println("matchint " + matchMethodName + " to " + methName);                        if (matchMethodName.equals(meth.getName()) && (matchMethodParamCount == meth.getArgumentCount())) {                            h.setDangerous(true);                            found = true;                            break;                        }                    }                }            }        }        return found;    }    /**     * marks constructors dangerous if they call any dangerous methods     * Requires only a single pass as methods are already marked     * @todo optimize by having methods already evaluated somehow!?     */    private void evaluateDangerOfConstructors1(Map classConstructorMap, Set evaluatedMethods) {        //check each constructor in the class        for (Iterator constIter = classConstructorMap.keySet().iterator(); constIter.hasNext();) {            ConstructorHolder ch = (ConstructorHolder) constIter.next();            if (!ch.isDangerous()) {//if its not dangerous then evaluate if it should be                //if it calls dangerous method mark it as dangerous                List calledMeths = (List) classConstructorMap.get(ch);                //check each method it calls                for (Iterator calledMethsIter = calledMeths.iterator(); calledMethsIter.hasNext() && !ch.isDangerous();) {//but thee are diff objects which represent same thing but were never evaluated, they need reevaluation                    MethodInvocation meth = (MethodInvocation) calledMethsIter.next();//CCE                    String methName = meth.getName();                    int methArgCount = meth.getArgumentCount();                    //check each of the already evaluated methods: need to optimize this out                    for (Iterator evaldMethsIter = evaluatedMethods.iterator(); evaldMethsIter.hasNext();) {                        MethodHolder h = (MethodHolder) evaldMethsIter.next();                        if (h.isDangerous()) {                            String matchName = h.getASTMethodDeclarator().getImage();                            int matchParamCount = h.getASTMethodDeclarator().getParameterCount();                            if (methName.equals(matchName) && (methArgCount == matchParamCount)) {                                ch.setDangerous(true);                                //System.out.println("evaluateDangerOfConstructors1 setting dangerous constructor with " + ch.getASTConstructorDeclaration().getParameterCount() + " params");                                break;                            }                        }                    }                }            }        }    }    /**     * Constructor map should contain a key for each private constructor, and     * maps to a List which contains all called constructors of that key.     * marks dangerous if call dangerous private constructor     * we ignore all non-private constructors here.  That is, the map passed in     * should not contain any non-private constructors.     * we return boolean in order to limit the number of passes through this method     * but it seems as if we can forgo that and just process it till its done.     */    private boolean evaluateDangerOfConstructors2(Map classConstructorMap) {        boolean found = false;//triggers on danger state change        //check each constructor in the class        for (Iterator constIter = classConstructorMap.keySet().iterator(); constIter.hasNext();) {            ConstructorHolder ch = (ConstructorHolder) constIter.next();            ConstructorInvocation calledC = ch.getCalledConstructor();            if (calledC == null || ch.isDangerous()) {                continue;            }            //if its not dangerous then evaluate if it should be            //if it calls dangerous constructor mark it as dangerous            int cCount = calledC.getArgumentCount();            for (Iterator innerConstIter = classConstructorMap.keySet().iterator(); innerConstIter.hasNext() && !ch.isDangerous();) { //forget skipping self because that introduces another check for each, but only 1 hit                ConstructorHolder h2 = (ConstructorHolder) innerConstIter.next();                if (h2.isDangerous()) {                    int matchConstArgCount = h2.getASTConstructorDeclaration().getParameterCount();                    if (matchConstArgCount == cCount) {                        ch.setDangerous(true);                        found = true;                        //System.out.println("evaluateDangerOfConstructors2 setting dangerous constructor with " + ch.getASTConstructorDeclaration().getParameterCount() + " params");                    }                }            }        }        return found;    }    ////////////////////////////////////////////////////////////////////////////////    ////////////////////////////////////////////////////////////////////////////////    ////////////////////////////////////////////////////////////////////////////////    //The Visited Methods    /**     * Work on each file independently.     */    public Object visit(ASTCompilationUnit node, Object data) {        clearEvalPackages();        //		try {        return super.visit(node, data);        //		}        //		catch(Exception e){        //			e.printStackTrace();        //		}    }    //for testing only    //	public Object visit(ASTPackageDeclaration node, Object data){    //		System.out.println("package= " + ((ASTName)node.jjtGetChild(0)).getImage());    //		return super.visit(node,data);    //	}    /**     * This check must be evaluated independelty for each class.  Inner classses     * get their own EvalPackage in order to perform independent evaluation.     */    public Object visit(ASTClassDeclaration node, Object data) {        return visitClassDec(node, data);    }    public Object visit(ASTNestedClassDeclaration node, Object data) {        return visitClassDec(node, data);    }    public Object visit(ASTInterfaceDeclaration node, Object data) {        putEvalPackage(nullEvalPackage);        Object o = super.visit(node, data);//interface may have inner classes, possible? if not just skip whole interface        removeCurrentEvalPackage();        return o;    }    public Object visit(ASTNestedInterfaceDeclaration node, Object data) {        putEvalPackage(nullEvalPackage);        Object o = super.visit(node, data);//interface may have inner classes, possible? if not just skip whole interface        removeCurrentEvalPackage();        return o;    }    /**     * Non-private constructor's methods are added to a list for later safety     * evaluation.  Non-private constructor's calls on private constructors     * are added to a list for later safety evaluation.  Private constructors     * are added to a list so their safety to be called can be later evaluated.     *     * Note: We are not checking private constructor's calls on non-private     * constructors because all non-private constructors will be evaluated for     * safety anyway.  This means we wont flag a private constructor as unsafe     * just because it calls an unsafe public constructor.  We want to show only     * 1 instance of an error, and this would be 2 instances of the same error.     *     * @todo eliminate the redundency     */    public Object visit(ASTConstructorDeclaration node, Object data) {        if (!(getCurrentEvalPackage() instanceof NullEvalPackage)) {//only evaluate if we have an eval package for this class            List calledMethodsOfConstructor = new ArrayList();            ConstructorHolder ch = new ConstructorHolder(node);            addCalledMethodsOfNode(node, calledMethodsOfConstructor, getCurrentEvalPackage().m_ClassName);            if (!node.isPrivate()) {                //these calledMethods are what we will evaluate for being called badly                getCurrentEvalPackage().calledMethods.addAll(calledMethodsOfConstructor);                //these called private constructors are what we will evaluate for being called badly                //we add all constructors invoked by non-private constructors                //but we are only interested in the private ones.  We just can't tell the difference here                ASTExplicitConstructorInvocation eci = ch.getASTExplicitConstructorInvocation();                if (eci != null && eci.isThis()) {                    getCurrentEvalPackage().calledConstructors.add(ch.getCalledConstructor());                }            } else {                //add all private constructors to list for later evaluation on if they are safe to call from another constructor                //store this constructorHolder for later evaluation                getCurrentEvalPackage().allPrivateConstructorsOfClass.put(ch, calledMethodsOfConstructor);            }        }        return super.visit(node, data);    }    /**     * Create a MethodHolder to hold the method.     * Store the MethodHolder in the Map as the key     * Store each method called by the current method as a List in the Map as the Object     */    public Object visit(ASTMethodDeclarator node, Object data) {        if (!(getCurrentEvalPackage() instanceof NullEvalPackage)) {//only evaluate if we have an eval package for this class            AccessNode parent = (AccessNode) node.jjtGetParent();            MethodHolder h = new MethodHolder(node);            if (!parent.isPrivate() && !parent.isStatic() && !parent.isFinal()) {                h.setDangerous(true);//this method is overridable            }            List l = new ArrayList();            addCalledMethodsOfNode((SimpleNode) parent, l, getCurrentEvalPackage().m_ClassName);            getCurrentEvalPackage().allMethodsOfClass.put(h, l);        }        return super.visit(node, data);    }    ////////////////////////////////////////////////////////////////////////////////    ////////////////////////////////////////////////////////////////////////////////    ////////////////////////////////////////////////////////////////////////////////    //Helper methods to process visits    private static void addCalledMethodsOfNode(AccessNode node, List calledMethods, String className) {        List expressions = new ArrayList();        node.findChildrenOfType(ASTPrimaryExpression.class, expressions, false);        addCalledMethodsOfNodeImpl(expressions, calledMethods, className);    }    /**     * Adds all methods called on this instance from within this Node.     */    private static void addCalledMethodsOfNode(SimpleNode node, List calledMethods, String className) {        List expressions = new ArrayList();        node.findChildrenOfType(ASTPrimaryExpression.class, expressions);        addCalledMethodsOfNodeImpl(expressions, calledMethods, className);    }    private static void addCalledMethodsOfNodeImpl(List expressions, List calledMethods, String className) {        for (Iterator it = expressions.iterator(); it.hasNext();) {            ASTPrimaryExpression ape = (ASTPrimaryExpression) it.next();            MethodInvocation meth = findMethod(ape, className);            if (meth != null) {                //System.out.println("Adding call " + methName);                calledMethods.add(meth);            }        }    }    /**     * @todo Need a better way to match the class and package name to the actual     *       method being called.     * @return A method call on the class passed in, or null if no method call     *         is found.     */    private static MethodInvocation findMethod(ASTPrimaryExpression node, String className) {        if (node.jjtGetNumChildren() > 0	    && node.jjtGetChild(0).jjtGetNumChildren() > 0	    && node.jjtGetChild(0).jjtGetChild(0) instanceof ASTLiteral) {            return null;        }        MethodInvocation meth = MethodInvocation.getMethod(node);        boolean found = false;        //		if(meth != null){        //			meth.show();        //		}        if (meth != null) {            //if it's a call on a variable, or on its superclass ignore it.            if ((meth.getReferenceNames().size() == 0) && !meth.isSuper()) {                //if this list does not contain our class name, then its not referencing our class                //this is a cheezy test... but it errs on the side of less false hits.                List packClass = meth.getQualifierNames();                if (packClass.size() > 0) {                    for (Iterator it = packClass.iterator(); it.hasNext();) {                        String name = (String) it.next();                        if (name.equals(className)) {                            found = true;                            break;                        }                    }                } else {                    found = true;                }            }        }        if (found) {            return meth;        } else {            return null;        }    }    /**     *  ASTPrimaryPrefix has name in child node of ASTName     */    private static String getNameFromPrefix(ASTPrimaryPrefix node) {        String name = null;        //should only be 1 child, if more I need more knowledge        if (node.jjtGetNumChildren() == 1) { //safety check            Node nnode = node.jjtGetChild(0);            if (nnode instanceof ASTName) { //just as easy as null check and it should be an ASTName anyway                name = ((ASTName) nnode).getImage();            }        }        return name;    }    /**     * ASTPrimarySuffix has name in itself     */    private static String getNameFromSuffix(ASTPrimarySuffix node) {        return node.getImage();    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -