Merge pull request #3184 from jf205/migration-28

CodeQL docs: update query console link text
This commit is contained in:
James Fletcher
2020-04-01 18:20:24 +01:00
committed by GitHub
36 changed files with 148 additions and 148 deletions

View File

@@ -103,7 +103,7 @@ Now try applying ``isAllowedIn(string region)`` to a person ``p``. If ``p`` is n
You know that the fire starters live in the south *and* that they must have been able to travel to the north. Write a query to find the possible suspects. You could also extend the ``select`` clause to list the age of the suspects. That way you can clearly see that all the children have been excluded from the list.
`See the answer in the query console <https://lgtm.com/query/2551838470440192723/>`__
`See the answer in the query console on LGTM.com <https://lgtm.com/query/2551838470440192723/>`__
You can now continue to gather more clues and find out which of your suspects started the fire...
@@ -140,7 +140,7 @@ The predicate ``isBald`` is defined to take a ``Person``, so it can also take a
You can now write a query to select the bald southerners who are allowed into the north.
`See the answer in the query console <https://lgtm.com/query/2572701606358725253/>`__
`See the answer in the query console on LGTM.com <https://lgtm.com/query/2572701606358725253/>`__
You have found the two fire starters! They are arrested and the villagers are once again impressed with your work.

View File

@@ -251,15 +251,15 @@ Here are some more example queries that solve the river crossing puzzle:
#. This query uses a modified ``path`` variable to describe the resulting path in
more detail.
`See solution in the query console <https://lgtm.com/query/659603593702729237/>`__
`See solution in the query console on LGTM.com <https://lgtm.com/query/659603593702729237/>`__
#. This query models the man and the cargo items in a different way, using an
`abstract <https://help.semmle.com/QL/ql-handbook/annotations.html#abstract>`__
class and predicate. It also displays the resulting path in a more visual way.
`See solution in the query console <https://lgtm.com/query/1025323464423811143/>`__
`See solution in the query console on LGTM.com <https://lgtm.com/query/1025323464423811143/>`__
#. This query introduces `algebraic datatypes <https://help.semmle.com/QL/ql-handbook/types.html#algebraic-datatypes>`__
to model the situation, instead of defining everything as a subclass of ``string``.
`See solution in the query console <https://lgtm.com/query/7260748307619718263/>`__
`See solution in the query console on LGTM.com <https://lgtm.com/query/7260748307619718263/>`__

View File

@@ -127,7 +127,7 @@ Here is one way to define ``relativeOf()``:
Don't forget to use the predicate ``isDeceased()`` to find relatives that are still alive.
`See the answer in the query console <https://lgtm.com/query/6710025057257064639/>`__
`See the answer in the query console on LGTM.com <https://lgtm.com/query/6710025057257064639/>`__
Select the true heir
--------------------
@@ -140,7 +140,7 @@ To decide who should inherit the king's fortune, the villagers carefully read th
As your final challenge, define a predicate ``hasCriminalRecord`` so that ``hasCriminalRecord(p)`` holds if ``p`` is any of the criminals you unmasked earlier (in the :doc:`Find the thief <find-the-thief>` and :doc:`Catch the fire starter <catch-the-fire-starter>` tutorials).
`See the answer in the query console <https://lgtm.com/query/1820692755164273290/>`__
`See the answer in the query console on LGTM.com <https://lgtm.com/query/1820692755164273290/>`__
Experimental explorations
-------------------------

View File

@@ -46,7 +46,7 @@ You start asking some creative questions and making notes of the answers so you
There is too much information to search through by hand, so you decide to use your newly acquired QL skills to help you with your investigation...
#. Open the `query console <https://lgtm.com/query>`__ to get started.
#. Open the `query console on LGTM.com <https://lgtm.com/query>`__ to get started.
#. Select a language and a demo project. For this tutorial, any language and project will do.
#. Delete the default code ``import <language> select "hello world"``.
@@ -205,7 +205,7 @@ Hints
Once you have finished, you will have a list of possible suspects. One of those people must be the thief!
`See the answer in the query console <https://lgtm.com/query/1505743955992/>`__
`See the answer in the query console on LGTM.com <https://lgtm.com/query/1505743955992/>`__
.. pull-quote::
@@ -287,7 +287,7 @@ You can now translate the remaining questions into QL:
Have you found the thief?
`See the answer in the query console <https://lgtm.com/query/1505744186085/>`__
`See the answer in the query console on LGTM.com <https://lgtm.com/query/1505744186085/>`__
What next?
----------

View File

@@ -163,7 +163,7 @@ Our starting point for the query is pairs of a base class and a derived class, c
where derived.getABaseClass+() = base
select base, derived, "The second class is derived from the first."
`See this in the query console <https://lgtm.com/query/1505902347211/>`__
`See this in the query console on LGTM.com <https://lgtm.com/query/1505902347211/>`__
Note that the transitive closure symbol ``+`` indicates that ``Class.getABaseClass()`` may be followed one or more times, rather than only accepting a direct base class.
@@ -175,7 +175,7 @@ A lot of the results are uninteresting template parameters. You can remove those
and not exists(base.getATemplateArgument())
and not exists(derived.getATemplateArgument())
`See this in the query console <https://lgtm.com/query/1505907047251/>`__
`See this in the query console on LGTM.com <https://lgtm.com/query/1505907047251/>`__
Finding derived classes with destructors
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -194,7 +194,7 @@ Now we can extend the query to find derived classes with destructors, using the
and d2 = derived.getDestructor()
select base, derived, "The second class is derived from the first, and both have a destructor."
`See this in the query console <https://lgtm.com/query/1505901767389/>`__
`See this in the query console on LGTM.com <https://lgtm.com/query/1505901767389/>`__
Notice that getting the destructor implicitly asserts that one exists. As a result, this version of the query returns fewer results than before.
@@ -214,7 +214,7 @@ Our last change is to use ``Function.isVirtual()`` to find cases where the base
and not d1.isVirtual()
select d1, "This destructor should probably be virtual."
`See this in the query console <https://lgtm.com/query/1505908156827/>`__
`See this in the query console on LGTM.com <https://lgtm.com/query/1505908156827/>`__
That completes the query.
@@ -227,4 +227,4 @@ Further reading
- Take a look at the :doc:`Analyzing data flow in C and C++ <dataflow>` tutorial.
- Try the worked examples in the following topics: :doc:`Refining a query to account for edge cases <private-field-initialization>`, and :doc:`Detecting a potential buffer overflow <zero-space-terminator>`.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__ on LGTM.com.

View File

@@ -300,7 +300,7 @@ Further reading
- Try the worked examples in the following topics: :doc:`Refining a query to account for edge cases <private-field-initialization>` and :doc:`Detecting a potential buffer overflow <zero-space-terminator>`.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__ on LGTM.com.
Answers
-------

View File

