Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
003b600
TypeScript: disable queries that rely on token information
asger-semmle Sep 4, 2018
2b8bc63
TypeScript: add change note
asger-semmle Sep 4, 2018
6ceb103
TypeScript: rephrase change note
asger-semmle Sep 4, 2018
e0c0733
C++: Remove CP in getOperandMemoryAccess
jbj Sep 1, 2018
42faabc
C#: Rename and restructure control flow graph entities
hvitved Aug 31, 2018
82b2c00
C#: Add change note
hvitved Sep 4, 2018
061b3d4
C#: Fix typos in change note
hvitved Sep 4, 2018
727ab94
Merge pull request #140 from hvitved/csharp/cfg/renaming
calumgrant Sep 5, 2018
7a77740
C#: Extractor tests for
calumgrant Sep 5, 2018
8c2d773
C#: Extractor test for `join ... into`
calumgrant Sep 5, 2018
cff0050
C#: Implementation of `case ... when ...:` which was not previously h…
calumgrant Sep 5, 2018
c2f3cb6
C#: Update analysis change notes.
calumgrant Sep 5, 2018
3718237
C#: Implement CFG for `ConstCase` statements with a condition.
calumgrant Sep 5, 2018
62e9946
Merge pull request #150 from asger-semmle/ts-asi-bug
semmle-qlci Sep 5, 2018
10329fa
Merge pull request #134 from jbj/getOperandMemoryAccess-this
semmle-qlci Sep 6, 2018
d5eacf8
C#: Change expected output. Address review comments.
calumgrant Sep 6, 2018
0cd4340
C#: Address review comment: refactor `last()` predicate for `ConstCas…
calumgrant Sep 7, 2018
58cf95b
C#: Rewrite `not` using `if`.
calumgrant Sep 7, 2018
6aa6b64
Remove placeholders and sort table
Sep 7, 2018
e7116f5
Add query identifiers
Sep 7, 2018
2e0818d
Text changes for consistency and clarity
Sep 7, 2018
3eab1de
Remove non-LGTM queries from notes (will move to 'studio-cpp.md')
Sep 7, 2018
f3eed4a
Merge pull request #163 from calumgrant/cs/extractor-fixes
hvitved Sep 7, 2018
9ec2172
C#: Fix CFG for unknown expressions, and add a test that also covers …
calumgrant Aug 3, 2018
ecb3efb
C#: Fix merge conflicts.
calumgrant Sep 7, 2018
a08177f
Address initial feebback
Sep 9, 2018
4051e34
Merge pull request #169 from felicity-semmle/1.18/cpp-finalize-change…
jbj Sep 9, 2018
4473ccd
Java: Add Mockito.verify to MockitoMockMethod.
aschackmull Sep 6, 2018
35a83bf
Merge pull request #173 from aschackmull/java/mockito-verify2
semmle-qlci Sep 10, 2018
621d845
Merge pull request #11 from calumgrant/cs/standalone-cfg-fixes
hvitved Sep 10, 2018
70e7131
Merge branch 'rc/1.18' into merge-rc
hvitved Sep 11, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 14 additions & 26 deletions change-notes/1.18/analysis-cpp.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,28 @@
# Improvements to C/C++ analysis

## General improvements

> Changes that affect alerts in many files or from many queries
> For example, changes to file classification

## New queries

| **Query** | **Tags** | **Purpose** |
|-----------------------------|-----------|--------------------------------------------------------------------|
| Upcast array used in pointer arithmetic | reliability, correctness, external/cwe/cwe-119 | Finds undefined behavior caused by doing pointer arithmetic on an array of objects that has been cast to an array of a supertype. |
| Upcast array used in pointer arithmetic (`cpp/upcast-array-pointer-arithmetic`) | reliability, correctness, external/cwe/cwe-119 | Finds undefined behavior caused by doing pointer arithmetic on an array of objects that has been cast to an array of a supertype. |

## Changes to existing queries

