mirror of
https://github.com/github/codeql.git
synced 2026-04-27 17:55:19 +02:00
docs: update query console link text
This commit is contained in:
@@ -45,7 +45,7 @@ Example finding unreachable AST nodes
|
||||
where not exists(node.getAFlowNode())
|
||||
select node
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/669220024/>`__. The demo projects on LGTM.com all have some code that has no control flow node, and is therefore unreachable. However, since the ``Module`` class is also a subclass of the ``AstNode`` class, the query also finds any modules implemented in C or with no source code. Therefore, it is better to find all unreachable statements.
|
||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/669220024/>`__. The demo projects on LGTM.com all have some code that has no control flow node, and is therefore unreachable. However, since the ``Module`` class is also a subclass of the ``AstNode`` class, the query also finds any modules implemented in C or with no source code. Therefore, it is better to find all unreachable statements.
|
||||
|
||||
Example finding unreachable statements
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@@ -58,7 +58,7 @@ Example finding unreachable statements
|
||||
where not exists(s.getAFlowNode())
|
||||
select s
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/670720181/>`__. This query gives fewer results, but most of the projects have some unreachable nodes. These are also highlighted by the standard "Unreachable code" query. For more information, see `Unreachable code <https://lgtm.com/rules/3980095>`__ on LGTM.com.
|
||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/670720181/>`__. This query gives fewer results, but most of the projects have some unreachable nodes. These are also highlighted by the standard "Unreachable code" query. For more information, see `Unreachable code <https://lgtm.com/rules/3980095>`__ on LGTM.com.
|
||||
|
||||
The ``BasicBlock`` class
|
||||
------------------------
|
||||
@@ -112,7 +112,7 @@ Example finding mutually exclusive blocks within the same function
|
||||
)
|
||||
select b1, b2
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/671000028/>`__. This typically gives a very large number of results, because it is a common occurrence in normal control flow. It is, however, an example of the sort of control-flow analysis that is possible. Control-flow analyses such as this are an important aid to data flow analysis. For more information, see :doc:`Analyzing data flow and tracking tainted data in Python <taint-tracking>`.
|
||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/671000028/>`__. This typically gives a very large number of results, because it is a common occurrence in normal control flow. It is, however, an example of the sort of control-flow analysis that is possible. Control-flow analyses such as this are an important aid to data flow analysis. For more information, see :doc:`Analyzing data flow and tracking tainted data in Python <taint-tracking>`.
|
||||
|
||||
Further reading
|
||||
---------------
|
||||
|
||||
@@ -26,7 +26,7 @@ Using the member predicate ``Function.getName()``, we can list all of the getter
|
||||
where f.getName().matches("get%")
|
||||
select f, "This is a function called get..."
|
||||
|
||||
➤ `See this in the query console <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.
|
||||
➤ `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..."
|
||||
-----------------------------------
|
||||
@@ -41,7 +41,7 @@ You can modify the query above to return more interesting results. As we are onl
|
||||
where f.getName().matches("get%") and f.isMethod()
|
||||
select f, "This is a method called get..."
|
||||
|
||||
➤ `See this in the query console <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.
|
||||
➤ `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..."
|
||||
----------------------------------------
|
||||
@@ -57,7 +57,7 @@ We can modify the query further to include only methods whose body consists of a
|
||||
and count(f.getAStmt()) = 1
|
||||
select f, "This function is (probably) a getter."
|
||||
|
||||
➤ `See this in the query console <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>`."
|
||||
➤ `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
|
||||
-------------------------------------
|
||||
@@ -72,7 +72,7 @@ This query uses ``Call`` and ``Name`` to find calls to the function ``eval`` - w
|
||||
where call.getFunc() = name and name.getId() = "eval"
|
||||
select call, "call to 'eval'."
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/6718356557331218618/>`__. Some of the demo projects on LGTM.com use this function.
|
||||
➤ `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.
|
||||
|
||||
@@ -47,7 +47,7 @@ All scopes are basically a list of statements, although ``Scope`` classes have a
|
||||
where f.getScope() instanceof Function
|
||||
select f
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/665620040/>`__. Many projects have nested functions.
|
||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/665620040/>`__. Many projects have nested functions.
|
||||
|
||||
Statement
|
||||
^^^^^^^^^
|
||||
@@ -89,7 +89,7 @@ As an example, to find expressions of the form ``a+2`` where the left is a simpl
|
||||
where bin.getLeft() instanceof Name and bin.getRight() instanceof Num
|
||||
select bin
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/669950026/>`__. Many projects include examples of this pattern.
|
||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/669950026/>`__. Many projects include examples of this pattern.
|
||||
|
||||
Variable
|
||||
^^^^^^^^
|
||||
@@ -120,7 +120,7 @@ For our first example, we can find all ``finally`` blocks by using the ``Try`` c
|
||||
from Try t
|
||||
select t.getFinalbody()
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/659662193/>`__. Many projects include examples of this pattern.
|
||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/659662193/>`__. Many projects include examples of this pattern.
|
||||
|
||||
2. Finding ``except`` blocks that do nothing
|
||||
''''''''''''''''''''''''''''''''''''''''''''
|
||||
@@ -151,7 +151,7 @@ Both forms are equivalent. Using the positive expression, the whole query looks
|
||||
where forall(Stmt s | s = ex.getAStmt() | s instanceof Pass)
|
||||
select ex
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/690010036/>`__. Many projects include pass-only ``except`` blocks.
|
||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/690010036/>`__. Many projects include pass-only ``except`` blocks.
|
||||
|
||||
Summary
|
||||
^^^^^^^
|
||||
@@ -272,7 +272,7 @@ Using this predicate we can select the longest ``BasicBlock`` by selecting the `
|
||||
where bb_length(b) = max(bb_length(_))
|
||||
select b
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/666730036/>`__. When we ran it on the LGTM.com demo projects, the *openstack/nova* and *ytdl-org/youtube-dl* projects both contained source code results for this query.
|
||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/666730036/>`__. When we ran it on the LGTM.com demo projects, the *openstack/nova* and *ytdl-org/youtube-dl* projects both contained source code results for this query.
|
||||
|
||||
.. pull-quote::
|
||||
|
||||
@@ -309,7 +309,7 @@ For example, which ``ClassValue``\ s are iterable can be determined using the qu
|
||||
where cls.hasAttribute("__iter__")
|
||||
select cls
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/5151030165280978402/>`__ This query returns a list of classes for the projects analyzed. If you want to include the results for ``builtin`` classes, which do not have any Python source code, show the non-source results. For more information, see `builtin classes <http://docs.python.org/library/stdtypes.html>`__ in the Python documentation.
|
||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/5151030165280978402/>`__ This query returns a list of classes for the projects analyzed. If you want to include the results for ``builtin`` classes, which do not have any Python source code, show the non-source results. For more information, see `builtin classes <http://docs.python.org/library/stdtypes.html>`__ in the Python documentation.
|
||||
|
||||
Summary
|
||||
^^^^^^^
|
||||
|
||||
@@ -74,7 +74,7 @@ First we can write a query to find ordered pairs of ``except`` blocks for a ``tr
|
||||
)
|
||||
select t, ex1, ex2
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/672320024/>`__. Many projects contain ordered ``except`` blocks in a ``try`` statement.
|
||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/672320024/>`__. Many projects contain ordered ``except`` blocks in a ``try`` statement.
|
||||
|
||||
Here ``ex1`` and ``ex2`` are both ``except`` handlers in the ``try`` statement ``t``. By using the indices ``i`` and ``j`` we can also ensure that ``ex1`` precedes ``ex2``.
|
||||
|
||||
@@ -121,7 +121,7 @@ Combining the parts of the query we get this:
|
||||
)
|
||||
select t, ex1, ex2
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/669950027/>`__. This query finds only one result in the demo projects on LGTM.com (`youtube-dl <https://lgtm.com/projects/g/ytdl-org/youtube-dl/rev/39e9d524e5fe289936160d4c599a77f10f6e9061/files/devscripts/buildserver.py?sort=name&dir=ASC&mode=heatmap#L413>`__). The result is also highlighted by the standard "Unreachable 'except' block" query. For more information, see `Unreachable 'except' block <https://lgtm.com/rules/7900089>`__ on LGTM.com.
|
||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/669950027/>`__. This query finds only one result in the demo projects on LGTM.com (`youtube-dl <https://lgtm.com/projects/g/ytdl-org/youtube-dl/rev/39e9d524e5fe289936160d4c599a77f10f6e9061/files/devscripts/buildserver.py?sort=name&dir=ASC&mode=heatmap#L413>`__). The result is also highlighted by the standard "Unreachable 'except' block" query. For more information, see `Unreachable 'except' block <https://lgtm.com/rules/7900089>`__ on LGTM.com.
|
||||
|
||||
.. pull-quote::
|
||||
|
||||
@@ -156,7 +156,7 @@ Then we need to determine if the object ``iter`` is iterable. We can test ``Clas
|
||||
not exists(cls.lookup("__iter__"))
|
||||
select loop, cls
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/5636475906111506420/>`__. Many projects use a non-iterable as a loop iterator.
|
||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/5636475906111506420/>`__. Many projects use a non-iterable as a loop iterator.
|
||||
|
||||
Many of the results shown will have ``cls`` as ``NoneType``. It is more informative to show where these ``None`` values may come from. To do this we use the final field of ``pointsTo``, as follows:
|
||||
|
||||
@@ -172,7 +172,7 @@ Many of the results shown will have ``cls`` as ``NoneType``. It is more informat
|
||||
not cls.hasAttribute("__iter__")
|
||||
select loop, cls, origin
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/3795352249440053606/>`__. This reports the same results, but with a third column showing the source of the ``None`` values.
|
||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/3795352249440053606/>`__. This reports the same results, but with a third column showing the source of the ``None`` values.
|
||||
|
||||
Finding calls using call-graph analysis
|
||||
----------------------------------------------------
|
||||
@@ -193,7 +193,7 @@ The original query looked this:
|
||||
where call.getFunc() = name and name.getId() = "eval"
|
||||
select call, "call to 'eval'."
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/6718356557331218618/>`__. Some of the demo projects on LGTM.com have calls that match this pattern.
|
||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/6718356557331218618/>`__. Some of the demo projects on LGTM.com have calls that match this pattern.
|
||||
|
||||
There are two problems with this query:
|
||||
|
||||
@@ -221,7 +221,7 @@ Then we can use ``Value.getACall()`` to identify calls to the ``eval`` function,
|
||||
call = eval.getACall()
|
||||
select call, "call to 'eval'."
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/535131812579637425/>`__. This accurately identifies calls to the builtin ``eval`` function even when they are referred to using an alternative name. Any false positive results with calls to other ``eval`` functions, reported by the original query, have been eliminated.
|
||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/535131812579637425/>`__. This accurately identifies calls to the builtin ``eval`` function even when they are referred to using an alternative name. Any false positive results with calls to other ``eval`` functions, reported by the original query, have been eliminated.
|
||||
|
||||
Further reading
|
||||
---------------
|
||||
|
||||
@@ -52,7 +52,7 @@ The ``global`` statement in Python declares a variable with a global (module-lev
|
||||
where g.getScope() instanceof Module
|
||||
select g
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/686330052/>`__. None of the demo projects on LGTM.com has a global statement that matches this pattern.
|
||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/686330052/>`__. None of the demo projects on LGTM.com has a global statement that matches this pattern.
|
||||
|
||||
The line: ``g.getScope() instanceof Module`` ensures that the ``Scope`` of ``Global g`` is a ``Module``, rather than a class or function.
|
||||
|
||||
@@ -79,7 +79,7 @@ To find statements like this that could be simplified we can write a query.
|
||||
and forall(Stmt p | p = l.getAnItem() | p instanceof Pass)
|
||||
select i
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/672230053/>`__. Many projects have some ``if`` statements that match this pattern.
|
||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/672230053/>`__. Many projects have some ``if`` statements that match this pattern.
|
||||
|
||||
The line: ``(l = i.getBody() or l = i.getOrelse())`` restricts the ``StmtList l`` to branches of the ``if`` statement.
|
||||
|
||||
@@ -148,7 +148,7 @@ We can check for these using a query.
|
||||
and cmp.getOp(0) instanceof Is and cmp.getComparator(0) = literal
|
||||
select cmp
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/688180010/>`__. Two of the demo projects on LGTM.com use this pattern: *saltstack/salt* and *openstack/nova*.
|
||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/688180010/>`__. Two of the demo projects on LGTM.com use this pattern: *saltstack/salt* and *openstack/nova*.
|
||||
|
||||
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.
|
||||
|
||||
@@ -178,7 +178,7 @@ If there are duplicate keys in a Python dictionary, then the second key will ove
|
||||
and k1 != k2 and same_key(k1, k2)
|
||||
select k1, "Duplicate key in dict literal"
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/663330305/>`__. When we ran this query on LGTM.com, the source code of the *saltstack/salt* project contained an example of duplicate dictionary keys. The results were also highlighted as alerts by the standard "Duplicate key in dict literal" query. Two of the other demo projects on LGTM.com refer to duplicate dictionary keys in library files. For more information, see `Duplicate key in dict literal <https://lgtm.com/rules/3980087>`__ on LGTM.com.
|
||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/663330305/>`__. When we ran this query on LGTM.com, the source code of the *saltstack/salt* project contained an example of duplicate dictionary keys. The results were also highlighted as alerts by the standard "Duplicate key in dict literal" query. Two of the other demo projects on LGTM.com refer to duplicate dictionary keys in library files. For more information, see `Duplicate key in dict literal <https://lgtm.com/rules/3980087>`__ on LGTM.com.
|
||||
|
||||
The supporting predicate ``same_key`` checks that the keys have the same identifier. Separating this part of the logic into a supporting predicate, instead of directly including it in the query, makes it easier to understand the query as a whole. The casts defined in the predicate restrict the expression to the type specified and allow predicates to be called on the type that is cast-to. For example:
|
||||
|
||||
@@ -220,7 +220,7 @@ This basic query can be improved by checking that the one line of code is a Java
|
||||
and attr.getObject() = self and self.getId() = "self"
|
||||
select f, "This function is a Java-style getter."
|
||||
|
||||
➤ `See this in the query console <https://lgtm.com/query/669220054/>`__. Of the demo projects on LGTM.com, only the *openstack/nova* project has examples of functions that appear to be Java-style getters.
|
||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/669220054/>`__. Of the demo projects on LGTM.com, only the *openstack/nova* project has examples of functions that appear to be Java-style getters.
|
||||
|
||||
.. code-block:: ql
|
||||
|
||||
|
||||
Reference in New Issue
Block a user