mirror of
https://github.com/github/codeql.git
synced 2025-12-17 17:23:36 +01:00
90 lines
4.1 KiB
ReStructuredText
90 lines
4.1 KiB
ReStructuredText
Functions in Python
|
|
===================
|
|
|
|
You can use syntactic classes from the standard CodeQL library to find Python functions and identify calls to them.
|
|
|
|
These examples use the standard CodeQL class `Function <https://help.semmle.com/qldoc/python/semmle/python/Function.qll/type.Function$Function.html>`__. For more information, see ":doc:`Introducing the Python libraries <introduce-libraries-python>`."
|
|
|
|
Finding all functions called "get..."
|
|
-------------------------------------
|
|
|
|
In this example we look for all the "getters" in a program. Programmers moving to Python from Java are often tempted to write lots of getter and setter methods, rather than use properties. We might want to find those methods.
|
|
|
|
Using the member predicate ``Function.getName()``, we can list all of the getter functions in a database:
|
|
|
|
.. pull-quote::
|
|
|
|
Tip
|
|
|
|
Instead of copying this query, try typing the code. As you start to write a name that matches a library class, a pop-up is displayed making it easy for you to select the class that you want.
|
|
|
|
.. code-block:: ql
|
|
|
|
import python
|
|
|
|
from Function f
|
|
where f.getName().matches("get%")
|
|
select f, "This is a function called get..."
|
|
|
|
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/669220031/>`__. This query typically finds a large number of results. Usually, many of these results are for functions (rather than methods) which we are not interested in.
|
|
|
|
Finding all methods called "get..."
|
|
-----------------------------------
|
|
|
|
You can modify the query above to return more interesting results. As we are only interested in methods, we can use the ``Function.isMethod()`` predicate to refine the query.
|
|
|
|
.. code-block:: ql
|
|
|
|
import python
|
|
|
|
from Function f
|
|
where f.getName().matches("get%") and f.isMethod()
|
|
select f, "This is a method called get..."
|
|
|
|
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/690010035/>`__. This finds methods whose name starts with ``"get"``, but many of those are not the sort of simple getters we are interested in.
|
|
|
|
Finding one line methods called "get..."
|
|
----------------------------------------
|
|
|
|
We can modify the query further to include only methods whose body consists of a single statement. We do this by counting the number of lines in each method.
|
|
|
|
.. code-block:: ql
|
|
|
|
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."
|
|
|
|
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/667290044/>`__. This query returns fewer results, but if you examine the results you can see that there are still refinements to be made. This is refined further in ":doc:`Expressions and statements in Python <statements-expressions>`."
|
|
|
|
Finding a call to a specific function
|
|
-------------------------------------
|
|
|
|
This query uses ``Call`` and ``Name`` to find calls to the function ``eval`` - which might potentially be a security hazard.
|
|
|
|
.. code-block:: ql
|
|
|
|
import python
|
|
|
|
from Call call, Name name
|
|
where call.getFunc() = name and name.getId() = "eval"
|
|
select call, "call to 'eval'."
|
|
|
|
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/6718356557331218618/>`__. Some of the demo projects on LGTM.com use this function.
|
|
|
|
The ``Call`` class represents calls in Python. The ``Call.getFunc()`` predicate gets the expression being called. ``Name.getId()`` gets the identifier (as a string) of the ``Name`` expression.
|
|
Due to the dynamic nature of Python, this query will select any call of the form ``eval(...)`` regardless of whether it is a call to the built-in function ``eval`` or not.
|
|
In a later tutorial we will see how to use the type-inference library to find calls to the built-in function ``eval`` regardless of name of the variable called.
|
|
|
|
Further reading
|
|
---------------
|
|
|
|
- ":doc:`Expressions and statements in Python <statements-expressions>`"
|
|
- ":doc:`Pointer analysis and type inference in Python <pointsto-type-infer>`"
|
|
- ":doc:`Analyzing control flow in Python <control-flow>`"
|
|
- ":doc:`Analyzing data flow and tracking tainted data in Python <taint-tracking>`"
|
|
|
|
.. include:: ../../reusables/python-other-resources.rst
|