3

Q (tldr;):如何使用JavaScannerinandroid-lint检查以特定字符串作为参数的特定函数调用是否被 try/catch 块包围。

详细信息:我已经完成了官网的android-lint教程,并浏览了现有的lint-checks. 但是,我似乎无法掌握这种基于 AST 的 JavaScanner 解析的工作流程。我想要实现的是捕获一个设置特定属性的函数并用 try/catch 块包围它。例如:

MyPropertySettings.set("SOME_PROPERTY", "SOME_VAL"); 

不应触发 lint 规则,但:

MyPropertySettings.set("SOME_SENSITIVE_PROPERTY", "SOME_VAL"); 

应该是因为它没有被带有SetPropertyException. 我不想将 try/catch 引入函数本身,因为它只在极少数情况下抛出异常(并且函数的内部结构基于一些反射 mojo)。

对于这个问题,即使是工作流程/提示也可以。如果我能掌握最初的几个步骤,我可能会更好地掌握它。

更新:

经过更多研究,我发现我需要设置set上面的函数,getApplicableMethodNames()然后以某种方式读取该函数的属性以确定检查是否适用。那部分应该很容易。

围绕 try/catch 会更加困难,我认为我需要做一些“流分析”。现在问题怎么样了。

4

2 回答 2

2

好吧,除了getApplicableMethodNames()方法之外,您还需要覆盖该visitMethod()函数。你会得到MethodInvocationNode. 只需使用该node.astArguments()函数获取调用中传递的参数。这将返回一个参数列表,您可以使用StrictListAccessor. 检查传递的参数,如果它符合您的标准,运行一个循环并继续计算调用节点的父节点,直到try找到一个节点。如果它是一个 try 节点,那么您可以使用 node.astCatches(). 扫描列表并找到适当的例外。如果没有找到,然后报告。

于 2014-02-13T09:42:08.310 回答
1

你可以这样编码:检查它是否被 try/catch 包围:

@Override
public void visitMethod(JavaContext context, AstVisitor visitor, MethodInvocation node) {
    // check the specified class that invoke the method
    JavaParser.ResolvedMethod method = (JavaParser.ResolvedMethod) context.resolve(node);
    JavaParser.ResolvedClass clzz = method.getContainingClass();
    boolean isSubClass = false;
    // sSupportSuperType = {"class name"};
    for (int i = 0; i < sSupportSuperType.length; i++) {
        if (clzz.isSubclassOf(sSupportSuperType[i], false)) {
            isSubClass = true;
            break;
        }
    }
    if (!isSubClass) return;
    // check if surrounded by try/catch
    Node parent = node;
    while (true) {
        Try tryCatch = context.getParentOfType(parent, Try.class);
        if (tryCatch == null) {
            break;
        } else {
            for (Catch aCatch : tryCatch.astCatches()) {
                TypeReference catchType = aCatch.astExceptionDeclaration().astTypeReference();
            }
            parent = tryCatch;
        }
    }
    // get the arguments string
    String str = node.astArguments().first().toString();
    if (!str.startsWith("\"SOME_PROPERTY\"")) {
        context.report(ISSUE, node, context.getLocation(node), "message");
    }

}

在此之前,您必须通过覆盖定义特定方法:

@Override
public List<String> getApplicableMethodNames() {
    return Collections.singletonList("set");
}
于 2015-12-08T04:50:05.003 回答