@@ -21,7 +21,7 @@ In the following example we find instances of ``AssignExpr`` which assign the co
where e.getRValue().getValue().toInt() = 0
select e, "Assigning the value 0 to something."
`See this in the query console <https://lgtm.com/query/1505908086530/>`__
`See this in the query console on LGTM.com <https://lgtm.com/query/1505908086530/>`__
The ``where`` clause in this example gets the expression on the right side of the assignment, ``getRValue()``, and compares it with zero. Notice that there are no checks to make sure that the right side of the assignment is an integer or that it has a value (that is, it is compile-time constant, rather than a variable). For expressions where either of these assumptions is wrong, the associated predicate simply does not return anything and the ``where`` clause will not produce a result. You could think of it as if there is an implicit ``exists(e.getRValue().getValue().toInt())`` at the beginning of this line.
@@ -47,7 +47,7 @@ We can make the query more specific by defining a condition for the left side of
and e.getLValue().getType().getUnspecifiedType() instanceof IntegralType
select e, "Assigning the value 0 to an integer."
`See this in the query console <https://lgtm.com/query/1505906986578/>`__
`See this in the query console on LGTM.com <https://lgtm.com/query/1505906986578/>`__
This checks that the left side of the assignment has a type that is some kind of integer. Note the call to ``Type.getUnspecifiedType()``. This resolves ``typedef`` types to their underlying types so that the query finds assignments like this one:
@@ -107,7 +107,7 @@ Unfortunately this would not quite work, because the loop initialization is actu
and e.getLValue().getType().getUnspecifiedType() instanceof IntegralType
select e, "Assigning the value 0 to an integer, inside a for loop initialization."
`See this in the query console <https://lgtm.com/query/1505909016965/>`__
`See this in the query console on LGTM.com <https://lgtm.com/query/1505909016965/>`__
Finding assignments of 0 within the loop body
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -125,7 +125,7 @@ We can find assignments inside the loop body using similar code with the predica
and e.getLValue().getType().getUnderlyingType() instanceof IntegralType
select e, "Assigning the value 0 to an integer, inside a for loop body."
`See this in the query console <https://lgtm.com/query/1505901437190/>`__
`See this in the query console on LGTM.com <https://lgtm.com/query/1505901437190/>`__
Note that we replaced ``e.getEnclosingStmt()`` with ``e.getEnclosingStmt().getParentStmt*()``, to find an assignment expression that is deeply nested inside the loop body. The transitive closure modifier ``*`` here indicates that ``Stmt.getParentStmt()`` may be followed zero or more times, rather than just once, giving us the statement, its parent statement, its parent's parent statement etc.
@@ -135,4 +135,4 @@ Further reading
- Explore other ways of finding types and statements using examples from the C/C++ cookbook for `types <https://help.semmle.com/wiki/label/CBCPP/type>`__ and `statements <https://help.semmle.com/wiki/label/CBCPP/statement>`__.
- Take a look at the :doc:`Conversions and classes in C and C++ <conversions-classes>` and :doc:`Analyzing data flow in C and C++ <dataflow>` tutorials.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__ on LGTM.com.

View File

@@ -38,7 +38,7 @@ It might be more interesting to find functions that are not called, using the st
where not exists(FunctionCall fc | fc.getTarget() = f)
select f, "This function is never called."
`See this in the query console <https://lgtm.com/query/1505891246456/>`__
`See this in the query console on LGTM.com <https://lgtm.com/query/1505891246456/>`__
The new query finds functions that are not the target of any ``FunctionCall``—in other words, functions that are never called. You may be surprised by how many results the query finds. However, if you examine the results, you can see that many of the functions it finds are used indirectly. To create a query that finds only unused functions, we need to refine the query and exclude other ways of using a function.
@@ -56,7 +56,7 @@ You can modify the query to remove functions where a function pointer is used to
and not exists(FunctionAccess fa | fa.getTarget() = f)
select f, "This function is never called, or referenced with a function pointer."
`See this in the query console <https://lgtm.com/query/1505890446605/>`__
`See this in the query console on LGTM.com <https://lgtm.com/query/1505890446605/>`__
This query returns fewer results. However, if you examine the results then you can probably still find potential refinements.
@@ -78,7 +78,7 @@ This query uses ``Function`` and ``FunctionCall`` to find calls to the function
and not fc.getArgument(1) instanceof StringLiteral
select fc, "sprintf called with variable format string."
`See this in the query console <https://lgtm.com/query/1505889506751/>`__
`See this in the query console on LGTM.com <https://lgtm.com/query/1505889506751/>`__
This uses:
@@ -95,4 +95,4 @@ Further reading
- Explore other ways of finding functions using examples from the `C/C++ cookbook <https://help.semmle.com/wiki/label/CBCPP/function>`__.
- Take a look at some other tutorials: :doc:`Expressions, types and statements in C and C++ <introduce-libraries-cpp>`, :doc:`Conversions and classes in C and C++ <conversions-classes>`, and :doc:`Analyzing data flow in C and C++ <dataflow>`.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__ on LGTM.com.

View File

@@ -525,4 +525,4 @@ Further reading
- Experiment with the worked examples in the CodeQL for C/C++ topics: :doc:`Functions in C and C++ <function-classes>`, :doc:`Expressions, types, and statements in C and C++ <expressions-types>`, :doc:`Conversions and classes in C and C++ <conversions-classes>`, and :doc:`Analyzing data flow in C and C++ <dataflow>`.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__ on LGTM.com.

View File

@@ -144,11 +144,11 @@ Finally we can simplify the query by using the transitive closure operator. In t
and exists(c.getBlock())
select c, "Constructor does not initialize fields $@.", f, f.getName()
`See this in the query console <https://lgtm.com/query/1505896968215/>`__
`See this in the query console on LGTM.com <https://lgtm.com/query/1505896968215/>`__
Further reading
---------------
- Take a look at another example: :doc:`Detecting a potential buffer overflow <zero-space-terminator>`.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__ on LGTM.com.

View File

@@ -225,4 +225,4 @@ Further reading
---------------
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__ on LGTM.com.

View File

@@ -551,4 +551,4 @@ Further reading
- Learn about the standard libraries used to write queries for C# in :doc:`Introducing the C# libraries <introduce-libraries-csharp>`.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__ on LGTM.com.

View File

@@ -1124,4 +1124,4 @@ Further reading
- Visit :doc:`Analyzing data flow in C# <dataflow>` to learn more about writing queries using the standard data flow and taint tracking libraries.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__ on LGTM.com.

View File

@@ -1,7 +1,7 @@
What's in a CodeQL database?
============================
A CodeQL database contains a variety of data related to a particular code base at a particular point in time. For details of how the database is generated see `Database generation <https://lgtm.com/help/lgtm/generate-database>`__.
A CodeQL database contains a variety of data related to a particular code base at a particular point in time. For details of how the database is generated see `Database generation <https://lgtm.com/help/lgtm/generate-database>`__ on LGTM.com.
The database contains a full, hierarchical representation of the program defined by the code base. The database schema varies according to the language analyzed. The schema provides an interface between the initial lexical analysis during the extraction process, and the actual complex analysis using CodeQL. When the source code languages being analyzed change (such as Java 7 evolving into Java 8), this interface between the analysis phases can also change.

View File

@@ -4,7 +4,7 @@ Learning CodeQL
CodeQL is the code analysis platform used by security researchers to automate variant analysis.
You can use CodeQL queries to explore code and quickly find variants of security vulnerabilities and bugs.
These queries are easy to write and sharevisit the topics below and `our open source repository on GitHub <https://github.com/Semmle/ql>`__ to learn more.
You can also try out CodeQL in the `query console <https://lgtm.com/query>`__ on `LGTM.com <https://lgtm.com>`__.
You can also try out CodeQL in the `query console on LGTM.com <https://lgtm.com/query>`__.
Here, you can query open source projects directly, without having to download CodeQL databases and libraries.
CodeQL is based on a powerful query language called QL. The following topics help you understand QL in general, as well as how to use it when analyzing code with CodeQL.

View File