| **Query** | **Expected impact** | **Change** |
|----------------------------|------------------------|------------------------------------------------------------------|
| Self comparison | Fewer false positive results | Range checks of the form `x == (T)x` are no longer flagged unless they are guaranteed to have the same result on all platforms. |
| [Nested loops with same variable] | Fewer false positive results | Results where the loop variable is a member of a class or struct now account for the object. |
| [For loop variable changed in body] | Fewer false positive results | Results where the loop variable is a member of a class or struct now account for the object. |
| [Local variable hides global variable] | Fewer false positive results | Results for parameters are now only reported if the name of the global variable is the same as the name of the parameter as used in the function definition (not just a function declaration). |
| [Memory may not be freed] | More correct results | This query now models calls to `realloc` more accurately. |
| Wrong number of arguments to formatting function | Fewer false positive results | Some false positives related to custom printf-like functions have been fixed. |
| Wrong number of arguments to formatting function | Clear separation between results of high and low severity | This query has been split into two queries: a high-severity query named [Too few arguments to formatting function] and a low-severity query named [Too many arguments to formatting function]. |
| [Too few arguments to formatting function] | More correct and fewer false positives results | This query now understands positional format arguments as supported by some libraries. |
| [Too many arguments to formatting function] | More correct and fewer false positives results | This query now understands positional format arguments as supported by some libraries. |
| [Variable used in its own initializer] | Fewer false positive results | Results where a macro is used to indicate deliberate uninitialization are now excluded |
| [Assignment where comparison was intended] | Fewer false positive results | Results are no longer reported if the variable is not yet defined. |
| [Comparison where assignment was intended] | More correct results | "This query now includes results where an overloaded `operator==` is used in the wrong context. |
| [User-controlled data in arithmetic expression] | More correct results | Increment / decrement / addition assignment / subtraction assignment operations are now understood as arithmetic operations in this query. |
| [Uncontrolled data in arithmetic expression] | More correct results | Increment / decrement / addition assignment / subtraction assignment operations are now understood as arithmetic operations in this query. |
| [Use of extreme values in arithmetic expression] | More correct results | Increment / decrement / addition assignment / subtraction assignment operations are now understood as arithmetic operations in this query. |
| [Use of extreme values in arithmetic expression] | Fewer false positives | The query now considers whether a particular expression might cause an overflow of minimum or maximum values only. |
| Assignment where comparison was intended (`cpp/assign-where-compare-meant`) | Fewer false positive results | Results are no longer reported if the variable is not yet defined. |
| Comparison where assignment was intended (`cpp/compare-where-assign-meant`) | More results | This query now includes results where an overloaded `operator==` is used in the wrong context. |
| For loop variable changed in body (`cpp/loop-variable-changed`) | Fewer false positive results | Results where the loop variable is a member of a class or struct now account for the object. |
| Local variable hides global variable (`cpp/local-variable-hides-global-variable`) | Fewer false positive results | Results for parameters are now only reported if the name of the global variable is the same as the name of the parameter as used in the function definition (not just a function declaration). |
| Nested loops with same variable (`cpp/nested-loops-with-same-variable`) | Fewer false positive results | Results where the loop variable is a member of a class or struct now account for the object. |
| Self comparison (`cpp/comparison-of-identical-expressions`) | Fewer false positive results | Range checks of the form `x == (T)x` are no longer flagged unless they are guaranteed to have the same result on all platforms. |
| Too few arguments to formatting function (`cpp/wrong-number-format-arguments`) | More precise results | This was previously known as "Wrong number of arguments to formatting function". It now focuses only on functions calls that are missing arguments, which tend to be more severe. See the next row for the new query that reports lower-severity alerts for calls with too many arguments. In addition, both queries now understand positional format arguments as supported by some libraries, and some false positive results for custom printf-like functions have been fixed.|
| Too many arguments to formatting function (`cpp/too-many-format-arguments`) | More precise results | This new query was created by splitting the old "Wrong number of arguments to formatting function" query (see row above). It reports function calls with too many arguments. |
| User-controlled data in arithmetic expression (`cpp/tainted-arithmetic`) | More results | The query is extended to analyze increment, decrement, addition-assignment, and subtraction-assignment operations. |
| Variable used in its own initializer (`cpp/use-in-own-initializer`) | Fewer false positive results | Results where a macro is used to indicate deliberate uninitialization are now excluded. |
|Uncontrolled data in arithmetic expression (`cpp/uncontrolled-arithmetic`) | More results | The query is extended to analyze increment, decrement, addition-assignment, and subtraction-assignment operations. |

## Changes to QL libraries

