Skip to content

Commit 4075f57

Browse files
authored
Merge pull request #1151 from xiemaisi/rc/1.20-merge-master
Approved by asger-semmle, hvitved
2 parents 8ab4dae + 8c460ae commit 4075f57

File tree

14 files changed

+179
-167
lines changed

14 files changed

+179
-167
lines changed

change-notes/1.20/analysis-python.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
# Improvements to Python analysis
22

3+
## General improvements
34

4-
## General improvements
5+
### Extractor changes
56

6-
> Changes that affect alerts in many files or from many queries
7-
> For example, changes to file classification
7+
The extractor now parses all Python code from a single unified grammar. This means that almost all Python code will be successfully parsed, even if mutually incompatible Python code is present in the same project. This also means that Python code for any version can be correctly parsed on a worker running any other supported version of Python. For example, Python 3.7 code is parsed correctly, even if the installed version of Python is only 3.5. This will reduce the number of syntax errors found in many projects.
8+
9+
### Regular expression analysis improvements
10+
11+
The Python `re` (regular expressions) module library has a couple of constants called `MULTILINE` and `VERBOSE` which determine the parsing of regular expressions. Python 3.6 changed the implementation of these constants, which resulted in false positive results for some queries. The relevant QL libraries have been updated to support both implementations which will remove false positive results from projects that use Python 3.6 and later versions.
12+
13+
### API improvements
814

9-
The constants `MULTILINE` and `VERBOSE` in `re` module, are now understood for Python 3.6 and upward.
10-
Removes false positives seen when using Python 3.6, but not when using earlier versions.
1115
The API has been improved to declutter the global namespace and improve discoverability and readability.
1216
* New predicates `ModuleObject::named(name)` and `ModuleObject.attr(name)` have been added, allowing more readable access to common objects. For example, `(any ModuleObject m | m.getName() = "sys").getAttribute("exit")` can be replaced with `ModuleObject::named("sys").attr("exit")`
13-
* The API for accessing builtin functions has been improved. Predicates of the form `theXXXFunction()`, such as `theLenFunction()`, have been deprecated in favour of `Object::builtin(name)`.
17+
* The API for accessing builtin functions has been improved. Predicates of the form `theXXXFunction()`, such as `theLenFunction()`, have been deprecated in favor of `Object::builtin(name)`.
1418
* A configuration based API has been added for writing data flow and taint tracking queries. This is provided as a convenience for query authors who have written data flow or taint tracking queries for other languages, so they can use a similar format of query across multiple languages.
1519

16-
## New queries
20+
## New queries
1721

1822
| **Query** | **Tags** | **Purpose** |
1923
|-----------------------------|-----------|--------------------------------------------------------------------|
@@ -24,7 +28,7 @@ The API has been improved to declutter the global namespace and improve discover
2428
| Overly permissive file permissions (`py/overly-permissive-file`) | security, external/cwe/cwe-732 | Finds instances where a file is created with overly permissive permissions. Results are not shown on LGTM by default. |
2529
| Use of insecure SSL/TLS version (`py/insecure-protocol`) | security, external/cwe/cwe-327 | Finds instances where a known insecure protocol has been specified. Results are shown on LGTM by default. |
2630

27-
## Changes to existing queries
31+
## Changes to existing queries
2832

2933
| **Query** | **Expected impact** | **Change** |
3034
|----------------------------|------------------------|------------------------------------------------------------------|
@@ -35,11 +39,8 @@ The API has been improved to declutter the global namespace and improve discover
3539
| Unused import (`py/unused-import`) | Fewer false positive results | Results where the imported module is used in a `doctest` string are no longer reported. |
3640
| Unused import (`py/unused-import`) | Fewer false positive results | Results where the imported module is used in a type-hint comment are no longer reported. |
3741

38-
## Changes to code extraction
39-
40-
* The extractor now parses all Python code from a single unified grammar. This means that almost all Python code will be successfully parsed, even if mutually incompatible Python code is present in the same project. This also means that Python code for any version can be correctly parsed on a worker running any other supported version of Python. For example, Python 3.7 code is parsed correctly, even if the installed version of Python is only 3.5.
4142

42-
## Changes to QL libraries
43+
## Changes to QL libraries
4344

4445
* Added support for the `dill` pickle library.
4546
* Added support for the `bottle` web framework.

change-notes/1.20/extractor-javascript.md

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,11 @@
22