@@ -16,7 +16,7 @@ Basic syntax
The basic syntax of QL will look familiar to anyone who has used SQL, but it is used somewhat differently.
A query is defined by a **select** clause, which specifies what the result of the query should be. You can try out the examples and exercises in this topic directly in LGTM. Open the `query console <https://lgtm.com/query>`__. Before you can run a query, you need to select a language and project to query (for these logic examples, any language and project will do).
A query is defined by a **select** clause, which specifies what the result of the query should be. You can try out the examples and exercises in this topic directly in LGTM. Open the `query console on LGTM.com <https://lgtm.com/query>`__. Before you can run a query, you need to select a language and project to query (for these logic examples, any language and project will do).
Once you have selected a language, the query console is populated with the query:
@@ -97,7 +97,7 @@ The exercises above all show queries with exactly one result, but in fact many q
x*x + y*y = z*z
select x, y, z
`See this in the query console <https://lgtm.com/query/2100790036/>`__
`See this in the query console on LGTM.com <https://lgtm.com/query/2100790036/>`__
To simplify the query, we can introduce a class ``SmallInt`` representing the integers between 1 and 10. We can also define a predicate ``square()`` on integers in that class. Defining classes and predicates in this way makes it easy to reuse code without having to repeat it every time.
@@ -112,10 +112,10 @@ To simplify the query, we can introduce a class ``SmallInt`` representing the in
where x.square() + y.square() = z.square()
select x, y, z
`See this in the query console <https://lgtm.com/query/2101340747/>`__
`See this in the query console on LGTM.com <https://lgtm.com/query/2101340747/>`__
Now that you've seen some general examples, let's use the CodeQL libraries to analyze projects.
In particular, LGTM generates a database representing the code and then CodeQL is used to query this database. See `Database generation <https://lgtm.com/help/lgtm/generate-database>`__ for more details on how the database is built.
In particular, LGTM generates a database representing the code and then CodeQL is used to query this database. For more information, see `Database generation <https://lgtm.com/help/lgtm/generate-database>`__ on LGTM.com.
.. XX: Perhaps a link to the "CodeQL libraries for X"?
@@ -132,7 +132,7 @@ Python
where count(f.getAnArg()) > 7
select f
`See this in the query console <https://lgtm.com/query/2096810474/>`__. The ``from`` clause defines a variable ``f`` representing a function. The ``where`` part limits the functions ``f`` to those with more than 7 arguments. Finally, the ``select`` clause lists these functions.
`See this in the query console on LGTM.com <https://lgtm.com/query/2096810474/>`__. The ``from`` clause defines a variable ``f`` representing a function. The ``where`` part limits the functions ``f`` to those with more than 7 arguments. Finally, the ``select`` clause lists these functions.
JavaScript
~~~~~~~~~~
@@ -145,7 +145,7 @@ JavaScript
where c.getText().regexpMatch("(?si).*\\bTODO\\b.*")
select c
`See this in the query console <https://lgtm.com/query/2101530483/>`__. The ``from`` clause defines a variable ``c`` representing a comment. The ``where`` part limits the comments ``c`` to those containing the word ``"TODO"``. The ``select`` clause lists these comments.
`See this in the query console on LGTM.com <https://lgtm.com/query/2101530483/>`__. The ``from`` clause defines a variable ``c`` representing a comment. The ``where`` part limits the comments ``c`` to those containing the word ``"TODO"``. The ``select`` clause lists these comments.
Java
~~~~
@@ -158,7 +158,7 @@ Java
where not exists(p.getAnAccess())
select p
`See this in the query console <https://lgtm.com/query/2098670762/>`__. The ``from`` clause defines a variable ``p`` representing a parameter. The ``where`` clause finds unused parameters by limiting the parameters ``p`` to those which are not accessed. Finally, the ``select`` clause lists these parameters.
`See this in the query console on LGTM.com <https://lgtm.com/query/2098670762/>`__. The ``from`` clause defines a variable ``p`` representing a parameter. The ``where`` clause finds unused parameters by limiting the parameters ``p`` to those which are not accessed. Finally, the ``select`` clause lists these parameters.
Learning CodeQL
---------------

View File

@@ -49,7 +49,7 @@ We could then write this query to find all ``@SuppressWarnings`` annotations att
anntp.hasQualifiedName("java.lang", "SuppressWarnings")
select ann, ann.getValue("value")
`See the full query in the query console <https://lgtm.com/query/632150601>`__. Several of the LGTM.com demo projects use the ``@SuppressWarnings`` annotation. Looking at the ``value``\ s of the annotation element returned by the query, we can see that the *apache/activemq* project uses the ``"rawtypes"`` value described above.
`See the full query in the query console on LGTM.com <https://lgtm.com/query/632150601>`__. Several of the LGTM.com demo projects use the ``@SuppressWarnings`` annotation. Looking at the ``value``\ s of the annotation element returned by the query, we can see that the *apache/activemq* project uses the ``"rawtypes"`` value described above.
As another example, this query finds all annotation types that only have a single annotation element, which has name ``value``:
@@ -64,7 +64,7 @@ As another example, this query finds all annotation types that only have a singl
)
select anntp
`See the full query in the query console <https://lgtm.com/query/669220001>`__.
`See the full query in the query console on LGTM.com <https://lgtm.com/query/669220001>`__.
Example: Finding missing ``@Override`` annotations
--------------------------------------------------
@@ -122,7 +122,7 @@ This makes it very easy to write our query for finding methods that override ano
not overriding.getAnAnnotation() instanceof OverrideAnnotation
select overriding, "Method overrides another method, but does not have an @Override annotation."
`See this in the query console <https://lgtm.com/query/1505752756202/>`__. In practice, this query may yield many results from compiled library code, which aren't very interesting. It's therefore a good idea to add another conjunct ``overriding.fromSource()`` to restrict the result to only report methods for which source code is available.
`See this in the query console on LGTM.com <https://lgtm.com/query/1505752756202/>`__. In practice, this query may yield many results from compiled library code, which aren't very interesting. It's therefore a good idea to add another conjunct ``overriding.fromSource()`` to restrict the result to only report methods for which source code is available.
Example: Finding calls to deprecated methods
--------------------------------------------
@@ -235,7 +235,7 @@ Now we can extend our query to filter out calls in methods carrying a ``Suppress
and not call.getCaller().getAnAnnotation() instanceof SuppressDeprecationWarningAnnotation
select call, "This call invokes a deprecated method."
`See this in the query console <https://lgtm.com/query/665760001>`__. It's fairly common for projects to contain calls to methods that appear to be deprecated.
`See this in the query console on LGTM.com <https://lgtm.com/query/665760001>`__. It's fairly common for projects to contain calls to methods that appear to be deprecated.
Further reading
---------------

View File

