зеркало из https://github.com/github/codeql.git
First set of updates for JavaScript articles
This commit is contained in:
Родитель
8eeba92a47
Коммит
179941daab
|
@ -18,7 +18,7 @@ Experiment and learn how to write effective and efficient queries for CodeQL dat
|
||||||
abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs
|
abstract-syntax-tree-classes-for-working-with-javascript-and-typescript-programs
|
||||||
data-flow-cheat-sheet-for-javascript
|
data-flow-cheat-sheet-for-javascript
|
||||||
|
|
||||||
- :doc:`Basic query for JavaScript code <basic-query-for-javascript-code>`: Learn to write and run a simple CodeQL query using LGTM.
|
- :doc:`Basic query for JavaScript code <basic-query-for-javascript-code>`: Learn to write and run a simple CodeQL query.
|
||||||
|
|
||||||
- :doc:`CodeQL library for JavaScript <codeql-library-for-javascript>`: When you're analyzing a JavaScript program, you can make use of the large collection of classes in the CodeQL library for JavaScript.
|
- :doc:`CodeQL library for JavaScript <codeql-library-for-javascript>`: When you're analyzing a JavaScript program, you can make use of the large collection of classes in the CodeQL library for JavaScript.
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ Textual level
|
||||||
|
|
||||||
At its most basic level, a JavaScript code base can simply be viewed as a collection of files organized into folders, where each file is composed of zero or more lines of text.
|
At its most basic level, a JavaScript code base can simply be viewed as a collection of files organized into folders, where each file is composed of zero or more lines of text.
|
||||||
|
|
||||||
Note that the textual content of a program is not included in the CodeQL database unless you specifically request it during extraction. In particular, databases on LGTM (also known as "snapshots") do not normally include textual information.
|
Note that the textual content of a program is not included in the CodeQL database unless you specifically request it during extraction.
|
||||||
|
|
||||||
Files and folders
|
Files and folders
|
||||||
^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^
|
||||||
|
@ -77,7 +77,7 @@ For example, the following query computes, for each folder, the number of JavaSc
|
||||||
from Folder d
|
from Folder d
|
||||||
select d.getRelativePath(), count(File f | f = d.getAFile() and f.getExtension() = "js")
|
select d.getRelativePath(), count(File f | f = d.getAFile() and f.getExtension() = "js")
|
||||||
|
|
||||||
➤ `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.
|
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
|
Locations
|
||||||
^^^^^^^^^
|
^^^^^^^^^
|
||||||
|
@ -138,7 +138,7 @@ As an example of a query operating entirely on the lexical level, consider the f
|
||||||
where comma.getNextToken() instanceof CommaToken
|
where comma.getNextToken() instanceof CommaToken
|
||||||
select comma, "Omitted array elements are bad style."
|
select comma, "Omitted array elements are bad style."
|
||||||
|
|
||||||
➤ `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.
|
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.
|
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.
|
||||||
|
|
||||||
|
@ -179,8 +179,6 @@ As an example of a query using only lexical information, consider the following
|
||||||
from HtmlLineComment c
|
from HtmlLineComment c
|
||||||
select c, "Do not use HTML comments."
|
select c, "Do not use 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
|
Syntactic level
|
||||||
~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -351,8 +349,6 @@ As an example of how to use expression AST nodes, here is a query that finds exp
|
||||||
where add = shift.getAnOperand()
|
where add = shift.getAnOperand()
|
||||||
select add, "This expression should be bracketed to clarify precedence rules."
|
select add, "This expression should be bracketed to clarify precedence rules."
|
||||||
|
|
||||||
➤ `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
|
Functions
|
||||||
^^^^^^^^^
|
^^^^^^^^^
|
||||||
|
|
||||||
|
@ -373,8 +369,6 @@ As an example, here is a query that finds all expression closures:
|
||||||
where fe.getBody() instanceof Expr
|
where fe.getBody() instanceof Expr
|
||||||
select fe, "Use arrow expressions instead of expression closures."
|
select fe, "Use arrow expressions instead of expression closures."
|
||||||
|
|
||||||
➤ `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:
|
As another example, this query finds functions that have two parameters that bind the same variable:
|
||||||
|
|
||||||
.. code-block:: ql
|
.. code-block:: ql
|
||||||
|
@ -388,8 +382,6 @@ As another example, this query finds functions that have two parameters that bin
|
||||||
p.getAVariable() = q.getAVariable()
|
p.getAVariable() = q.getAVariable()
|
||||||
select fun, "This function has two parameters that bind the same variable."
|
select fun, "This function has two parameters that 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
|
Classes
|
||||||
^^^^^^^
|
^^^^^^^
|
||||||
|
|
||||||
|
@ -444,7 +436,7 @@ Here is an example of a query to find declaration statements that declare the sa
|
||||||
not ds.getTopLevel().isMinified()
|
not ds.getTopLevel().isMinified()
|
||||||
select ds, "Variable " + v.getName() + " is declared both $@ and $@.", d1, "here", d2, "here"
|
select ds, "Variable " + v.getName() + " is declared both $@ and $@.", d1, "here", d2, "here"
|
||||||
|
|
||||||
➤ `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.
|
This is not a common problem, so you may not find any results in your own projects.
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
|
@ -471,8 +463,6 @@ As an example of a query involving properties, consider the following query that
|
||||||
not oe.getTopLevel().isMinified()
|
not oe.getTopLevel().isMinified()
|
||||||
select oe, "Property " + p1.getName() + " is defined both $@ and $@.", p1, "here", p2, "here"
|
select oe, "Property " + p1.getName() + " is defined both $@ and $@.", p1, "here", p2, "here"
|
||||||
|
|
||||||
➤ `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
|
Modules
|
||||||
^^^^^^^
|
^^^^^^^
|
||||||
|
|
||||||
|
@ -537,7 +527,7 @@ As an example, consider the following query which finds distinct function declar
|
||||||
not g.getTopLevel().isMinified()
|
not g.getTopLevel().isMinified()
|
||||||
select f, g
|
select f, g
|
||||||
|
|
||||||
➤ `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.
|
Some projects declare conflicting functions of the same name and rely on platform-specific behavior to disambiguate the two declarations.
|
||||||
|
|
||||||
Control flow
|
Control flow
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
|
@ -574,7 +564,7 @@ As an example of an analysis using basic blocks, ``BasicBlock.isLiveAtEntry(v, u
|
||||||
not f.getStartBB().isLiveAtEntry(gv, _)
|
not f.getStartBB().isLiveAtEntry(gv, _)
|
||||||
select f, "This function uses " + gv + " like a local variable."
|
select f, "This function uses " + gv + " like a local variable."
|
||||||
|
|
||||||
➤ `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.
|
Many projects have some variables which look as if they were intended to be local.
|
||||||
|
|
||||||
Data flow
|
Data flow
|
||||||
~~~~~~~~~
|
~~~~~~~~~
|
||||||
|
@ -599,8 +589,6 @@ As an example, the following query finds definitions of local variables that are
|
||||||
not exists (VarUse use | def = use.getADef())
|
not exists (VarUse use | def = use.getADef())
|
||||||
select def, "Dead store of local variable."
|
select def, "Dead store of local variable."
|
||||||
|
|
||||||
➤ `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
|
SSA
|
||||||
^^^
|
^^^
|
||||||
|
|
||||||
|
@ -642,8 +630,6 @@ For example, here is a query that finds all invocations of a method called ``sen
|
||||||
send.getMethodName() = "send"
|
send.getMethodName() = "send"
|
||||||
select send
|
select send
|
||||||
|
|
||||||
➤ `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.
|
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.
|
||||||
|
|
||||||
Type inference
|
Type inference
|
||||||
|
@ -707,8 +693,6 @@ As an example of a call-graph-based query, here is a query to find invocations f
|
||||||
not exists(invk.getACallee())
|
not exists(invk.getACallee())
|
||||||
select invk, "Unable to find a callee for this invocation."
|
select invk, "Unable to find a callee for this invocation."
|
||||||
|
|
||||||
➤ `See this in the query console on LGTM.com <https://lgtm.com/query/3260345690335671362/>`__
|
|
||||||
|
|
||||||
Inter-procedural data flow
|
Inter-procedural data flow
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -843,7 +827,7 @@ As an example of the use of these classes, here is a query that counts for every
|
||||||
from NodeModule m
|
from NodeModule m
|
||||||
select m, count(m.getAnImportedModule())
|
select m, count(m.getAnImportedModule())
|
||||||
|
|
||||||
➤ `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.
|
When you analyze a project, for each module you can see how many other modules it imports.
|
||||||
|
|
||||||
NPM
|
NPM
|
||||||
^^^
|
^^^
|
||||||
|
@ -872,8 +856,6 @@ 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())
|
not exists (Require req | req.getTopLevel() = pkg.getAModule() | name = req.getImportedPath().getValue())
|
||||||
select deps, "Unused dependency '" + name + "'."
|
select deps, "Unused dependency '" + name + "'."
|
||||||
|
|
||||||
➤ `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
|
React
|
||||||
^^^^^
|
^^^^^
|
||||||
|
|
||||||
|
@ -899,8 +881,6 @@ For example, here is a query to find SQL queries that use string concatenation (
|
||||||
where ss instanceof AddExpr
|
where ss instanceof AddExpr
|
||||||
select ss, "Use templating instead of string concatenation."
|
select ss, "Use templating instead of string concatenation."
|
||||||
|
|
||||||
➤ `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
|
Miscellaneous
|
||||||
~~~~~~~~~~~~~
|
~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -965,8 +945,6 @@ As an example, here is a query that finds ``@param`` tags that do not specify th
|
||||||
not exists(t.getName())
|
not exists(t.getName())
|
||||||
select t, "@param tag is missing name."
|
select t, "@param tag is missing 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://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSDoc.qll/module.JSDoc.html>`__.
|
For full details on these and other classes representing JSDoc comments and type expressions, see `the API documentation <https://codeql.github.com/codeql-standard-libraries/javascript/semmle/javascript/JSDoc.qll/module.JSDoc.html>`__.
|
||||||
|
|
||||||
JSX
|
JSX
|
||||||
|
|
Загрузка…
Ссылка в новой задаче