* Fixes for aggregate initializers using designators:
* `ClassAggregateLiteral.getFieldExpr()` previously assumed initializer expressions appeared in the same order as the declaration order of the fields, causing it to associate the expressions with the wrong fields when using designated initializers. This has been fixed.
* `ArrayAggregateLiteral.getElementExpr()` previously assumed initializer expressions appeared in the same order as the corresponding array elements, causing it to associate the expressions with the wrong array elements when using designated initializers. This has been fixed.
* `Element.getEnclosingElement()` no longer includes macro accesses in its results. To explore parents and children of macro accesses, use the relevant member predicates on `MacroAccess` or `MacroInvocation`.
* The `ClassAggregateLiteral.getFieldExpr()` and `ArrayAggregateLiteral.getElementExpr()` predicates incorrectly assumed that initializer expressions appeared in the same order as the declaration order of the elements. This resulted in the association of the expressions with the wrong elements when designated initializers were used. This has been fixed.
* Results for the `Element.getEnclosingElement()` predicate no longer included macro accesses. To explore parents and children of macro accesses, use the relevant member predicates on `MacroAccess` or `MacroInvocation`.
25 changes: 24 additions & 1 deletion change-notes/1.18/analysis-csharp.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,31 @@

## Changes to code extraction

* The `into` part of `join` clauses is now extracted.
* The `when` part of constant cases is now extracted.
* Fixed a bug where `while(x is T y) ...` was not extracted correctly.

* *Series of bullet points*

## Changes to QL libraries

* A new non-member predicate `mayBeDisposed()` can be used to determine if a variable is potentially disposed inside a library. It will analyse the CIL code in the library to determine this.
* A new non-member predicate `mayBeDisposed()` can be used to determine if a variable is potentially disposed inside a library. It will analyse the CIL code in the library to determine this.
* Several control flow graph entities have been renamed (the old names still exist for backwards compatibility):
- `ControlFlowNode` has been renamed to `ControlFlow::Node`.
- `CallableEntryNode` has been renamed to `ControlFlow::Nodes::EntryNode`.
- `CallableExitNode` has been renamed to `ControlFlow::Nodes::ExitNode`.
- `ControlFlowEdgeType` has been renamed to `ControlFlow::SuccessorType`.
- `ControlFlowEdgeSuccessor` has been renamed to `ControlFlow::SuccessorTypes::NormalSuccessor`.
- `ControlFlowEdgeConditional` has been renamed to `ControlFlow::SuccessorTypes::ConditionalSuccessor`.
- `ControlFlowEdgeBoolean` has been renamed to `ControlFlow::SuccessorTypes::BooleanSuccessor`.
- `ControlFlowEdgeNullness` has been renamed to `ControlFlow::SuccessorTypes::NullnessSuccessor`.
- `ControlFlowEdgeMatching` has been renamed to `ControlFlow::SuccessorTypes::MatchingSuccessor`.
- `ControlFlowEdgeEmptiness` has been renamed to `ControlFlow::SuccessorTypes::EmptinessSuccessor`.
- `ControlFlowEdgeReturn` has been renamed to `ControlFlow::SuccessorTypes::ReturnSuccessor`.
- `ControlFlowEdgeBreak` has been renamed to `ControlFlow::SuccessorTypes::BreakSuccessor`.
- `ControlFlowEdgeContinue` has been renamed to `ControlFlow::SuccessorTypes::ContinueSuccessor`.
- `ControlFlowEdgeGotoLabel` has been renamed to `ControlFlow::SuccessorTypes::GotoLabelSuccessor`.
- `ControlFlowEdgeGotoCase` has been renamed to `ControlFlow::SuccessorTypes::GotoCaseSuccessor`.
- `ControlFlowEdgeGotoDefault` has been renamed to `ControlFlow::SuccessorTypes::GotoDefaultSuccessor`.
- `ControlFlowEdgeException` has been renamed to `ControlFlow::SuccessorTypes::ExceptionSuccessor`.
* The predicate `getCondition()` has been moved from `TypeCase` to `CaseStmt`. It is now possible to get the condition of a `ConstCase` using its `getCondition()` predicate.
3 changes: 3 additions & 0 deletions change-notes/1.18/analysis-javascript.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,12 @@
| Hard-coded credentials | More true-positive results | This rule now recognizes secret cryptographic keys. |
| Incomplete string escaping or encoding | Better name, more true-positive results | This rule has been renamed to more clearly reflect its purpose. Also, it now recognizes incomplete URL encoding and decoding. |
| Insecure randomness | More true-positive results | This rule now recognizes secret cryptographic keys. |
| Misleading indentation after control statement | Fewer results | This rule temporarily ignores TypeScript files. |
| Missing rate limiting | More true-positive results, fewer false-positive results | This rule now recognizes additional rate limiters and expensive route handlers. |
| Missing X-Frame-Options HTTP header | Fewer false-positive results | This rule now treats header names case-insensitively. |
| Omitted array element | Fewer results | This rule temporarily ignores TypeScript files. |
| Reflected cross-site scripting | Fewer false-positive results | This rule now treats header names case-insensitively. |
| Semicolon insertion | Fewer results | This rule temporarily ignores TypeScript files. |
| Server-side URL redirect | More true-positive results | This rule now treats header names case-insensitively. |
| Superfluous trailing arguments | Fewer false-positive results | This rule now ignores calls to some empty functions. |
| Type confusion through parameter tampering | Fewer false-positive results | This rule no longer flags emptiness checks. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ class ReturnValueInstruction extends ReturnInstruction {
}