@@ -78,7 +78,7 @@ We can use the ``Callable`` class to write a query that finds methods that are n
where not exists(Callable caller | caller.polyCalls(callee))
select callee
`See this in the query console <https://lgtm.com/query/665280012/>`__. This simple query typically returns a large number of results.
`See this in the query console on LGTM.com <https://lgtm.com/query/665280012/>`__. This simple query typically returns a large number of results.
.. pull-quote::
@@ -97,7 +97,7 @@ Running this query on a typical Java project results in lots of hits in the Java
callee.getCompilationUnit().fromSource()
select callee, "Not called."
`See this in the query console <https://lgtm.com/query/668510015/>`__. This change reduces the number of results returned for most projects.
`See this in the query console on LGTM.com <https://lgtm.com/query/668510015/>`__. This change reduces the number of results returned for most projects.
We might also notice several unused methods with the somewhat strange name ``<clinit>``: these are class initializers; while they are not explicitly called anywhere in the code, they are called implicitly whenever the surrounding class is loaded. Hence it makes sense to exclude them from our query. While we are at it, we can also exclude finalizers, which are similarly invoked implicitly:
@@ -111,7 +111,7 @@ We might also notice several unused methods with the somewhat strange name ``<cl
not callee.hasName("<clinit>") and not callee.hasName("finalize")
select callee, "Not called."
`See this in the query console <https://lgtm.com/query/672230002/>`__. This also reduces the number of results returned by most projects.
`See this in the query console on LGTM.com <https://lgtm.com/query/672230002/>`__. This also reduces the number of results returned by most projects.
We may also want to exclude public methods from our query, since they may be external API entry points:
@@ -126,7 +126,7 @@ We may also want to exclude public methods from our query, since they may be ext
not callee.isPublic()
select callee, "Not called."
`See this in the query console <https://lgtm.com/query/667290016/>`__. This should have a more noticeable effect on the number of results returned.
`See this in the query console on LGTM.com <https://lgtm.com/query/667290016/>`__. This should have a more noticeable effect on the number of results returned.
A further special case is non-public default constructors: in the singleton pattern, for example, a class is provided with private empty default constructor to prevent it from being instantiated. Since the very purpose of such constructors is their not being called, they should not be flagged up:
@@ -142,7 +142,7 @@ A further special case is non-public default constructors: in the singleton patt
not callee.(Constructor).getNumberOfParameters() = 0
select callee, "Not called."
`See this in the query console <https://lgtm.com/query/673060008/>`__. This change has a large effect on the results for some projects but little effect on the results for others. Use of this pattern varies widely between different projects.
`See this in the query console on LGTM.com <https://lgtm.com/query/673060008/>`__. This change has a large effect on the results for some projects but little effect on the results for others. Use of this pattern varies widely between different projects.
Finally, on many Java projects there are methods that are invoked indirectly by reflection. So, while there are no calls invoking these methods, they are, in fact, used. It is in general very hard to identify such methods. A very common special case, however, is JUnit test methods, which are reflectively invoked by a test runner. The QL Java library has support for recognizing test classes of JUnit and other testing frameworks, which we can employ to filter out methods defined in such classes:
@@ -159,7 +159,7 @@ Finally, on many Java projects there are methods that are invoked indirectly by
not callee.getDeclaringType() instanceof TestClass
select callee, "Not called."
`See this in the query console <https://lgtm.com/query/665760002/>`__. This should give a further reduction in the number of results returned.
`See this in the query console on LGTM.com <https://lgtm.com/query/665760002/>`__. This should give a further reduction in the number of results returned.
Further reading
---------------

View File

@@ -258,7 +258,7 @@ Further reading
- Try the worked examples in these articles: :doc:`Navigating the call graph <call-graph>` and :doc:`Working with source locations <source-locations>`.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__ on LGTM.com.
Answers
-------

View File

