在我們使用codeql
進行**審計之前,不妨先學習一些ql
的基礎語法,磨刀不誤砍柴工。
在這個教程中我們作為乙個偵探,為了解決遇到的問題使用ql
進行相應的調查
在這個ql偵探謎題中,你將會學會如何使用遞迴來編寫更複雜的查詢
害,在經歷了一系列事件之後,村子裡終於不再有犯罪--我們也終於可以離開村子回家了。
但我們在村子裡的最後一晚,老國王--偉大的巴西爾國王--在睡夢中死去,到處都是混亂!
國王終生未婚,也沒有孩子,所以沒人知道誰應該繼承國王的城堡和財產。隨即,許多村民聲稱他們是國王的後裔,他們是真正的繼承人,人們爭論和戰鬥,似乎這樣的情況沒有解決辦法。
最終我們決定留在村子裡解決爭論並找到真正的王位繼承人。
你想知道村里是否有人真的與國王有關係,雖然看起來這是一項很艱鉅的任務,但我們現在已經很了解村民了,而且我們擁有乙個村里所有父母和他們孩子的名單,所以我們自信地開始工作。
要了解有關國王及其家人的更多資訊,我們可以進入城堡並找到一些古老的家譜,另外我們將這些關係包含在ql資料庫中,以檢視國王家族中是否還有人活在世上。
以下謂詞有助於我們訪問資料:
例如,我們可以列出所有的孩子以及他們的父母
import tutorial
from person p
select parentof(p) + " is a parent of "+p
手動搜尋的資訊太多了,所以我們還需要進一步優化查詢來幫助我們找到國王的繼承人。
我們知道國王自己沒有孩子,但也許他有兄弟姐妹,編寫ql查詢
國王確實有兄弟姐妹!但是我們需要檢查他們是否還活著...這時我們需要用到另外乙個謂詞isdeceased()
使用該謂詞優化我們的查詢,檢視國王的任何兄弟姐妹是否還活著
不幸的是,巴西爾國王的兄弟姐妹比他的壽命更短暫。是時候進一步調查了,childof()
定義乙個返回該人孩子的謂詞,該謂詞可能對我們有所幫助。為此,我們可以在原有的查詢中使用childof()
。
person childof(person p)
將其用於我們的查詢中
import tutorial
person childof(person p)
from person p
where parentof(p)=parentof("king basil") and
not p="king basil"
select childof(p)
沒有任何的結果,因此國王的兄弟姐妹們也沒有子嗣,但或許巴西爾國王有乙個堂兄在世?或者兩個堂兄,或者...
情況變得越來越複雜,理想情況下,我們希望能定義乙個謂詞relativeof(person p
來列出所有的親戚
我們怎麼樣才能做到這一點?
我們可以引入謂詞ancestorof(person p)
來列出某人的所有祖先,或者這個祖先的父母,或者祖先的父母的父母...不幸的是,這導致了無窮無盡的父母名單,而我們不知道什麼時候才能結束,我們無法編寫無限的ql查詢,因此必須要有更簡單的方法。
啊哈,通過思考你有了乙個好點子,對於每乙個祖先,他要麼是當前查詢的人的父母,要麼是已經知道是祖先的人的父母,將其轉換為ql為
person ancestorof(person p)
如**所示,我們使用遞迴完成了這個查詢。這種遞迴,其中多次應用相同的操作(即parentof()
),這在ql中非常常見,被稱為操作的傳遞閉包,有兩個特殊符號+
和*
在使用傳遞閉包時非常有用。
嘗試使用這個新符號來定義乙個謂詞relativeof()
,並用它來列出國王的所有在世親屬
person relativeof(person p)
新增上還活在世上的限制之後
成功找到了兩名國王的親戚
在下一次村民會議上,我們宣布有兩個在世的國王親戚。
王位繼承者是國王在世的最親近的親屬,任何有犯罪記錄的人都不會被考慮。如果有多個候選人,年齡最大的就是繼承人。作為我們的最後乙個挑戰,定義乙個謂詞
hascriminalrecord
,以便在我們之前揭露的任何犯罪分子中成立(即前面的找到小偷和抓住縱火犯的教程中的罪犯)
import tutorial
person relativeof(person p)
predicate hascriminalrecord(person p)
from person p
where p=relativeof("king basil") and
not p.isdeceased() and
not hascriminalrecord(p)
select p
好的,clara
!他就是最後的王位合法繼承人!
恭喜!我們已經找到了王位繼承人並回覆了村莊的和平。但是,我們暫時不必離開村民,我們還可以通過編寫ql查詢為村民回答一些關於村莊憲法的問題:
到這裡ql
的語法我們就學習完畢了,雖然原鏈結後面還有乙個過河
問題,但我不認為這與ql
語法有太大的關聯,該問題更偏向於演算法吧,如果後面做leetcode
有機會遇到類似的問題,我會單獨出一篇文章來討論它
學完ql
語法之後,我們就可以開始準備實戰的工作了,後面的博文中會先從比較簡單的小例子開始由淺入深逐步介紹codeql
這款工具
P4合法C識別符號
給定乙個不包含空白符的字串,請判斷是否是c語言合法的識別符號號 注 題目保證這些字串一定不是c語言的保留字 c語言識別符號要求 1.非保留字 2.只包含字母 數字及下劃線 3.不以數字開頭。輸入格式 一行,包含乙個字串,字串中不包含任何空白字元,且長度不大於20。輸出格式 一行,如果它是c語言的合法...
C 反射教程(4)
展開 c using system 匯入相應的命名空間 using system.reflection using system.io class 宣告assembly型別物件am assembly am try 捕獲檔案未找到異常 catch filenotfoundexception e e.m...
HGE教程翻譯(4)
渲染紋理 首先我們宣告渲染物件的控制代碼和配合使用的精靈。hgesprite tar htarget target gfxrestorefunc 函式。bool gfxrestorefunc 在renderfunc中我們首先渲染所有的素材到紋理,在 gfx beginscene 中詳細指定渲染物件。...