override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
tag instanceof ReturnValueOperand and
exists(this.getOperand(tag.(ReturnValueOperand))) and
result instanceof IndirectMemoryAccess
}
}
Expand All @@ -629,7 +629,7 @@ class LoadInstruction extends CopyInstruction {
}

override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
tag instanceof CopySourceOperand and
exists(this.getOperand(tag.(CopySourceOperand))) and
result instanceof IndirectMemoryAccess
}

Expand Down Expand Up @@ -1015,7 +1015,7 @@ class ThrowValueInstruction extends ThrowInstruction {
}

override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
tag instanceof ExceptionOperand and
exists(this.getOperand(tag.(ExceptionOperand))) and
result instanceof IndirectMemoryAccess
}

Expand Down Expand Up @@ -1114,7 +1114,7 @@ class UnmodeledUseInstruction extends Instruction {
}

override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
tag instanceof UnmodeledUseOperand and
exists(this.getOperand(tag.(UnmodeledUseOperand))) and
result instanceof UnmodeledMemoryAccess
}
}
Expand All @@ -1125,7 +1125,7 @@ class PhiInstruction extends Instruction {
}

override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
tag instanceof PhiOperand and
exists(this.getOperand(tag.(PhiOperand))) and
result instanceof PhiMemoryAccess
}

Expand Down
10 changes: 5 additions & 5 deletions cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ class ReturnValueInstruction extends ReturnInstruction {
}

override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
tag instanceof ReturnValueOperand and
exists(this.getOperand(tag.(ReturnValueOperand))) and
result instanceof IndirectMemoryAccess
}
}
Expand All @@ -629,7 +629,7 @@ class LoadInstruction extends CopyInstruction {
}

override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
tag instanceof CopySourceOperand and
exists(this.getOperand(tag.(CopySourceOperand))) and
result instanceof IndirectMemoryAccess
}

Expand Down Expand Up @@ -1015,7 +1015,7 @@ class ThrowValueInstruction extends ThrowInstruction {
}

override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
tag instanceof ExceptionOperand and
exists(this.getOperand(tag.(ExceptionOperand))) and
result instanceof IndirectMemoryAccess
}

Expand Down Expand Up @@ -1114,7 +1114,7 @@ class UnmodeledUseInstruction extends Instruction {
}

override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
tag instanceof UnmodeledUseOperand and
exists(this.getOperand(tag.(UnmodeledUseOperand))) and
result instanceof UnmodeledMemoryAccess
}
}
Expand All @@ -1125,7 +1125,7 @@ class PhiInstruction extends Instruction {
}

override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
tag instanceof PhiOperand and
exists(this.getOperand(tag.(PhiOperand))) and
result instanceof PhiMemoryAccess
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ class ReturnValueInstruction extends ReturnInstruction {
}

override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
tag instanceof ReturnValueOperand and
exists(this.getOperand(tag.(ReturnValueOperand))) and
result instanceof IndirectMemoryAccess
}
}
Expand All @@ -629,7 +629,7 @@ class LoadInstruction extends CopyInstruction {
}

