You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/codeql/writing-codeql-queries/about-codeql-queries.rst
+3-1Lines changed: 3 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,7 +21,9 @@ For more information on how to format your code when contributing queries to the
21
21
Basic query structure
22
22
*********************
23
23
24
-
:ref:`Queries <queries>` written with CodeQL have the file extension ``.ql``, and contain a ``select`` clause. Many of the existing queries include additional optional information, and have the following structure::
24
+
:ref:`Queries <queries>` written with CodeQL have the file extension ``.ql``, and contain a ``select`` clause. Many of the existing queries include additional optional information, and have the following structure:
Copy file name to clipboardExpand all lines: docs/codeql/writing-codeql-queries/creating-path-queries.rst
+27-9Lines changed: 27 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -44,7 +44,9 @@ Constructing a path query
44
44
Path queries require certain metadata, query predicates, and ``select`` statement structures.
45
45
Many of the built-in path queries included in CodeQL follow a simple structure, which depends on how the language you are analyzing is modeled with CodeQL.
46
46
47
-
For C/C++, C#, Java, and JavaScript you should use the following template::
47
+
For C/C++, C#, Java, and JavaScript you should use the following template:
48
+
49
+
.. code-block:: ql
48
50
49
51
/**
50
52
* ...
@@ -66,7 +68,9 @@ Where:
66
68
- ``source`` and ``sink`` are nodes on the `path graph <https://en.wikipedia.org/wiki/Path_graph>`__, and ``DataFlow::PathNode`` is their type.
67
69
- ``Configuration`` is a class containing the predicates which define how data may flow between the ``source`` and the ``sink``.
68
70
69
-
For Python you should use a slightly different template::
71
+
For Python you should use a slightly different template:
72
+
73
+
.. code-block:: ql
70
74
71
75
/**
72
76
* ...
@@ -104,13 +108,17 @@ To do this you need to define a :ref:`query predicate <query-predicates>` called
104
108
This predicate defines the edge relations of the graph you are computing, and it is used to compute the paths related to each result that your query generates.
105
109
You can import a predefined ``edges`` predicate from a path graph module in one of the standard data flow libraries. In addition to the path graph module, the data flow libraries contain the other ``classes``, ``predicates``, and ``modules`` that are commonly used in data flow analysis. The import statement to use depends on the language that you are analyzing.
106
110
107
-
For C/C++, C#, Java, and JavaScript you would use::
111
+
For C/C++, C#, Java, and JavaScript you would use:
112
+
113
+
.. code-block:: ql
108
114
109
115
import DataFlow::PathGraph
110
116
111
117
This statement imports the ``PathGraph`` module from the data flow library (``DataFlow.qll``), in which ``edges`` is defined.
112
118
113
-
For Python, the ``Paths`` module contains the ``edges`` predicate::
119
+
For Python, the ``Paths`` module contains the ``edges`` predicate:
120
+
121
+
.. code-block:: ql
114
122
115
123
import semmle.python.security.Paths
116
124
@@ -121,7 +129,9 @@ For all languages, you can also optionally define a ``nodes`` query predicate, w
121
129
Defining your own ``edges`` predicate
122
130
-------------------------------------
123
131
124
-
You can also define your own ``edges`` predicate in the body of your query. It should take the following form::
132
+
You can also define your own ``edges`` predicate in the body of your query. It should take the following form:
133
+
134
+
.. code-block:: ql
125
135
126
136
query predicate edges(PathNode a, PathNode b) {
127
137
/** Logical conditions which hold if `(a,b)` is an edge in the data flow graph */
@@ -136,7 +146,9 @@ You must provide information about the ``source`` and ``sink`` in your path quer
136
146
The name and the type of the ``source`` and the ``sink`` must be declared in the ``from`` statement of the query, and the types must be compatible with the nodes of the graph computed by the ``edges`` predicate.
137
147
138
148
If you are querying C/C++, C#, Java, or JavaScript code (and you have used ``import DataFlow::PathGraph`` in your query), the definitions of the ``source`` and ``sink`` are accessed via the ``Configuration`` class in the data flow library. You should declare all three of these objects in the ``from`` statement.
139
-
For example::
149
+
For example:
150
+
151
+
.. code-block:: ql
140
152
141
153
from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink
142
154
@@ -149,7 +161,9 @@ For more information on using the configuration class in your analysis see the s
149
161
150
162
You can also create a configuration for different frameworks and environments by extending the ``Configuration`` class. For more information, see ":ref:`Types <defining-a-class>`" in the QL language reference.
151
163
152
-
If you are querying Python code (and you have used ``import semmle.python.security.Paths`` in your query) you should declare ``TaintedPathSource source, TaintedPathSink sink`` in your ``from`` statement. You do not need to declare a ``Configuration`` class as the definitions of the ``TaintedPathSource`` and ``TaintedPathSink`` contain all of the type information that is required::
164
+
If you are querying Python code (and you have used ``import semmle.python.security.Paths`` in your query) you should declare ``TaintedPathSource source, TaintedPathSink sink`` in your ``from`` statement. You do not need to declare a ``Configuration`` class as the definitions of the ``TaintedPathSource`` and ``TaintedPathSink`` contain all of the type information that is required:
165
+
166
+
.. code-block:: ql
153
167
154
168
from TaintedPathSource source, TaintedPathSink sink
155
169
@@ -163,11 +177,15 @@ This clause can use :ref:`aggregations <aggregations>`, :ref:`predicates <predic
163
177
164
178
When writing a path queries, you would typically include a predicate that holds only if data flows from the ``source`` to the ``sink``.
165
179
166
-
For C/C++, C#, Java or JavaScript, you would use the ``hasFlowPath`` predicate to define flow from the ``source`` to the ``sink`` for a given ``Configuration``::
180
+
For C/C++, C#, Java or JavaScript, you would use the ``hasFlowPath`` predicate to define flow from the ``source`` to the ``sink`` for a given ``Configuration``:
181
+
182
+
.. code-block:: ql
167
183
168
184
where config.hasFlowPath(source, sink)
169
185
170
-
For Python, you would simply use the ``flowsTo`` predicate to define flow from the ``source`` to the ``sink``::
186
+
For Python, you would simply use the ``flowsTo`` predicate to define flow from the ``source`` to the ``sink``:
Copy file name to clipboardExpand all lines: docs/codeql/writing-codeql-queries/troubleshooting-query-performance.rst
+15-5Lines changed: 15 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -27,7 +27,9 @@ The performance of a predicate can often be judged by considering roughly how ma
27
27
One way of creating badly performing predicates is by using two variables without relating them in any way, or only relating them using a negation.
28
28
This leads to computing the `Cartesian product <https://en.wikipedia.org/wiki/Cartesian_product>`__ between the sets of possible values for each variable, potentially generating a huge table of results.
29
29
This can occur if you don't specify restrictions on your variables.
30
-
For instance, consider the following predicate that checks whether a Java method ``m`` may access a field ``f``::
30
+
For instance, consider the following predicate that checks whether a Java method ``m`` may access a field ``f``:
31
+
32
+
.. code-block:: ql
31
33
32
34
predicate mayAccess(Method m, Field f) {
33
35
f.getAnAccess().getEnclosingCallable() = m
@@ -39,7 +41,9 @@ The predicate holds if ``m`` contains an access to ``f``, but also conservativel
39
41
40
42
However, if ``m`` is a native method, the table computed by ``mayAccess`` will contain a row ``m, f`` for *all* fields ``f`` in the codebase, making it potentially very large.
41
43
42
-
This example shows a similar mistake in a member predicate::
44
+
This example shows a similar mistake in a member predicate:
45
+
46
+
.. code-block:: ql
43
47
44
48
class Foo extends Class {
45
49
...
@@ -57,11 +61,15 @@ Use specific types
57
61
~~~~~~~~~~~~~~~~~~
58
62
59
63
":ref:`Types <types>`" provide an upper bound on the size of a relation.
60
-
This helps the query optimizer be more effective, so it's generally good to use the most specific types possible. For example::
64
+
This helps the query optimizer be more effective, so it's generally good to use the most specific types possible. For example:
65
+
66
+
.. code-block:: ql
61
67
62
68
predicate foo(LoggingCall e)
63
69
64
-
is preferred over::
70
+
is preferred over:
71
+
72
+
.. code-block:: ql
65
73
66
74
predicate foo(Expr e)
67
75
@@ -95,7 +103,9 @@ Avoid complex recursion
95
103
":ref:`Recursion <recursion>`" is about self-referencing definitions.
96
104
It can be extremely powerful as long as it is used appropriately.
97
105
On the whole, you should try to make recursive predicates as simple as possible.
98
-
That is, you should define a *base case* that allows the predicate to *bottom out*, along with a single *recursive call*::
106
+
That is, you should define a *base case* that allows the predicate to *bottom out*, along with a single *recursive call*:
107
+
108
+
.. code-block:: ql
99
109
100
110
int depth(Stmt s) {
101
111
exists(Callable c | c.getBody() = s | result = 0) // base case
0 commit comments