0.前言
PMD作為開源的靜態代碼掃描工具有很強的擴展能力,可使用java或xpath定制rule.第一篇從操作上講解如何定制一個用於掃描xml是否規范的規則.首先我們知道xml格式的文件在java工程里往往用於配置文件,像web的ssm框架里的applicationContext.xml或者是sqlMapConfig.xml等等.在安卓工程里同樣會使用xml,本文主要以安卓的配置清單--AndroidManifest.xml做基礎來講解.
1.准備
工程准備:
需要有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細節:

3.配置執行
打開PMD工程,打開pmd-xml子工程如果是你最新版,會是如下,如果是5.幾版本相應的xml規則在ruleSets里.

<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文件下,然后按上文配置即可. 具體的程序啟動就不細講了~~官網都講了.
