diff --git a/docs/codeql/codeql-language-guides/codeql-library-for-csharp.rst b/docs/codeql/codeql-language-guides/codeql-library-for-csharp.rst index c9357be9772..03a1e449ea8 100644 --- a/docs/codeql/codeql-language-guides/codeql-library-for-csharp.rst +++ b/docs/codeql/codeql-language-guides/codeql-library-for-csharp.rst @@ -108,8 +108,8 @@ Count the number of lines of code, excluding the directory ``external``: .. code-block:: ql select sum(SourceFile f | - not exists(Folder external | external.getShortName() = "external" | - external.getAFolder*().getAFile() = f) | + not exists(Folder ext | ext.getShortName() = "external" | + ext.getAFolder*().getAFile() = f) | f.getNumberOfLines()) Exercises @@ -961,7 +961,7 @@ Find all obsolete elements: Model NUnit test fixtures: -.. code-block:: csharp +.. code-block:: ql class TestFixture extends Class { diff --git a/docs/codeql/writing-codeql-queries/about-codeql-queries.rst b/docs/codeql/writing-codeql-queries/about-codeql-queries.rst index 24b68a0ad28..39442f1823e 100644 --- a/docs/codeql/writing-codeql-queries/about-codeql-queries.rst +++ b/docs/codeql/writing-codeql-queries/about-codeql-queries.rst @@ -21,7 +21,9 @@ For more information on how to format your code when contributing queries to the Basic query structure ********************* -:ref:`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:: +:ref:`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: + +.. code-block:: ql /** * diff --git a/docs/codeql/writing-codeql-queries/creating-path-queries.rst b/docs/codeql/writing-codeql-queries/creating-path-queries.rst index 4d65351ec31..9b15b6ed4cb 100644 --- a/docs/codeql/writing-codeql-queries/creating-path-queries.rst +++ b/docs/codeql/writing-codeql-queries/creating-path-queries.rst @@ -44,7 +44,9 @@ Constructing a path query Path queries require certain metadata, query predicates, and ``select`` statement structures. 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. -For C/C++, C#, Java, and JavaScript you should use the following template:: +For C/C++, C#, Java, and JavaScript you should use the following template: + +.. code-block:: ql /** * ... @@ -66,7 +68,9 @@ Where: - ``source`` and ``sink`` are nodes on the `path graph `__, and ``DataFlow::PathNode`` is their type. - ``Configuration`` is a class containing the predicates which define how data may flow between the ``source`` and the ``sink``. -For Python you should use a slightly different template:: +For Python you should use a slightly different template: + +.. code-block:: ql /** * ... @@ -104,13 +108,17 @@ To do this you need to define a :ref:`query predicate ` called 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. 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. -For C/C++, C#, Java, and JavaScript you would use:: +For C/C++, C#, Java, and JavaScript you would use: + +.. code-block:: ql import DataFlow::PathGraph This statement imports the ``PathGraph`` module from the data flow library (``DataFlow.qll``), in which ``edges`` is defined. -For Python, the ``Paths`` module contains the ``edges`` predicate:: +For Python, the ``Paths`` module contains the ``edges`` predicate: + +.. code-block:: ql import semmle.python.security.Paths @@ -121,7 +129,9 @@ For all languages, you can also optionally define a ``nodes`` query predicate, w Defining your own ``edges`` predicate ------------------------------------- -You can also define your own ``edges`` predicate in the body of your query. It should take the following form:: +You can also define your own ``edges`` predicate in the body of your query. It should take the following form: + +.. code-block:: ql query predicate edges(PathNode a, PathNode b) { /** 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 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. 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. -For example:: +For example: + +.. code-block:: ql from Configuration config, DataFlow::PathNode source, DataFlow::PathNode sink @@ -149,7 +161,9 @@ For more information on using the configuration class in your analysis see the s You can also create a configuration for different frameworks and environments by extending the ``Configuration`` class. For more information, see ":ref:`Types `" in the QL language reference. -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:: +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: + +.. code-block:: ql from TaintedPathSource source, TaintedPathSink sink @@ -163,11 +177,15 @@ This clause can use :ref:`aggregations `, :ref:`predicates `. *Show/hide code* .. literalinclude:: river-crossing-1.ql + :language: ql :lines: 33-40,87 We are interested in two particular states, namely the initial state and the goal state, @@ -94,6 +97,7 @@ Assuming that all items start on the left shore and end up on the right shore, d *Show/hide code* .. literalinclude:: river-crossing-1.ql + :language: ql :lines: 89-97 .. pull-quote:: @@ -112,6 +116,7 @@ Using the above note, the QL code so far looks like this: *Show/hide code* .. literalinclude:: river-crossing.ql + :language: ql :lines: 15-52,103-113 Model the action of "ferrying" @@ -130,6 +135,7 @@ after ferrying a particular cargo. (Hint: Use the predicate ``other``.) *Show/hide code* .. literalinclude:: river-crossing.ql + :language: ql :lines: 54-67 Of course, not all ferrying actions are possible. Add some extra conditions to describe when a ferrying @@ -147,6 +153,7 @@ For example, follow these steps: *Show/hide code* .. literalinclude:: river-crossing.ql + :language: ql :lines: 69-81 Find paths from one state to another @@ -185,6 +192,7 @@ for example ``steps <= 7``. *Show/hide code* .. literalinclude:: river-crossing-1.ql + :language: ql :lines: 70-86 However, although this ensures that the solution is finite, it can still contain loops if the upper bound @@ -215,6 +223,7 @@ the given path without revisiting any previously visited states. *Show/hide code* .. literalinclude:: river-crossing.ql + :language: ql :lines: 83-102 Display the results @@ -230,6 +239,7 @@ that returns the resulting path. *Show/hide code* .. literalinclude:: river-crossing.ql + :language: ql :lines: 115-117 The :ref:`don't-care expression ` (``_``), diff --git a/docs/codeql/writing-codeql-queries/troubleshooting-query-performance.rst b/docs/codeql/writing-codeql-queries/troubleshooting-query-performance.rst index 9444677917c..41f5883e0b7 100644 --- a/docs/codeql/writing-codeql-queries/troubleshooting-query-performance.rst +++ b/docs/codeql/writing-codeql-queries/troubleshooting-query-performance.rst @@ -27,7 +27,9 @@ The performance of a predicate can often be judged by considering roughly how ma 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. This leads to computing the `Cartesian product `__ between the sets of possible values for each variable, potentially generating a huge table of results. This can occur if you don't specify restrictions on your variables. -For instance, consider the following predicate that checks whether a Java method ``m`` may access a field ``f``:: +For instance, consider the following predicate that checks whether a Java method ``m`` may access a field ``f``: + +.. code-block:: ql predicate mayAccess(Method m, Field f) { f.getAnAccess().getEnclosingCallable() = m @@ -39,7 +41,9 @@ The predicate holds if ``m`` contains an access to ``f``, but also conservativel 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. -This example shows a similar mistake in a member predicate:: +This example shows a similar mistake in a member predicate: + +.. code-block:: ql class Foo extends Class { ... @@ -57,11 +61,15 @@ Use specific types ~~~~~~~~~~~~~~~~~~ ":ref:`Types `" provide an upper bound on the size of a relation. -This helps the query optimizer be more effective, so it's generally good to use the most specific types possible. For example:: +This helps the query optimizer be more effective, so it's generally good to use the most specific types possible. For example: + +.. code-block:: ql predicate foo(LoggingCall e) -is preferred over:: +is preferred over: + +.. code-block:: ql predicate foo(Expr e) @@ -95,7 +103,9 @@ Avoid complex recursion ":ref:`Recursion `" is about self-referencing definitions. It can be extremely powerful as long as it is used appropriately. On the whole, you should try to make recursive predicates as simple as possible. -That is, you should define a *base case* that allows the predicate to *bottom out*, along with a single *recursive call*:: +That is, you should define a *base case* that allows the predicate to *bottom out*, along with a single *recursive call*: + +.. code-block:: ql int depth(Stmt s) { exists(Callable c | c.getBody() = s | result = 0) // base case