歡迎來到 黑吧安全網 聚焦網絡安全前沿資訊,精華內容,交流技術心得!

代碼分析平臺CodeQL學習手記(六)

來源:本站整理 作者:佚名 時間:2020-01-22 TAG: 我要投稿

在前面的文章中,我們通過一個抓小偷的例子,為大家展示了邏輯謂詞、連接詞和聚合操作的威力。在本文中,我們將通過一個抓縱火犯的例子來復習謂詞的知識,并進一步學習類的定義和用法,以及如何覆蓋父類的成員謂詞。
簡介
上一次,我們用QL破獲了王冠失竊案,之后我們便獲得了QL大偵探的美譽?墒,不久之后,村里又發生了一起案件:村北的莊稼地被人惡意縱火,導致地里的農作物顆粒無收,村民損失慘重。所以,我們奉命找出縱火犯。
現在,我們除了手頭上的村民信息之外,還掌握了一條重要線索:村南和村北的村民之間交惡已久,所以,縱火犯很可能就是住在村南的村民。
在破案過程中,我們將進一步介紹如何在QL代碼中定義和使用謂詞和類。有了它們,不僅可以讓我們編寫的查詢邏輯變得更加易于理解,同時,還有助于簡化我們的偵查工作。
縮小包圍圈
現在,懷疑對象已經被鎖定為一個特定的村民群體,即那些生活在村莊南部的村民。因此,我們可以定義一個新的謂詞southern,用于遴選住在村南的村民,這樣的話,就不必在所有查詢這些村民的代碼中加入GetLocation()=“south”這一條件了。謂詞southern的定義如下所示:
predicate southern(Person p) {
    p.getLocation() = "south"
}
使用謂詞southern(p)時,我們需要提供一個參數p,以便讓謂詞檢查p是否滿足條件p.getLocation() = "south",也就是住在村南。
好了,根據上面的例子,我們再次復習一下謂詞的定義和分類。我們知道,謂詞分為兩類:一類是帶有返回值的謂詞,另一類是沒有返回值的謂詞。在定義謂詞時,首先要注意的是,謂詞的名稱必須以小寫字母開頭。另外,上面的這個謂詞屬于沒有返回結果的謂詞,定義這種類型的謂詞時,需要使用關鍵字predicate;不過,當需要定義帶有返回結果的謂詞的時候,需要把這里的關鍵字predicate替換為返回結果的數據類型。這時,還需要引入了一個新的參數來保存返回結果——特殊變量result。例如,int getAge() {result = ...}便是定義了一個返回整型數據的謂詞。
現在,我們就可以利用上面定義的謂詞來找出所有住在村南的居民了,具體代碼如下所示:
/* 謂詞southern的定義如上所示 */
from Person p
where southern(p)
select p

運行結果如下所示:

如您所見,利用謂詞的好處是,不僅使得我們的代碼的邏輯更加清晰,同時,也能提高編寫代碼的效率。對于上面的查詢代碼,from子句表示要考察所有村民(Person p),然后,在where子句中加入了一個限制條件:住在村南的居民(southern(p))。
實際上,除了利用上面的查詢來找出考察對象之外,我們還可以自定義一個Southerner類,用它來找出我們的考察對象,也就是住在村南的居民,具體代碼如下所示:
class Southerner extends Person {
    Southerner() { southern(this) }
}
對于QL語言來說,可以用類來表示一個邏輯屬性:當一個值滿足該屬性時,它就是類的成員。這意味著一個值可以屬于多個類,這其實不難理解,舉例來說,3既屬于“整數”類,也屬于“奇數”類,同時屬于“質數”類,等等。
在上面的類的定義中,表達式southern(this)定義了這個類所表示的邏輯屬性,我們稱這個謂詞為這個類的特征謂詞。需要注意的是,這個表達式中使用了一個特殊變量this,就這里來耍,該變量表示一個Person類型的值,也就是一個村民;如果this滿足southern(this)這一限制條件,那么,this代表的村民就屬于Southerner類,也就是居住在村南的村民。
對于熟悉面向對象編程語言的讀者來說,會發現特征謂詞跟構造函數非常類似。不過,特征謂詞并非構造函數,實際上它是一個邏輯屬性,并且不創建任何對象。
在QL語言中,我們通常需要根據現有的類(超集)來定義新的類(子集)。 在我們的例子中,Southerner是村民中的一個特殊群體,所以,我們說Southerner(住在村南的村民)類繼承自Person(村民)類,換句話說,Southerner是Person的一個子集。
借助于這個類,在列出所有住在村南的居民的時候,相應的代碼會變得更加簡潔:
from Southerner s
select s
第一句是聲明變量,就是住在村南的村民,然后,沒有附加任何條件就直接列出這些變量了。完整的代碼如下所示:

運行結果如下所示:

通過上面的例子,您可能已經注意到,有些謂詞是跟在某些變量后面的,例如p.getAge();而有些則是以參數的形式傳遞變量,例如southern(p)。這是因為,getAge()是一個定義在類Person中的一個成員謂詞(類似于成員函數),也就是說,它是一個只能用于該類中的成員變量的謂詞。在定義類時,我們也可定義自己的成員謂詞,這一點將在下面看到。相反,謂詞southern是單獨定義的,不屬于任何類。實際上,我們還可以將多個成員謂詞串起來完成一系列的操作,例如,p. getage ().sqrt(),這里首先獲取村民p的年齡,然后計算年齡的平方根——用起來是不是特別方便!
出行管制
在這里,我們還要考慮另一個因素:發生王冠失竊案后,村子里實施了出行管制。案發之前,村民是可以在村子里自由走動的,因此,謂詞isAllowedIn(string region) 是適用于任何村民和任何區域的。舉例來說,下面的查詢代碼將會列出所有村民,因為他們都可以去村北:

[1] [2]  下一頁

【聲明】:黑吧安全網(http://www.zjtpzs.live)登載此文出于傳遞更多信息之目的,并不代表本站贊同其觀點和對其真實性負責,僅適于網絡安全技術愛好者學習研究使用,學習中請遵循國家相關法律法規。如有問題請聯系我們,聯系郵箱[email protected],我們會在最短的時間內進行處理。
  • 最新更新
    • 相關閱讀
      • 本類熱門
        • 最近下載
        神秘东方电子游艺 网上怎么赚钱的 日本女优性感翘臀诱惑写真 白小姐四肖必选一有 湖北快3跨度分布 pk10精准一期计 遇乐棋牌登录大厅 天津十一选五开奖结果今天 足球彩票比分直播360 浙江20选5中奖金额 微乐麻将下载 安装 广西十一选五加奖 广东36选7好彩一走势图 欢乐棋牌大厅下载 nba排行 上海十一选五前三组开奖 欧美av女星最漂亮排名