mirror of
https://github.com/github/codeql.git
synced 2026-04-25 16:55:19 +02:00
docs: fix some formatting issues
This commit is contained in:
@@ -10,6 +10,8 @@ In this example we look for all the "getters" in a program. Programmers moving t
|
||||
|
||||
Using the member predicate ``Function.getName()``, we can list all of the getter functions in a snapshot:
|
||||
|
||||
.. 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.
|
||||
|
||||
@@ -33,7 +33,7 @@ This part of the library represents the Python source code. The ``Module``, ``Cl
|
||||
Scope
|
||||
^^^^^
|
||||
|
||||
A Python program is a group of modules. Technically a module is just a list of statements, but we often think of it as composed of classes and functions. These top-level entities, the module, class and function are represented by the three classes (`Module <https://help.semmle.com/qldoc/python/semmle/python/Module.qll/type.Module$Module.html>`__, `Class <https://help.semmle.com/qldoc/python/semmle/python/Class.qll/type.Class$Class.html>`__ and `Function <https://help.semmle.com/qldoc/python/semmle/python/Function.qll/type.Function$Function.html>`__ which are all subclasses of ``Scope``.
|
||||
A Python program is a group of modules. Technically a module is just a list of statements, but we often think of it as composed of classes and functions. These top-level entities, the module, class and function are represented by the three classes `Module <https://help.semmle.com/qldoc/python/semmle/python/Module.qll/type.Module$Module.html>`__, `Class <https://help.semmle.com/qldoc/python/semmle/python/Class.qll/type.Class$Class.html>`__ and `Function <https://help.semmle.com/qldoc/python/semmle/python/Function.qll/type.Function$Function.html>`__, which are all subclasses of ``Scope``.
|
||||
|
||||
- ``Scope``
|
||||
|
||||
@@ -110,12 +110,12 @@ Examples
|
||||
|
||||
Each syntactic element in Python source is recorded in the snapshot. These can be queried via the corresponding class. Let us start with a couple of simple examples.
|
||||
|
||||
1. Finding all finally blocks
|
||||
'''''''''''''''''''''''''''''
|
||||
1. Finding all ``finally`` blocks
|
||||
'''''''''''''''''''''''''''''''''
|
||||
|
||||
For our first example, we can find all ``finally`` blocks by using the ``Try`` class:
|
||||
|
||||
**Find all ``finally`` blocks**
|
||||
**Find all** ``finally`` **blocks**
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
@@ -126,8 +126,8 @@ For our first example, we can find all ``finally`` blocks by using the ``Try`` c
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/659662193/>`__. Many projects include examples of this pattern.
|
||||
|
||||
2. Finding 'except' blocks that do nothing
|
||||
''''''''''''''''''''''''''''''''''''''''''
|
||||
2. Finding ``except`` blocks that do nothing
|
||||
''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
For our second example, we can use a simplified version of a query from the standard query set. We look for all ``except`` blocks that do nothing.
|
||||
|
||||
@@ -137,7 +137,7 @@ A block that does nothing is one that contains no statements except ``pass`` sta
|
||||
|
||||
not exists(Stmt s | s = ex.getAStmt() | not s instanceof Pass)
|
||||
|
||||
where ``ex`` is an ``ExceptStmt`` and ``Pass`` is the class representing ``pass`` statements. Instead of using the double negative, **"no**\ *statements that are*\ **not**\ *pass statements"*, this can also be expressed positively, "all statements must be pass statements." The positive form is expressed in QL using the ``forall`` quantifier:
|
||||
where ``ex`` is an ``ExceptStmt`` and ``Pass`` is the class representing ``pass`` statements. Instead of using the double negative, *no statements that are not pass statements*, this can also be expressed positively, *all statements must be pass statements*. The positive form is expressed in QL using the ``forall`` quantifier:
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
@@ -145,7 +145,7 @@ where ``ex`` is an ``ExceptStmt`` and ``Pass`` is the class representing ``pass`
|
||||
|
||||
Both forms are equivalent. Using the positive QL expression, the whole query looks like this:
|
||||
|
||||
**Find pass-only ``except`` blocks**
|
||||
**Find pass-only** ``except`` **blocks**
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
|
||||
@@ -37,7 +37,8 @@ The predicate ``ControlFlowNode.pointsTo(...)`` shows which object a control flo
|
||||
predicate pointsTo(Context context, Value object, ControlFlowNode origin)
|
||||
|
||||
``object`` is an object that the control flow node refers to, and ``origin`` is where the object comes from, which is useful for displaying meaningful results.
|
||||
The third form includes the ``context`` in which the control flow node refers to the ``object``. This form can usually be ignored.
|
||||
|
||||
The third form includes the ``context`` in which the control flow node refers to the ``object``. This form can usually be ignored.
|
||||
|
||||
.. pull-quote::
|
||||
|
||||
@@ -62,7 +63,7 @@ We want to find ``except`` blocks in a ``try`` statement that are in the wrong o
|
||||
|
||||
First we can write a query to find ordered pairs of ``except`` blocks for a ``try`` statement.
|
||||
|
||||
**Ordered except blocks in same ``try`` statement**
|
||||
**Ordered except blocks in same** ``try`` **statement**
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
@@ -81,7 +82,7 @@ Here ``ex1`` and ``ex2`` are both ``except`` handlers in the ``try`` statement `
|
||||
|
||||
The results of this query need to be filtered to return only results where ``ex1`` is more general than ``ex2``. We can use the fact that an ``except`` block is more general than another block if the class it handles is a superclass of the other.
|
||||
|
||||
**More general ``except`` block**
|
||||
**More general** ``except`` **block**
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
@@ -102,7 +103,7 @@ ensures that ``cls1`` is a ``ClassValue`` that the ``except`` block would handle
|
||||
|
||||
Combining the parts of the query we get this:
|
||||
|
||||
**More general ``except`` block precedes more specific**
|
||||
**More general** ``except`` **block precedes more specific**
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ Python implementations commonly cache small integers and single character string
|
||||
|
||||
We can check for these as follows:
|
||||
|
||||
**Find comparisons to integer or string literals using ``is``**
|
||||
**Find comparisons to integer or string literals using** ``is``
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
@@ -158,6 +158,8 @@ We can check for these as follows:
|
||||
|
||||
The clause ``cmp.getOp(0) instanceof Is and cmp.getComparator(0) = literal`` checks that the first comparison operator is "is" and that the first comparator is a literal.
|
||||
|
||||
.. pull-quote::
|
||||
|
||||
Tip
|
||||
|
||||
We have to use ``cmp.getOp(0)`` and ``cmp.getComparator(0)``\ as there is no ``cmp.getOp()`` or ``cmp.getComparator()``. The reason for this is that a ``Compare`` expression can have multiple operators. For example, the expression ``3 < x < 7`` has two operators and two comparators. You use ``cmp.getComparator(0)`` to get the first comparator (in this example the ``3``) and ``cmp.getComparator(1)`` to get the second comparator (in this example the ``7``).
|
||||
@@ -253,9 +255,7 @@ checks that the value of the attribute (the expression to the left of the dot in
|
||||
Class and function definitions
|
||||
------------------------------
|
||||
|
||||
As Python is a dynamically typed language, class, and function definitions are executable statements. This means that a class statement is both a statement and a scope containing statements. To represent this cleanly the class definition is broken into a number of parts. At runtime, when a class definition is executed a class object is created and then assigned to a variable of the same name in the scope enclosing the class. This class is created from a code-object representing the source code for the body of the class. To represent this the ``ClassDef`` class (which represents a ``class`` statement) subclasses ``Assign``. The ``Class`` class, which represents the body of the class, can be accessed via the ``ClassDef.getDefinedClass()``
|
||||
|
||||
``FunctionDef``, ``Function`` are handled similarly.
|
||||
As Python is a dynamically typed language, class, and function definitions are executable statements. This means that a class statement is both a statement and a scope containing statements. To represent this cleanly the class definition is broken into a number of parts. At runtime, when a class definition is executed a class object is created and then assigned to a variable of the same name in the scope enclosing the class. This class is created from a code-object representing the source code for the body of the class. To represent this the ``ClassDef`` class (which represents a ``class`` statement) subclasses ``Assign``. The ``Class`` class, which represents the body of the class, can be accessed via the ``ClassDef.getDefinedClass()``. ``FunctionDef`` and ``Function`` are handled similarly.
|
||||
|
||||
Here is the relevant part of the class hierarchy:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user