override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
tag instanceof CopySourceOperand and
exists(this.getOperand(tag.(CopySourceOperand))) and
result instanceof IndirectMemoryAccess
}

Expand Down Expand Up @@ -1015,7 +1015,7 @@ class ThrowValueInstruction extends ThrowInstruction {
}

override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
tag instanceof ExceptionOperand and
exists(this.getOperand(tag.(ExceptionOperand))) and
result instanceof IndirectMemoryAccess
}

Expand Down Expand Up @@ -1114,7 +1114,7 @@ class UnmodeledUseInstruction extends Instruction {
}

override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
tag instanceof UnmodeledUseOperand and
exists(this.getOperand(tag.(UnmodeledUseOperand))) and
result instanceof UnmodeledMemoryAccess
}
}
Expand All @@ -1125,7 +1125,7 @@ class PhiInstruction extends Instruction {
}

override final MemoryAccessKind getOperandMemoryAccess(OperandTag tag) {
tag instanceof PhiOperand and
exists(this.getOperand(tag.(PhiOperand))) and
result instanceof PhiMemoryAccess
}

Expand Down
6 changes: 3 additions & 3 deletions csharp/ql/src/API Abuse/Dispose.qll
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ private import semmle.code.csharp.frameworks.system.web.UI

class DisposableType extends RefType {
DisposableType() {
this.getABaseType+() = getSystemIDisposableInterface()
this.getABaseType+() instanceof SystemIDisposableInterface
}
}

Expand All @@ -17,13 +17,13 @@ class DisposableField extends Field {

class WebControl extends RefType {
WebControl() {
this.getBaseClass*() = getSystemWebUIControlClass()
this.getBaseClass*() instanceof SystemWebUIControlClass
}
}

class WebPage extends RefType {
WebPage() {
this.getBaseClass*() = getSystemWebUIPageClass()
this.getBaseClass*() instanceof SystemWebUIPageClass
}
}

Expand Down
13 changes: 6 additions & 7 deletions csharp/ql/src/Bad Practices/Control-Flow/ConstantCondition.ql
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import csharp
import semmle.code.csharp.commons.Assertions
import semmle.code.csharp.commons.Constants
import ControlFlowGraph

/** A constant condition. */
abstract class ConstantCondition extends Expr {
Expand Down Expand Up @@ -76,13 +75,13 @@ class ConstantNullnessCondition extends ConstantCondition {
boolean b;

ConstantNullnessCondition() {
forex(ControlFlowNode cfn |
forex(ControlFlow::Node cfn |
cfn = this.getAControlFlowNode() |
exists(ControlFlowEdgeNullness t |
exists(ControlFlow::SuccessorTypes::NullnessSuccessor t |
exists(cfn.getASuccessorByType(t)) |
if t.isNull() then b = true else b = false
) and
strictcount(ControlFlowEdgeType t | exists(cfn.getASuccessorByType(t))) = 1
strictcount(ControlFlow::SuccessorType t | exists(cfn.getASuccessorByType(t))) = 1
)
}

Expand All @@ -99,13 +98,13 @@ class ConstantMatchingCondition extends ConstantCondition {
boolean b;

ConstantMatchingCondition() {
forex(ControlFlowNode cfn |
forex(ControlFlow::Node cfn |
cfn = this.getAControlFlowNode() |
exists(ControlFlowEdgeMatching t |
exists(ControlFlow::SuccessorTypes::MatchingSuccessor t |
exists(cfn.getASuccessorByType(t)) |
if t.isMatch() then b = true else b = false
) and
strictcount(ControlFlowEdgeType t | exists(cfn.getASuccessorByType(t))) = 1
strictcount(ControlFlow::SuccessorType t | exists(cfn.getASuccessorByType(t))) = 1
)
}

Expand Down
2 changes: 1 addition & 1 deletion csharp/ql/src/Bad Practices/ErroneousClassCompare.ql
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ class StringComparison extends Expr {
from StringComparison sc, PropertyAccess pa
where sc.getAnOperand() instanceof StringLiteral
and sc.getAnOperand() = pa
and pa.getTarget() = getSystemTypeClass().getFullNameProperty()
and pa.getTarget() = any(SystemTypeClass c).getFullNameProperty()
select sc, "Erroneous class compare."
Loading