@@ -42,7 +42,7 @@ We'll start by writing a query that finds less-than expressions (CodeQL class ``
expr.getRightOperand().getType().hasName("long")
select expr
`See this in the query console <https://lgtm.com/query/672320008/>`__. This query usually finds results on most projects.
`See this in the query console on LGTM.com <https://lgtm.com/query/672320008/>`__. This query usually finds results on most projects.
Notice that we use the predicate ``getType`` (available on all subclasses of ``Expr``) to determine the type of the operands. Types, in turn, define the ``hasName`` predicate, which allows us to identify the primitive types ``int`` and ``long``. As it stands, this query finds *all* less-than expressions comparing ``int`` and ``long``, but in fact we are only interested in comparisons that are part of a loop condition. Also, we want to filter out comparisons where either operand is constant, since these are less likely to be real bugs. The revised query looks like this:
@@ -57,7 +57,7 @@ Notice that we use the predicate ``getType`` (available on all subclasses of ``E
not expr.getAnOperand().isCompileTimeConstant()
select expr
`See this in the query console <https://lgtm.com/query/690010001/>`__. Notice that fewer results are found.
`See this in the query console on LGTM.com <https://lgtm.com/query/690010001/>`__. Notice that fewer results are found.
The class ``LoopStmt`` is a common superclass of all loops, including, in particular, ``for`` loops as in our example above. While different kinds of loops have different syntax, they all have a loop condition, which can be accessed through predicate ``getCondition``. We use the reflexive transitive closure operator ``*`` applied to the ``getAChildExpr`` predicate to express the requirement that ``expr`` should be nested inside the loop condition. In particular, it can be the loop condition itself.
@@ -120,7 +120,7 @@ Now we rewrite our query to make use of these new classes:
not expr.getAnOperand().isCompileTimeConstant()
select expr
`See the full query in the query console <https://lgtm.com/query/1951710018/lang:java/>`__.
`See the full query in the query console on LGTM.com <https://lgtm.com/query/1951710018/lang:java/>`__.
Further reading
---------------

View File

@@ -68,7 +68,7 @@ For example, the following query finds all variables of type ``int`` in the prog
pt.hasName("int")
select v
`See this in the query console <https://lgtm.com/query/660700018/>`__. You're likely to get many results when you run this query because most projects contain many variables of type ``int``.
`See this in the query console on LGTM.com <https://lgtm.com/query/660700018/>`__. You're likely to get many results when you run this query because most projects contain many variables of type ``int``.
Reference types are also categorized according to their declaration scope:
@@ -85,7 +85,7 @@ For instance, this query finds all top-level types whose name is not the same as
where tl.getName() != tl.getCompilationUnit().getName()
select tl
`See this in the query console <https://lgtm.com/query/674620002/>`__. This pattern is seen in many projects. When we ran it on the LGTM.com demo projects, most of the projects had at least one instance of this problem in the source code. There were many more instances in the files referenced by the source code.
`See this in the query console on LGTM.com <https://lgtm.com/query/674620002/>`__. This pattern is seen in many projects. When we ran it on the LGTM.com demo projects, most of the projects had at least one instance of this problem in the source code. There were many more instances in the files referenced by the source code.
Several more specialized classes are available as well:
@@ -107,7 +107,7 @@ As an example, we can write a query that finds all nested classes that directly
where nc.getASupertype() instanceof TypeObject
select nc
`See this in the query console <https://lgtm.com/query/672230026/>`__. You're likely to get many results when you run this query because many projects include nested classes that extend ``Object`` directly.
`See this in the query console on LGTM.com <https://lgtm.com/query/672230026/>`__. You're likely to get many results when you run this query because many projects include nested classes that extend ``Object`` directly.
Generics
~~~~~~~~
@@ -141,7 +141,7 @@ For instance, we could use the following query to find all parameterized instanc
pt.getSourceDeclaration() = map
select pt
`See this in the query console <https://lgtm.com/query/660700019/>`__. None of the LGTM.com demo projects contain parameterized instances of ``java.util.Map`` in their source code, but they all have results in reference files.
`See this in the query console on LGTM.com <https://lgtm.com/query/660700019/>`__. None of the LGTM.com demo projects contain parameterized instances of ``java.util.Map`` in their source code, but they all have results in reference files.
In general, generic types may restrict which types a type parameter can be bound to. For instance, a type of maps from strings to numbers could be declared as follows:
@@ -164,7 +164,7 @@ As an example, the following query finds all type variables with type bound ``Nu
tb.getType().hasQualifiedName("java.lang", "Number")
select tv
`See this in the query console <https://lgtm.com/query/690010016/>`__. When we ran it on the LGTM.com demo projects, the *neo4j/neo4j*, *gradle/gradle* and *hibernate/hibernate-orm* projects all contained examples of this pattern.
`See this in the query console on LGTM.com <https://lgtm.com/query/690010016/>`__. When we ran it on the LGTM.com demo projects, the *neo4j/neo4j*, *gradle/gradle* and *hibernate/hibernate-orm* projects all contained examples of this pattern.
For dealing with legacy code that is unaware of generics, every generic type has a "raw" version without any type parameters. In the CodeQL libraries, raw types are represented using class ``RawType``, which has the expected subclasses ``RawClass`` and ``RawInterface``. Again, there is a predicate ``getSourceDeclaration`` for obtaining the corresponding generic type. As an example, we can find variables of (raw) type ``Map``:
@@ -177,7 +177,7 @@ For dealing with legacy code that is unaware of generics, every generic type has
rt.getSourceDeclaration().hasQualifiedName("java.util", "Map")
select v
`See this in the query console <https://lgtm.com/query/686320008/>`__. Many projects have variables of raw type ``Map``.
`See this in the query console on LGTM.com <https://lgtm.com/query/686320008/>`__. Many projects have variables of raw type ``Map``.
For example, in the following code snippet this query would find ``m1``, but not ``m2``:
@@ -228,7 +228,7 @@ For example, the following query finds all expressions whose parents are ``retur
where e.getParent() instanceof ReturnStmt
select e
`See this in the query console <https://lgtm.com/query/668700463/>`__. Many projects have examples of ``return`` statements with child statements.
`See this in the query console on LGTM.com <https://lgtm.com/query/668700463/>`__. Many projects have examples of ``return`` statements with child statements.
Therefore, if the program contains a return statement ``return x + y;``, this query will return ``x + y``.
@@ -242,7 +242,7 @@ As another example, the following query finds statements whose parent is an ``if
where s.getParent() instanceof IfStmt
select s
`See this in the query console <https://lgtm.com/query/670720173/>`__. Many projects have examples of ``if`` statements with child statements.
`See this in the query console on LGTM.com <https://lgtm.com/query/670720173/>`__. Many projects have examples of ``if`` statements with child statements.
This query will find both ``then`` branches and ``else`` branches of all ``if`` statements in the program.
@@ -256,7 +256,7 @@ Finally, here is a query that finds method bodies:
where s.getParent() instanceof Method
select s
`See this in the query console <https://lgtm.com/query/663740023/>`__. Most projects have many method bodies.
`See this in the query console on LGTM.com <https://lgtm.com/query/663740023/>`__. Most projects have many method bodies.
As these examples show, the parent node of an expression is not always an expression: it may also be a statement, for example, an ``IfStmt``. Similarly, the parent node of a statement is not always a statement: it may also be a method or a constructor. To capture this, the QL Java library provides two abstract class ``ExprParent`` and ``StmtParent``, the former representing any node that may be the parent node of an expression, and the latter any node that may be the parent node of a statement.
@@ -276,7 +276,7 @@ For annotations, class ``Annotatable`` is a superclass of all program elements t
from Constructor c
select c.getAnAnnotation()
`See this in the query console <https://lgtm.com/query/665620008/>`__. The LGTM.com demo projects all use annotations, you can see examples where they are used to suppress warnings and mark code as deprecated.
`See this in the query console on LGTM.com <https://lgtm.com/query/665620008/>`__. The LGTM.com demo projects all use annotations, you can see examples where they are used to suppress warnings and mark code as deprecated.
These annotations are represented by class ``Annotation``. An annotation is simply an expression whose type is an ``AnnotationType``. For example, you can amend this query so that it only reports deprecated constructors:
@@ -290,7 +290,7 @@ These annotations are represented by class ``Annotation``. An annotation is simp
anntp.hasQualifiedName("java.lang", "Deprecated")
select ann
`See this in the query console <https://lgtm.com/query/659662167/>`__. Only constructors with the ``@deprecated`` annotation are reported this time.
`See this in the query console on LGTM.com <https://lgtm.com/query/659662167/>`__. Only constructors with the ``@deprecated`` annotation are reported this time.
For more information on working with annotations, see the :doc:`article on annotations <annotations>`.
@@ -305,7 +305,7 @@ For Javadoc, class ``Element`` has a member predicate ``getDoc`` that returns a
jdoc = f.getDoc().getJavadoc()
select jdoc
`See this in the query console <https://lgtm.com/query/663330296/>`__. You can see this pattern in many projects.
`See this in the query console on LGTM.com <https://lgtm.com/query/663330296/>`__. You can see this pattern in many projects.
Class ``Javadoc`` represents an entire Javadoc comment as a tree of ``JavadocElement`` nodes, which can be traversed using member predicates ``getAChild`` and ``getParent``. For instance, you could edit the query so that it finds all ``@author`` tags in Javadoc comments on private fields:
@@ -319,7 +319,7 @@ Class ``Javadoc`` represents an entire Javadoc comment as a tree of ``JavadocEle
at.getParent+() = jdoc
select at
`See this in the query console <https://lgtm.com/query/670490015/>`__. None of the LGTM.com demo projects uses the ``@author`` tag on private fields.
`See this in the query console on LGTM.com <https://lgtm.com/query/670490015/>`__. None of the LGTM.com demo projects uses the ``@author`` tag on private fields.
.. pull-quote::
@@ -347,7 +347,7 @@ For example, the following query finds methods with a `cyclomatic complexity <ht
mc.getCyclomaticComplexity() > 40
select m
`See this in the query console <https://lgtm.com/query/670720174/>`__. Most large projects include some methods with a very high cyclomatic complexity. These methods are likely to be difficult to understand and test.
`See this in the query console on LGTM.com <https://lgtm.com/query/670720174/>`__. Most large projects include some methods with a very high cyclomatic complexity. These methods are likely to be difficult to understand and test.
Call graph
----------
@@ -367,7 +367,7 @@ We can use predicate ``Call.getCallee`` to find out which method or constructor
m.hasName("println")
select c
`See this in the query console <https://lgtm.com/query/669220009/>`__. The LGTM.com demo projects all include many calls to methods of this name.
`See this in the query console on LGTM.com <https://lgtm.com/query/669220009/>`__. The LGTM.com demo projects all include many calls to methods of this name.
Conversely, ``Callable.getAReference`` returns a ``Call`` that refers to it. So we can find methods and constructors that are never called using this query:
@@ -379,7 +379,7 @@ Conversely, ``Callable.getAReference`` returns a ``Call`` that refers to it. So
where not exists(c.getAReference())
select c
`See this in the query console <https://lgtm.com/query/666680036/>`__. The LGTM.com demo projects all appear to have many methods that are not called directly, but this is unlikely to be the whole story. To explore this area further, see :doc:`Navigating the call graph <call-graph>`.
`See this in the query console on LGTM.com <https://lgtm.com/query/666680036/>`__. The LGTM.com demo projects all appear to have many methods that are not called directly, but this is unlikely to be the whole story. To explore this area further, see :doc:`Navigating the call graph <call-graph>`.
For more information about callables and calls, see the :doc:`article on the call graph <call-graph>`.

View File

@@ -147,7 +147,7 @@ Now we can write a query for finding all callables ``c`` and ``@throws`` tags ``
not mayThrow(c, exn)
select tt, "Spurious @throws tag."
`See this in the query console <https://lgtm.com/query/1505752646058/>`__. This finds several results in the LGTM.com demo projects.
`See this in the query console on LGTM.com <https://lgtm.com/query/1505752646058/>`__. This finds several results in the LGTM.com demo projects.
Improvements
~~~~~~~~~~~~
@@ -214,7 +214,7 @@ The first case can be covered by changing ``getDocumentedException`` to use the
(result.hasName(tt.getExceptionName()) and visibleIn(tt.getFile(), result))
}
`See this in the query console <https://lgtm.com/query/1505751136101/>`__. This finds many fewer, more interesting results in the LGTM.com demo projects.
`See this in the query console on LGTM.com <https://lgtm.com/query/1505751136101/>`__. This finds many fewer, more interesting results in the LGTM.com demo projects.
Currently, ``visibleIn`` only considers single-type imports, but you could extend it with support for other kinds of imports.

