Python 中的函数¶
可以使用标准 CodeQL 库中的语法类来查找 Python 函数并识别对它们的调用。
这些示例使用标准 CodeQL 类 Function。有关更多信息,请参阅“适用于 Python 的 CodeQL 库”。
查找所有名为“get…”的函数¶
在此示例中,我们查找程序中的所有“getter”。从 Java 转移到 Python 的程序员经常会倾向于编写大量 getter 和 setter 方法,而不是使用属性。我们可能希望找到这些方法。
使用成员谓词 Function.getName()
,我们可以列出数据库中的所有 getter 函数
提示
不要复制此查询,而是尝试键入代码。当您开始编写与库类匹配的名称时,会显示一个弹出窗口,让您轻松选择所需的类。
import python
from Function f
where f.getName().matches("get%")
select f, "This is a function called get..."
此查询通常会找到大量结果。通常,其中许多结果是针对我们不感兴趣的函数(而不是方法)。
查找所有名为“get…”的方法¶
您可以修改上面的查询以返回更有趣的结果。因为我们只对方法感兴趣,所以可以使用 Function.isMethod()
谓词来细化查询。
import python
from Function f
where f.getName().matches("get%") and f.isMethod()
select f, "This is a method called get..."
这将找到名称以 "get"
开头的函数,但其中许多不是我们感兴趣的简单 getter。
查找名为“get…”的单行方法¶
我们可以进一步修改查询,只包含主体由单个语句组成的函数。我们通过计算每个函数中的行数来实现这一点。
import python
from Function f
where f.getName().matches("get%") and f.isMethod()
and count(f.getAStmt()) = 1
select f, "This function is (probably) a getter."
此查询返回的结果更少,但如果检查结果,您会发现还有改进的空间。在“Python 中的表达式和语句”中对此进行了进一步细化。
查找对特定函数的调用¶
此查询使用 Call
和 Name
来查找对函数 eval
的调用,这可能存在安全风险。
import python
from Call call, Name name
where call.getFunc() = name and name.getId() = "eval"
select call, "call to 'eval'."
类 Call
表示 Python 中的调用。谓词 Call.getFunc()
获取被调用的表达式。 Name.getId()
获取 Name
表达式的标识符(以字符串形式)。此查询将选择任何形式为 eval(...)
的调用,无论它是对内置函数 eval
的调用还是其他调用。由于 Python 的动态特性,此类语法查询可能不准确。如果要查找对内置函数 eval
的调用,建议使用 API 图,请参阅“在 Python 中使用 API 图”。