Person getAChildOf(Person p) {
p = getAParentOf(result) # result的parent是p, 即p的child是result
}
多返回值谓词
string getFunc(string action) {
action = "rce" and result = "popen"
or
action = "rce" and result = "system"
or
action = "ssrf" and result = "file_get_contents"
or
action = "ssrf" and result = "curl_exec"
}
getFunc("rce")返回两个结果popen、system
getFunc("csrf")不返回结果
递归谓词
string getANeighbor(string country) {
country = "France" and result = "Belgium"
or
country = "France" and result = "Germany"
or
country = "Germany" and result = "Austria"
or
country = "Germany" and result = "Belgium"
or
country = getANeighbor(result)
}
int getSuccessor(int i) { // 1. Non-member predicate
result = i + 1 and
i in [1 .. 9]
}
class FavoriteNumbers extends int {
FavoriteNumbers() { // 2. Characteristic predicate
this = 1 or
this = 4 or
this = 9
}
string getName() { // 3. Member predicate for the class `FavoriteNumbers`
this = 1 and result = "one"
or
this = 4 and result = "four"
or
this = 9 and result = "nine"
}
}
集合绑定
上面说到谓词的参数和返回结果的值域都要是有限的tuple,即谓词只能包含有限数量的元组
如下的谓词编译时就会报错。
/*
Compilation errors:
ERROR: "i" is not bound to a value.
ERROR: "result" is not bound to a value.
ERROR: expression "i * 4" is not bound to a value.
*/
int multiplyBy4(int i) {
result = i * 4
}
/*
Compilation errors:
ERROR: "str" is not bound to a value.
ERROR: expression "str.length()" is not bound to a value.
*/
predicate shortString(string str) {
str.length() < 10
}
可以通过在谓词上使用bindingset标志,其声明了该谓词的输入绑定到了有限的数据集合
bindingset[x] bindingset[y]
predicate plusOne(int x, int y) {
x + 1 = y
}
from int x, int y
where y = 42 and plusOne(x, y)
select x, y
bindingset[x] bindingset[y]是or关系,即x或y是有限的
而bindingset[x, y]是and关系,即x和y必须是有限的
bindingset[str, len]
string truncate(string str, int len) {
if str.length() > len
then result = str.prefix(len)
else result = str
}