Phinehasz Zhi

超越你看到的

静态代码扫描工具PMD定制xml的规则(一)操作篇

0.前言
PMD作为开源的静态代码扫描工具有很强的扩展能力,可使用java或xpath定制rule.第一篇从操作上讲解如何定制一个用于扫描xml是否规范的规则.首先我们知道xml格式的文件在java工程里往往用于配置文件,像web的ssm框架里的applicationContext.xml或者是sqlMapConfig.xml等等.在安卓工程里同样会使用xml,本文主要以安卓的配置清单--AndroidManifest.xml做基础来讲解.
1.准备
知识准备:http://www.w3school.com.cn/xpath/ xpath语法学习
工程准备:
需要有PMD-bin工程,我选择5.7.0版本,目前最新是6.xx的.(新增了几个语法,对rule分类做了调整)
打开本地的 \pmd-bin-5.7.0\bin\designer.bat
-->选择左上角,language下的XML
讲解下PMD Rule Designer这个GUI的几个分类:
a)Source Code就是写我们要查的代码的地方,java代码必须具体到class(导包无所谓),不能只是method;xml代码必须有文档声明,每个元素必须正确结尾.
b)xpath query是写xpath做设计测试的地方,有三个xpath的语言版本可选择,2.0的xpath语法扩展了for,return,if,else等语法,在操作上有更多步数和设计余地.选择的语言版本稍后讲解.
c)AST Tree 就是抽象代码树,下方的栏目是封装的scope及提醒了你xpath能拿到的属性,另一个分页是DFA数据流,目前PMD支持的不太好.
d)右下角,则是告警的地方,显示几行几列,什么节点处.
另外需要PMD的master工程,将其导入到eclipse里.你可以只导入core和xml子工程.
2.分析设计
使用的代码示例如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="tk.jianmo.study" android:versionCode="2" android:versionName="2.0" > 
        <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > 
    <service android:name=".killpoccessserve"/> />
     <activity android:label="@string/app_name" android:name=".MainActivity"
    android:exported="false"  > 
    <intent-filter > 
        <action android:name="android.intent.action.MAIN" /> 
    </intent-filter> 
    </activity>
        </application>
</manifest>
使用xpath定制规则,我们的核心是写出xpath语句,而后续配置是很简单的.
需求:寻找不暴露的activity,也就是查找exported为false的activity标签.
这是非常简单的需求!你知道xpath语法后,你觉得可以这样找://activity[@android:exported = 'false'] 先找节点,然后看对应的属性是否为相应的值.其实这样就错了.为什么?我们首先第一步是要去分析PMD解析的AST,下图中发现,工具提供的activity这个节点,对应的attribute没有我们想要的,更不存在android:exported!所以肯定是失败.
其实这里是一个坑.在xpath语法中可以通过@属性来获得对应属性的情况,但是在PMD里的不行,原因是AST解析的不同.怎么办呢?笔者最终在stackoverFlow上找到一个方法.如下格式即可.
//activity[@*[name()=‘android:exported’ ]=‘false’] (版本xpath1.0 试过2.0不行)先拿activity,再@*从所有属性匹配,再匹配符合的值。这样我们就满足了需求.以下是designer细节:

所以我们要配置的xpath代码就是: //activity[@*[name()=‘android:exported’ ]=‘false’] 并且选择1.0的语言版本
3.配置执行
打开PMD工程,打开pmd-xml子工程如果是你最新版,会是如下,如果是5.几版本相应的xml规则在ruleSets里.

打开errorprone.xml文件(其他都还是空的),发现里面就是rule的配置方法.(细节不懂的可以去https://pmd.github.io/),具体rule节点一般如下:
   <rule name="规则名字"
          language="xml"
          since="5.0"
          message="规则信息"
          class="net.sourceforge.pmd.lang.rule.XPathRule"  必须配置,意味着该规则交给XPathRule类做分析
          externalInfoUrl="规则解释链接,一般不需要,如果公司有对应安全库网站,可以配置相应url">
        <description>   这里是规则的描述
        </description>
        <priority>3</priority>
        <properties>
      <property name="version" value="1.0" /> 添加这行,可以配置xpath对应语言版本
<property name="xpath"> <value> <![CDATA[ 规则代码例如: //activity[@*[name()='android:exported']='false'] ]]> </value> </property> </properties> <example> <![CDATA[ 规则场景代码 ]]> </example> </rule>

复制一份xml,到该resources文件下,然后按上文配置即可. 具体的程序启动就不细讲了~~官网都讲了.

posted @ 2018-05-19 16:03  phinehasz  阅读(3373)  评论(0编辑  收藏  举报