View File

@@ -110,7 +110,7 @@ Here's a first version of our query:
wsinner > wsouter
select outer, "Whitespace around nested operators contradicts precedence."
`See this in the query console <https://lgtm.com/query/672230027/>`__. This query is likely to find results on most projects.
`See this in the query console on LGTM.com <https://lgtm.com/query/672230027/>`__. This query is likely to find results on most projects.
The first conjunct of the ``where`` clause restricts ``inner`` to be an operand of ``outer``, the second conjunct binds ``wsinner`` and ``wsouter``, while the last conjunct selects the suspicious cases.
@@ -141,7 +141,7 @@ Note that our predicate ``operatorWS`` computes the **total** amount of white sp
wsinner > wsouter
select outer, "Whitespace around nested operators contradicts precedence."
`See this in the query console <https://lgtm.com/query/665761067/>`__. Any results will be refined by our changes to the query.
`See this in the query console on LGTM.com <https://lgtm.com/query/665761067/>`__. Any results will be refined by our changes to the query.
Another source of false positives are associative operators: in an expression of the form ``x + y+z``, the first plus is syntactically nested inside the second, since + in Java associates to the left; hence the expression is flagged as suspicious. But since + is associative to begin with, it does not matter which way around the operators are nested, so this is a false positive.To exclude these cases, let us define a new class identifying binary expressions with an associative operator:
@@ -173,7 +173,7 @@ Now we can extend our query to discard results where the outer and the inner exp
wsinner > wsouter
select outer, "Whitespace around nested operators contradicts precedence."
`See this in the query console <https://lgtm.com/query/659662169/>`__.
`See this in the query console on LGTM.com <https://lgtm.com/query/659662169/>`__.
Notice that we again use ``getOp``, this time to determine whether two binary expressions have the same operator. Running our improved query now finds the Java standard library bug described in the Overview. It also flags up the following suspicious code in `Hadoop HBase <http://hbase.apache.org/>`__:

View File