33
# Improvements to JavaScript analysis
44

5-
> NOTES
6-
>
7-
> Please describe your changes in terms that are suitable for
8-
> customers to read. These notes will have only minor tidying up
9-
> before they are published as part of the release notes.
10-
>
11-
> This file is written for lgtm users and should contain *only*
12-
> notes about changes that affect lgtm enterprise users. Add
13-
> any other customer-facing changes to the `studio-java.md`
14-
> file.
15-
>
16-
17-
## General improvements
18-
195
## Changes to code extraction
206

21-
* Parallel extraction of JavaScript files (but not TypeScript files) on LGTM is now supported. The `LGTM_THREADS` environment variable can be set to indicate how many files should be extracted in parallel. If this variable is not set, parallel extraction is disabled.
22-
* The extractor now offers experimental support for [E4X](https://developer.mozilla.org/en-US/docs/Archive/Web/E4X), a legacy language extension developed by Mozilla.
23-
* The extractor now supports additional [Flow](https://flow.org/) syntax.
24-
* The extractor now supports [Nullish Coalescing](https://github.com/tc39/proposal-nullish-coalescing) expressions.
25-
* The extractor now supports [TypeScript 3.2](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-2.html).
26-
* The TypeScript extractor now handles the control-flow of logical operators and destructuring assignments more accurately.
7+
* Parallel extraction of JavaScript files (but not TypeScript files) on LGTM is now supported. If LGTM is configured to evaluate queries using multiple threads, then JavaScript files are also extracted using multiple threads.
8+
* Experimental support for [E4X](https://developer.mozilla.org/en-US/docs/Archive/Web/E4X), a legacy language extension developed by Mozilla, is available.
9+
* Additional [Flow](https://flow.org/) syntax is now supported.
10+
* [Nullish Coalescing](https://github.com/tc39/proposal-nullish-coalescing) expressions are now supported.
11+
* [TypeScript 3.2](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-2.html) is now supported.
12+
* The TypeScript extractor now handles the control flow of logical operators and destructuring assignments more accurately.

change-notes/1.20/support/versions-compilers.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@ Java,"Java 6 to 11 [2]_.","javac (OpenJDK and Oracle JDK)
1313
Eclipse compiler for Java (ECJ) batch compiler",``.java``
1414
JavaScript,ECMAScript 2018 or lower,Not applicable,"``.js``, ``.jsx``, ``.mjs``, ``.es``, ``.es6``, ``.htm``, ``.html``, ``.xhm``, ``.xhtml``, ``.vue``, ``.json`` [3]_."
1515
Python,"2.7, 3.5, 3.6, 3.7",Not applicable,``.py``
16-
TypeScript [4]_.,"2.6, 2.7, 2.8, 2.9, 3.0, 3.1",Standard TypeScript compiler,"``.ts``, ``.tsx``"
16+
TypeScript [4]_.,"2.6, 2.7, 2.8, 2.9, 3.0, 3.1, 3.2",Standard TypeScript compiler,"``.ts``, ``.tsx``"

csharp/ql/src/API Abuse/DisposeNotCalledOnException.ql

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,28 @@ predicate isTriedAgainstException(ControlFlowElement cfe, ExceptionClass ec) {
4949
)
5050
}
5151

52+
private class DisposeCall extends MethodCall {
53+
DisposeCall() { this.getTarget() instanceof DisposeMethod }
54+
}
55+
56+
private predicate reachesDisposeCall(DisposeCall disposeCall, DataFlow::Node node) {
57+
DataFlow::localFlowStep(node, DataFlow::exprNode(disposeCall.getQualifier()))
58+
or
59+
exists(DataFlow::Node mid | reachesDisposeCall(disposeCall, mid) |
60+
DataFlow::localFlowStep(node, mid)
61+
)
62+
}
63+
5264
/**
5365
* Holds if `disposeCall` disposes the object created by `disposableCreation`.
5466
*/
55-
predicate disposeReachableFromDisposableCreation(MethodCall disposeCall, Expr disposableCreation) {
67+
predicate disposeReachableFromDisposableCreation(DisposeCall disposeCall, Expr disposableCreation) {
5668
// The qualifier of the Dispose call flows from something that introduced a disposable into scope
5769
(
5870
disposableCreation instanceof LocalScopeDisposableCreation or
5971
disposableCreation instanceof MethodCall
6072
) and
61-
DataFlow::localFlowStep+(DataFlow::exprNode(disposableCreation),
62-
DataFlow::exprNode(disposeCall.getQualifier())) and
63-
disposeCall.getTarget() instanceof DisposeMethod
73+
reachesDisposeCall(disposeCall, DataFlow::exprNode(disposableCreation))
6474
}
6575

6676
class MethodCallThatMayThrow extends MethodCall {
@@ -73,7 +83,7 @@ ControlFlowElement getACatchOrFinallyClauseChild() {
7383
result = getACatchOrFinallyClauseChild().getAChild()
7484
}
7585

76-
from MethodCall disposeCall, Expr disposableCreation, MethodCallThatMayThrow callThatThrows
86+
from DisposeCall disposeCall, Expr disposableCreation, MethodCallThatMayThrow callThatThrows
7787
where
7888
disposeReachableFromDisposableCreation(disposeCall, disposableCreation) and
7989
// The dispose call is not, itself, within a dispose method.

csharp/ql/src/semmle/code/csharp/Assignable.qll

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ class AssignableRead extends AssignableAccess {
7676
not nameOfChild(_, this)
7777
}
7878

79+
pragma[noinline]
80+
private ControlFlow::Node getAnAdjacentReadSameVar() {
81+
Ssa::Internal::adjacentReadPairSameVar(this.getAControlFlowNode(), result)
82+
}
83+
7984
/**
8085
* Gets a next read of the same underlying assignable. That is, a read
8186
* that can be reached from this read without passing through any other reads,
@@ -102,7 +107,7 @@ class AssignableRead extends AssignableAccess {
102107
*/
103108
AssignableRead getANextRead() {
104109
forex(ControlFlow::Node cfn | cfn = result.getAControlFlowNode() |
105-
Ssa::Internal::adjacentReadPairSameVar(this.getAControlFlowNode(), cfn)
110+
cfn = this.getAnAdjacentReadSameVar()
106111
)
107112
}
108113

csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,7 @@ module DataFlow {
704704
)
705705
}
706706

707+
pragma[nomagic]
707708
private ControlFlowElement getANonExactScopeChild(ControlFlowElement scope) {
708709
scope = getAScope(false) and
709710
result = scope

javascript/extractor/src/com/semmle/js/extractor/ASTExtractor.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
import com.semmle.js.ast.Identifier;
4343
import com.semmle.js.ast.IfStatement;
4444
import com.semmle.js.ast.ImportDeclaration;
45-
import com.semmle.js.ast.ImportNamespaceSpecifier;
4645
import com.semmle.js.ast.ImportSpecifier;
4746
import com.semmle.js.ast.InvokeExpression;
4847
import com.semmle.js.ast.JumpStatement;
@@ -1449,13 +1448,7 @@ public Label visit(ImportDeclaration nd, Context c) {
14491448
public Label visit(ImportSpecifier nd, Context c) {
14501449
Label lbl = super.visit(nd, c);
14511450
visit(nd.getImported(), lbl, 0, IdContext.label);
1452-
visit(
1453-
nd.getLocal(),
1454-
lbl,
1455-
1,
1456-
nd instanceof ImportNamespaceSpecifier
1457-
? IdContext.varAndNamespaceDecl
1458-
: IdContext.varAndTypeAndNamespaceDecl);
1451+
visit(nd.getLocal(), lbl, 1, IdContext.varAndTypeAndNamespaceDecl);
14591452
return lbl;
14601453
}
14611454

javascript/extractor/src/com/semmle/js/extractor/ScopeManager.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import com.semmle.js.ast.Identifier;
1818
import com.semmle.js.ast.IfStatement;
1919
import com.semmle.js.ast.ImportDeclaration;
20-
import com.semmle.js.ast.ImportNamespaceSpecifier;
2120
import com.semmle.js.ast.ImportSpecifier;
2221
import com.semmle.js.ast.LabeledStatement;
2322
import com.semmle.js.ast.LetExpression;
@@ -559,9 +558,7 @@ public Void visit(ImportDeclaration nd, Void c) {
559558

560559
@Override
561560
public Void visit(ImportSpecifier nd, Void c) {
562-
return visit(
563-
nd.getLocal(),
564-
nd instanceof ImportNamespaceSpecifier ? DeclKind.varAndNamespace : DeclKind.all);
561+
return visit(nd.getLocal(), DeclKind.all);
565562
}
566563

567564
@Override

javascript/extractor/tests/es2015/output/trap/import5.js.trap

Lines changed: 39 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -65,45 +65,49 @@ isModule(#20001)
6565
isES2015Module(#20001)
6666
#20021=@"var;{foo};{#20020}"
6767
variables(#20021,"foo",#20020)
68-
#20022=@"local_namespace_name;{foo};{#20020}"
69-
local_namespace_names(#20022,"foo",#20020)
68+
#20022=@"local_type_name;{foo};{#20020}"
69+
local_type_names(#20022,"foo",#20020)
70+
#20023=@"local_namespace_name;{foo};{#20020}"
71+
local_namespace_names(#20023,"foo",#20020)
7072
variables(#20021,"foo",#20020)
71-
local_namespace_names(#20022,"foo",#20020)
72-
#20023=*
73-
stmts(#20023,27,#20001,0,"import ... 'foo';")
74-
hasLocation(#20023,#20003)
75-
stmtContainers(#20023,#20001)
73+
local_type_names(#20022,"foo",#20020)
74+
local_namespace_names(#20023,"foo",#20020)
7675
#20024=*
77-
exprs(#20024,4,#20023,-1,"'foo'")
78-
hasLocation(#20024,#20015)
79-
enclosingStmt(#20024,#20023)
80-
exprContainers(#20024,#20001)
81-
literals("foo","'foo'",#20024)
76+
stmts(#20024,27,#20001,0,"import ... 'foo';")
77+
hasLocation(#20024,#20003)
78+
stmtContainers(#20024,#20001)
8279
#20025=*
83-
exprs(#20025,85,#20023,0,"* as foo")
84-
#20026=@"loc,{#10000},1,8,1,15"
85-
locations_default(#20026,#10000,1,8,1,15)
86-
hasLocation(#20025,#20026)
87-
enclosingStmt(#20025,#20023)
80+
exprs(#20025,4,#20024,-1,"'foo'")
81+
hasLocation(#20025,#20015)
82+
enclosingStmt(#20025,#20024)
8883
exprContainers(#20025,#20001)
89-
#20027=*
90-
exprs(#20027,78,#20025,1,"foo")
91-
hasLocation(#20027,#20011)
92-
enclosingStmt(#20027,#20023)
93-
exprContainers(#20027,#20001)
94-
literals("foo","foo",#20027)
95-
decl(#20027,#20021)
96-
namespacedecl(#20027,#20022)
84+
literals("foo","'foo'",#20025)
85+
#20026=*
86+
exprs(#20026,85,#20024,0,"* as foo")
87+
#20027=@"loc,{#10000},1,8,1,15"
88+
locations_default(#20027,#10000,1,8,1,15)
89+
hasLocation(#20026,#20027)
90+
enclosingStmt(#20026,#20024)
91+
exprContainers(#20026,#20001)
9792
#20028=*
98-
entry_cfg_node(#20028,#20001)
99-
#20029=@"loc,{#10000},1,1,1,0"
100-
locations_default(#20029,#10000,1,1,1,0)
101-
hasLocation(#20028,#20029)
102-
#20030=*
103-
exit_cfg_node(#20030,#20001)
104-
hasLocation(#20030,#20019)
105-
successor(#20023,#20030)
106-
successor(#20025,#20023)
107-
successor(#20028,#20025)
93+
exprs(#20028,78,#20026,1,"foo")
94+
hasLocation(#20028,#20011)
95+
enclosingStmt(#20028,#20024)
96+
exprContainers(#20028,#20001)
97+
literals("foo","foo",#20028)
98+
decl(#20028,#20021)
99+
typedecl(#20028,#20022)
100+
namespacedecl(#20028,#20023)
101+
#20029=*
102+
entry_cfg_node(#20029,#20001)
103+
#20030=@"loc,{#10000},1,1,1,0"
104+
locations_default(#20030,#10000,1,1,1,0)
105+
hasLocation(#20029,#20030)
106+
#20031=*
107+
exit_cfg_node(#20031,#20001)
108+
hasLocation(#20031,#20019)
109+
successor(#20024,#20031)
110+
successor(#20026,#20024)
111+
successor(#20029,#20026)
108112
numlines(#10000,1,1,0)
109113
filetype(#10000,"javascript")

0 commit comments

Comments
 (0)