@@ -32,7 +32,7 @@ To determine ancestor types (including immediate super types, and also *their* s
where B.hasName("B")
select B.getASupertype+()
`See this in the query console <https://lgtm.com/query/674620010/>`__. If this query were run on the example snippet above, the query would return ``A``, ``I``, and ``java.lang.Object``.
`See this in the query console on LGTM.com <https://lgtm.com/query/674620010/>`__. If this query were run on the example snippet above, the query would return ``A``, ``I``, and ``java.lang.Object``.
.. pull-quote::
@@ -78,7 +78,7 @@ This recipe is not too difficult to translate into a query:
target.getElementType().(RefType).getASupertype+() = source.getElementType()
select ce, "Potentially problematic array downcast."
`See this in the query console <https://lgtm.com/query/666680038/>`__. Many projects return results for this query.
`See this in the query console on LGTM.com <https://lgtm.com/query/666680038/>`__. Many projects return results for this query.
Note that by casting ``target.getElementType()`` to a ``RefType``, we eliminate all cases where the element type is a primitive type, that is, ``target`` is an array of primitive type: the problem we are looking for cannot arise in that case. Unlike in Java, a cast in QL never fails: if an expression cannot be cast to the desired type, it is simply excluded from the query results, which is exactly what we want.
@@ -141,7 +141,7 @@ Using these new classes we can extend our query to exclude calls to ``toArray``
not ce.getExpr().(CollectionToArrayCall).getActualReturnType() = target
select ce, "Potentially problematic array downcast."
`See this in the query console <https://lgtm.com/query/668700471/>`__. Notice that fewer results are found by this improved query.
`See this in the query console on LGTM.com <https://lgtm.com/query/668700471/>`__. Notice that fewer results are found by this improved query.
Example: Finding mismatched contains checks
-------------------------------------------
@@ -267,7 +267,7 @@ Now we are ready to write a first version of our query:
not haveCommonDescendant(collEltType, argType)
select juccc, "Element type " + collEltType + " is incompatible with argument type " + argType
`See this in the query console <https://lgtm.com/query/1505750556420/>`__.
`See this in the query console on LGTM.com <https://lgtm.com/query/1505750556420/>`__.
Improvements
~~~~~~~~~~~~
@@ -294,7 +294,7 @@ Adding these three improvements, our final query becomes:
not argType.hasName("<nulltype>")
select juccc, "Element type " + collEltType + " is incompatible with argument type " + argType
`See the full query in the query console <https://lgtm.com/query/1505753056300/>`__.
`See the full query in the query console on LGTM.com <https://lgtm.com/query/1505753056300/>`__.
Further reading
---------------

View File

@@ -468,7 +468,7 @@ Further reading
---------------
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__ on LGTM.com.
- Learn about writing more precise data-flow analyses in :doc:`Using flow labels for precise data flow analysis <flow-labels>`
Answers

View File

@@ -400,4 +400,4 @@ Further reading
- Learn about the standard CodeQL libraries used to write queries for JavaScript in :doc:`CodeQL libraries for JavaScript <introduce-libraries-js>`.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__ on LGTM.com.

View File

@@ -75,7 +75,7 @@ For example, the following query computes, for each folder, the number of JavaSc
from Folder d
select d.getRelativePath(), count(File f | f = d.getAFile() and f.getExtension() = "js")
`See this in the query console <https://lgtm.com/query/1506075865985/>`__. When you run the query on most projects, the results include folders that contain files with a ``js`` extension and folders that don't.
`See this in the query console on LGTM.com <https://lgtm.com/query/1506075865985/>`__. When you run the query on most projects, the results include folders that contain files with a ``js`` extension and folders that don't.
Locations
^^^^^^^^^
@@ -136,7 +136,7 @@ As an example of a query operating entirely on the lexical level, consider the f
where comma.getNextToken() instanceof CommaToken
select comma, "Omitted array elements are bad style."
`See this in the query console <https://lgtm.com/query/659662177/>`__. If the query returns no results, this pattern isn't used in the projects that you analyzed.
`See this in the query console on LGTM.com <https://lgtm.com/query/659662177/>`__. If the query returns no results, this pattern isn't used in the projects that you analyzed.
You can use predicate ``Locatable.getFirstToken()`` and ``Locatable.getLastToken()`` to access the first and last token (if any) belonging to an element with a source location.
@@ -177,7 +177,7 @@ As an example of a query using only lexical information, consider the following
from HtmlLineComment c
select c, "Do not use HTML comments."
`See this in the query console <https://lgtm.com/query/686330023/>`__. When we ran this query on the *mozilla/pdf.js* project in LGTM.com, we found three HTML comments.
`See this in the query console on LGTM.com <https://lgtm.com/query/686330023/>`__. When we ran this query on the *mozilla/pdf.js* project in LGTM.com, we found three HTML comments.
Syntactic level
~~~~~~~~~~~~~~~
@@ -349,7 +349,7 @@ As an example of how to use expression AST nodes, here is a query that finds exp
where add = shift.getAnOperand()
select add, "This expression should be bracketed to clarify precedence rules."
`See this in the query console <https://lgtm.com/query/690010024/>`__. When we ran this query on the *meteor/meteor* project in LGTM.com, we found many results where precedence could be clarified using brackets.
`See this in the query console on LGTM.com <https://lgtm.com/query/690010024/>`__. When we ran this query on the *meteor/meteor* project in LGTM.com, we found many results where precedence could be clarified using brackets.
Functions
^^^^^^^^^
@@ -371,7 +371,7 @@ As an example, here is a query that finds all expression closures:
where fe.getBody() instanceof Expr
select fe, "Use arrow expressions instead of expression closures."
`See this in the query console <https://lgtm.com/query/668510056/>`__. None of the LGTM.com demo projects uses expression closures, but you may find this query gets results on other projects.
`See this in the query console on LGTM.com <https://lgtm.com/query/668510056/>`__. None of the LGTM.com demo projects uses expression closures, but you may find this query gets results on other projects.
As another example, this query finds functions that have two parameters that bind the same variable:
@@ -386,7 +386,7 @@ As another example, this query finds functions that have two parameters that bin
p.getAVariable() = q.getAVariable()
select fun, "This function has two parameters that bind the same variable."
`See this in the query console <https://lgtm.com/query/673860037/>`__. None of the LGTM.com demo projects has functions where two parameters bind the same variable.
`See this in the query console on LGTM.com <https://lgtm.com/query/673860037/>`__. None of the LGTM.com demo projects has functions where two parameters bind the same variable.
Classes
^^^^^^^
@@ -442,7 +442,7 @@ Here is an example of a query to find declaration statements that declare the sa
not ds.getTopLevel().isMinified()
select ds, "Variable " + v.getName() + " is declared both $@ and $@.", d1, "here", d2, "here"
`See this in the query console <https://lgtm.com/query/668700496/>`__. This is not a common problem, so you may not find any results in your own projects. The *angular/angular.js* project on LGTM.com has one instance of this problem at the time of writing.
`See this in the query console on LGTM.com <https://lgtm.com/query/668700496/>`__. This is not a common problem, so you may not find any results in your own projects. The *angular/angular.js* project on LGTM.com has one instance of this problem at the time of writing.
Notice the use of ``not ... isMinified()`` here and in the next few queries. This excludes any results found in minified code. If you delete ``and not ds.getTopLevel().isMinified()`` and re-run the query, two results in minified code in the *meteor/meteor* project are reported.
@@ -469,7 +469,7 @@ As an example of a query involving properties, consider the following query that
not oe.getTopLevel().isMinified()
select oe, "Property " + p1.getName() + " is defined both $@ and $@.", p1, "here", p2, "here"
`See this in the query console <https://lgtm.com/query/660700064/>`__. Many projects have a few instances of object expressions with two identically named properties.
`See this in the query console on LGTM.com <https://lgtm.com/query/660700064/>`__. Many projects have a few instances of object expressions with two identically named properties.
Modules
^^^^^^^
@@ -535,7 +535,7 @@ As an example, consider the following query which finds distinct function declar
not g.getTopLevel().isMinified()
select f, g
`See this in the query console <https://lgtm.com/query/667290067/>`__. Some projects declare conflicting functions of the same name and rely on platform-specific behavior to disambiguate the two declarations.
`See this in the query console on LGTM.com <https://lgtm.com/query/667290067/>`__. Some projects declare conflicting functions of the same name and rely on platform-specific behavior to disambiguate the two declarations.
Control flow
~~~~~~~~~~~~
@@ -572,7 +572,7 @@ As an example of an analysis using basic blocks, ``BasicBlock.isLiveAtEntry(v, u
not f.getStartBB().isLiveAtEntry(gv, _)
select f, "This function uses " + gv + " like a local variable."
`See this in the query console <https://lgtm.com/query/686320048/>`__. Many projects have some variables which look as if they were intended to be local.
`See this in the query console on LGTM.com <https://lgtm.com/query/686320048/>`__. Many projects have some variables which look as if they were intended to be local.
Data flow
~~~~~~~~~
@@ -597,7 +597,7 @@ As an example, the following query finds definitions of local variables that are
not exists (VarUse use | def = use.getADef())
select def, "Dead store of local variable."
`See this in the query console <https://lgtm.com/query/2086440429/>`__. Many projects have some examples of useless assignments to local variables.
`See this in the query console on LGTM.com <https://lgtm.com/query/2086440429/>`__. Many projects have some examples of useless assignments to local variables.
SSA
^^^
@@ -640,7 +640,7 @@ For example, here is a query that finds all invocations of a method called ``sen
send.getMethodName() = "send"
select send
`See this in the query console <https://lgtm.com/query/1506058347056/>`__. The query finds HTTP response sends in the `AMP HTML <https://lgtm.com/projects/g/ampproject/amphtml>`__ project.
`See this in the query console on LGTM.com <https://lgtm.com/query/1506058347056/>`__. The query finds HTTP response sends in the `AMP HTML <https://lgtm.com/projects/g/ampproject/amphtml>`__ project.
Note that the data flow modeling in this library is intraprocedural, that is, flow across function calls and returns is *not* modeled. Likewise, flow through object properties and global variables is not modeled.
@@ -705,7 +705,7 @@ As an example of a call-graph-based query, here is a query to find invocations f
not exists(invk.getACallee())
select invk, "Unable to find a callee for this invocation."
`See this in the query console <https://lgtm.com/query/3260345690335671362/>`__
`See this in the query console on LGTM.com <https://lgtm.com/query/3260345690335671362/>`__
Inter-procedural data flow
~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -841,7 +841,7 @@ As an example of the use of these classes, here is a query that counts for every
from NodeModule m
select m, count(m.getAnImportedModule())
`See this in the query console <https://lgtm.com/query/659662207/>`__. When you analyze a project, for each module you can see how many other modules it imports.
`See this in the query console on LGTM.com <https://lgtm.com/query/659662207/>`__. When you analyze a project, for each module you can see how many other modules it imports.
NPM
^^^
@@ -870,7 +870,7 @@ As an example of the use of these classes, here is a query that identifies unuse
not exists (Require req | req.getTopLevel() = pkg.getAModule() | name = req.getImportedPath().getValue())
select deps, "Unused dependency '" + name + "'."
`See this in the query console <https://lgtm.com/query/666680077/>`__. It is not uncommon for projects to have some unused dependencies.
`See this in the query console on LGTM.com <https://lgtm.com/query/666680077/>`__. It is not uncommon for projects to have some unused dependencies.
React
^^^^^
@@ -897,7 +897,7 @@ For example, here is a query to find SQL queries that use string concatenation (
where ss instanceof AddExpr
select ss, "Use templating instead of string concatenation."
`See this in the query console <https://lgtm.com/query/1506076336224/>`__, showing two (benign) results on `strong-arc <https://lgtm.com/projects/g/strongloop/strong-arc/>`__.
`See this in the query console on LGTM.com <https://lgtm.com/query/1506076336224/>`__, showing two (benign) results on `strong-arc <https://lgtm.com/projects/g/strongloop/strong-arc/>`__.
Miscellaneous
~~~~~~~~~~~~~
@@ -963,7 +963,7 @@ As an example, here is a query that finds ``@param`` tags that do not specify th
not exists(t.getName())
select t, "@param tag is missing name."
`See this in the query console <https://lgtm.com/query/673060054/>`__. Of the LGTM.com demo projects analyzed, only *Semantic-Org/Semantic-UI* has an example where the ``@param`` tag omits the name.
`See this in the query console on LGTM.com <https://lgtm.com/query/673060054/>`__. Of the LGTM.com demo projects analyzed, only *Semantic-Org/Semantic-UI* has an example where the ``@param`` tag omits the name.
For full details on these and other classes representing JSDoc comments and type expressions, see `the API documentation <https://help.semmle.com/qldoc/javascript/semmle/javascript/JSDoc.qll/module.JSDoc.html>`__.
@@ -1033,4 +1033,4 @@ Further reading
- Learn about the standard CodeQL libraries used to write queries for TypeScript in :doc:`CodeQL libraries for TypeScript <introduce-libraries-ts>`.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__ on LGTM.com.

View File

@@ -121,7 +121,7 @@ Select expressions that cast a value to a type parameter:
where assertion.getTypeAnnotation() = param.getLocalTypeName().getAnAccess()
select assertion, "Cast to type parameter."
`See this in the query console <https://lgtm.com/query/1505979606441/>`__.
`See this in the query console on LGTM.com <https://lgtm.com/query/1505979606441/>`__.
Classes and interfaces
~~~~~~~~~~~~~~~~~~~~~~
@@ -407,7 +407,7 @@ It is best to use `TypeName <https://help.semmle.com/qldoc/javascript/semmle/jav
and not access.hasTypeArguments()
select access, "Type arguments are omitted"
`See this in the query console <https://lgtm.com/query/1505985316500/>`__.
`See this in the query console on LGTM.com <https://lgtm.com/query/1505985316500/>`__.
Find imported names that are used as both a type and a value:
@@ -420,7 +420,7 @@ Find imported names that are used as both a type and a value:
and exists (VarAccess access | access.getVariable().getADeclaration() = spec.getLocal())
select spec, "Used as both variable and type"
`See this in the query console <https://lgtm.com/query/1505975787348/>`__.
`See this in the query console on LGTM.com <https://lgtm.com/query/1505975787348/>`__.
Namespace names
~~~~~~~~~~~~~~~
@@ -451,4 +451,4 @@ Further reading
- Learn about the standard CodeQL libraries used to write queries for JavaScript in :doc:`CodeQL libraries for JavaScript <introduce-libraries-js>`.
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__ on LGTM.com.

View File

@@ -522,5 +522,5 @@ Further reading
---------------
- Find out more about QL in the `QL language handbook <https://help.semmle.com/QL/ql-handbook/index.html>`__ and `QL language specification <https://help.semmle.com/QL/ql-spec/language.html>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__.
- Learn more about the query console in `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__ on LGTM.com.
- Learn about writing precise data-flow analyses in :doc:`Using flow labels for precise data flow analysis <flow-labels>`.

View File

@@ -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
---------------

View File

@@ -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.

View File

@@ -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
^^^^^^^

View File

@@ -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
---------------

View File

@@ -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

View File

@@ -55,7 +55,7 @@ Query metadata is used to identify your custom queries when they are added to th
- If you are contributing a query to the GitHub repository, please read the `query metadata style guide <https://github.com/Semmle/ql/blob/master/docs/query-metadata-style-guide.md#metadata-area>`__.
- If you are adding a custom query to a query pack for analysis using LGTM , see `Writing custom queries to include in LGTM analysis <https://lgtm.com/help/lgtm/writing-custom-queries>`__.
- If you are analyzing a database using the `CodeQL CLI <https://help.semmle.com/codeql/codeql-cli.html>`__, your query metadata must contain ``@kind``.
- If you are running a query in the query console on LGTM or with the CodeQL extension for VS Code, metadata is not mandatory. However, if you want your results to be displayed as either an 'alert' or a 'path', you must specify the correct ``@kind`` property, as explained below. For more information, `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__ and `Using the extension <https://help.semmle.com/codeql/codeql-for-vscode/procedures/using-extension.html>`__.
- If you are running a query in the query console on LGTM or with the CodeQL extension for VS Code, metadata is not mandatory. However, if you want your results to be displayed as either an 'alert' or a 'path', you must specify the correct ``@kind`` property, as explained below. For more information, see `Using the query console <https://lgtm.com/help/lgtm/using-query-console>`__ on LGTM.com and `Using the extension <https://help.semmle.com/codeql/codeql-for-vscode/procedures/using-extension.html>`__ in the CodeQL for VS Code help.
.. pull-quote::

View File

@@ -22,24 +22,24 @@ Core properties
The following properties are supported by all query files:
+-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Property | Value | Description |
+=======================+===========================+=============================================================================================================================================================================================================================================================================================================================================================================================================================================================================+
| ``@description`` | ``<text>`` | A sentence or short paragraph to describe the purpose of the query and *why* the result is useful or important. The description is written in plain text, and uses single quotes (``'``) to enclose code elements. |
+-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``@id`` | ``<text>`` | A sequence of words composed of lowercase letters or digits, delimited by ``/`` or ``-``, identifying and classifying the query. Each query must have a **unique** ID. To ensure this, it may be helpful to use a fixed structure for each ID. For example, the standard LGTM queries have the following format: ``<language>/<brief-description>``. |
+-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``@kind`` | | ``problem`` | Identifies the query is an alert (``@kind problem``), a path (``@kind path-problem``), or a metric (``@kind metric``). For further information on these query types, see :doc:`About CodeQL queries <introduction-to-queries>` |
| | | ``path-problem`` | |
| | | ``metric`` | |
+-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``@name`` | ``<text>`` | A statement that defines the label of the query. The name is written in plain text, and uses single quotes (``'``) to enclose code elements. |
+-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``@tags`` | | ``correctness`` | These tags group queries together in broad categories to make it easier to search for them and identify them. You can also `filter alerts <https://lgtm.com/help/lgtm/alert-filtering>`__ based on their tags. In addition to the common tags listed here, there are also a number of more specific categories. For more information about some of the tags that are already used and what they mean, see `Query tags <https://lgtm.com/help/lgtm/query-tags>`__. |
| | | ``mantainability`` | |
| | | ``readability`` | |
| | | ``security`` | |
+-----------------------+---------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
+-----------------------+---------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Property | Value | Description |
+=======================+===========================+==============================================================================================================================================================================================================================================================================================================================================================================+
| ``@description`` | ``<text>`` | A sentence or short paragraph to describe the purpose of the query and *why* the result is useful or important. The description is written in plain text, and uses single quotes (``'``) to enclose code elements. |
+-----------------------+---------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``@id`` | ``<text>`` | A sequence of words composed of lowercase letters or digits, delimited by ``/`` or ``-``, identifying and classifying the query. Each query must have a **unique** ID. To ensure this, it may be helpful to use a fixed structure for each ID. For example, the standard LGTM queries have the following format: ``<language>/<brief-description>``. |
+-----------------------+---------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``@kind`` | | ``problem`` | Identifies the query is an alert (``@kind problem``), a path (``@kind path-problem``), or a metric (``@kind metric``). For further information on these query types, see :doc:`About CodeQL queries <introduction-to-queries>`. |
| | | ``path-problem`` | |
| | | ``metric`` | |
+-----------------------+---------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``@name`` | ``<text>`` | A statement that defines the label of the query. The name is written in plain text, and uses single quotes (``'``) to enclose code elements. |
+-----------------------+---------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ``@tags`` | | ``correctness`` | These tags group queries together in broad categories to make it easier to search for them and identify them. In addition to the common tags listed here, there are also a number of more specific categories. For more information about some of the tags that are already used and what they mean, see `Query tags <https://lgtm.com/help/lgtm/query-tags>`__ on LGTM.com. |
| | | ``mantainability`` | |
| | | ``readability`` | |
| | | ``security`` | |
+-----------------------+---------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Additional properties for problem and path-problem queries