mirror of
https://github.com/github/codeql.git
synced 2026-07-20 18:58:36 +02:00
Merge branch 'master' into ir-this-parameter
Bring in new tests so their output can be fixed
This commit is contained in:
@@ -16,6 +16,7 @@ The following changes in version 1.25 affect C/C++ analysis in all applications.
|
||||
|
||||
## Changes to libraries
|
||||
|
||||
* The library `VCS.qll` and all queries that imported it have been removed.
|
||||
* The data-flow library has been improved, which affects most security queries by potentially
|
||||
adding more results. Flow through functions now takes nested field reads/writes into account.
|
||||
For example, the library is able to track flow from `taint()` to `sink()` via the method
|
||||
@@ -39,3 +40,5 @@ The following changes in version 1.25 affect C/C++ analysis in all applications.
|
||||
}
|
||||
};
|
||||
```
|
||||
* The security pack taint tracking library (`semmle.code.cpp.security.TaintTracking`) now considers that equality checks may block the flow of taint. This results in fewer false positive results from queries that use this library.
|
||||
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
## General improvements
|
||||
|
||||
* Support for the following frameworks and libraries has been improved:
|
||||
- [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
|
||||
- [bluebird](http://bluebirdjs.com/)
|
||||
- [express](https://www.npmjs.com/package/express)
|
||||
- [fastify](https://www.npmjs.com/package/fastify)
|
||||
- [fstream](https://www.npmjs.com/package/fstream)
|
||||
- [jGrowl](https://github.com/stanlemon/jGrowl)
|
||||
- [jQuery](https://jquery.com/)
|
||||
@@ -13,12 +15,11 @@
|
||||
- [mssql](https://www.npmjs.com/package/mssql)
|
||||
- [mysql](https://www.npmjs.com/package/mysql)
|
||||
- [pg](https://www.npmjs.com/package/pg)
|
||||
- [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)
|
||||
- [sequelize](https://www.npmjs.com/package/sequelize)
|
||||
- [spanner](https://www.npmjs.com/package/spanner)
|
||||
- [sqlite](https://www.npmjs.com/package/sqlite)
|
||||
- [ssh2](https://www.npmjs.com/package/ssh2)
|
||||
- [ssh2-streams](https://www.npmjs.com/package/ssh2-streams)
|
||||
- [ssh2](https://www.npmjs.com/package/ssh2)
|
||||
|
||||
* TypeScript 3.9 is now supported.
|
||||
|
||||
@@ -35,41 +36,43 @@
|
||||
|
||||
| **Query** | **Expected impact** | **Change** |
|
||||
|--------------------------------|------------------------------|---------------------------------------------------------------------------|
|
||||
| Misspelled variable name (`js/misspelled-variable-name`) | Message changed | The message for this query now correctly identifies the misspelled variable in additional cases. |
|
||||
| Uncontrolled data used in path expression (`js/path-injection`) | More results | This query now recognizes additional file system calls. |
|
||||
| Uncontrolled command line (`js/command-line-injection`) | More results | This query now recognizes additional command execution calls. |
|
||||
| Client-side URL redirect (`js/client-side-unvalidated-url-redirection`) | Less results | This query now recognizes additional safe patterns of doing URL redirects. |
|
||||
| Client-side cross-site scripting (`js/xss`) | Less results | This query now recognizes additional safe strings based on URLs. |
|
||||
| Incomplete URL scheme check (`js/incomplete-url-scheme-check`) | More results | This query now recognizes additional url scheme checks. |
|
||||
| Prototype pollution in utility function (`js/prototype-pollution-utility`) | More results | This query now recognizes additional utility functions as vulnerable to prototype polution. |
|
||||
| Expression has no effect (`js/useless-expression`) | Less results | This query no longer flags an expression when that expression is the only content of the containing file. |
|
||||
| Unknown directive (`js/unknown-directive`) | Less results | This query no longer flags directives generated by the Babel compiler. |
|
||||
| Client-side cross-site scripting (`js/xss`) | Fewer results | This query no longer flags optionally sanitized values. |
|
||||
| Client-side URL redirect (`js/client-side-unvalidated-url-redirection`) | Fewer results | This query now recognizes additional safe patterns of doing URL redirects. |
|
||||
| Client-side cross-site scripting (`js/xss`) | Fewer results | This query now recognizes additional safe patterns of constructing HTML. |
|
||||
| Code injection (`js/code-injection`) | More results | More potential vulnerabilities involving NoSQL code operators are now recognized. |
|
||||
| Expression has no effect (`js/useless-expression`) | Fewer results | This query no longer flags an expression when that expression is the only content of the containing file. |
|
||||
| Incomplete URL scheme check (`js/incomplete-url-scheme-check`) | More results | This query now recognizes additional url scheme checks. |
|
||||
| Misspelled variable name (`js/misspelled-variable-name`) | Message changed | The message for this query now correctly identifies the misspelled variable in additional cases. |
|
||||
| Prototype pollution in utility function (`js/prototype-pollution-utility`) | More results | This query now recognizes additional utility functions as vulnerable to prototype polution. |
|
||||
| Prototype pollution in utility function (`js/prototype-pollution-utility`) | More results | This query now recognizes more coding patterns that are vulnerable to prototype pollution. |
|
||||
| Uncontrolled command line (`js/command-line-injection`) | More results | This query now recognizes additional command execution calls. |
|
||||
| Uncontrolled data used in path expression (`js/path-injection`) | More results | This query now recognizes additional file system calls. |
|
||||
| Unknown directive (`js/unknown-directive`) | Fewer results | This query no longer flags directives generated by the Babel compiler. |
|
||||
| Unused property (`js/unused-property`) | Fewer results | This query no longer flags properties of objects that are operands of `yield` expressions. |
|
||||
| Zip Slip (`js/zipslip`) | More results | This query now recognizes additional vulnerabilities. |
|
||||
| Unused property (`js/unused-property`) | Less results | This query no longer flags properties of objects that are operands of `yield` expressions. |
|
||||
|
||||
The following low-precision queries are no longer run by default on LGTM (their results already were not displayed):
|
||||
|
||||
- `js/angular/dead-event-listener`
|
||||
- `js/angular/unused-dependency`
|
||||
- `js/conflicting-html-attribute`
|
||||
- `js/useless-assignment-to-global`
|
||||
- `js/too-many-parameters`
|
||||
- `js/unused-property`
|
||||
- `js/bitwise-sign-check`
|
||||
- `js/comparison-of-identical-expressions`
|
||||
- `js/misspelled-identifier`
|
||||
- `js/jsdoc/malformed-param-tag`
|
||||
- `js/jsdoc/unknown-parameter`
|
||||
- `js/jsdoc/missing-parameter`
|
||||
- `js/omitted-array-element`
|
||||
- `js/conflicting-html-attribute`
|
||||
- `js/ignored-setter-parameter`
|
||||
- `js/jsdoc/malformed-param-tag`
|
||||
- `js/jsdoc/missing-parameter`
|
||||
- `js/jsdoc/unknown-parameter`
|
||||
- `js/json-in-javascript-file`
|
||||
- `js/misspelled-identifier`
|
||||
- `js/nested-loops-with-same-variable`
|
||||
- `js/node/cyclic-import`
|
||||
- `js/node/unused-npm-dependency`
|
||||
- `js/single-run-loop`
|
||||
- `js/nested-loops-with-same-variable`
|
||||
- `js/omitted-array-element`
|
||||
- `js/return-outside-function`
|
||||
- `js/single-run-loop`
|
||||
- `js/too-many-parameters`
|
||||
- `js/unused-property`
|
||||
- `js/useless-assignment-to-global`
|
||||
|
||||
## Changes to libraries
|
||||
|
||||
@@ -79,3 +82,4 @@ The following low-precision queries are no longer run by default on LGTM (their
|
||||
- `Parameter.flow()` now gets the correct data flow node for a parameter. Previously this had a result, but the node was disconnected from the data flow graph.
|
||||
- `ParameterNode.asExpr()` and `.getAstNode()` now gets the parameter's AST node, whereas previously it had no result.
|
||||
- `Expr.flow()` now has a more meaningful result for destructuring patterns. Previously this node was disconnected from the data flow graph. Now it represents the values being destructured by the pattern.
|
||||
* The global data-flow and taint-tracking libraries now model indirect parameter accesses through the `arguments` object in some cases, which may lead to additional results from some of the security queries, particularly "Prototype pollution in utility function".
|
||||
|
||||
@@ -6,29 +6,50 @@
|
||||
|
||||
import cpp
|
||||
|
||||
// True if function was ()-declared, but not (void)-declared or K&R-defined
|
||||
/**
|
||||
* Holds if `fde` has a parameter declaration that's clear on the minimum
|
||||
* number of parameters. This is essentially true for everything except
|
||||
* `()`-declarations.
|
||||
*/
|
||||
private predicate hasDefiniteNumberOfParameters(FunctionDeclarationEntry fde) {
|
||||
fde.hasVoidParamList()
|
||||
or
|
||||
fde.getNumberOfParameters() > 0
|
||||
or
|
||||
fde.isDefinition()
|
||||
}
|
||||
|
||||
/* Holds if function was ()-declared, but not (void)-declared or K&R-defined. */
|
||||
private predicate hasZeroParamDecl(Function f) {
|
||||
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
|
||||
not fde.hasVoidParamList() and fde.getNumberOfParameters() = 0 and not fde.isDefinition()
|
||||
not hasDefiniteNumberOfParameters(fde)
|
||||
)
|
||||
}
|
||||
|
||||
// True if this file (or header) was compiled as a C file
|
||||
/* Holds if this file (or header) was compiled as a C file. */
|
||||
private predicate isCompiledAsC(File f) {
|
||||
f.compiledAsC()
|
||||
or
|
||||
exists(File src | isCompiledAsC(src) | src.getAnIncludedFile() = f)
|
||||
}
|
||||
|
||||
/** Holds if `fc` is a call to `f` with too few arguments. */
|
||||
predicate tooFewArguments(FunctionCall fc, Function f) {
|
||||
f = fc.getTarget() and
|
||||
not f.isVarargs() and
|
||||
not f instanceof BuiltInFunction and
|
||||
// This query should only have results on C (not C++) functions that have a
|
||||
// `()` parameter list somewhere. If it has results on other functions, then
|
||||
// it's probably because the extractor only saw a partial compilation.
|
||||
hasZeroParamDecl(f) and
|
||||
isCompiledAsC(f.getFile()) and
|
||||
// There is an explicit declaration of the function whose parameter count is larger
|
||||
// than the number of call arguments
|
||||
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
|
||||
// Produce an alert when all declarations that are authoritative on the
|
||||
// parameter count specify a parameter count larger than the number of call
|
||||
// arguments.
|
||||
forex(FunctionDeclarationEntry fde |
|
||||
fde = f.getADeclarationEntry() and
|
||||
hasDefiniteNumberOfParameters(fde)
|
||||
|
|
||||
fde.getNumberOfParameters() > fc.getNumberOfArguments()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/**
|
||||
* @name Churned lines per file
|
||||
* @description Number of churned lines per file, across the revision
|
||||
* history in the database.
|
||||
* @kind treemap
|
||||
* @id cpp/historical-churn
|
||||
* @treemap.warnOn highValues
|
||||
* @metricType file
|
||||
* @metricAggregate avg sum max
|
||||
* @tags external-data
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import external.VCS
|
||||
|
||||
from File f, int n
|
||||
where
|
||||
n =
|
||||
sum(Commit entry, int churn |
|
||||
churn = entry.getRecentChurnForFile(f) and
|
||||
not artificialChange(entry)
|
||||
|
|
||||
churn
|
||||
) and
|
||||
exists(f.getMetrics().getNumberOfLinesOfCode())
|
||||
select f, n order by n desc
|
||||
@@ -1,27 +0,0 @@
|
||||
/**
|
||||
* @name Added lines per file
|
||||
* @description Number of added lines per file, across the revision
|
||||
* history in the database.
|
||||
* @kind treemap
|
||||
* @id cpp/historical-lines-added
|
||||
* @treemap.warnOn highValues
|
||||
* @metricType file
|
||||
* @metricAggregate avg sum max
|
||||
* @tags external-data
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import external.VCS
|
||||
|
||||
from File f, int n
|
||||
where
|
||||
n =
|
||||
sum(Commit entry, int churn |
|
||||
churn = entry.getRecentAdditionsForFile(f) and
|
||||
not artificialChange(entry)
|
||||
|
|
||||
churn
|
||||
) and
|
||||
exists(f.getMetrics().getNumberOfLinesOfCode())
|
||||
select f, n order by n desc
|
||||
@@ -1,27 +0,0 @@
|
||||
/**
|
||||
* @name Deleted lines per file
|
||||
* @description Number of deleted lines per file, across the revision
|
||||
* history in the database.
|
||||
* @kind treemap
|
||||
* @id cpp/historical-lines-deleted
|
||||
* @treemap.warnOn highValues
|
||||
* @metricType file
|
||||
* @metricAggregate avg sum max
|
||||
* @tags external-data
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import external.VCS
|
||||
|
||||
from File f, int n
|
||||
where
|
||||
n =
|
||||
sum(Commit entry, int churn |
|
||||
churn = entry.getRecentDeletionsForFile(f) and
|
||||
not artificialChange(entry)
|
||||
|
|
||||
churn
|
||||
) and
|
||||
exists(f.getMetrics().getNumberOfLinesOfCode())
|
||||
select f, n order by n desc
|
||||
@@ -1,18 +0,0 @@
|
||||
/**
|
||||
* @name Number of authors
|
||||
* @description Number of distinct authors for each file.
|
||||
* @kind treemap
|
||||
* @id cpp/historical-number-of-authors
|
||||
* @treemap.warnOn highValues
|
||||
* @metricType file
|
||||
* @metricAggregate avg min max
|
||||
* @tags external-data
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import external.VCS
|
||||
|
||||
from File f
|
||||
where exists(f.getMetrics().getNumberOfLinesOfCode())
|
||||
select f, count(Author author | author.getAnEditedFile() = f)
|
||||
@@ -1,19 +0,0 @@
|
||||
/**
|
||||
* @name Number of file-level changes
|
||||
* @description The number of file-level changes made (by version
|
||||
* control history).
|
||||
* @kind treemap
|
||||
* @id cpp/historical-number-of-changes
|
||||
* @treemap.warnOn highValues
|
||||
* @metricType file
|
||||
* @metricAggregate avg min max sum
|
||||
* @tags external-data
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import external.VCS
|
||||
|
||||
from File f
|
||||
where exists(f.getMetrics().getNumberOfLinesOfCode())
|
||||
select f, count(Commit svn | f = svn.getAnAffectedFile() and not artificialChange(svn))
|
||||
@@ -1,21 +0,0 @@
|
||||
/**
|
||||
* @name Number of co-committed files
|
||||
* @description The average number of other files that are touched
|
||||
* whenever a file is affected by a commit.
|
||||
* @kind treemap
|
||||
* @id cpp/historical-number-of-co-commits
|
||||
* @treemap.warnOn highValues
|
||||
* @metricType file
|
||||
* @metricAggregate avg min max
|
||||
* @tags external-data
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import external.VCS
|
||||
|
||||
int committedFiles(Commit commit) { result = count(commit.getAnAffectedFile()) }
|
||||
|
||||
from File f
|
||||
where exists(f.getMetrics().getNumberOfLinesOfCode())
|
||||
select f, avg(Commit commit | commit.getAnAffectedFile() = f | committedFiles(commit) - 1)
|
||||
@@ -1,37 +0,0 @@
|
||||
/**
|
||||
* @name Number of re-commits for each file
|
||||
* @description A re-commit is taken to mean a commit to a file that
|
||||
* was touched less than five days ago.
|
||||
* @kind treemap
|
||||
* @id cpp/historical-number-of-re-commits
|
||||
* @treemap.warnOn highValues
|
||||
* @metricType file
|
||||
* @metricAggregate avg min max
|
||||
* @tags external-data
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import external.VCS
|
||||
|
||||
predicate inRange(Commit first, Commit second) {
|
||||
first.getAnAffectedFile() = second.getAnAffectedFile() and
|
||||
first != second and
|
||||
exists(int n |
|
||||
n = first.getDate().daysTo(second.getDate()) and
|
||||
n >= 0 and
|
||||
n < 5
|
||||
)
|
||||
}
|
||||
|
||||
int recommitsForFile(File f) {
|
||||
result =
|
||||
count(Commit recommit |
|
||||
f = recommit.getAnAffectedFile() and
|
||||
exists(Commit prev | inRange(prev, recommit))
|
||||
)
|
||||
}
|
||||
|
||||
from File f
|
||||
where exists(f.getMetrics().getNumberOfLinesOfCode())
|
||||
select f, recommitsForFile(f)
|
||||
@@ -1,27 +0,0 @@
|
||||
/**
|
||||
* @name Number of recent authors
|
||||
* @description Number of distinct authors that have recently made
|
||||
* changes.
|
||||
* @kind treemap
|
||||
* @id cpp/historical-number-of-recent-authors
|
||||
* @treemap.warnOn highValues
|
||||
* @metricType file
|
||||
* @metricAggregate avg min max
|
||||
* @tags external-data
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import external.VCS
|
||||
|
||||
from File f
|
||||
where exists(f.getMetrics().getNumberOfLinesOfCode())
|
||||
select f,
|
||||
count(Author author |
|
||||
exists(Commit e |
|
||||
e = author.getACommit() and
|
||||
f = e.getAnAffectedFile() and
|
||||
e.daysToNow() <= 180 and
|
||||
not artificialChange(e)
|
||||
)
|
||||
)
|
||||
@@ -1,24 +0,0 @@
|
||||
/**
|
||||
* @name Recently changed files
|
||||
* @description Number of files recently edited.
|
||||
* @kind treemap
|
||||
* @id cpp/historical-number-of-recent-changed-files
|
||||
* @treemap.warnOn highValues
|
||||
* @metricType file
|
||||
* @metricAggregate avg min max sum
|
||||
* @tags external-data
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import external.VCS
|
||||
|
||||
from File f
|
||||
where
|
||||
exists(Commit e |
|
||||
e.getAnAffectedFile() = f and
|
||||
e.daysToNow() <= 180 and
|
||||
not artificialChange(e)
|
||||
) and
|
||||
exists(f.getMetrics().getNumberOfLinesOfCode())
|
||||
select f, 1
|
||||
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
* @name Recent changes
|
||||
* @description Number of recent commits to this file.
|
||||
* @kind treemap
|
||||
* @id cpp/historical-number-of-recent-changes
|
||||
* @treemap.warnOn highValues
|
||||
* @metricType file
|
||||
* @metricAggregate avg min max sum
|
||||
* @tags external-data
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import external.VCS
|
||||
|
||||
from File f, int n
|
||||
where
|
||||
n =
|
||||
count(Commit e |
|
||||
e.getAnAffectedFile() = f and
|
||||
e.daysToNow() <= 180 and
|
||||
not artificialChange(e)
|
||||
) and
|
||||
exists(f.getMetrics().getNumberOfLinesOfCode())
|
||||
select f, n order by n desc
|
||||
@@ -1 +1,7 @@
|
||||
/**
|
||||
* DEPRECATED: use `import cpp` instead of `import default`.
|
||||
*
|
||||
* Provides classes and predicates for working with C/C++ code.
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
65
cpp/ql/src/external/CodeDuplication.qll
vendored
65
cpp/ql/src/external/CodeDuplication.qll
vendored
@@ -1,3 +1,5 @@
|
||||
/** Provides classes for detecting duplicate or similar code. */
|
||||
|
||||
import cpp
|
||||
|
||||
private string relativePath(File file) { result = file.getRelativePath().replaceAll("\\", "/") }
|
||||
@@ -8,9 +10,12 @@ private predicate tokenLocation(string path, int sl, int sc, int ec, int el, Cop
|
||||
tokens(copy, index, sl, sc, ec, el)
|
||||
}
|
||||
|
||||
/** A token block used for detection of duplicate and similar code. */
|
||||
class Copy extends @duplication_or_similarity {
|
||||
/** Gets the index of the last token in this block. */
|
||||
private int lastToken() { result = max(int i | tokens(this, i, _, _, _, _) | i) }
|
||||
|
||||
/** Gets the index of the token in this block starting at the location `loc`, if any. */
|
||||
int tokenStartingAt(Location loc) {
|
||||
exists(string filepath, int startline, int startcol |
|
||||
loc.hasLocationInfo(filepath, startline, startcol, _, _) and
|
||||
@@ -18,6 +23,7 @@ class Copy extends @duplication_or_similarity {
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the index of the token in this block ending at the location `loc`, if any. */
|
||||
int tokenEndingAt(Location loc) {
|
||||
exists(string filepath, int endline, int endcol |
|
||||
loc.hasLocationInfo(filepath, _, _, endline, endcol) and
|
||||
@@ -25,24 +31,38 @@ class Copy extends @duplication_or_similarity {
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the line on which the first token in this block starts. */
|
||||
int sourceStartLine() { tokens(this, 0, result, _, _, _) }
|
||||
|
||||
/** Gets the column on which the first token in this block starts. */
|
||||
int sourceStartColumn() { tokens(this, 0, _, result, _, _) }
|
||||
|
||||
/** Gets the line on which the last token in this block ends. */
|
||||
int sourceEndLine() { tokens(this, lastToken(), _, _, result, _) }
|
||||
|
||||
/** Gets the column on which the last token in this block ends. */
|
||||
int sourceEndColumn() { tokens(this, lastToken(), _, _, _, result) }
|
||||
|
||||
/** Gets the number of lines containing at least (part of) one token in this block. */
|
||||
int sourceLines() { result = this.sourceEndLine() + 1 - this.sourceStartLine() }
|
||||
|
||||
/** Gets an opaque identifier for the equivalence class of this block. */
|
||||
int getEquivalenceClass() { duplicateCode(this, _, result) or similarCode(this, _, result) }
|
||||
|
||||
/** Gets the source file in which this block appears. */
|
||||
File sourceFile() {
|
||||
exists(string name | duplicateCode(this, name, _) or similarCode(this, name, _) |
|
||||
name.replaceAll("\\", "/") = relativePath(result)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
*/
|
||||
predicate hasLocationInfo(
|
||||
string filepath, int startline, int startcolumn, int endline, int endcolumn
|
||||
) {
|
||||
@@ -53,25 +73,30 @@ class Copy extends @duplication_or_similarity {
|
||||
endcolumn = sourceEndColumn()
|
||||
}
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
/** A block of duplicated code. */
|
||||
class DuplicateBlock extends Copy, @duplication {
|
||||
override string toString() { result = "Duplicate code: " + sourceLines() + " duplicated lines." }
|
||||
}
|
||||
|
||||
/** A block of similar code. */
|
||||
class SimilarBlock extends Copy, @similarity {
|
||||
override string toString() {
|
||||
result = "Similar code: " + sourceLines() + " almost duplicated lines."
|
||||
}
|
||||
}
|
||||
|
||||
/** Gets a function with a body and a location. */
|
||||
FunctionDeclarationEntry sourceMethod() {
|
||||
result.isDefinition() and
|
||||
exists(result.getLocation()) and
|
||||
numlines(unresolveElement(result.getFunction()), _, _, _)
|
||||
}
|
||||
|
||||
/** Gets the number of member functions in `c` with a body and a location. */
|
||||
int numberOfSourceMethods(Class c) {
|
||||
result =
|
||||
count(FunctionDeclarationEntry m |
|
||||
@@ -108,6 +133,10 @@ private predicate duplicateStatement(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `m1` is a function with `total` lines, and `m2` is a function
|
||||
* that has `duplicate` lines in common with `m1`.
|
||||
*/
|
||||
predicate duplicateStatements(
|
||||
FunctionDeclarationEntry m1, FunctionDeclarationEntry m2, int duplicate, int total
|
||||
) {
|
||||
@@ -115,13 +144,16 @@ predicate duplicateStatements(
|
||||
total = strictcount(statementInMethod(m1))
|
||||
}
|
||||
|
||||
/**
|
||||
* Find pairs of methods are identical
|
||||
*/
|
||||
/** Holds if `m` and other are identical functions. */
|
||||
predicate duplicateMethod(FunctionDeclarationEntry m, FunctionDeclarationEntry other) {
|
||||
exists(int total | duplicateStatements(m, other, total, total))
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: do not use.
|
||||
*
|
||||
* Holds if `line` in `f` is similar to a line somewhere else.
|
||||
*/
|
||||
predicate similarLines(File f, int line) {
|
||||
exists(SimilarBlock b | b.sourceFile() = f and line in [b.sourceStartLine() .. b.sourceEndLine()])
|
||||
}
|
||||
@@ -152,6 +184,7 @@ private predicate similarLinesCoveredFiles(File f, File otherFile) {
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `coveredLines` lines of `f` are similar to lines in `otherFile`. */
|
||||
predicate similarLinesCovered(File f, int coveredLines, File otherFile) {
|
||||
exists(int numLines | numLines = f.getMetrics().getNumberOfLines() |
|
||||
similarLinesCoveredFiles(f, otherFile) and
|
||||
@@ -166,6 +199,11 @@ predicate similarLinesCovered(File f, int coveredLines, File otherFile) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: do not use.
|
||||
*
|
||||
* Holds if `line` in `f` is duplicated by a line somewhere else.
|
||||
*/
|
||||
predicate duplicateLines(File f, int line) {
|
||||
exists(DuplicateBlock b |
|
||||
b.sourceFile() = f and line in [b.sourceStartLine() .. b.sourceEndLine()]
|
||||
@@ -182,6 +220,7 @@ private predicate duplicateLinesPerEquivalenceClass(int equivClass, int lines, F
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `coveredLines` lines of `f` are duplicates of lines in `otherFile`. */
|
||||
predicate duplicateLinesCovered(File f, int coveredLines, File otherFile) {
|
||||
exists(int numLines | numLines = f.getMetrics().getNumberOfLines() |
|
||||
exists(int coveredApprox |
|
||||
@@ -206,6 +245,7 @@ predicate duplicateLinesCovered(File f, int coveredLines, File otherFile) {
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if most of `f` (`percent`%) is similar to `other`. */
|
||||
predicate similarFiles(File f, File other, int percent) {
|
||||
exists(int covered, int total |
|
||||
similarLinesCovered(f, covered, other) and
|
||||
@@ -216,6 +256,7 @@ predicate similarFiles(File f, File other, int percent) {
|
||||
not duplicateFiles(f, other, _)
|
||||
}
|
||||
|
||||
/** Holds if most of `f` (`percent`%) is duplicated by `other`. */
|
||||
predicate duplicateFiles(File f, File other, int percent) {
|
||||
exists(int covered, int total |
|
||||
duplicateLinesCovered(f, covered, other) and
|
||||
@@ -225,6 +266,10 @@ predicate duplicateFiles(File f, File other, int percent) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if most member functions of `c` (`numDup` out of `total`) are
|
||||
* duplicates of member functions in `other`.
|
||||
*/
|
||||
predicate mostlyDuplicateClassBase(Class c, Class other, int numDup, int total) {
|
||||
numDup =
|
||||
strictcount(FunctionDeclarationEntry m1 |
|
||||
@@ -240,6 +285,11 @@ predicate mostlyDuplicateClassBase(Class c, Class other, int numDup, int total)
|
||||
(numDup * 100) / total > 80
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if most member functions of `c` are duplicates of member functions in
|
||||
* `other`. Provides the human-readable `message` to describe the amount of
|
||||
* duplication.
|
||||
*/
|
||||
predicate mostlyDuplicateClass(Class c, Class other, string message) {
|
||||
exists(int numDup, int total |
|
||||
mostlyDuplicateClassBase(c, other, numDup, total) and
|
||||
@@ -264,12 +314,21 @@ predicate mostlyDuplicateClass(Class c, Class other, string message) {
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `f` and `other` are similar or duplicates. */
|
||||
predicate fileLevelDuplication(File f, File other) {
|
||||
similarFiles(f, other, _) or duplicateFiles(f, other, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if most member functions of `c` are duplicates of member functions in
|
||||
* `other`.
|
||||
*/
|
||||
predicate classLevelDuplication(Class c, Class other) { mostlyDuplicateClass(c, other, _) }
|
||||
|
||||
/**
|
||||
* Holds if `line` in `f` should be allowed to be duplicated. This is the case
|
||||
* for `#include` directives.
|
||||
*/
|
||||
predicate whitelistedLineForDuplication(File f, int line) {
|
||||
exists(Include i | i.getFile() = f and i.getLocation().getStartLine() = line)
|
||||
}
|
||||
|
||||
21
cpp/ql/src/external/DefectFilter.qll
vendored
21
cpp/ql/src/external/DefectFilter.qll
vendored
@@ -1,31 +1,52 @@
|
||||
/** Provides a class for working with defect query results stored in dashboard databases. */
|
||||
|
||||
import cpp
|
||||
|
||||
/**
|
||||
* Holds if `id` in the opaque identifier of a result reported by query `queryPath`,
|
||||
* such that `message` is the associated message and the location of the result spans
|
||||
* column `startcolumn` of line `startline` to column `endcolumn` of line `endline`
|
||||
* in file `filepath`.
|
||||
*
|
||||
* For more information, see [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
*/
|
||||
external predicate defectResults(
|
||||
int id, string queryPath, string file, int startline, int startcol, int endline, int endcol,
|
||||
string message
|
||||
);
|
||||
|
||||
/**
|
||||
* A defect query result stored in a dashboard database.
|
||||
*/
|
||||
class DefectResult extends int {
|
||||
DefectResult() { defectResults(this, _, _, _, _, _, _, _) }
|
||||
|
||||
/** Gets the path of the query that reported the result. */
|
||||
string getQueryPath() { defectResults(this, result, _, _, _, _, _, _) }
|
||||
|
||||
/** Gets the file in which this query result was reported. */
|
||||
File getFile() {
|
||||
exists(string path |
|
||||
defectResults(this, _, path, _, _, _, _, _) and result.getAbsolutePath() = path
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the line on which the location of this query result starts. */
|
||||
int getStartLine() { defectResults(this, _, _, result, _, _, _, _) }
|
||||
|
||||
/** Gets the column on which the location of this query result starts. */
|
||||
int getStartColumn() { defectResults(this, _, _, _, result, _, _, _) }
|
||||
|
||||
/** Gets the line on which the location of this query result ends. */
|
||||
int getEndLine() { defectResults(this, _, _, _, _, result, _, _) }
|
||||
|
||||
/** Gets the column on which the location of this query result ends. */
|
||||
int getEndColumn() { defectResults(this, _, _, _, _, _, result, _) }
|
||||
|
||||
/** Gets the message associated with this query result. */
|
||||
string getMessage() { defectResults(this, _, _, _, _, _, _, result) }
|
||||
|
||||
/** Gets the URL corresponding to the location of this query result. */
|
||||
string getURL() {
|
||||
result =
|
||||
"file://" + getFile().getAbsolutePath() + ":" + getStartLine() + ":" + getStartColumn() + ":" +
|
||||
|
||||
35
cpp/ql/src/external/ExternalArtifact.qll
vendored
35
cpp/ql/src/external/ExternalArtifact.qll
vendored
@@ -1,26 +1,45 @@
|
||||
/**
|
||||
* Provides classes for working with external data.
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
/**
|
||||
* An external data item.
|
||||
*/
|
||||
class ExternalData extends @externalDataElement {
|
||||
/** Gets the path of the file this data was loaded from. */
|
||||
string getDataPath() { externalData(this, result, _, _) }
|
||||
|
||||
/**
|
||||
* Gets the path of the file this data was loaded from, with its
|
||||
* extension replaced by `.ql`.
|
||||
*/
|
||||
string getQueryPath() { result = getDataPath().regexpReplaceAll("\\.[^.]*$", ".ql") }
|
||||
|
||||
/** Gets the number of fields in this data item. */
|
||||
int getNumFields() { result = 1 + max(int i | externalData(this, _, i, _) | i) }
|
||||
|
||||
string getField(int index) { externalData(this, _, index, result) }
|
||||
/** Gets the value of the `i`th field of this data item. */
|
||||
string getField(int i) { externalData(this, _, i, result) }
|
||||
|
||||
int getFieldAsInt(int index) { result = getField(index).toInt() }
|
||||
/** Gets the integer value of the `i`th field of this data item. */
|
||||
int getFieldAsInt(int i) { result = getField(i).toInt() }
|
||||
|
||||
float getFieldAsFloat(int index) { result = getField(index).toFloat() }
|
||||
/** Gets the floating-point value of the `i`th field of this data item. */
|
||||
float getFieldAsFloat(int i) { result = getField(i).toFloat() }
|
||||
|
||||
date getFieldAsDate(int index) { result = getField(index).toDate() }
|
||||
/** Gets the value of the `i`th field of this data item, interpreted as a date. */
|
||||
date getFieldAsDate(int i) { result = getField(i).toDate() }
|
||||
|
||||
/** Gets a textual representation of this data item. */
|
||||
string toString() { result = getQueryPath() + ": " + buildTupleString(0) }
|
||||
|
||||
private string buildTupleString(int start) {
|
||||
start = getNumFields() - 1 and result = getField(start)
|
||||
/** Gets a textual representation of this data item, starting with the `n`th field. */
|
||||
private string buildTupleString(int n) {
|
||||
n = getNumFields() - 1 and result = getField(n)
|
||||
or
|
||||
start < getNumFields() - 1 and result = getField(start) + "," + buildTupleString(start + 1)
|
||||
n < getNumFields() - 1 and result = getField(n) + "," + buildTupleString(n + 1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +52,9 @@ class DefectExternalData extends ExternalData {
|
||||
this.getNumFields() = 2
|
||||
}
|
||||
|
||||
/** Gets the URL associated with this data item. */
|
||||
string getURL() { result = getField(0) }
|
||||
|
||||
/** Gets the message associated with this data item. */
|
||||
string getMessage() { result = getField(1) }
|
||||
}
|
||||
|
||||
29
cpp/ql/src/external/MetricFilter.qll
vendored
29
cpp/ql/src/external/MetricFilter.qll
vendored
@@ -1,31 +1,58 @@
|
||||
/** Provides a class for working with metric query results stored in dashboard databases. */
|
||||
|
||||
import cpp
|
||||
|
||||
/**
|
||||
* Holds if `id` in the opaque identifier of a result reported by query `queryPath`,
|
||||
* such that `value` is the reported metric value and the location of the result spans
|
||||
* column `startcolumn` of line `startline` to column `endcolumn` of line `endline`
|
||||
* in file `filepath`.
|
||||
*
|
||||
* For more information, see [Locations](https://help.semmle.com/QL/learn-ql/ql/locations.html).
|
||||
*/
|
||||
external predicate metricResults(
|
||||
int id, string queryPath, string file, int startline, int startcol, int endline, int endcol,
|
||||
float value
|
||||
);
|
||||
|
||||
/**
|
||||
* A metric query result stored in a dashboard database.
|
||||
*/
|
||||
class MetricResult extends int {
|
||||
MetricResult() { metricResults(this, _, _, _, _, _, _, _) }
|
||||
|
||||
/** Gets the path of the query that reported the result. */
|
||||
string getQueryPath() { metricResults(this, result, _, _, _, _, _, _) }
|
||||
|
||||
/** Gets the file in which this query result was reported. */
|
||||
File getFile() {
|
||||
exists(string path |
|
||||
metricResults(this, _, path, _, _, _, _, _) and result.getAbsolutePath() = path
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the line on which the location of this query result starts. */
|
||||
int getStartLine() { metricResults(this, _, _, result, _, _, _, _) }
|
||||
|
||||
/** Gets the column on which the location of this query result starts. */
|
||||
int getStartColumn() { metricResults(this, _, _, _, result, _, _, _) }
|
||||
|
||||
/** Gets the line on which the location of this query result ends. */
|
||||
int getEndLine() { metricResults(this, _, _, _, _, result, _, _) }
|
||||
|
||||
/** Gets the column on which the location of this query result ends. */
|
||||
int getEndColumn() { metricResults(this, _, _, _, _, _, result, _) }
|
||||
|
||||
/**
|
||||
* Holds if there is a `Location` entity whose location is the same as
|
||||
* the location of this query result.
|
||||
*/
|
||||
predicate hasMatchingLocation() { exists(this.getMatchingLocation()) }
|
||||
|
||||
/**
|
||||
* Gets the `Location` entity whose location is the same as the location
|
||||
* of this query result.
|
||||
*/
|
||||
Location getMatchingLocation() {
|
||||
result.getFile() = this.getFile() and
|
||||
result.getStartLine() = this.getStartLine() and
|
||||
@@ -34,8 +61,10 @@ class MetricResult extends int {
|
||||
result.getEndColumn() = this.getEndColumn()
|
||||
}
|
||||
|
||||
/** Gets the value associated with this query result. */
|
||||
float getValue() { metricResults(this, _, _, _, _, _, _, result) }
|
||||
|
||||
/** Gets the URL corresponding to the location of this query result. */
|
||||
string getURL() {
|
||||
result =
|
||||
"file://" + getFile().getAbsolutePath() + ":" + getStartLine() + ":" + getStartColumn() + ":" +
|
||||
|
||||
92
cpp/ql/src/external/VCS.qll
vendored
92
cpp/ql/src/external/VCS.qll
vendored
@@ -1,92 +0,0 @@
|
||||
import cpp
|
||||
|
||||
class Commit extends @svnentry {
|
||||
Commit() {
|
||||
svnaffectedfiles(this, _, _) and
|
||||
exists(date svnDate, date snapshotDate |
|
||||
svnentries(this, _, _, svnDate, _) and
|
||||
snapshotDate(snapshotDate) and
|
||||
svnDate <= snapshotDate
|
||||
)
|
||||
}
|
||||
|
||||
string toString() { result = this.getRevisionName() }
|
||||
|
||||
string getRevisionName() { svnentries(this, result, _, _, _) }
|
||||
|
||||
string getAuthor() { svnentries(this, _, result, _, _) }
|
||||
|
||||
date getDate() { svnentries(this, _, _, result, _) }
|
||||
|
||||
int getChangeSize() { svnentries(this, _, _, _, result) }
|
||||
|
||||
string getMessage() { svnentrymsg(this, result) }
|
||||
|
||||
string getAnAffectedFilePath(string action) {
|
||||
exists(File rawFile | svnaffectedfiles(this, unresolveElement(rawFile), action) |
|
||||
result = rawFile.getAbsolutePath()
|
||||
)
|
||||
}
|
||||
|
||||
string getAnAffectedFilePath() { result = getAnAffectedFilePath(_) }
|
||||
|
||||
File getAnAffectedFile(string action) {
|
||||
// Workaround for incorrect keys in SVN data
|
||||
exists(File svnFile | svnFile.getAbsolutePath() = result.getAbsolutePath() |
|
||||
svnaffectedfiles(this, unresolveElement(svnFile), action)
|
||||
) and
|
||||
exists(result.getMetrics().getNumberOfLinesOfCode())
|
||||
}
|
||||
|
||||
File getAnAffectedFile() { exists(string action | result = this.getAnAffectedFile(action)) }
|
||||
|
||||
private predicate churnForFile(File f, int added, int deleted) {
|
||||
// Workaround for incorrect keys in SVN data
|
||||
exists(File svnFile | svnFile.getAbsolutePath() = f.getAbsolutePath() |
|
||||
svnchurn(this, unresolveElement(svnFile), added, deleted)
|
||||
) and
|
||||
exists(f.getMetrics().getNumberOfLinesOfCode())
|
||||
}
|
||||
|
||||
int getRecentChurnForFile(File f) {
|
||||
exists(int added, int deleted | churnForFile(f, added, deleted) and result = added + deleted)
|
||||
}
|
||||
|
||||
int getRecentAdditionsForFile(File f) { churnForFile(f, result, _) }
|
||||
|
||||
int getRecentDeletionsForFile(File f) { churnForFile(f, _, result) }
|
||||
|
||||
predicate isRecent() { recentCommit(this) }
|
||||
|
||||
int daysToNow() {
|
||||
exists(date now | snapshotDate(now) | result = getDate().daysTo(now) and result >= 0)
|
||||
}
|
||||
}
|
||||
|
||||
class Author extends string {
|
||||
Author() { exists(Commit e | this = e.getAuthor()) }
|
||||
|
||||
Commit getACommit() { result.getAuthor() = this }
|
||||
|
||||
File getAnEditedFile() { result = this.getACommit().getAnAffectedFile() }
|
||||
}
|
||||
|
||||
predicate recentCommit(Commit e) {
|
||||
exists(date snapshotDate, date commitDate, int days |
|
||||
snapshotDate(snapshotDate) and
|
||||
e.getDate() = commitDate and
|
||||
days = commitDate.daysTo(snapshotDate) and
|
||||
days >= 0 and
|
||||
days <= 60
|
||||
)
|
||||
}
|
||||
|
||||
date firstChange(File f) {
|
||||
result = min(Commit e, date toMin | f = e.getAnAffectedFile() and toMin = e.getDate() | toMin)
|
||||
}
|
||||
|
||||
predicate firstCommit(Commit e) {
|
||||
not exists(File f | f = e.getAnAffectedFile() | firstChange(f) < e.getDate())
|
||||
}
|
||||
|
||||
predicate artificialChange(Commit e) { firstCommit(e) or e.getChangeSize() >= 50000 }
|
||||
20
cpp/ql/src/external/tests/DefectFromSVN.ql
vendored
20
cpp/ql/src/external/tests/DefectFromSVN.ql
vendored
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* @name Defect from SVN
|
||||
* @description A test case for creating a defect from SVN data.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @tags external-data
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import external.ExternalArtifact
|
||||
import external.VCS
|
||||
|
||||
predicate numCommits(File f, int i) { i = count(Commit e | e.getAnAffectedFile() = f) }
|
||||
|
||||
predicate maxCommits(int i) { i = max(File f, int j | numCommits(f, j) | j) }
|
||||
|
||||
from File f, int i
|
||||
where numCommits(f, i) and maxCommits(i)
|
||||
select f, "This file has " + i + " commits."
|
||||
17
cpp/ql/src/external/tests/MetricFromSVN.ql
vendored
17
cpp/ql/src/external/tests/MetricFromSVN.ql
vendored
@@ -1,17 +0,0 @@
|
||||
/**
|
||||
* @name Metric from SVN
|
||||
* @description Find number of commits for a file
|
||||
* @treemap.warnOn lowValues
|
||||
* @metricType file
|
||||
* @tags external-data
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import external.VCS
|
||||
|
||||
predicate numCommits(File f, int i) { i = count(Commit e | e.getAnAffectedFile() = f) }
|
||||
|
||||
from File f, int i
|
||||
where numCommits(f, i)
|
||||
select f, i
|
||||
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
* @name Filter: exclude results from files that have not recently been
|
||||
* edited
|
||||
* @description Use this filter to return results only if they are
|
||||
* located in files that have been modified in the 60 days
|
||||
* before the date of the snapshot.
|
||||
* @kind problem
|
||||
* @id cpp/recent-defects-filter
|
||||
* @tags filter
|
||||
* external-data
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import external.DefectFilter
|
||||
import external.VCS
|
||||
|
||||
pragma[noopt]
|
||||
private predicate recent(File file) {
|
||||
exists(Commit e | file = e.getAnAffectedFile() | e.isRecent() and not artificialChange(e))
|
||||
}
|
||||
|
||||
from DefectResult res
|
||||
where recent(res.getFile())
|
||||
select res, res.getMessage()
|
||||
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
* @name Metric filter: exclude results from files that have not
|
||||
* recently been edited
|
||||
* @description Use this filter to return results only if they are
|
||||
* located in files that have been modified in the 60 days
|
||||
* before the snapshot.
|
||||
* @kind treemap
|
||||
* @id cpp/recent-defects-for-metric-filter
|
||||
* @tags filter
|
||||
* external-data
|
||||
* @deprecated
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import external.MetricFilter
|
||||
import external.VCS
|
||||
|
||||
pragma[noopt]
|
||||
private predicate recent(File file) {
|
||||
exists(Commit e | file = e.getAnAffectedFile() | e.isRecent() and not artificialChange(e))
|
||||
}
|
||||
|
||||
from MetricResult res
|
||||
where recent(res.getFile())
|
||||
select res, res.getValue()
|
||||
@@ -1 +1,7 @@
|
||||
/**
|
||||
* DEPRECATED: Objective C is no longer supported.
|
||||
*
|
||||
* Import `cpp` instead of `objc`.
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
||||
@@ -98,7 +98,12 @@ class Declaration extends Locatable, @declaration {
|
||||
this.hasQualifiedName(namespaceQualifier, "", baseName)
|
||||
}
|
||||
|
||||
override string toString() { result = this.getName() }
|
||||
/**
|
||||
* Gets a description of this `Declaration` for display purposes.
|
||||
*/
|
||||
string getDescription() { result = this.getName() }
|
||||
|
||||
final override string toString() { result = this.getDescription() }
|
||||
|
||||
/**
|
||||
* Gets the name of this declaration.
|
||||
|
||||
@@ -79,7 +79,10 @@ class Namespace extends NameQualifyingElement, @namespace {
|
||||
/** Gets the metric namespace. */
|
||||
MetricNamespace getMetrics() { result = this }
|
||||
|
||||
override string toString() { result = this.getQualifiedName() }
|
||||
/** Gets a version of the `QualifiedName` that is more suitable for display purposes. */
|
||||
string getFriendlyName() { result = this.getQualifiedName() }
|
||||
|
||||
final override string toString() { result = getFriendlyName() }
|
||||
|
||||
/** Gets a declaration of (part of) this namespace. */
|
||||
NamespaceDeclarationEntry getADeclarationEntry() { result.getNamespace() = this }
|
||||
@@ -104,7 +107,7 @@ class NamespaceDeclarationEntry extends Locatable, @namespace_decl {
|
||||
namespace_decls(underlyingElement(this), unresolveElement(result), _, _)
|
||||
}
|
||||
|
||||
override string toString() { result = this.getNamespace().toString() }
|
||||
override string toString() { result = this.getNamespace().getFriendlyName() }
|
||||
|
||||
/**
|
||||
* Gets the location of the token preceding the namespace declaration
|
||||
@@ -150,7 +153,7 @@ class UsingDeclarationEntry extends UsingEntry {
|
||||
*/
|
||||
Declaration getDeclaration() { usings(underlyingElement(this), unresolveElement(result), _) }
|
||||
|
||||
override string toString() { result = "using " + this.getDeclaration().toString() }
|
||||
override string toString() { result = "using " + this.getDeclaration().getDescription() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -169,7 +172,7 @@ class UsingDirectiveEntry extends UsingEntry {
|
||||
*/
|
||||
Namespace getNamespace() { usings(underlyingElement(this), unresolveElement(result), _) }
|
||||
|
||||
override string toString() { result = "using namespace " + this.getNamespace().toString() }
|
||||
override string toString() { result = "using namespace " + this.getNamespace().getFriendlyName() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,7 +207,7 @@ class GlobalNamespace extends Namespace {
|
||||
*/
|
||||
deprecated string getFullName() { result = this.getName() }
|
||||
|
||||
override string toString() { result = "(global namespace)" }
|
||||
override string getFriendlyName() { result = "(global namespace)" }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -260,24 +260,33 @@ class ParameterDeclarationEntry extends VariableDeclarationEntry {
|
||||
*/
|
||||
int getIndex() { param_decl_bind(underlyingElement(this), result, _) }
|
||||
|
||||
private string getAnonymousParameterDescription() {
|
||||
not exists(getName()) and
|
||||
exists(string idx |
|
||||
idx =
|
||||
((getIndex() + 1).toString() + "th")
|
||||
.replaceAll("1th", "1st")
|
||||
.replaceAll("2th", "2nd")
|
||||
.replaceAll("3th", "3rd")
|
||||
.replaceAll("11st", "11th")
|
||||
.replaceAll("12nd", "12th")
|
||||
.replaceAll("13rd", "13th") and
|
||||
if exists(getCanonicalName())
|
||||
then result = "declaration of " + getCanonicalName() + " as anonymous " + idx + " parameter"
|
||||
else result = "declaration of " + idx + " parameter"
|
||||
)
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
if exists(getName())
|
||||
then result = super.toString()
|
||||
else
|
||||
exists(string idx |
|
||||
idx =
|
||||
((getIndex() + 1).toString() + "th")
|
||||
.replaceAll("1th", "1st")
|
||||
.replaceAll("2th", "2nd")
|
||||
.replaceAll("3th", "3rd")
|
||||
.replaceAll("11st", "11th")
|
||||
.replaceAll("12nd", "12th")
|
||||
.replaceAll("13rd", "13th")
|
||||
|
|
||||
if exists(getCanonicalName())
|
||||
then result = "declaration of " + getCanonicalName() + " as anonymous " + idx + " parameter"
|
||||
else result = "declaration of " + idx + " parameter"
|
||||
)
|
||||
isDefinition() and
|
||||
result = "definition of " + getName()
|
||||
or
|
||||
not isDefinition() and
|
||||
if getName() = getCanonicalName()
|
||||
then result = "declaration of " + getName()
|
||||
else result = "declaration of " + getCanonicalName() + " as " + getName()
|
||||
or
|
||||
result = getAnonymousParameterDescription()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -116,7 +116,7 @@ class XMLFile extends XMLParent, File {
|
||||
XMLFile() { xmlEncoding(this, _) }
|
||||
|
||||
/** Gets a printable representation of this XML file. */
|
||||
override string toString() { result = XMLParent.super.toString() }
|
||||
override string toString() { result = getName() }
|
||||
|
||||
/** Gets the name of this XML file. */
|
||||
override string getName() { result = File.super.getAbsolutePath() }
|
||||
@@ -236,7 +236,7 @@ class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
|
||||
string getAttributeValue(string name) { result = this.getAttribute(name).getValue() }
|
||||
|
||||
/** Gets a printable representation of this XML element. */
|
||||
override string toString() { result = XMLParent.super.toString() }
|
||||
override string toString() { result = getName() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Provides a library for reasoning about control flow at the granularity of basic blocks.
|
||||
* This is usually much more efficient than reasoning directly at the level of `ControlFlowNode`s.
|
||||
*/
|
||||
|
||||
import cpp
|
||||
private import internal.PrimitiveBasicBlocks
|
||||
private import internal.ConstantExprs
|
||||
@@ -148,22 +153,37 @@ predicate bb_successor = bb_successor_cached/2;
|
||||
class BasicBlock extends ControlFlowNodeBase {
|
||||
BasicBlock() { basic_block_entry_node(this) }
|
||||
|
||||
/** Holds if this basic block contains `node`. */
|
||||
predicate contains(ControlFlowNode node) { basic_block_member(node, this, _) }
|
||||
|
||||
/** Gets the `ControlFlowNode` at position `pos` in this basic block. */
|
||||
ControlFlowNode getNode(int pos) { basic_block_member(result, this, pos) }
|
||||
|
||||
/** Gets a `ControlFlowNode` in this basic block. */
|
||||
ControlFlowNode getANode() { basic_block_member(result, this, _) }
|
||||
|
||||
/** Gets a `BasicBlock` that is a direct successor of this basic block. */
|
||||
BasicBlock getASuccessor() { bb_successor(this, result) }
|
||||
|
||||
/** Gets a `BasicBlock` that is a direct predecessor of this basic block. */
|
||||
BasicBlock getAPredecessor() { bb_successor(result, this) }
|
||||
|
||||
/**
|
||||
* Gets a `BasicBlock` such that the control-flow edge `(this, result)` may be taken
|
||||
* when the outgoing edge of this basic block is an expression that is true.
|
||||
*/
|
||||
BasicBlock getATrueSuccessor() { result.getStart() = this.getEnd().getATrueSuccessor() }
|
||||
|
||||
/**
|
||||
* Gets a `BasicBlock` such that the control-flow edge `(this, result)` may be taken
|
||||
* when the outgoing edge of this basic block is an expression that is false.
|
||||
*/
|
||||
BasicBlock getAFalseSuccessor() { result.getStart() = this.getEnd().getAFalseSuccessor() }
|
||||
|
||||
/** Gets the final `ControlFlowNode` of this basic block. */
|
||||
ControlFlowNode getEnd() { basic_block_member(result, this, bb_length(this) - 1) }
|
||||
|
||||
/** Gets the first `ControlFlowNode` of this basic block. */
|
||||
ControlFlowNode getStart() { result = this }
|
||||
|
||||
/** Gets the number of `ControlFlowNode`s in this basic block. */
|
||||
@@ -192,6 +212,7 @@ class BasicBlock extends ControlFlowNodeBase {
|
||||
this.getEnd().getLocation().hasLocationInfo(endf, _, _, endl, endc)
|
||||
}
|
||||
|
||||
/** Gets the function containing this basic block. */
|
||||
Function getEnclosingFunction() { result = this.getStart().getControlFlowScope() }
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/**
|
||||
* Provides a library for reasoning about control flow at the granularity of
|
||||
* individual nodes in the control-flow graph.
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import BasicBlocks
|
||||
private import semmle.code.cpp.controlflow.internal.ConstantExprs
|
||||
@@ -29,8 +34,10 @@ private import semmle.code.cpp.controlflow.internal.CFG
|
||||
* `Handler`. There are no edges from function calls to `Handler`s.
|
||||
*/
|
||||
class ControlFlowNode extends Locatable, ControlFlowNodeBase {
|
||||
/** Gets a direct successor of this control-flow node, if any. */
|
||||
ControlFlowNode getASuccessor() { successors_adapted(this, result) }
|
||||
|
||||
/** Gets a direct predecessor of this control-flow node, if any. */
|
||||
ControlFlowNode getAPredecessor() { this = result.getASuccessor() }
|
||||
|
||||
/** Gets the function containing this control-flow node. */
|
||||
@@ -71,6 +78,7 @@ class ControlFlowNode extends Locatable, ControlFlowNodeBase {
|
||||
result = getASuccessor()
|
||||
}
|
||||
|
||||
/** Gets the `BasicBlock` containing this control-flow node. */
|
||||
BasicBlock getBasicBlock() { result.getANode() = this }
|
||||
}
|
||||
|
||||
@@ -86,10 +94,18 @@ import ControlFlowGraphPublic
|
||||
*/
|
||||
class ControlFlowNodeBase extends ElementBase, @cfgnode { }
|
||||
|
||||
/**
|
||||
* Holds when `n2` is a control-flow node such that the control-flow
|
||||
* edge `(n1, n2)` may be taken when `n1` is an expression that is true.
|
||||
*/
|
||||
predicate truecond_base(ControlFlowNodeBase n1, ControlFlowNodeBase n2) {
|
||||
qlCFGTrueSuccessor(n1, n2)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds when `n2` is a control-flow node such that the control-flow
|
||||
* edge `(n1, n2)` may be taken when `n1` is an expression that is false.
|
||||
*/
|
||||
predicate falsecond_base(ControlFlowNodeBase n1, ControlFlowNodeBase n2) {
|
||||
qlCFGFalseSuccessor(n1, n2)
|
||||
}
|
||||
|
||||
@@ -15,14 +15,25 @@ import Dereferenced
|
||||
abstract class DataflowAnnotation extends string {
|
||||
DataflowAnnotation() { this = "pointer-null" or this = "pointer-valid" }
|
||||
|
||||
/** Holds if this annotation is the default annotation. */
|
||||
abstract predicate isDefault();
|
||||
|
||||
/** Holds if this annotation is generated when analyzing expression `e`. */
|
||||
abstract predicate generatedOn(Expr e);
|
||||
|
||||
/**
|
||||
* Holds if this annotation is generated for the variable `v` when
|
||||
* the control-flow edge `(src, dest)` is taken.
|
||||
*/
|
||||
abstract predicate generatedBy(LocalScopeVariable v, ControlFlowNode src, ControlFlowNode dest);
|
||||
|
||||
/**
|
||||
* Holds if this annotation is removed for the variable `v` when
|
||||
* the control-flow edge `(src, dest)` is taken.
|
||||
*/
|
||||
abstract predicate killedBy(LocalScopeVariable v, ControlFlowNode src, ControlFlowNode dest);
|
||||
|
||||
/** Holds if expression `e` is given this annotation. */
|
||||
predicate marks(Expr e) {
|
||||
this.generatedOn(e) and reachable(e)
|
||||
or
|
||||
@@ -31,6 +42,7 @@ abstract class DataflowAnnotation extends string {
|
||||
exists(LocalScopeVariable v | this.marks(v, e) and e = v.getAnAccess())
|
||||
}
|
||||
|
||||
/** Holds if the variable `v` accessed in control-flow node `n` is given this annotation. */
|
||||
predicate marks(LocalScopeVariable v, ControlFlowNode n) {
|
||||
v.getAnAccess().getEnclosingFunction().getBlock() = n and
|
||||
this.isDefault()
|
||||
@@ -57,6 +69,10 @@ abstract class DataflowAnnotation extends string {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the variable `v` preserves this annotation when the control-flow
|
||||
* edge `(src, dest)` is taken.
|
||||
*/
|
||||
predicate preservedBy(LocalScopeVariable v, ControlFlowNode src, ControlFlowNode dest) {
|
||||
this.marks(v, src) and
|
||||
src.getASuccessor() = dest and
|
||||
@@ -64,6 +80,10 @@ abstract class DataflowAnnotation extends string {
|
||||
not v.getAnAssignment() = src
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the variable `v` is assigned this annotation when `src` is an assignment
|
||||
* expression that assigns to `v` and the control-flow edge `(src, dest)` is taken.
|
||||
*/
|
||||
predicate assignedBy(LocalScopeVariable v, ControlFlowNode src, ControlFlowNode dest) {
|
||||
this.marks(src.(AssignExpr).getRValue()) and
|
||||
src = v.getAnAssignment() and
|
||||
|
||||
@@ -66,9 +66,6 @@ abstract class Configuration extends string {
|
||||
*/
|
||||
predicate isBarrier(Node node) { none() }
|
||||
|
||||
/** DEPRECATED: override `isBarrierIn` and `isBarrierOut` instead. */
|
||||
deprecated predicate isBarrierEdge(Node node1, Node node2) { none() }
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isBarrierIn(Node node) { none() }
|
||||
|
||||
|
||||
@@ -66,9 +66,6 @@ abstract class Configuration extends string {
|
||||
*/
|
||||
predicate isBarrier(Node node) { none() }
|
||||
|
||||
/** DEPRECATED: override `isBarrierIn` and `isBarrierOut` instead. */
|
||||
deprecated predicate isBarrierEdge(Node node1, Node node2) { none() }
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isBarrierIn(Node node) { none() }
|
||||
|
||||
|
||||
@@ -66,9 +66,6 @@ abstract class Configuration extends string {
|
||||
*/
|
||||
predicate isBarrier(Node node) { none() }
|
||||
|
||||
/** DEPRECATED: override `isBarrierIn` and `isBarrierOut` instead. */
|
||||
deprecated predicate isBarrierEdge(Node node1, Node node2) { none() }
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isBarrierIn(Node node) { none() }
|
||||
|
||||
|
||||
@@ -66,9 +66,6 @@ abstract class Configuration extends string {
|
||||
*/
|
||||
predicate isBarrier(Node node) { none() }
|
||||
|
||||
/** DEPRECATED: override `isBarrierIn` and `isBarrierOut` instead. */
|
||||
deprecated predicate isBarrierEdge(Node node1, Node node2) { none() }
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isBarrierIn(Node node) { none() }
|
||||
|
||||
|
||||
@@ -66,9 +66,6 @@ abstract class Configuration extends string {
|
||||
*/
|
||||
predicate isBarrier(Node node) { none() }
|
||||
|
||||
/** DEPRECATED: override `isBarrierIn` and `isBarrierOut` instead. */
|
||||
deprecated predicate isBarrierEdge(Node node1, Node node2) { none() }
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isBarrierIn(Node node) { none() }
|
||||
|
||||
|
||||
@@ -79,13 +79,6 @@ abstract class Configuration extends DataFlow::Configuration {
|
||||
defaultTaintBarrier(node)
|
||||
}
|
||||
|
||||
/** DEPRECATED: override `isSanitizerIn` and `isSanitizerOut` instead. */
|
||||
deprecated predicate isSanitizerEdge(DataFlow::Node node1, DataFlow::Node node2) { none() }
|
||||
|
||||
deprecated final override predicate isBarrierEdge(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
isSanitizerEdge(node1, node2)
|
||||
}
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isSanitizerIn(DataFlow::Node node) { none() }
|
||||
|
||||
|
||||
@@ -79,13 +79,6 @@ abstract class Configuration extends DataFlow::Configuration {
|
||||
defaultTaintBarrier(node)
|
||||
}
|
||||
|
||||
/** DEPRECATED: override `isSanitizerIn` and `isSanitizerOut` instead. */
|
||||
deprecated predicate isSanitizerEdge(DataFlow::Node node1, DataFlow::Node node2) { none() }
|
||||
|
||||
deprecated final override predicate isBarrierEdge(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
isSanitizerEdge(node1, node2)
|
||||
}
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isSanitizerIn(DataFlow::Node node) { none() }
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ class Closure extends Class {
|
||||
result.getName() = "operator()"
|
||||
}
|
||||
|
||||
override string toString() { result = "decltype([...](...){...})" }
|
||||
override string getDescription() { result = "decltype([...](...){...})" }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -99,7 +99,7 @@ class Closure extends Class {
|
||||
* ```
|
||||
*/
|
||||
class LambdaCapture extends Locatable, @lambdacapture {
|
||||
override string toString() { result = getField().toString() }
|
||||
override string toString() { result = getField().getName() }
|
||||
|
||||
override string getCanonicalQLClass() { result = "LambdaCapture" }
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.security.Security
|
||||
private import semmle.code.cpp.ir.dataflow.DataFlow
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
|
||||
private import semmle.code.cpp.ir.dataflow.DataFlow2
|
||||
private import semmle.code.cpp.ir.dataflow.DataFlow3
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import semmle.code.cpp.ir.dataflow.internal.DataFlowDispatch as Dispatch
|
||||
private import semmle.code.cpp.controlflow.IRGuards
|
||||
private import semmle.code.cpp.models.interfaces.Taint
|
||||
private import semmle.code.cpp.models.interfaces.DataFlow
|
||||
|
||||
@@ -170,11 +172,34 @@ private predicate hasUpperBoundsCheck(Variable var) {
|
||||
)
|
||||
}
|
||||
|
||||
private predicate nodeIsBarrierEqualityCandidate(
|
||||
DataFlow::Node node, Operand access, Variable checkedVar
|
||||
) {
|
||||
readsVariable(node.asInstruction(), checkedVar) and
|
||||
any(IRGuardCondition guard).ensuresEq(access, _, _, node.asInstruction().getBlock(), true)
|
||||
}
|
||||
|
||||
private predicate nodeIsBarrier(DataFlow::Node node) {
|
||||
exists(Variable checkedVar |
|
||||
readsVariable(node.asInstruction(), checkedVar) and
|
||||
hasUpperBoundsCheck(checkedVar)
|
||||
)
|
||||
or
|
||||
exists(Variable checkedVar, Operand access |
|
||||
/*
|
||||
* This node is guarded by a condition that forces the accessed variable
|
||||
* to equal something else. For example:
|
||||
* ```
|
||||
* x = taintsource()
|
||||
* if (x == 10) {
|
||||
* taintsink(x); // not considered tainted
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
|
||||
nodeIsBarrierEqualityCandidate(node, access, checkedVar) and
|
||||
readsVariable(access.getDef(), checkedVar)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate nodeIsBarrierIn(DataFlow::Node node) {
|
||||
|
||||
@@ -66,9 +66,6 @@ abstract class Configuration extends string {
|
||||
*/
|
||||
predicate isBarrier(Node node) { none() }
|
||||
|
||||
/** DEPRECATED: override `isBarrierIn` and `isBarrierOut` instead. */
|
||||
deprecated predicate isBarrierEdge(Node node1, Node node2) { none() }
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isBarrierIn(Node node) { none() }
|
||||
|
||||
|
||||
@@ -66,9 +66,6 @@ abstract class Configuration extends string {
|
||||
*/
|
||||
predicate isBarrier(Node node) { none() }
|
||||
|
||||
/** DEPRECATED: override `isBarrierIn` and `isBarrierOut` instead. */
|
||||
deprecated predicate isBarrierEdge(Node node1, Node node2) { none() }
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isBarrierIn(Node node) { none() }
|
||||
|
||||
|
||||
@@ -66,9 +66,6 @@ abstract class Configuration extends string {
|
||||
*/
|
||||
predicate isBarrier(Node node) { none() }
|
||||
|
||||
/** DEPRECATED: override `isBarrierIn` and `isBarrierOut` instead. */
|
||||
deprecated predicate isBarrierEdge(Node node1, Node node2) { none() }
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isBarrierIn(Node node) { none() }
|
||||
|
||||
|
||||
@@ -66,9 +66,6 @@ abstract class Configuration extends string {
|
||||
*/
|
||||
predicate isBarrier(Node node) { none() }
|
||||
|
||||
/** DEPRECATED: override `isBarrierIn` and `isBarrierOut` instead. */
|
||||
deprecated predicate isBarrierEdge(Node node1, Node node2) { none() }
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isBarrierIn(Node node) { none() }
|
||||
|
||||
|
||||
@@ -71,9 +71,7 @@ class Node extends TIRDataFlowNode {
|
||||
* `x.set(taint())` is a partial definition of `x`, and `transfer(&x, taint())` is
|
||||
* a partial definition of `&x`).
|
||||
*/
|
||||
Expr asPartialDefinition() {
|
||||
result = this.(PartialDefinitionNode).getInstruction().getUnconvertedResultExpression()
|
||||
}
|
||||
Expr asPartialDefinition() { result = this.(PartialDefinitionNode).getDefinedExpr() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: See UninitializedNode.
|
||||
@@ -247,14 +245,17 @@ abstract class PostUpdateNode extends InstructionNode {
|
||||
* setY(&x); // a partial definition of the object `x`.
|
||||
* ```
|
||||
*/
|
||||
abstract private class PartialDefinitionNode extends PostUpdateNode, TInstructionNode { }
|
||||
abstract private class PartialDefinitionNode extends PostUpdateNode, TInstructionNode {
|
||||
abstract Expr getDefinedExpr();
|
||||
}
|
||||
|
||||
private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode {
|
||||
override ChiInstruction instr;
|
||||
FieldAddressInstruction field;
|
||||
|
||||
ExplicitFieldStoreQualifierNode() {
|
||||
not instr.isResultConflated() and
|
||||
exists(StoreInstruction store, FieldInstruction field |
|
||||
exists(StoreInstruction store |
|
||||
instr.getPartial() = store and field = store.getDestinationAddress()
|
||||
)
|
||||
}
|
||||
@@ -264,6 +265,10 @@ private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode {
|
||||
// DataFlowImplConsistency::Consistency. However, it's not clear what (if any) implications
|
||||
// this consistency failure has.
|
||||
override Node getPreUpdateNode() { result.asInstruction() = instr.getTotal() }
|
||||
|
||||
override Expr getDefinedExpr() {
|
||||
result = field.getObjectAddress().getUnconvertedResultExpression()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,15 +279,18 @@ private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode {
|
||||
*/
|
||||
private class ExplicitSingleFieldStoreQualifierNode extends PartialDefinitionNode {
|
||||
override StoreInstruction instr;
|
||||
FieldAddressInstruction field;
|
||||
|
||||
ExplicitSingleFieldStoreQualifierNode() {
|
||||
exists(FieldAddressInstruction field |
|
||||
field = instr.getDestinationAddress() and
|
||||
not exists(ChiInstruction chi | chi.getPartial() = instr)
|
||||
)
|
||||
field = instr.getDestinationAddress() and
|
||||
not exists(ChiInstruction chi | chi.getPartial() = instr)
|
||||
}
|
||||
|
||||
override Node getPreUpdateNode() { none() }
|
||||
|
||||
override Expr getDefinedExpr() {
|
||||
result = field.getObjectAddress().getUnconvertedResultExpression()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -454,9 +462,9 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
|
||||
// for now.
|
||||
iTo.getAnOperand().(ChiTotalOperand).getDef() = iFrom
|
||||
or
|
||||
// The next two rules allow flow from partial definitions in setters to succeeding loads in the caller.
|
||||
// First, we add flow from write side-effects to non-conflated chi instructions through their
|
||||
// partial operands. Consider the following example:
|
||||
// Add flow from write side-effects to non-conflated chi instructions through their
|
||||
// partial operands. From there, a `readStep` will find subsequent reads of that field.
|
||||
// Consider the following example:
|
||||
// ```
|
||||
// void setX(Point* p, int new_x) {
|
||||
// p->x = new_x;
|
||||
@@ -466,14 +474,9 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
|
||||
// ```
|
||||
// Here, a `WriteSideEffectInstruction` will provide a new definition for `p->x` after the call to
|
||||
// `setX`, which will be melded into `p` through a chi instruction.
|
||||
iTo.getAnOperand().(ChiPartialOperand).getDef() = iFrom.(WriteSideEffectInstruction) and
|
||||
not iTo.isResultConflated()
|
||||
or
|
||||
// Next, we add flow from non-conflated chi instructions to loads (even when they are not precise).
|
||||
// This ensures that loads of `p->x` gets data flow from the `WriteSideEffectInstruction` above.
|
||||
exists(ChiInstruction chi | iFrom = chi |
|
||||
not chi.isResultConflated() and
|
||||
iTo.(LoadInstruction).getSourceValueOperand().getAnyDef() = chi
|
||||
exists(ChiInstruction chi | chi = iTo |
|
||||
chi.getPartialOperand().getDef() = iFrom.(WriteSideEffectInstruction) and
|
||||
not chi.isResultConflated()
|
||||
)
|
||||
or
|
||||
// Flow from stores to structs with a single field to a load of that field.
|
||||
|
||||
@@ -79,13 +79,6 @@ abstract class Configuration extends DataFlow::Configuration {
|
||||
defaultTaintBarrier(node)
|
||||
}
|
||||
|
||||
/** DEPRECATED: override `isSanitizerIn` and `isSanitizerOut` instead. */
|
||||
deprecated predicate isSanitizerEdge(DataFlow::Node node1, DataFlow::Node node2) { none() }
|
||||
|
||||
deprecated final override predicate isBarrierEdge(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
isSanitizerEdge(node1, node2)
|
||||
}
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isSanitizerIn(DataFlow::Node node) { none() }
|
||||
|
||||
|
||||
@@ -79,13 +79,6 @@ abstract class Configuration extends DataFlow::Configuration {
|
||||
defaultTaintBarrier(node)
|
||||
}
|
||||
|
||||
/** DEPRECATED: override `isSanitizerIn` and `isSanitizerOut` instead. */
|
||||
deprecated predicate isSanitizerEdge(DataFlow::Node node1, DataFlow::Node node2) { none() }
|
||||
|
||||
deprecated final override predicate isBarrierEdge(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
isSanitizerEdge(node1, node2)
|
||||
}
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isSanitizerIn(DataFlow::Node node) { none() }
|
||||
|
||||
|
||||
@@ -362,7 +362,7 @@ CppType getTypeForPRValueOrUnknown(Type type) {
|
||||
/**
|
||||
* Gets the `CppType` that represents a glvalue of type `type`.
|
||||
*/
|
||||
CppType getTypeForGLValue(Type type) { result.hasType(type, true) }
|
||||
CppGLValueAddressType getTypeForGLValue(Type type) { result.hasType(type, true) }
|
||||
|
||||
/**
|
||||
* Gets the `CppType` that represents a prvalue of type `int`.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import default
|
||||
import cpp
|
||||
|
||||
from Class c, string n
|
||||
where n = count(Class x | x.getName() = c.getName()) + " distinct class(es) called " + c.getName()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import default
|
||||
import cpp
|
||||
import semmle.code.cpp.models.implementations.Allocation
|
||||
|
||||
query predicate newExprs(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import default
|
||||
import cpp
|
||||
|
||||
string getValueCategoryString(Expr expr) {
|
||||
if expr.isLValueCategory()
|
||||
|
||||
@@ -115,5 +115,5 @@ void test_conflated_fields3() {
|
||||
XY xy;
|
||||
xy.x = 0;
|
||||
taint_y(&xy);
|
||||
sink(xy.x); // not tainted [FALSE POSITIVE]
|
||||
sink(xy.x); // not tainted
|
||||
}
|
||||
|
||||
@@ -103,8 +103,6 @@
|
||||
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:110:17:110:32 | (int)... |
|
||||
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:110:17:110:32 | access to array |
|
||||
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:111:12:111:18 | tainted |
|
||||
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:118:11:118:11 | x |
|
||||
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | shared.h:6:15:6:23 | sinkparam |
|
||||
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:28:24:28:27 | call to atoi |
|
||||
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:28:29:28:34 | call to getenv |
|
||||
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:28:29:28:45 | (const char *)... |
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | p2 | IR only |
|
||||
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | shared.h:5:23:5:31 | sinkparam | IR only |
|
||||
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:111:8:111:8 | y | AST only |
|
||||
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:118:11:118:11 | x | IR only |
|
||||
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | shared.h:6:15:6:23 | sinkparam | IR only |
|
||||
| globals.cpp:13:15:13:20 | call to getenv | globals.cpp:13:5:13:11 | global1 | AST only |
|
||||
| globals.cpp:23:15:23:20 | call to getenv | globals.cpp:23:5:23:11 | global2 | AST only |
|
||||
| test_diff.cpp:104:12:104:15 | argv | test_diff.cpp:104:11:104:20 | (...) | IR only |
|
||||
|
||||
@@ -0,0 +1,370 @@
|
||||
| A.cpp:25:7:25:10 | this | AST only |
|
||||
| A.cpp:25:13:25:13 | c | AST only |
|
||||
| A.cpp:27:22:27:25 | this | AST only |
|
||||
| A.cpp:27:28:27:28 | c | AST only |
|
||||
| A.cpp:31:20:31:20 | c | AST only |
|
||||
| A.cpp:40:5:40:6 | cc | AST only |
|
||||
| A.cpp:41:5:41:6 | ct | AST only |
|
||||
| A.cpp:42:10:42:12 | & ... | AST only |
|
||||
| A.cpp:43:10:43:12 | & ... | AST only |
|
||||
| A.cpp:48:20:48:20 | c | AST only |
|
||||
| A.cpp:49:10:49:10 | b | AST only |
|
||||
| A.cpp:49:13:49:13 | c | AST only |
|
||||
| A.cpp:55:5:55:5 | b | AST only |
|
||||
| A.cpp:56:10:56:10 | b | AST only |
|
||||
| A.cpp:56:13:56:15 | call to get | AST only |
|
||||
| A.cpp:57:28:57:30 | call to get | AST only |
|
||||
| A.cpp:64:17:64:18 | b1 | AST only |
|
||||
| A.cpp:65:10:65:11 | b1 | AST only |
|
||||
| A.cpp:65:14:65:14 | c | AST only |
|
||||
| A.cpp:66:10:66:11 | b2 | AST only |
|
||||
| A.cpp:66:14:66:14 | c | AST only |
|
||||
| A.cpp:73:21:73:22 | b1 | AST only |
|
||||
| A.cpp:74:10:74:11 | b1 | AST only |
|
||||
| A.cpp:74:14:74:14 | c | AST only |
|
||||
| A.cpp:75:10:75:11 | b2 | AST only |
|
||||
| A.cpp:75:14:75:14 | c | AST only |
|
||||
| A.cpp:81:17:81:18 | b1 | AST only |
|
||||
| A.cpp:81:21:81:21 | c | AST only |
|
||||
| A.cpp:90:7:90:8 | b2 | AST only |
|
||||
| A.cpp:90:15:90:15 | c | AST only |
|
||||
| A.cpp:100:9:100:9 | a | AST only |
|
||||
| A.cpp:101:8:101:9 | c1 | AST only |
|
||||
| A.cpp:107:12:107:13 | c1 | AST only |
|
||||
| A.cpp:107:16:107:16 | a | AST only |
|
||||
| A.cpp:120:12:120:13 | c1 | AST only |
|
||||
| A.cpp:120:16:120:16 | a | AST only |
|
||||
| A.cpp:126:5:126:5 | b | AST only |
|
||||
| A.cpp:131:8:131:8 | b | AST only |
|
||||
| A.cpp:132:10:132:10 | b | AST only |
|
||||
| A.cpp:132:13:132:13 | c | AST only |
|
||||
| A.cpp:142:10:142:10 | c | AST only |
|
||||
| A.cpp:143:7:143:10 | this | AST only |
|
||||
| A.cpp:143:13:143:13 | b | AST only |
|
||||
| A.cpp:151:18:151:18 | b | AST only |
|
||||
| A.cpp:152:10:152:10 | d | AST only |
|
||||
| A.cpp:152:13:152:13 | b | AST only |
|
||||
| A.cpp:153:10:153:10 | d | AST only |
|
||||
| A.cpp:153:13:153:13 | b | AST only |
|
||||
| A.cpp:153:16:153:16 | c | AST only |
|
||||
| A.cpp:154:10:154:10 | b | AST only |
|
||||
| A.cpp:154:13:154:13 | c | AST only |
|
||||
| A.cpp:160:29:160:29 | b | AST only |
|
||||
| A.cpp:161:38:161:39 | l1 | AST only |
|
||||
| A.cpp:162:38:162:39 | l2 | AST only |
|
||||
| A.cpp:163:10:163:11 | l3 | AST only |
|
||||
| A.cpp:163:14:163:17 | head | AST only |
|
||||
| A.cpp:164:10:164:11 | l3 | AST only |
|
||||
| A.cpp:164:14:164:17 | next | AST only |
|
||||
| A.cpp:164:20:164:23 | head | AST only |
|
||||
| A.cpp:165:10:165:11 | l3 | AST only |
|
||||
| A.cpp:165:14:165:17 | next | AST only |
|
||||
| A.cpp:165:20:165:23 | next | AST only |
|
||||
| A.cpp:165:26:165:29 | head | AST only |
|
||||
| A.cpp:166:10:166:11 | l3 | AST only |
|
||||
| A.cpp:166:14:166:17 | next | AST only |
|
||||
| A.cpp:166:20:166:23 | next | AST only |
|
||||
| A.cpp:166:26:166:29 | next | AST only |
|
||||
| A.cpp:166:32:166:35 | head | AST only |
|
||||
| A.cpp:169:12:169:12 | l | AST only |
|
||||
| A.cpp:169:15:169:18 | head | AST only |
|
||||
| A.cpp:183:7:183:10 | head | AST only |
|
||||
| A.cpp:183:7:183:10 | this | AST only |
|
||||
| A.cpp:184:7:184:10 | this | AST only |
|
||||
| A.cpp:184:13:184:16 | next | AST only |
|
||||
| B.cpp:7:25:7:25 | e | AST only |
|
||||
| B.cpp:8:25:8:26 | b1 | AST only |
|
||||
| B.cpp:9:10:9:11 | b2 | AST only |
|
||||
| B.cpp:9:14:9:17 | box1 | AST only |
|
||||
| B.cpp:9:20:9:24 | elem1 | AST only |
|
||||
| B.cpp:10:10:10:11 | b2 | AST only |
|
||||
| B.cpp:10:14:10:17 | box1 | AST only |
|
||||
| B.cpp:10:20:10:24 | elem2 | AST only |
|
||||
| B.cpp:16:37:16:37 | e | AST only |
|
||||
| B.cpp:17:25:17:26 | b1 | AST only |
|
||||
| B.cpp:18:10:18:11 | b2 | AST only |
|
||||
| B.cpp:18:14:18:17 | box1 | AST only |
|
||||
| B.cpp:18:20:18:24 | elem1 | AST only |
|
||||
| B.cpp:19:10:19:11 | b2 | AST only |
|
||||
| B.cpp:19:14:19:17 | box1 | AST only |
|
||||
| B.cpp:19:20:19:24 | elem2 | AST only |
|
||||
| B.cpp:35:7:35:10 | this | AST only |
|
||||
| B.cpp:35:13:35:17 | elem1 | AST only |
|
||||
| B.cpp:36:7:36:10 | this | AST only |
|
||||
| B.cpp:36:13:36:17 | elem2 | AST only |
|
||||
| B.cpp:46:7:46:10 | this | AST only |
|
||||
| B.cpp:46:13:46:16 | box1 | AST only |
|
||||
| C.cpp:19:5:19:5 | c | AST only |
|
||||
| C.cpp:24:5:24:8 | this | AST only |
|
||||
| C.cpp:24:11:24:12 | s3 | AST only |
|
||||
| D.cpp:9:21:9:24 | elem | AST only |
|
||||
| D.cpp:9:21:9:24 | this | AST only |
|
||||
| D.cpp:11:29:11:32 | elem | AST only |
|
||||
| D.cpp:11:29:11:32 | this | AST only |
|
||||
| D.cpp:16:21:16:23 | box | AST only |
|
||||
| D.cpp:16:21:16:23 | this | AST only |
|
||||
| D.cpp:18:29:18:31 | box | AST only |
|
||||
| D.cpp:18:29:18:31 | this | AST only |
|
||||
| D.cpp:22:10:22:11 | b2 | AST only |
|
||||
| D.cpp:22:14:22:20 | call to getBox1 | AST only |
|
||||
| D.cpp:22:25:22:31 | call to getElem | AST only |
|
||||
| D.cpp:30:5:30:5 | b | AST only |
|
||||
| D.cpp:30:8:30:10 | box | AST only |
|
||||
| D.cpp:30:13:30:16 | elem | AST only |
|
||||
| D.cpp:31:14:31:14 | b | AST only |
|
||||
| D.cpp:37:5:37:5 | b | AST only |
|
||||
| D.cpp:37:8:37:10 | box | AST only |
|
||||
| D.cpp:37:21:37:21 | e | AST only |
|
||||
| D.cpp:38:14:38:14 | b | AST only |
|
||||
| D.cpp:44:5:44:5 | b | AST only |
|
||||
| D.cpp:44:8:44:14 | call to getBox1 | AST only |
|
||||
| D.cpp:44:19:44:22 | elem | AST only |
|
||||
| D.cpp:45:14:45:14 | b | AST only |
|
||||
| D.cpp:51:5:51:5 | b | AST only |
|
||||
| D.cpp:51:8:51:14 | call to getBox1 | AST only |
|
||||
| D.cpp:51:27:51:27 | e | AST only |
|
||||
| D.cpp:52:14:52:14 | b | AST only |
|
||||
| D.cpp:57:5:57:12 | boxfield | AST only |
|
||||
| D.cpp:57:5:57:12 | this | AST only |
|
||||
| D.cpp:58:5:58:12 | boxfield | AST only |
|
||||
| D.cpp:58:5:58:12 | this | AST only |
|
||||
| D.cpp:58:15:58:17 | box | AST only |
|
||||
| D.cpp:58:20:58:23 | elem | AST only |
|
||||
| D.cpp:64:10:64:17 | boxfield | AST only |
|
||||
| D.cpp:64:10:64:17 | this | AST only |
|
||||
| D.cpp:64:20:64:22 | box | AST only |
|
||||
| D.cpp:64:25:64:28 | elem | AST only |
|
||||
| E.cpp:21:10:21:10 | p | AST only |
|
||||
| E.cpp:21:13:21:16 | data | AST only |
|
||||
| E.cpp:21:18:21:23 | buffer | AST only |
|
||||
| E.cpp:28:21:28:23 | raw | AST only |
|
||||
| E.cpp:29:21:29:21 | b | AST only |
|
||||
| E.cpp:29:24:29:29 | buffer | AST only |
|
||||
| E.cpp:30:21:30:21 | p | AST only |
|
||||
| E.cpp:30:23:30:26 | data | AST only |
|
||||
| E.cpp:30:28:30:33 | buffer | AST only |
|
||||
| E.cpp:31:10:31:12 | raw | AST only |
|
||||
| E.cpp:32:10:32:10 | b | AST only |
|
||||
| E.cpp:32:13:32:18 | buffer | AST only |
|
||||
| E.cpp:33:18:33:19 | & ... | AST only |
|
||||
| aliasing.cpp:9:6:9:7 | m1 | AST only |
|
||||
| aliasing.cpp:13:5:13:6 | m1 | AST only |
|
||||
| aliasing.cpp:17:5:17:6 | m1 | AST only |
|
||||
| aliasing.cpp:25:17:25:19 | & ... | AST only |
|
||||
| aliasing.cpp:26:19:26:20 | s2 | AST only |
|
||||
| aliasing.cpp:37:8:37:9 | m1 | AST only |
|
||||
| aliasing.cpp:42:6:42:7 | m1 | AST only |
|
||||
| aliasing.cpp:49:9:49:10 | m1 | AST only |
|
||||
| aliasing.cpp:54:6:54:7 | m1 | AST only |
|
||||
| aliasing.cpp:60:6:60:7 | m1 | AST only |
|
||||
| aliasing.cpp:72:5:72:6 | m1 | AST only |
|
||||
| aliasing.cpp:79:6:79:7 | m1 | AST only |
|
||||
| aliasing.cpp:86:5:86:6 | m1 | AST only |
|
||||
| aliasing.cpp:92:3:92:3 | w | AST only |
|
||||
| aliasing.cpp:92:7:92:8 | m1 | AST only |
|
||||
| by_reference.cpp:12:8:12:8 | a | AST only |
|
||||
| by_reference.cpp:16:5:16:8 | this | AST only |
|
||||
| by_reference.cpp:16:11:16:11 | a | AST only |
|
||||
| by_reference.cpp:20:5:20:8 | this | AST only |
|
||||
| by_reference.cpp:20:23:20:27 | value | AST only |
|
||||
| by_reference.cpp:24:19:24:22 | this | AST only |
|
||||
| by_reference.cpp:24:25:24:29 | value | AST only |
|
||||
| by_reference.cpp:50:3:50:3 | s | AST only |
|
||||
| by_reference.cpp:50:17:50:26 | call to user_input | AST only |
|
||||
| by_reference.cpp:51:10:51:20 | call to getDirectly | AST only |
|
||||
| by_reference.cpp:56:3:56:3 | s | AST only |
|
||||
| by_reference.cpp:56:19:56:28 | call to user_input | AST only |
|
||||
| by_reference.cpp:57:10:57:22 | call to getIndirectly | AST only |
|
||||
| by_reference.cpp:62:3:62:3 | s | AST only |
|
||||
| by_reference.cpp:62:25:62:34 | call to user_input | AST only |
|
||||
| by_reference.cpp:63:10:63:28 | call to getThroughNonMember | AST only |
|
||||
| by_reference.cpp:68:17:68:18 | & ... | AST only |
|
||||
| by_reference.cpp:68:21:68:30 | call to user_input | AST only |
|
||||
| by_reference.cpp:69:8:69:20 | call to nonMemberGetA | AST only |
|
||||
| by_reference.cpp:84:10:84:10 | a | AST only |
|
||||
| by_reference.cpp:88:9:88:9 | a | AST only |
|
||||
| by_reference.cpp:102:21:102:39 | & ... | AST only |
|
||||
| by_reference.cpp:102:22:102:26 | outer | AST only |
|
||||
| by_reference.cpp:103:21:103:25 | outer | AST only |
|
||||
| by_reference.cpp:103:27:103:35 | inner_ptr | AST only |
|
||||
| by_reference.cpp:104:15:104:22 | & ... | AST only |
|
||||
| by_reference.cpp:104:16:104:20 | outer | AST only |
|
||||
| by_reference.cpp:106:21:106:41 | & ... | AST only |
|
||||
| by_reference.cpp:106:22:106:27 | pouter | AST only |
|
||||
| by_reference.cpp:107:21:107:26 | pouter | AST only |
|
||||
| by_reference.cpp:107:29:107:37 | inner_ptr | AST only |
|
||||
| by_reference.cpp:108:15:108:24 | & ... | AST only |
|
||||
| by_reference.cpp:108:16:108:21 | pouter | AST only |
|
||||
| by_reference.cpp:110:8:110:12 | outer | AST only |
|
||||
| by_reference.cpp:110:14:110:25 | inner_nested | AST only |
|
||||
| by_reference.cpp:110:27:110:27 | a | AST only |
|
||||
| by_reference.cpp:111:8:111:12 | outer | AST only |
|
||||
| by_reference.cpp:111:14:111:22 | inner_ptr | AST only |
|
||||
| by_reference.cpp:111:25:111:25 | a | AST only |
|
||||
| by_reference.cpp:112:8:112:12 | outer | AST only |
|
||||
| by_reference.cpp:112:14:112:14 | a | AST only |
|
||||
| by_reference.cpp:114:8:114:13 | pouter | AST only |
|
||||
| by_reference.cpp:114:16:114:27 | inner_nested | AST only |
|
||||
| by_reference.cpp:114:29:114:29 | a | AST only |
|
||||
| by_reference.cpp:115:8:115:13 | pouter | AST only |
|
||||
| by_reference.cpp:115:16:115:24 | inner_ptr | AST only |
|
||||
| by_reference.cpp:115:27:115:27 | a | AST only |
|
||||
| by_reference.cpp:116:8:116:13 | pouter | AST only |
|
||||
| by_reference.cpp:116:16:116:16 | a | AST only |
|
||||
| by_reference.cpp:122:21:122:25 | outer | AST only |
|
||||
| by_reference.cpp:122:27:122:38 | inner_nested | AST only |
|
||||
| by_reference.cpp:123:21:123:36 | * ... | AST only |
|
||||
| by_reference.cpp:123:22:123:26 | outer | AST only |
|
||||
| by_reference.cpp:124:15:124:19 | outer | AST only |
|
||||
| by_reference.cpp:124:21:124:21 | a | AST only |
|
||||
| by_reference.cpp:126:21:126:26 | pouter | AST only |
|
||||
| by_reference.cpp:126:29:126:40 | inner_nested | AST only |
|
||||
| by_reference.cpp:127:21:127:38 | * ... | AST only |
|
||||
| by_reference.cpp:127:22:127:27 | pouter | AST only |
|
||||
| by_reference.cpp:128:15:128:20 | pouter | AST only |
|
||||
| by_reference.cpp:128:23:128:23 | a | AST only |
|
||||
| by_reference.cpp:130:8:130:12 | outer | AST only |
|
||||
| by_reference.cpp:130:14:130:25 | inner_nested | AST only |
|
||||
| by_reference.cpp:130:27:130:27 | a | AST only |
|
||||
| by_reference.cpp:131:8:131:12 | outer | AST only |
|
||||
| by_reference.cpp:131:14:131:22 | inner_ptr | AST only |
|
||||
| by_reference.cpp:131:25:131:25 | a | AST only |
|
||||
| by_reference.cpp:132:8:132:12 | outer | AST only |
|
||||
| by_reference.cpp:132:14:132:14 | a | AST only |
|
||||
| by_reference.cpp:134:8:134:13 | pouter | AST only |
|
||||
| by_reference.cpp:134:16:134:27 | inner_nested | AST only |
|
||||
| by_reference.cpp:134:29:134:29 | a | AST only |
|
||||
| by_reference.cpp:135:8:135:13 | pouter | AST only |
|
||||
| by_reference.cpp:135:16:135:24 | inner_ptr | AST only |
|
||||
| by_reference.cpp:135:27:135:27 | a | AST only |
|
||||
| by_reference.cpp:136:8:136:13 | pouter | AST only |
|
||||
| by_reference.cpp:136:16:136:16 | a | AST only |
|
||||
| complex.cpp:11:22:11:23 | a_ | AST only |
|
||||
| complex.cpp:11:22:11:23 | this | AST only |
|
||||
| complex.cpp:12:22:12:23 | b_ | AST only |
|
||||
| complex.cpp:12:22:12:23 | this | AST only |
|
||||
| complex.cpp:51:8:51:8 | b | AST only |
|
||||
| complex.cpp:51:10:51:14 | inner | AST only |
|
||||
| complex.cpp:51:16:51:16 | f | AST only |
|
||||
| complex.cpp:52:8:52:8 | b | AST only |
|
||||
| complex.cpp:52:10:52:14 | inner | AST only |
|
||||
| complex.cpp:52:16:52:16 | f | AST only |
|
||||
| complex.cpp:62:3:62:4 | b1 | AST only |
|
||||
| complex.cpp:62:6:62:10 | inner | AST only |
|
||||
| complex.cpp:62:12:62:12 | f | AST only |
|
||||
| complex.cpp:63:3:63:4 | b2 | AST only |
|
||||
| complex.cpp:63:6:63:10 | inner | AST only |
|
||||
| complex.cpp:63:12:63:12 | f | AST only |
|
||||
| complex.cpp:64:3:64:4 | b3 | AST only |
|
||||
| complex.cpp:64:6:64:10 | inner | AST only |
|
||||
| complex.cpp:64:12:64:12 | f | AST only |
|
||||
| complex.cpp:65:3:65:4 | b3 | AST only |
|
||||
| complex.cpp:65:6:65:10 | inner | AST only |
|
||||
| complex.cpp:65:12:65:12 | f | AST only |
|
||||
| complex.cpp:68:7:68:8 | b1 | AST only |
|
||||
| complex.cpp:71:7:71:8 | b2 | AST only |
|
||||
| complex.cpp:74:7:74:8 | b3 | AST only |
|
||||
| complex.cpp:77:7:77:8 | b4 | AST only |
|
||||
| constructors.cpp:20:24:20:25 | a_ | AST only |
|
||||
| constructors.cpp:20:24:20:25 | this | AST only |
|
||||
| constructors.cpp:21:24:21:25 | b_ | AST only |
|
||||
| constructors.cpp:21:24:21:25 | this | AST only |
|
||||
| constructors.cpp:28:10:28:10 | f | AST only |
|
||||
| constructors.cpp:29:10:29:10 | f | AST only |
|
||||
| constructors.cpp:40:9:40:9 | f | AST only |
|
||||
| constructors.cpp:43:9:43:9 | g | AST only |
|
||||
| constructors.cpp:46:9:46:9 | h | AST only |
|
||||
| constructors.cpp:49:9:49:9 | i | AST only |
|
||||
| file://:0:0:0:0 | this | AST only |
|
||||
| file://:0:0:0:0 | this | AST only |
|
||||
| file://:0:0:0:0 | this | AST only |
|
||||
| file://:0:0:0:0 | this | AST only |
|
||||
| file://:0:0:0:0 | this | AST only |
|
||||
| file://:0:0:0:0 | this | AST only |
|
||||
| file://:0:0:0:0 | this | AST only |
|
||||
| file://:0:0:0:0 | this | AST only |
|
||||
| file://:0:0:0:0 | this | AST only |
|
||||
| file://:0:0:0:0 | this | AST only |
|
||||
| qualifiers.cpp:9:30:9:33 | this | AST only |
|
||||
| qualifiers.cpp:9:36:9:36 | a | AST only |
|
||||
| qualifiers.cpp:12:56:12:56 | a | AST only |
|
||||
| qualifiers.cpp:13:57:13:57 | a | AST only |
|
||||
| qualifiers.cpp:22:5:22:9 | outer | AST only |
|
||||
| qualifiers.cpp:22:11:22:18 | call to getInner | AST only |
|
||||
| qualifiers.cpp:22:23:22:23 | a | AST only |
|
||||
| qualifiers.cpp:23:10:23:14 | outer | AST only |
|
||||
| qualifiers.cpp:23:16:23:20 | inner | AST only |
|
||||
| qualifiers.cpp:23:23:23:23 | a | AST only |
|
||||
| qualifiers.cpp:27:5:27:9 | outer | AST only |
|
||||
| qualifiers.cpp:27:11:27:18 | call to getInner | AST only |
|
||||
| qualifiers.cpp:27:28:27:37 | call to user_input | AST only |
|
||||
| qualifiers.cpp:28:10:28:14 | outer | AST only |
|
||||
| qualifiers.cpp:28:16:28:20 | inner | AST only |
|
||||
| qualifiers.cpp:28:23:28:23 | a | AST only |
|
||||
| qualifiers.cpp:32:17:32:21 | outer | AST only |
|
||||
| qualifiers.cpp:32:23:32:30 | call to getInner | AST only |
|
||||
| qualifiers.cpp:32:35:32:44 | call to user_input | AST only |
|
||||
| qualifiers.cpp:33:10:33:14 | outer | AST only |
|
||||
| qualifiers.cpp:33:16:33:20 | inner | AST only |
|
||||
| qualifiers.cpp:33:23:33:23 | a | AST only |
|
||||
| qualifiers.cpp:37:19:37:35 | * ... | AST only |
|
||||
| qualifiers.cpp:37:20:37:24 | outer | AST only |
|
||||
| qualifiers.cpp:37:38:37:47 | call to user_input | AST only |
|
||||
| qualifiers.cpp:38:10:38:14 | outer | AST only |
|
||||
| qualifiers.cpp:38:16:38:20 | inner | AST only |
|
||||
| qualifiers.cpp:38:23:38:23 | a | AST only |
|
||||
| qualifiers.cpp:42:6:42:22 | * ... | AST only |
|
||||
| qualifiers.cpp:42:7:42:11 | outer | AST only |
|
||||
| qualifiers.cpp:42:25:42:25 | a | AST only |
|
||||
| qualifiers.cpp:43:10:43:14 | outer | AST only |
|
||||
| qualifiers.cpp:43:16:43:20 | inner | AST only |
|
||||
| qualifiers.cpp:43:23:43:23 | a | AST only |
|
||||
| qualifiers.cpp:47:6:47:11 | & ... | AST only |
|
||||
| qualifiers.cpp:47:15:47:22 | call to getInner | AST only |
|
||||
| qualifiers.cpp:47:27:47:27 | a | AST only |
|
||||
| qualifiers.cpp:48:10:48:14 | outer | AST only |
|
||||
| qualifiers.cpp:48:16:48:20 | inner | AST only |
|
||||
| qualifiers.cpp:48:23:48:23 | a | AST only |
|
||||
| simple.cpp:20:24:20:25 | a_ | AST only |
|
||||
| simple.cpp:20:24:20:25 | this | AST only |
|
||||
| simple.cpp:21:24:21:25 | b_ | AST only |
|
||||
| simple.cpp:21:24:21:25 | this | AST only |
|
||||
| simple.cpp:28:10:28:10 | f | AST only |
|
||||
| simple.cpp:29:10:29:10 | f | AST only |
|
||||
| simple.cpp:39:5:39:5 | f | AST only |
|
||||
| simple.cpp:40:5:40:5 | g | AST only |
|
||||
| simple.cpp:41:5:41:5 | h | AST only |
|
||||
| simple.cpp:42:5:42:5 | h | AST only |
|
||||
| simple.cpp:45:9:45:9 | f | AST only |
|
||||
| simple.cpp:48:9:48:9 | g | AST only |
|
||||
| simple.cpp:51:9:51:9 | h | AST only |
|
||||
| simple.cpp:54:9:54:9 | i | AST only |
|
||||
| simple.cpp:65:7:65:7 | i | AST only |
|
||||
| simple.cpp:83:9:83:10 | f2 | AST only |
|
||||
| simple.cpp:83:9:83:10 | this | AST only |
|
||||
| simple.cpp:83:12:83:13 | f1 | AST only |
|
||||
| struct_init.c:15:8:15:9 | ab | AST only |
|
||||
| struct_init.c:15:12:15:12 | a | AST only |
|
||||
| struct_init.c:16:8:16:9 | ab | AST only |
|
||||
| struct_init.c:16:12:16:12 | b | AST only |
|
||||
| struct_init.c:22:8:22:9 | ab | AST only |
|
||||
| struct_init.c:22:11:22:11 | a | AST only |
|
||||
| struct_init.c:23:8:23:9 | ab | AST only |
|
||||
| struct_init.c:23:11:23:11 | b | AST only |
|
||||
| struct_init.c:24:10:24:12 | & ... | AST only |
|
||||
| struct_init.c:31:8:31:12 | outer | AST only |
|
||||
| struct_init.c:31:14:31:21 | nestedAB | AST only |
|
||||
| struct_init.c:31:23:31:23 | a | AST only |
|
||||
| struct_init.c:32:8:32:12 | outer | AST only |
|
||||
| struct_init.c:32:14:32:21 | nestedAB | AST only |
|
||||
| struct_init.c:32:23:32:23 | b | AST only |
|
||||
| struct_init.c:33:8:33:12 | outer | AST only |
|
||||
| struct_init.c:33:14:33:22 | pointerAB | AST only |
|
||||
| struct_init.c:33:25:33:25 | a | AST only |
|
||||
| struct_init.c:34:8:34:12 | outer | AST only |
|
||||
| struct_init.c:34:14:34:22 | pointerAB | AST only |
|
||||
| struct_init.c:34:25:34:25 | b | AST only |
|
||||
| struct_init.c:36:10:36:24 | & ... | AST only |
|
||||
| struct_init.c:36:11:36:15 | outer | AST only |
|
||||
| struct_init.c:46:10:46:14 | outer | AST only |
|
||||
| struct_init.c:46:16:46:24 | pointerAB | AST only |
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* @kind problem
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.dataflow.DataFlow::DataFlow as IR
|
||||
import semmle.code.cpp.dataflow.DataFlow::DataFlow as AST
|
||||
|
||||
newtype TNode =
|
||||
TASTNode(AST::Node n) or
|
||||
TIRNode(IR::Node n)
|
||||
|
||||
class Node extends TNode {
|
||||
string toString() { none() }
|
||||
|
||||
IR::Node asIR() { none() }
|
||||
|
||||
AST::Node asAST() { none() }
|
||||
|
||||
Location getLocation() { none() }
|
||||
}
|
||||
|
||||
class ASTNode extends Node, TASTNode {
|
||||
AST::Node n;
|
||||
|
||||
ASTNode() { this = TASTNode(n) }
|
||||
|
||||
override string toString() { result = n.asPartialDefinition().toString() }
|
||||
|
||||
override AST::Node asAST() { result = n }
|
||||
|
||||
override Location getLocation() { result = n.getLocation() }
|
||||
}
|
||||
|
||||
class IRNode extends Node, TIRNode {
|
||||
IR::Node n;
|
||||
|
||||
IRNode() { this = TIRNode(n) }
|
||||
|
||||
override string toString() { result = n.asPartialDefinition().toString() }
|
||||
|
||||
override IR::Node asIR() { result = n }
|
||||
|
||||
override Location getLocation() { result = n.getLocation() }
|
||||
}
|
||||
|
||||
from Node node, AST::Node astNode, IR::Node irNode, string msg
|
||||
where
|
||||
node.asIR() = irNode and
|
||||
exists(irNode.asPartialDefinition()) and
|
||||
not exists(AST::Node otherNode | otherNode.asPartialDefinition() = irNode.asPartialDefinition()) and
|
||||
msg = "IR only"
|
||||
or
|
||||
node.asAST() = astNode and
|
||||
exists(astNode.asPartialDefinition()) and
|
||||
not exists(IR::Node otherNode | otherNode.asPartialDefinition() = astNode.asPartialDefinition()) and
|
||||
msg = "AST only"
|
||||
select node, msg
|
||||
@@ -0,0 +1,20 @@
|
||||
| A.cpp:100:5:100:6 | c1 |
|
||||
| A.cpp:142:7:142:7 | b |
|
||||
| aliasing.cpp:9:3:9:3 | s |
|
||||
| aliasing.cpp:13:3:13:3 | s |
|
||||
| aliasing.cpp:17:3:17:3 | s |
|
||||
| aliasing.cpp:37:3:37:6 | ref1 |
|
||||
| aliasing.cpp:42:3:42:4 | s2 |
|
||||
| aliasing.cpp:49:3:49:7 | copy1 |
|
||||
| aliasing.cpp:54:3:54:4 | s2 |
|
||||
| aliasing.cpp:60:3:60:4 | s2 |
|
||||
| aliasing.cpp:72:3:72:3 | s |
|
||||
| aliasing.cpp:79:3:79:3 | s |
|
||||
| aliasing.cpp:86:3:86:3 | s |
|
||||
| aliasing.cpp:92:5:92:5 | s |
|
||||
| by_reference.cpp:12:5:12:5 | s |
|
||||
| by_reference.cpp:84:3:84:7 | inner |
|
||||
| by_reference.cpp:88:3:88:7 | inner |
|
||||
| qualifiers.cpp:12:49:12:53 | inner |
|
||||
| qualifiers.cpp:13:51:13:55 | inner |
|
||||
| simple.cpp:65:5:65:5 | a |
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @kind problem
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.dataflow.DataFlow::DataFlow
|
||||
|
||||
select any(Node n).asPartialDefinition()
|
||||
@@ -0,0 +1,390 @@
|
||||
| A.cpp:25:7:25:10 | this |
|
||||
| A.cpp:25:13:25:13 | c |
|
||||
| A.cpp:27:22:27:25 | this |
|
||||
| A.cpp:27:28:27:28 | c |
|
||||
| A.cpp:31:20:31:20 | c |
|
||||
| A.cpp:40:5:40:6 | cc |
|
||||
| A.cpp:41:5:41:6 | ct |
|
||||
| A.cpp:42:10:42:12 | & ... |
|
||||
| A.cpp:43:10:43:12 | & ... |
|
||||
| A.cpp:48:20:48:20 | c |
|
||||
| A.cpp:49:10:49:10 | b |
|
||||
| A.cpp:49:13:49:13 | c |
|
||||
| A.cpp:55:5:55:5 | b |
|
||||
| A.cpp:56:10:56:10 | b |
|
||||
| A.cpp:56:13:56:15 | call to get |
|
||||
| A.cpp:57:28:57:30 | call to get |
|
||||
| A.cpp:64:17:64:18 | b1 |
|
||||
| A.cpp:65:10:65:11 | b1 |
|
||||
| A.cpp:65:14:65:14 | c |
|
||||
| A.cpp:66:10:66:11 | b2 |
|
||||
| A.cpp:66:14:66:14 | c |
|
||||
| A.cpp:73:21:73:22 | b1 |
|
||||
| A.cpp:74:10:74:11 | b1 |
|
||||
| A.cpp:74:14:74:14 | c |
|
||||
| A.cpp:75:10:75:11 | b2 |
|
||||
| A.cpp:75:14:75:14 | c |
|
||||
| A.cpp:81:17:81:18 | b1 |
|
||||
| A.cpp:81:21:81:21 | c |
|
||||
| A.cpp:90:7:90:8 | b2 |
|
||||
| A.cpp:90:15:90:15 | c |
|
||||
| A.cpp:100:5:100:6 | c1 |
|
||||
| A.cpp:100:9:100:9 | a |
|
||||
| A.cpp:101:8:101:9 | c1 |
|
||||
| A.cpp:107:12:107:13 | c1 |
|
||||
| A.cpp:107:16:107:16 | a |
|
||||
| A.cpp:120:12:120:13 | c1 |
|
||||
| A.cpp:120:16:120:16 | a |
|
||||
| A.cpp:126:5:126:5 | b |
|
||||
| A.cpp:131:8:131:8 | b |
|
||||
| A.cpp:132:10:132:10 | b |
|
||||
| A.cpp:132:13:132:13 | c |
|
||||
| A.cpp:142:7:142:7 | b |
|
||||
| A.cpp:142:10:142:10 | c |
|
||||
| A.cpp:143:7:143:10 | this |
|
||||
| A.cpp:143:13:143:13 | b |
|
||||
| A.cpp:151:18:151:18 | b |
|
||||
| A.cpp:152:10:152:10 | d |
|
||||
| A.cpp:152:13:152:13 | b |
|
||||
| A.cpp:153:10:153:10 | d |
|
||||
| A.cpp:153:13:153:13 | b |
|
||||
| A.cpp:153:16:153:16 | c |
|
||||
| A.cpp:154:10:154:10 | b |
|
||||
| A.cpp:154:13:154:13 | c |
|
||||
| A.cpp:160:29:160:29 | b |
|
||||
| A.cpp:161:38:161:39 | l1 |
|
||||
| A.cpp:162:38:162:39 | l2 |
|
||||
| A.cpp:163:10:163:11 | l3 |
|
||||
| A.cpp:163:14:163:17 | head |
|
||||
| A.cpp:164:10:164:11 | l3 |
|
||||
| A.cpp:164:14:164:17 | next |
|
||||
| A.cpp:164:20:164:23 | head |
|
||||
| A.cpp:165:10:165:11 | l3 |
|
||||
| A.cpp:165:14:165:17 | next |
|
||||
| A.cpp:165:20:165:23 | next |
|
||||
| A.cpp:165:26:165:29 | head |
|
||||
| A.cpp:166:10:166:11 | l3 |
|
||||
| A.cpp:166:14:166:17 | next |
|
||||
| A.cpp:166:20:166:23 | next |
|
||||
| A.cpp:166:26:166:29 | next |
|
||||
| A.cpp:166:32:166:35 | head |
|
||||
| A.cpp:169:12:169:12 | l |
|
||||
| A.cpp:169:15:169:18 | head |
|
||||
| A.cpp:183:7:183:10 | head |
|
||||
| A.cpp:184:7:184:10 | this |
|
||||
| A.cpp:184:13:184:16 | next |
|
||||
| B.cpp:7:25:7:25 | e |
|
||||
| B.cpp:8:25:8:26 | b1 |
|
||||
| B.cpp:9:10:9:11 | b2 |
|
||||
| B.cpp:9:14:9:17 | box1 |
|
||||
| B.cpp:9:20:9:24 | elem1 |
|
||||
| B.cpp:10:10:10:11 | b2 |
|
||||
| B.cpp:10:14:10:17 | box1 |
|
||||
| B.cpp:10:20:10:24 | elem2 |
|
||||
| B.cpp:16:37:16:37 | e |
|
||||
| B.cpp:17:25:17:26 | b1 |
|
||||
| B.cpp:18:10:18:11 | b2 |
|
||||
| B.cpp:18:14:18:17 | box1 |
|
||||
| B.cpp:18:20:18:24 | elem1 |
|
||||
| B.cpp:19:10:19:11 | b2 |
|
||||
| B.cpp:19:14:19:17 | box1 |
|
||||
| B.cpp:19:20:19:24 | elem2 |
|
||||
| B.cpp:35:7:35:10 | this |
|
||||
| B.cpp:35:13:35:17 | elem1 |
|
||||
| B.cpp:36:7:36:10 | this |
|
||||
| B.cpp:36:13:36:17 | elem2 |
|
||||
| B.cpp:46:7:46:10 | this |
|
||||
| B.cpp:46:13:46:16 | box1 |
|
||||
| C.cpp:19:5:19:5 | c |
|
||||
| C.cpp:24:5:24:8 | this |
|
||||
| C.cpp:24:11:24:12 | s3 |
|
||||
| D.cpp:9:21:9:24 | elem |
|
||||
| D.cpp:11:29:11:32 | elem |
|
||||
| D.cpp:16:21:16:23 | box |
|
||||
| D.cpp:18:29:18:31 | box |
|
||||
| D.cpp:22:10:22:11 | b2 |
|
||||
| D.cpp:22:14:22:20 | call to getBox1 |
|
||||
| D.cpp:22:25:22:31 | call to getElem |
|
||||
| D.cpp:30:5:30:5 | b |
|
||||
| D.cpp:30:8:30:10 | box |
|
||||
| D.cpp:30:13:30:16 | elem |
|
||||
| D.cpp:31:14:31:14 | b |
|
||||
| D.cpp:37:5:37:5 | b |
|
||||
| D.cpp:37:8:37:10 | box |
|
||||
| D.cpp:37:21:37:21 | e |
|
||||
| D.cpp:38:14:38:14 | b |
|
||||
| D.cpp:44:5:44:5 | b |
|
||||
| D.cpp:44:8:44:14 | call to getBox1 |
|
||||
| D.cpp:44:19:44:22 | elem |
|
||||
| D.cpp:45:14:45:14 | b |
|
||||
| D.cpp:51:5:51:5 | b |
|
||||
| D.cpp:51:8:51:14 | call to getBox1 |
|
||||
| D.cpp:51:27:51:27 | e |
|
||||
| D.cpp:52:14:52:14 | b |
|
||||
| D.cpp:57:5:57:12 | boxfield |
|
||||
| D.cpp:58:5:58:12 | boxfield |
|
||||
| D.cpp:58:15:58:17 | box |
|
||||
| D.cpp:58:20:58:23 | elem |
|
||||
| D.cpp:64:10:64:17 | boxfield |
|
||||
| D.cpp:64:20:64:22 | box |
|
||||
| D.cpp:64:25:64:28 | elem |
|
||||
| E.cpp:21:10:21:10 | p |
|
||||
| E.cpp:21:13:21:16 | data |
|
||||
| E.cpp:21:18:21:23 | buffer |
|
||||
| E.cpp:28:21:28:23 | raw |
|
||||
| E.cpp:29:21:29:21 | b |
|
||||
| E.cpp:29:24:29:29 | buffer |
|
||||
| E.cpp:30:21:30:21 | p |
|
||||
| E.cpp:30:23:30:26 | data |
|
||||
| E.cpp:30:28:30:33 | buffer |
|
||||
| E.cpp:31:10:31:12 | raw |
|
||||
| E.cpp:32:10:32:10 | b |
|
||||
| E.cpp:32:13:32:18 | buffer |
|
||||
| E.cpp:33:18:33:19 | & ... |
|
||||
| aliasing.cpp:9:3:9:3 | s |
|
||||
| aliasing.cpp:9:6:9:7 | m1 |
|
||||
| aliasing.cpp:13:3:13:3 | s |
|
||||
| aliasing.cpp:13:5:13:6 | m1 |
|
||||
| aliasing.cpp:17:3:17:3 | s |
|
||||
| aliasing.cpp:17:5:17:6 | m1 |
|
||||
| aliasing.cpp:25:17:25:19 | & ... |
|
||||
| aliasing.cpp:26:19:26:20 | s2 |
|
||||
| aliasing.cpp:37:3:37:6 | ref1 |
|
||||
| aliasing.cpp:37:8:37:9 | m1 |
|
||||
| aliasing.cpp:42:3:42:4 | s2 |
|
||||
| aliasing.cpp:42:6:42:7 | m1 |
|
||||
| aliasing.cpp:49:3:49:7 | copy1 |
|
||||
| aliasing.cpp:49:9:49:10 | m1 |
|
||||
| aliasing.cpp:54:3:54:4 | s2 |
|
||||
| aliasing.cpp:54:6:54:7 | m1 |
|
||||
| aliasing.cpp:60:3:60:4 | s2 |
|
||||
| aliasing.cpp:60:6:60:7 | m1 |
|
||||
| aliasing.cpp:72:3:72:3 | s |
|
||||
| aliasing.cpp:72:5:72:6 | m1 |
|
||||
| aliasing.cpp:79:3:79:3 | s |
|
||||
| aliasing.cpp:79:6:79:7 | m1 |
|
||||
| aliasing.cpp:86:3:86:3 | s |
|
||||
| aliasing.cpp:86:5:86:6 | m1 |
|
||||
| aliasing.cpp:92:3:92:3 | w |
|
||||
| aliasing.cpp:92:5:92:5 | s |
|
||||
| aliasing.cpp:92:7:92:8 | m1 |
|
||||
| by_reference.cpp:12:5:12:5 | s |
|
||||
| by_reference.cpp:12:8:12:8 | a |
|
||||
| by_reference.cpp:16:5:16:8 | this |
|
||||
| by_reference.cpp:16:11:16:11 | a |
|
||||
| by_reference.cpp:20:5:20:8 | this |
|
||||
| by_reference.cpp:20:23:20:27 | value |
|
||||
| by_reference.cpp:24:19:24:22 | this |
|
||||
| by_reference.cpp:24:25:24:29 | value |
|
||||
| by_reference.cpp:50:3:50:3 | s |
|
||||
| by_reference.cpp:50:17:50:26 | call to user_input |
|
||||
| by_reference.cpp:51:10:51:20 | call to getDirectly |
|
||||
| by_reference.cpp:56:3:56:3 | s |
|
||||
| by_reference.cpp:56:19:56:28 | call to user_input |
|
||||
| by_reference.cpp:57:10:57:22 | call to getIndirectly |
|
||||
| by_reference.cpp:62:3:62:3 | s |
|
||||
| by_reference.cpp:62:25:62:34 | call to user_input |
|
||||
| by_reference.cpp:63:10:63:28 | call to getThroughNonMember |
|
||||
| by_reference.cpp:68:17:68:18 | & ... |
|
||||
| by_reference.cpp:68:21:68:30 | call to user_input |
|
||||
| by_reference.cpp:69:8:69:20 | call to nonMemberGetA |
|
||||
| by_reference.cpp:84:3:84:7 | inner |
|
||||
| by_reference.cpp:84:10:84:10 | a |
|
||||
| by_reference.cpp:88:3:88:7 | inner |
|
||||
| by_reference.cpp:88:9:88:9 | a |
|
||||
| by_reference.cpp:102:21:102:39 | & ... |
|
||||
| by_reference.cpp:102:22:102:26 | outer |
|
||||
| by_reference.cpp:103:21:103:25 | outer |
|
||||
| by_reference.cpp:103:27:103:35 | inner_ptr |
|
||||
| by_reference.cpp:104:15:104:22 | & ... |
|
||||
| by_reference.cpp:104:16:104:20 | outer |
|
||||
| by_reference.cpp:106:21:106:41 | & ... |
|
||||
| by_reference.cpp:106:22:106:27 | pouter |
|
||||
| by_reference.cpp:107:21:107:26 | pouter |
|
||||
| by_reference.cpp:107:29:107:37 | inner_ptr |
|
||||
| by_reference.cpp:108:15:108:24 | & ... |
|
||||
| by_reference.cpp:108:16:108:21 | pouter |
|
||||
| by_reference.cpp:110:8:110:12 | outer |
|
||||
| by_reference.cpp:110:14:110:25 | inner_nested |
|
||||
| by_reference.cpp:110:27:110:27 | a |
|
||||
| by_reference.cpp:111:8:111:12 | outer |
|
||||
| by_reference.cpp:111:14:111:22 | inner_ptr |
|
||||
| by_reference.cpp:111:25:111:25 | a |
|
||||
| by_reference.cpp:112:8:112:12 | outer |
|
||||
| by_reference.cpp:112:14:112:14 | a |
|
||||
| by_reference.cpp:114:8:114:13 | pouter |
|
||||
| by_reference.cpp:114:16:114:27 | inner_nested |
|
||||
| by_reference.cpp:114:29:114:29 | a |
|
||||
| by_reference.cpp:115:8:115:13 | pouter |
|
||||
| by_reference.cpp:115:16:115:24 | inner_ptr |
|
||||
| by_reference.cpp:115:27:115:27 | a |
|
||||
| by_reference.cpp:116:8:116:13 | pouter |
|
||||
| by_reference.cpp:116:16:116:16 | a |
|
||||
| by_reference.cpp:122:21:122:25 | outer |
|
||||
| by_reference.cpp:122:27:122:38 | inner_nested |
|
||||
| by_reference.cpp:123:21:123:36 | * ... |
|
||||
| by_reference.cpp:123:22:123:26 | outer |
|
||||
| by_reference.cpp:124:15:124:19 | outer |
|
||||
| by_reference.cpp:124:21:124:21 | a |
|
||||
| by_reference.cpp:126:21:126:26 | pouter |
|
||||
| by_reference.cpp:126:29:126:40 | inner_nested |
|
||||
| by_reference.cpp:127:21:127:38 | * ... |
|
||||
| by_reference.cpp:127:22:127:27 | pouter |
|
||||
| by_reference.cpp:128:15:128:20 | pouter |
|
||||
| by_reference.cpp:128:23:128:23 | a |
|
||||
| by_reference.cpp:130:8:130:12 | outer |
|
||||
| by_reference.cpp:130:14:130:25 | inner_nested |
|
||||
| by_reference.cpp:130:27:130:27 | a |
|
||||
| by_reference.cpp:131:8:131:12 | outer |
|
||||
| by_reference.cpp:131:14:131:22 | inner_ptr |
|
||||
| by_reference.cpp:131:25:131:25 | a |
|
||||
| by_reference.cpp:132:8:132:12 | outer |
|
||||
| by_reference.cpp:132:14:132:14 | a |
|
||||
| by_reference.cpp:134:8:134:13 | pouter |
|
||||
| by_reference.cpp:134:16:134:27 | inner_nested |
|
||||
| by_reference.cpp:134:29:134:29 | a |
|
||||
| by_reference.cpp:135:8:135:13 | pouter |
|
||||
| by_reference.cpp:135:16:135:24 | inner_ptr |
|
||||
| by_reference.cpp:135:27:135:27 | a |
|
||||
| by_reference.cpp:136:8:136:13 | pouter |
|
||||
| by_reference.cpp:136:16:136:16 | a |
|
||||
| complex.cpp:11:22:11:23 | a_ |
|
||||
| complex.cpp:12:22:12:23 | b_ |
|
||||
| complex.cpp:51:8:51:8 | b |
|
||||
| complex.cpp:51:10:51:14 | inner |
|
||||
| complex.cpp:51:16:51:16 | f |
|
||||
| complex.cpp:52:8:52:8 | b |
|
||||
| complex.cpp:52:10:52:14 | inner |
|
||||
| complex.cpp:52:16:52:16 | f |
|
||||
| complex.cpp:62:3:62:4 | b1 |
|
||||
| complex.cpp:62:6:62:10 | inner |
|
||||
| complex.cpp:62:12:62:12 | f |
|
||||
| complex.cpp:63:3:63:4 | b2 |
|
||||
| complex.cpp:63:6:63:10 | inner |
|
||||
| complex.cpp:63:12:63:12 | f |
|
||||
| complex.cpp:64:3:64:4 | b3 |
|
||||
| complex.cpp:64:6:64:10 | inner |
|
||||
| complex.cpp:64:12:64:12 | f |
|
||||
| complex.cpp:65:3:65:4 | b3 |
|
||||
| complex.cpp:65:6:65:10 | inner |
|
||||
| complex.cpp:65:12:65:12 | f |
|
||||
| complex.cpp:68:7:68:8 | b1 |
|
||||
| complex.cpp:71:7:71:8 | b2 |
|
||||
| complex.cpp:74:7:74:8 | b3 |
|
||||
| complex.cpp:77:7:77:8 | b4 |
|
||||
| constructors.cpp:20:24:20:25 | a_ |
|
||||
| constructors.cpp:21:24:21:25 | b_ |
|
||||
| constructors.cpp:28:10:28:10 | f |
|
||||
| constructors.cpp:29:10:29:10 | f |
|
||||
| constructors.cpp:40:9:40:9 | f |
|
||||
| constructors.cpp:43:9:43:9 | g |
|
||||
| constructors.cpp:46:9:46:9 | h |
|
||||
| constructors.cpp:49:9:49:9 | i |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| file://:0:0:0:0 | this |
|
||||
| qualifiers.cpp:9:30:9:33 | this |
|
||||
| qualifiers.cpp:9:36:9:36 | a |
|
||||
| qualifiers.cpp:12:49:12:53 | inner |
|
||||
| qualifiers.cpp:12:56:12:56 | a |
|
||||
| qualifiers.cpp:13:51:13:55 | inner |
|
||||
| qualifiers.cpp:13:57:13:57 | a |
|
||||
| qualifiers.cpp:22:5:22:9 | outer |
|
||||
| qualifiers.cpp:22:11:22:18 | call to getInner |
|
||||
| qualifiers.cpp:22:23:22:23 | a |
|
||||
| qualifiers.cpp:23:10:23:14 | outer |
|
||||
| qualifiers.cpp:23:16:23:20 | inner |
|
||||
| qualifiers.cpp:23:23:23:23 | a |
|
||||
| qualifiers.cpp:27:5:27:9 | outer |
|
||||
| qualifiers.cpp:27:11:27:18 | call to getInner |
|
||||
| qualifiers.cpp:27:28:27:37 | call to user_input |
|
||||
| qualifiers.cpp:28:10:28:14 | outer |
|
||||
| qualifiers.cpp:28:16:28:20 | inner |
|
||||
| qualifiers.cpp:28:23:28:23 | a |
|
||||
| qualifiers.cpp:32:17:32:21 | outer |
|
||||
| qualifiers.cpp:32:23:32:30 | call to getInner |
|
||||
| qualifiers.cpp:32:35:32:44 | call to user_input |
|
||||
| qualifiers.cpp:33:10:33:14 | outer |
|
||||
| qualifiers.cpp:33:16:33:20 | inner |
|
||||
| qualifiers.cpp:33:23:33:23 | a |
|
||||
| qualifiers.cpp:37:19:37:35 | * ... |
|
||||
| qualifiers.cpp:37:20:37:24 | outer |
|
||||
| qualifiers.cpp:37:38:37:47 | call to user_input |
|
||||
| qualifiers.cpp:38:10:38:14 | outer |
|
||||
| qualifiers.cpp:38:16:38:20 | inner |
|
||||
| qualifiers.cpp:38:23:38:23 | a |
|
||||
| qualifiers.cpp:42:6:42:22 | * ... |
|
||||
| qualifiers.cpp:42:7:42:11 | outer |
|
||||
| qualifiers.cpp:42:25:42:25 | a |
|
||||
| qualifiers.cpp:43:10:43:14 | outer |
|
||||
| qualifiers.cpp:43:16:43:20 | inner |
|
||||
| qualifiers.cpp:43:23:43:23 | a |
|
||||
| qualifiers.cpp:47:6:47:11 | & ... |
|
||||
| qualifiers.cpp:47:15:47:22 | call to getInner |
|
||||
| qualifiers.cpp:47:27:47:27 | a |
|
||||
| qualifiers.cpp:48:10:48:14 | outer |
|
||||
| qualifiers.cpp:48:16:48:20 | inner |
|
||||
| qualifiers.cpp:48:23:48:23 | a |
|
||||
| simple.cpp:20:24:20:25 | a_ |
|
||||
| simple.cpp:21:24:21:25 | b_ |
|
||||
| simple.cpp:28:10:28:10 | f |
|
||||
| simple.cpp:29:10:29:10 | f |
|
||||
| simple.cpp:39:5:39:5 | f |
|
||||
| simple.cpp:40:5:40:5 | g |
|
||||
| simple.cpp:41:5:41:5 | h |
|
||||
| simple.cpp:42:5:42:5 | h |
|
||||
| simple.cpp:45:9:45:9 | f |
|
||||
| simple.cpp:48:9:48:9 | g |
|
||||
| simple.cpp:51:9:51:9 | h |
|
||||
| simple.cpp:54:9:54:9 | i |
|
||||
| simple.cpp:65:5:65:5 | a |
|
||||
| simple.cpp:65:7:65:7 | i |
|
||||
| simple.cpp:83:9:83:10 | f2 |
|
||||
| simple.cpp:83:12:83:13 | f1 |
|
||||
| struct_init.c:15:8:15:9 | ab |
|
||||
| struct_init.c:15:12:15:12 | a |
|
||||
| struct_init.c:16:8:16:9 | ab |
|
||||
| struct_init.c:16:12:16:12 | b |
|
||||
| struct_init.c:22:8:22:9 | ab |
|
||||
| struct_init.c:22:11:22:11 | a |
|
||||
| struct_init.c:23:8:23:9 | ab |
|
||||
| struct_init.c:23:11:23:11 | b |
|
||||
| struct_init.c:24:10:24:12 | & ... |
|
||||
| struct_init.c:31:8:31:12 | outer |
|
||||
| struct_init.c:31:14:31:21 | nestedAB |
|
||||
| struct_init.c:31:23:31:23 | a |
|
||||
| struct_init.c:32:8:32:12 | outer |
|
||||
| struct_init.c:32:14:32:21 | nestedAB |
|
||||
| struct_init.c:32:23:32:23 | b |
|
||||
| struct_init.c:33:8:33:12 | outer |
|
||||
| struct_init.c:33:14:33:22 | pointerAB |
|
||||
| struct_init.c:33:25:33:25 | a |
|
||||
| struct_init.c:34:8:34:12 | outer |
|
||||
| struct_init.c:34:14:34:22 | pointerAB |
|
||||
| struct_init.c:34:25:34:25 | b |
|
||||
| struct_init.c:36:10:36:24 | & ... |
|
||||
| struct_init.c:36:11:36:15 | outer |
|
||||
| struct_init.c:46:10:46:14 | outer |
|
||||
| struct_init.c:46:16:46:24 | pointerAB |
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* @kind problem
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.dataflow.DataFlow::DataFlow
|
||||
|
||||
select any(Node n).asPartialDefinition()
|
||||
@@ -15,10 +15,14 @@ int vsnprintf(char *s, size_t n, const char *format, va_list arg);
|
||||
|
||||
int mysprintf(char *s, size_t n, const char *format, ...)
|
||||
{
|
||||
int result;
|
||||
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsnprintf(s, n, format, args);
|
||||
result = vsnprintf(s, n, format, args);
|
||||
va_end(args);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int sscanf(const char *s, const char *format, ...);
|
||||
|
||||
@@ -3,112 +3,114 @@
|
||||
| file://:0:0:0:0 | p#0 | file://:0:0:0:0 | p#0 | |
|
||||
| file://:0:0:0:0 | p#0 | file://:0:0:0:0 | p#0 | |
|
||||
| file://:0:0:0:0 | p#0 | file://:0:0:0:0 | p#0 | |
|
||||
| format.cpp:16:21:16:21 | s | format.cpp:20:13:20:13 | s | |
|
||||
| format.cpp:16:31:16:31 | n | format.cpp:20:16:20:16 | n | |
|
||||
| format.cpp:16:46:16:51 | format | format.cpp:20:19:20:24 | format | |
|
||||
| format.cpp:18:10:18:13 | args | format.cpp:20:27:20:30 | args | |
|
||||
| format.cpp:46:21:46:24 | {...} | format.cpp:47:17:47:22 | buffer | |
|
||||
| format.cpp:46:21:46:24 | {...} | format.cpp:48:8:48:13 | buffer | |
|
||||
| format.cpp:46:23:46:23 | 0 | format.cpp:46:21:46:24 | {...} | TAINT |
|
||||
| format.cpp:47:17:47:22 | ref arg buffer | format.cpp:48:8:48:13 | buffer | |
|
||||
| format.cpp:47:30:47:33 | %s | format.cpp:47:17:47:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:47:36:47:43 | Hello. | format.cpp:47:17:47:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:51:21:51:24 | {...} | format.cpp:52:17:52:22 | buffer | |
|
||||
| format.cpp:51:21:51:24 | {...} | format.cpp:53:8:53:13 | buffer | |
|
||||
| format.cpp:51:23:51:23 | 0 | format.cpp:51:21:51:24 | {...} | TAINT |
|
||||
| format.cpp:52:17:52:22 | ref arg buffer | format.cpp:53:8:53:13 | buffer | |
|
||||
| format.cpp:52:30:52:33 | %s | format.cpp:52:17:52:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:52:36:52:49 | call to source | format.cpp:52:17:52:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:56:21:56:24 | {...} | format.cpp:57:17:57:22 | buffer | |
|
||||
| format.cpp:56:21:56:24 | {...} | format.cpp:58:8:58:13 | buffer | |
|
||||
| format.cpp:56:23:56:23 | 0 | format.cpp:56:21:56:24 | {...} | TAINT |
|
||||
| format.cpp:57:17:57:22 | ref arg buffer | format.cpp:58:8:58:13 | buffer | |
|
||||
| format.cpp:57:30:57:43 | call to source | format.cpp:57:17:57:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:57:48:57:55 | Hello. | format.cpp:57:17:57:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:61:21:61:24 | {...} | format.cpp:62:17:62:22 | buffer | |
|
||||
| format.cpp:61:21:61:24 | {...} | format.cpp:63:8:63:13 | buffer | |
|
||||
| format.cpp:61:23:61:23 | 0 | format.cpp:61:21:61:24 | {...} | TAINT |
|
||||
| format.cpp:62:17:62:22 | ref arg buffer | format.cpp:63:8:63:13 | buffer | |
|
||||
| format.cpp:62:30:62:39 | %s %s %s | format.cpp:62:17:62:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:62:42:62:44 | a | format.cpp:62:17:62:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:62:47:62:49 | b | format.cpp:62:17:62:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:62:52:62:65 | call to source | format.cpp:62:17:62:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:66:21:66:24 | {...} | format.cpp:67:17:67:22 | buffer | |
|
||||
| format.cpp:66:21:66:24 | {...} | format.cpp:68:8:68:13 | buffer | |
|
||||
| format.cpp:66:23:66:23 | 0 | format.cpp:66:21:66:24 | {...} | TAINT |
|
||||
| format.cpp:67:17:67:22 | ref arg buffer | format.cpp:68:8:68:13 | buffer | |
|
||||
| format.cpp:67:30:67:35 | %.*s | format.cpp:67:17:67:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:67:38:67:39 | 10 | format.cpp:67:17:67:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:67:42:67:55 | call to source | format.cpp:67:17:67:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:72:21:72:24 | {...} | format.cpp:73:17:73:22 | buffer | |
|
||||
| format.cpp:72:21:72:24 | {...} | format.cpp:74:8:74:13 | buffer | |
|
||||
| format.cpp:72:23:72:23 | 0 | format.cpp:72:21:72:24 | {...} | TAINT |
|
||||
| format.cpp:73:17:73:22 | ref arg buffer | format.cpp:74:8:74:13 | buffer | |
|
||||
| format.cpp:73:30:73:33 | %i | format.cpp:73:17:73:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:73:36:73:36 | 0 | format.cpp:73:17:73:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:77:21:77:24 | {...} | format.cpp:78:17:78:22 | buffer | |
|
||||
| format.cpp:77:21:77:24 | {...} | format.cpp:79:8:79:13 | buffer | |
|
||||
| format.cpp:77:23:77:23 | 0 | format.cpp:77:21:77:24 | {...} | TAINT |
|
||||
| format.cpp:78:17:78:22 | ref arg buffer | format.cpp:79:8:79:13 | buffer | |
|
||||
| format.cpp:78:30:78:33 | %i | format.cpp:78:17:78:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:78:36:78:41 | call to source | format.cpp:78:17:78:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:82:21:82:24 | {...} | format.cpp:83:17:83:22 | buffer | |
|
||||
| format.cpp:82:21:82:24 | {...} | format.cpp:84:8:84:13 | buffer | |
|
||||
| format.cpp:82:23:82:23 | 0 | format.cpp:82:21:82:24 | {...} | TAINT |
|
||||
| format.cpp:83:17:83:22 | ref arg buffer | format.cpp:84:8:84:13 | buffer | |
|
||||
| format.cpp:83:30:83:35 | %.*s | format.cpp:83:17:83:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:83:38:83:43 | call to source | format.cpp:83:17:83:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:83:48:83:55 | Hello. | format.cpp:83:17:83:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:88:21:88:24 | {...} | format.cpp:89:17:89:22 | buffer | |
|
||||
| format.cpp:88:21:88:24 | {...} | format.cpp:90:8:90:13 | buffer | |
|
||||
| format.cpp:88:23:88:23 | 0 | format.cpp:88:21:88:24 | {...} | TAINT |
|
||||
| format.cpp:89:17:89:22 | ref arg buffer | format.cpp:90:8:90:13 | buffer | |
|
||||
| format.cpp:89:30:89:33 | %p | format.cpp:89:17:89:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:89:36:89:49 | call to source | format.cpp:89:17:89:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:94:21:94:24 | {...} | format.cpp:95:16:95:21 | buffer | |
|
||||
| format.cpp:94:21:94:24 | {...} | format.cpp:96:8:96:13 | buffer | |
|
||||
| format.cpp:94:23:94:23 | 0 | format.cpp:94:21:94:24 | {...} | TAINT |
|
||||
| format.cpp:95:16:95:21 | ref arg buffer | format.cpp:96:8:96:13 | buffer | |
|
||||
| format.cpp:95:24:95:27 | %s | format.cpp:95:16:95:21 | ref arg buffer | TAINT |
|
||||
| format.cpp:95:30:95:43 | call to source | format.cpp:95:16:95:21 | ref arg buffer | TAINT |
|
||||
| format.cpp:99:21:99:24 | {...} | format.cpp:100:16:100:21 | buffer | |
|
||||
| format.cpp:99:21:99:24 | {...} | format.cpp:101:8:101:13 | buffer | |
|
||||
| format.cpp:99:23:99:23 | 0 | format.cpp:99:21:99:24 | {...} | TAINT |
|
||||
| format.cpp:100:16:100:21 | ref arg buffer | format.cpp:101:8:101:13 | buffer | |
|
||||
| format.cpp:100:24:100:28 | %ls | format.cpp:100:16:100:21 | ref arg buffer | TAINT |
|
||||
| format.cpp:100:31:100:45 | call to source | format.cpp:100:16:100:21 | ref arg buffer | TAINT |
|
||||
| format.cpp:104:25:104:28 | {...} | format.cpp:105:17:105:23 | wbuffer | |
|
||||
| format.cpp:104:25:104:28 | {...} | format.cpp:106:8:106:14 | wbuffer | |
|
||||
| format.cpp:104:27:104:27 | 0 | format.cpp:104:25:104:28 | {...} | TAINT |
|
||||
| format.cpp:105:17:105:23 | ref arg wbuffer | format.cpp:106:8:106:14 | wbuffer | |
|
||||
| format.cpp:105:31:105:35 | %s | format.cpp:105:17:105:23 | ref arg wbuffer | TAINT |
|
||||
| format.cpp:105:38:105:52 | call to source | format.cpp:105:17:105:23 | ref arg wbuffer | TAINT |
|
||||
| format.cpp:109:21:109:24 | {...} | format.cpp:110:18:110:23 | buffer | |
|
||||
| format.cpp:109:21:109:24 | {...} | format.cpp:111:8:111:13 | buffer | |
|
||||
| format.cpp:109:23:109:23 | 0 | format.cpp:109:21:109:24 | {...} | TAINT |
|
||||
| format.cpp:110:18:110:23 | ref arg buffer | format.cpp:111:8:111:13 | buffer | |
|
||||
| format.cpp:115:10:115:11 | 0 | format.cpp:116:29:116:29 | i | |
|
||||
| format.cpp:115:10:115:11 | 0 | format.cpp:117:8:117:8 | i | |
|
||||
| format.cpp:116:28:116:29 | ref arg & ... | format.cpp:116:29:116:29 | i [inner post update] | |
|
||||
| format.cpp:116:28:116:29 | ref arg & ... | format.cpp:117:8:117:8 | i | |
|
||||
| format.cpp:116:29:116:29 | i | format.cpp:116:28:116:29 | & ... | |
|
||||
| format.cpp:120:10:120:11 | 0 | format.cpp:121:40:121:40 | i | |
|
||||
| format.cpp:120:10:120:11 | 0 | format.cpp:122:8:122:8 | i | |
|
||||
| format.cpp:121:39:121:40 | ref arg & ... | format.cpp:121:40:121:40 | i [inner post update] | |
|
||||
| format.cpp:121:39:121:40 | ref arg & ... | format.cpp:122:8:122:8 | i | |
|
||||
| format.cpp:121:40:121:40 | i | format.cpp:121:39:121:40 | & ... | |
|
||||
| format.cpp:125:21:125:24 | {...} | format.cpp:126:32:126:37 | buffer | |
|
||||
| format.cpp:125:21:125:24 | {...} | format.cpp:127:8:127:13 | buffer | |
|
||||
| format.cpp:125:23:125:23 | 0 | format.cpp:125:21:125:24 | {...} | TAINT |
|
||||
| format.cpp:126:31:126:37 | ref arg & ... | format.cpp:126:32:126:37 | buffer [inner post update] | |
|
||||
| format.cpp:126:31:126:37 | ref arg & ... | format.cpp:127:8:127:13 | buffer | |
|
||||
| format.cpp:126:32:126:37 | buffer | format.cpp:126:31:126:37 | & ... | |
|
||||
| format.cpp:130:21:130:24 | {...} | format.cpp:131:40:131:45 | buffer | |
|
||||
| format.cpp:130:21:130:24 | {...} | format.cpp:132:8:132:13 | buffer | |
|
||||
| format.cpp:130:23:130:23 | 0 | format.cpp:130:21:130:24 | {...} | TAINT |
|
||||
| format.cpp:131:39:131:45 | ref arg & ... | format.cpp:131:40:131:45 | buffer [inner post update] | |
|
||||
| format.cpp:131:39:131:45 | ref arg & ... | format.cpp:132:8:132:13 | buffer | |
|
||||
| format.cpp:131:40:131:45 | buffer | format.cpp:131:39:131:45 | & ... | |
|
||||
| format.cpp:16:21:16:21 | s | format.cpp:22:22:22:22 | s | |
|
||||
| format.cpp:16:31:16:31 | n | format.cpp:22:25:22:25 | n | |
|
||||
| format.cpp:16:46:16:51 | format | format.cpp:22:28:22:33 | format | |
|
||||
| format.cpp:20:10:20:13 | args | format.cpp:22:36:22:39 | args | |
|
||||
| format.cpp:22:12:22:20 | call to vsnprintf | format.cpp:22:3:22:40 | ... = ... | |
|
||||
| format.cpp:22:12:22:20 | call to vsnprintf | format.cpp:25:9:25:14 | result | |
|
||||
| format.cpp:50:21:50:24 | {...} | format.cpp:51:17:51:22 | buffer | |
|
||||
| format.cpp:50:21:50:24 | {...} | format.cpp:52:8:52:13 | buffer | |
|
||||
| format.cpp:50:23:50:23 | 0 | format.cpp:50:21:50:24 | {...} | TAINT |
|
||||
| format.cpp:51:17:51:22 | ref arg buffer | format.cpp:52:8:52:13 | buffer | |
|
||||
| format.cpp:51:30:51:33 | %s | format.cpp:51:17:51:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:51:36:51:43 | Hello. | format.cpp:51:17:51:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:55:21:55:24 | {...} | format.cpp:56:17:56:22 | buffer | |
|
||||
| format.cpp:55:21:55:24 | {...} | format.cpp:57:8:57:13 | buffer | |
|
||||
| format.cpp:55:23:55:23 | 0 | format.cpp:55:21:55:24 | {...} | TAINT |
|
||||
| format.cpp:56:17:56:22 | ref arg buffer | format.cpp:57:8:57:13 | buffer | |
|
||||
| format.cpp:56:30:56:33 | %s | format.cpp:56:17:56:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:56:36:56:49 | call to source | format.cpp:56:17:56:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:60:21:60:24 | {...} | format.cpp:61:17:61:22 | buffer | |
|
||||
| format.cpp:60:21:60:24 | {...} | format.cpp:62:8:62:13 | buffer | |
|
||||
| format.cpp:60:23:60:23 | 0 | format.cpp:60:21:60:24 | {...} | TAINT |
|
||||
| format.cpp:61:17:61:22 | ref arg buffer | format.cpp:62:8:62:13 | buffer | |
|
||||
| format.cpp:61:30:61:43 | call to source | format.cpp:61:17:61:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:61:48:61:55 | Hello. | format.cpp:61:17:61:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:65:21:65:24 | {...} | format.cpp:66:17:66:22 | buffer | |
|
||||
| format.cpp:65:21:65:24 | {...} | format.cpp:67:8:67:13 | buffer | |
|
||||
| format.cpp:65:23:65:23 | 0 | format.cpp:65:21:65:24 | {...} | TAINT |
|
||||
| format.cpp:66:17:66:22 | ref arg buffer | format.cpp:67:8:67:13 | buffer | |
|
||||
| format.cpp:66:30:66:39 | %s %s %s | format.cpp:66:17:66:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:66:42:66:44 | a | format.cpp:66:17:66:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:66:47:66:49 | b | format.cpp:66:17:66:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:66:52:66:65 | call to source | format.cpp:66:17:66:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:70:21:70:24 | {...} | format.cpp:71:17:71:22 | buffer | |
|
||||
| format.cpp:70:21:70:24 | {...} | format.cpp:72:8:72:13 | buffer | |
|
||||
| format.cpp:70:23:70:23 | 0 | format.cpp:70:21:70:24 | {...} | TAINT |
|
||||
| format.cpp:71:17:71:22 | ref arg buffer | format.cpp:72:8:72:13 | buffer | |
|
||||
| format.cpp:71:30:71:35 | %.*s | format.cpp:71:17:71:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:71:38:71:39 | 10 | format.cpp:71:17:71:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:71:42:71:55 | call to source | format.cpp:71:17:71:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:76:21:76:24 | {...} | format.cpp:77:17:77:22 | buffer | |
|
||||
| format.cpp:76:21:76:24 | {...} | format.cpp:78:8:78:13 | buffer | |
|
||||
| format.cpp:76:23:76:23 | 0 | format.cpp:76:21:76:24 | {...} | TAINT |
|
||||
| format.cpp:77:17:77:22 | ref arg buffer | format.cpp:78:8:78:13 | buffer | |
|
||||
| format.cpp:77:30:77:33 | %i | format.cpp:77:17:77:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:77:36:77:36 | 0 | format.cpp:77:17:77:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:81:21:81:24 | {...} | format.cpp:82:17:82:22 | buffer | |
|
||||
| format.cpp:81:21:81:24 | {...} | format.cpp:83:8:83:13 | buffer | |
|
||||
| format.cpp:81:23:81:23 | 0 | format.cpp:81:21:81:24 | {...} | TAINT |
|
||||
| format.cpp:82:17:82:22 | ref arg buffer | format.cpp:83:8:83:13 | buffer | |
|
||||
| format.cpp:82:30:82:33 | %i | format.cpp:82:17:82:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:82:36:82:41 | call to source | format.cpp:82:17:82:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:86:21:86:24 | {...} | format.cpp:87:17:87:22 | buffer | |
|
||||
| format.cpp:86:21:86:24 | {...} | format.cpp:88:8:88:13 | buffer | |
|
||||
| format.cpp:86:23:86:23 | 0 | format.cpp:86:21:86:24 | {...} | TAINT |
|
||||
| format.cpp:87:17:87:22 | ref arg buffer | format.cpp:88:8:88:13 | buffer | |
|
||||
| format.cpp:87:30:87:35 | %.*s | format.cpp:87:17:87:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:87:38:87:43 | call to source | format.cpp:87:17:87:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:87:48:87:55 | Hello. | format.cpp:87:17:87:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:92:21:92:24 | {...} | format.cpp:93:17:93:22 | buffer | |
|
||||
| format.cpp:92:21:92:24 | {...} | format.cpp:94:8:94:13 | buffer | |
|
||||
| format.cpp:92:23:92:23 | 0 | format.cpp:92:21:92:24 | {...} | TAINT |
|
||||
| format.cpp:93:17:93:22 | ref arg buffer | format.cpp:94:8:94:13 | buffer | |
|
||||
| format.cpp:93:30:93:33 | %p | format.cpp:93:17:93:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:93:36:93:49 | call to source | format.cpp:93:17:93:22 | ref arg buffer | TAINT |
|
||||
| format.cpp:98:21:98:24 | {...} | format.cpp:99:16:99:21 | buffer | |
|
||||
| format.cpp:98:21:98:24 | {...} | format.cpp:100:8:100:13 | buffer | |
|
||||
| format.cpp:98:23:98:23 | 0 | format.cpp:98:21:98:24 | {...} | TAINT |
|
||||
| format.cpp:99:16:99:21 | ref arg buffer | format.cpp:100:8:100:13 | buffer | |
|
||||
| format.cpp:99:24:99:27 | %s | format.cpp:99:16:99:21 | ref arg buffer | TAINT |
|
||||
| format.cpp:99:30:99:43 | call to source | format.cpp:99:16:99:21 | ref arg buffer | TAINT |
|
||||
| format.cpp:103:21:103:24 | {...} | format.cpp:104:16:104:21 | buffer | |
|
||||
| format.cpp:103:21:103:24 | {...} | format.cpp:105:8:105:13 | buffer | |
|
||||
| format.cpp:103:23:103:23 | 0 | format.cpp:103:21:103:24 | {...} | TAINT |
|
||||
| format.cpp:104:16:104:21 | ref arg buffer | format.cpp:105:8:105:13 | buffer | |
|
||||
| format.cpp:104:24:104:28 | %ls | format.cpp:104:16:104:21 | ref arg buffer | TAINT |
|
||||
| format.cpp:104:31:104:45 | call to source | format.cpp:104:16:104:21 | ref arg buffer | TAINT |
|
||||
| format.cpp:108:25:108:28 | {...} | format.cpp:109:17:109:23 | wbuffer | |
|
||||
| format.cpp:108:25:108:28 | {...} | format.cpp:110:8:110:14 | wbuffer | |
|
||||
| format.cpp:108:27:108:27 | 0 | format.cpp:108:25:108:28 | {...} | TAINT |
|
||||
| format.cpp:109:17:109:23 | ref arg wbuffer | format.cpp:110:8:110:14 | wbuffer | |
|
||||
| format.cpp:109:31:109:35 | %s | format.cpp:109:17:109:23 | ref arg wbuffer | TAINT |
|
||||
| format.cpp:109:38:109:52 | call to source | format.cpp:109:17:109:23 | ref arg wbuffer | TAINT |
|
||||
| format.cpp:113:21:113:24 | {...} | format.cpp:114:18:114:23 | buffer | |
|
||||
| format.cpp:113:21:113:24 | {...} | format.cpp:115:8:115:13 | buffer | |
|
||||
| format.cpp:113:23:113:23 | 0 | format.cpp:113:21:113:24 | {...} | TAINT |
|
||||
| format.cpp:114:18:114:23 | ref arg buffer | format.cpp:115:8:115:13 | buffer | |
|
||||
| format.cpp:119:10:119:11 | 0 | format.cpp:120:29:120:29 | i | |
|
||||
| format.cpp:119:10:119:11 | 0 | format.cpp:121:8:121:8 | i | |
|
||||
| format.cpp:120:28:120:29 | ref arg & ... | format.cpp:120:29:120:29 | i [inner post update] | |
|
||||
| format.cpp:120:28:120:29 | ref arg & ... | format.cpp:121:8:121:8 | i | |
|
||||
| format.cpp:120:29:120:29 | i | format.cpp:120:28:120:29 | & ... | |
|
||||
| format.cpp:124:10:124:11 | 0 | format.cpp:125:40:125:40 | i | |
|
||||
| format.cpp:124:10:124:11 | 0 | format.cpp:126:8:126:8 | i | |
|
||||
| format.cpp:125:39:125:40 | ref arg & ... | format.cpp:125:40:125:40 | i [inner post update] | |
|
||||
| format.cpp:125:39:125:40 | ref arg & ... | format.cpp:126:8:126:8 | i | |
|
||||
| format.cpp:125:40:125:40 | i | format.cpp:125:39:125:40 | & ... | |
|
||||
| format.cpp:129:21:129:24 | {...} | format.cpp:130:32:130:37 | buffer | |
|
||||
| format.cpp:129:21:129:24 | {...} | format.cpp:131:8:131:13 | buffer | |
|
||||
| format.cpp:129:23:129:23 | 0 | format.cpp:129:21:129:24 | {...} | TAINT |
|
||||
| format.cpp:130:31:130:37 | ref arg & ... | format.cpp:130:32:130:37 | buffer [inner post update] | |
|
||||
| format.cpp:130:31:130:37 | ref arg & ... | format.cpp:131:8:131:13 | buffer | |
|
||||
| format.cpp:130:32:130:37 | buffer | format.cpp:130:31:130:37 | & ... | |
|
||||
| format.cpp:134:21:134:24 | {...} | format.cpp:135:40:135:45 | buffer | |
|
||||
| format.cpp:134:21:134:24 | {...} | format.cpp:136:8:136:13 | buffer | |
|
||||
| format.cpp:134:23:134:23 | 0 | format.cpp:134:21:134:24 | {...} | TAINT |
|
||||
| format.cpp:135:39:135:45 | ref arg & ... | format.cpp:135:40:135:45 | buffer [inner post update] | |
|
||||
| format.cpp:135:39:135:45 | ref arg & ... | format.cpp:136:8:136:13 | buffer | |
|
||||
| format.cpp:135:40:135:45 | buffer | format.cpp:135:39:135:45 | & ... | |
|
||||
| stl.cpp:67:12:67:17 | call to source | stl.cpp:71:7:71:7 | a | |
|
||||
| stl.cpp:68:16:68:20 | 123 | stl.cpp:68:16:68:21 | call to basic_string | TAINT |
|
||||
| stl.cpp:68:16:68:21 | call to basic_string | stl.cpp:72:7:72:7 | b | |
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
| format.cpp:53:8:53:13 | buffer | format.cpp:52:36:52:49 | call to source |
|
||||
| format.cpp:58:8:58:13 | buffer | format.cpp:57:30:57:43 | call to source |
|
||||
| format.cpp:63:8:63:13 | buffer | format.cpp:62:52:62:65 | call to source |
|
||||
| format.cpp:68:8:68:13 | buffer | format.cpp:67:42:67:55 | call to source |
|
||||
| format.cpp:79:8:79:13 | buffer | format.cpp:78:36:78:41 | call to source |
|
||||
| format.cpp:84:8:84:13 | buffer | format.cpp:83:38:83:43 | call to source |
|
||||
| format.cpp:90:8:90:13 | buffer | format.cpp:89:36:89:49 | call to source |
|
||||
| format.cpp:96:8:96:13 | buffer | format.cpp:95:30:95:43 | call to source |
|
||||
| format.cpp:101:8:101:13 | buffer | format.cpp:100:31:100:45 | call to source |
|
||||
| format.cpp:106:8:106:14 | wbuffer | format.cpp:105:38:105:52 | call to source |
|
||||
| format.cpp:57:8:57:13 | buffer | format.cpp:56:36:56:49 | call to source |
|
||||
| format.cpp:62:8:62:13 | buffer | format.cpp:61:30:61:43 | call to source |
|
||||
| format.cpp:67:8:67:13 | buffer | format.cpp:66:52:66:65 | call to source |
|
||||
| format.cpp:72:8:72:13 | buffer | format.cpp:71:42:71:55 | call to source |
|
||||
| format.cpp:83:8:83:13 | buffer | format.cpp:82:36:82:41 | call to source |
|
||||
| format.cpp:88:8:88:13 | buffer | format.cpp:87:38:87:43 | call to source |
|
||||
| format.cpp:94:8:94:13 | buffer | format.cpp:93:36:93:49 | call to source |
|
||||
| format.cpp:100:8:100:13 | buffer | format.cpp:99:30:99:43 | call to source |
|
||||
| format.cpp:105:8:105:13 | buffer | format.cpp:104:31:104:45 | call to source |
|
||||
| format.cpp:110:8:110:14 | wbuffer | format.cpp:109:38:109:52 | call to source |
|
||||
| stl.cpp:71:7:71:7 | a | stl.cpp:67:12:67:17 | call to source |
|
||||
| stl.cpp:73:7:73:7 | c | stl.cpp:69:16:69:21 | call to source |
|
||||
| stl.cpp:75:9:75:13 | call to c_str | stl.cpp:69:16:69:21 | call to source |
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
| format.cpp:53:8:53:13 | format.cpp:52:36:52:49 | AST only |
|
||||
| format.cpp:58:8:58:13 | format.cpp:57:30:57:43 | AST only |
|
||||
| format.cpp:63:8:63:13 | format.cpp:62:52:62:65 | AST only |
|
||||
| format.cpp:68:8:68:13 | format.cpp:67:42:67:55 | AST only |
|
||||
| format.cpp:79:8:79:13 | format.cpp:78:36:78:41 | AST only |
|
||||
| format.cpp:84:8:84:13 | format.cpp:83:38:83:43 | AST only |
|
||||
| format.cpp:90:8:90:13 | format.cpp:89:36:89:49 | AST only |
|
||||
| format.cpp:96:8:96:13 | format.cpp:95:30:95:43 | AST only |
|
||||
| format.cpp:101:8:101:13 | format.cpp:100:31:100:45 | AST only |
|
||||
| format.cpp:106:8:106:14 | format.cpp:105:38:105:52 | AST only |
|
||||
| format.cpp:57:8:57:13 | format.cpp:56:36:56:49 | AST only |
|
||||
| format.cpp:62:8:62:13 | format.cpp:61:30:61:43 | AST only |
|
||||
| format.cpp:67:8:67:13 | format.cpp:66:52:66:65 | AST only |
|
||||
| format.cpp:72:8:72:13 | format.cpp:71:42:71:55 | AST only |
|
||||
| format.cpp:83:8:83:13 | format.cpp:82:36:82:41 | AST only |
|
||||
| format.cpp:88:8:88:13 | format.cpp:87:38:87:43 | AST only |
|
||||
| format.cpp:94:8:94:13 | format.cpp:93:36:93:49 | AST only |
|
||||
| format.cpp:100:8:100:13 | format.cpp:99:30:99:43 | AST only |
|
||||
| format.cpp:105:8:105:13 | format.cpp:104:31:104:45 | AST only |
|
||||
| format.cpp:110:8:110:14 | format.cpp:109:38:109:52 | AST only |
|
||||
| stl.cpp:73:7:73:7 | stl.cpp:69:16:69:21 | AST only |
|
||||
| stl.cpp:75:9:75:13 | stl.cpp:69:16:69:21 | AST only |
|
||||
| stl.cpp:125:13:125:17 | stl.cpp:117:10:117:15 | AST only |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import default
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.IR
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.constant.ConstantAnalysis
|
||||
import semmle.code.cpp.ir.internal.IntegerConstant
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import default
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.internal.AliasAnalysis
|
||||
import semmle.code.cpp.ir.implementation.raw.IR
|
||||
import semmle.code.cpp.ir.implementation.UseSoundEscapeAnalysis
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import default
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.internal.AliasAnalysis
|
||||
import semmle.code.cpp.ir.implementation.aliased_ssa.internal.AliasConfiguration
|
||||
import semmle.code.cpp.ir.implementation.unaliased_ssa.IR
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import default
|
||||
import cpp
|
||||
|
||||
query predicate classUuids(Class cls, string uuid) {
|
||||
if exists(cls.getUuid()) then uuid = cls.getUuid() else uuid = ""
|
||||
|
||||
@@ -2,7 +2,7 @@ import cpp
|
||||
|
||||
class FunctionMonkeyPatch extends Function {
|
||||
language[monotonicAggregates]
|
||||
override string toString() {
|
||||
override string getDescription() {
|
||||
exists(string name, string templateArgs, string args |
|
||||
result = name + templateArgs + args and
|
||||
name = this.getQualifiedName() and
|
||||
@@ -30,7 +30,9 @@ class FunctionMonkeyPatch extends Function {
|
||||
}
|
||||
|
||||
class ParameterMonkeyPatch extends Parameter {
|
||||
override string toString() { result = super.getType().getName() + " " + super.toString() }
|
||||
override string getDescription() {
|
||||
result = super.getType().getName() + " " + super.getDescription()
|
||||
}
|
||||
}
|
||||
|
||||
from Element e, Element ti
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
| templates.cpp:9:5:9:14 | using c |
|
||||
| usings.cpp:8:1:8:11 | using nf |
|
||||
| usings.cpp:9:1:9:17 | using namespace N |
|
||||
| usings.cpp:18:3:18:13 | using bf |
|
||||
| usings.cpp:21:5:21:14 | using gf |
|
||||
| usings.cpp:34:3:34:20 | using tbf |
|
||||
| usings.cpp:42:5:42:22 | using foo |
|
||||
| templates.cpp:9:5:9:14 | using c | UsingDeclarationEntry, enclosingElement:std |
|
||||
| usings.cpp:8:1:8:11 | using nf | UsingDeclarationEntry, enclosingElement:(global namespace) |
|
||||
| usings.cpp:9:1:9:17 | using namespace N | UsingDirectiveEntry, enclosingElement:(global namespace) |
|
||||
| usings.cpp:18:3:18:13 | using bf | UsingDeclarationEntry, enclosingElement:D |
|
||||
| usings.cpp:21:5:21:14 | using gf | UsingDeclarationEntry, enclosingElement:{ ... } |
|
||||
| usings.cpp:34:3:34:20 | using tbf | UsingDeclarationEntry, enclosingElement:TD |
|
||||
| usings.cpp:42:5:42:22 | using foo | UsingDeclarationEntry, enclosingElement:nsbar |
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
import cpp
|
||||
|
||||
string describe(UsingEntry ue) {
|
||||
ue instanceof UsingDeclarationEntry and
|
||||
result = "UsingDeclarationEntry"
|
||||
or
|
||||
ue instanceof UsingDirectiveEntry and
|
||||
result = "UsingDirectiveEntry"
|
||||
or
|
||||
result = "enclosingElement:" + ue.getEnclosingElement().toString()
|
||||
}
|
||||
|
||||
from UsingEntry ue
|
||||
select ue
|
||||
select ue, concat(describe(ue), ", ")
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
| templates.cpp:9:5:9:14 | using c | file://:0:0:0:0 | std |
|
||||
| usings.cpp:8:1:8:11 | using nf | file://:0:0:0:0 | (global namespace) |
|
||||
| usings.cpp:9:1:9:17 | using namespace N | file://:0:0:0:0 | (global namespace) |
|
||||
| usings.cpp:18:3:18:13 | using bf | usings.cpp:16:8:16:8 | D |
|
||||
| usings.cpp:21:5:21:14 | using gf | usings.cpp:20:13:23:3 | { ... } |
|
||||
| usings.cpp:34:3:34:20 | using tbf | usings.cpp:32:8:32:9 | TD |
|
||||
| usings.cpp:42:5:42:22 | using foo | usings.cpp:41:11:41:15 | nsbar |
|
||||
@@ -1,5 +0,0 @@
|
||||
import cpp
|
||||
|
||||
from UsingEntry ue, Element e
|
||||
where e = ue.getEnclosingElement()
|
||||
select ue, e
|
||||
@@ -1,13 +1,4 @@
|
||||
edges
|
||||
| field_conflation.c:12:22:12:27 | call to getenv | field_conflation.c:13:3:13:18 | Chi |
|
||||
| field_conflation.c:12:22:12:34 | (const char *)... | field_conflation.c:13:3:13:18 | Chi |
|
||||
| field_conflation.c:13:3:13:18 | Chi | field_conflation.c:19:15:19:17 | taint_array output argument |
|
||||
| field_conflation.c:19:15:19:17 | taint_array output argument | field_conflation.c:20:10:20:13 | (unsigned long)... |
|
||||
| field_conflation.c:19:15:19:17 | taint_array output argument | field_conflation.c:20:13:20:13 | x |
|
||||
| field_conflation.c:19:15:19:17 | taint_array output argument | field_conflation.c:20:13:20:13 | x |
|
||||
| field_conflation.c:19:15:19:17 | taint_array output argument | field_conflation.c:20:13:20:13 | x |
|
||||
| field_conflation.c:20:13:20:13 | x | field_conflation.c:20:10:20:13 | (unsigned long)... |
|
||||
| field_conflation.c:20:13:20:13 | x | field_conflation.c:20:13:20:13 | x |
|
||||
| test.cpp:39:21:39:24 | argv | test.cpp:42:38:42:44 | (size_t)... |
|
||||
| test.cpp:39:21:39:24 | argv | test.cpp:42:38:42:44 | (size_t)... |
|
||||
| test.cpp:39:21:39:24 | argv | test.cpp:42:38:42:44 | tainted |
|
||||
@@ -68,16 +59,27 @@ edges
|
||||
| test.cpp:227:24:227:37 | (const char *)... | test.cpp:237:10:237:19 | (size_t)... |
|
||||
| test.cpp:235:11:235:20 | (size_t)... | test.cpp:214:23:214:23 | s |
|
||||
| test.cpp:237:10:237:19 | (size_t)... | test.cpp:220:21:220:21 | s |
|
||||
| test.cpp:241:2:241:32 | Chi | test.cpp:279:17:279:20 | get_size output argument |
|
||||
| test.cpp:241:2:241:32 | Chi | test.cpp:295:18:295:21 | get_size output argument |
|
||||
| test.cpp:241:18:241:23 | call to getenv | test.cpp:241:2:241:32 | Chi |
|
||||
| test.cpp:241:18:241:31 | (const char *)... | test.cpp:241:2:241:32 | Chi |
|
||||
| test.cpp:249:20:249:25 | call to getenv | test.cpp:253:11:253:29 | ... * ... |
|
||||
| test.cpp:249:20:249:25 | call to getenv | test.cpp:253:11:253:29 | ... * ... |
|
||||
| test.cpp:249:20:249:33 | (const char *)... | test.cpp:253:11:253:29 | ... * ... |
|
||||
| test.cpp:249:20:249:33 | (const char *)... | test.cpp:253:11:253:29 | ... * ... |
|
||||
| test.cpp:279:17:279:20 | get_size output argument | test.cpp:281:11:281:28 | ... * ... |
|
||||
| test.cpp:279:17:279:20 | get_size output argument | test.cpp:281:11:281:28 | ... * ... |
|
||||
| test.cpp:295:18:295:21 | get_size output argument | test.cpp:298:10:298:27 | ... * ... |
|
||||
| test.cpp:295:18:295:21 | get_size output argument | test.cpp:298:10:298:27 | ... * ... |
|
||||
| test.cpp:301:19:301:24 | call to getenv | test.cpp:305:11:305:28 | ... * ... |
|
||||
| test.cpp:301:19:301:24 | call to getenv | test.cpp:305:11:305:28 | ... * ... |
|
||||
| test.cpp:301:19:301:32 | (const char *)... | test.cpp:305:11:305:28 | ... * ... |
|
||||
| test.cpp:301:19:301:32 | (const char *)... | test.cpp:305:11:305:28 | ... * ... |
|
||||
| test.cpp:309:19:309:24 | call to getenv | test.cpp:314:10:314:27 | ... * ... |
|
||||
| test.cpp:309:19:309:24 | call to getenv | test.cpp:314:10:314:27 | ... * ... |
|
||||
| test.cpp:309:19:309:32 | (const char *)... | test.cpp:314:10:314:27 | ... * ... |
|
||||
| test.cpp:309:19:309:32 | (const char *)... | test.cpp:314:10:314:27 | ... * ... |
|
||||
nodes
|
||||
| field_conflation.c:12:22:12:27 | call to getenv | semmle.label | call to getenv |
|
||||
| field_conflation.c:12:22:12:34 | (const char *)... | semmle.label | (const char *)... |
|
||||
| field_conflation.c:13:3:13:18 | Chi | semmle.label | Chi |
|
||||
| field_conflation.c:19:15:19:17 | taint_array output argument | semmle.label | taint_array output argument |
|
||||
| field_conflation.c:20:10:20:13 | (unsigned long)... | semmle.label | (unsigned long)... |
|
||||
| field_conflation.c:20:10:20:13 | (unsigned long)... | semmle.label | (unsigned long)... |
|
||||
| field_conflation.c:20:13:20:13 | x | semmle.label | x |
|
||||
| field_conflation.c:20:13:20:13 | x | semmle.label | x |
|
||||
| field_conflation.c:20:13:20:13 | x | semmle.label | x |
|
||||
| test.cpp:39:21:39:24 | argv | semmle.label | argv |
|
||||
| test.cpp:39:21:39:24 | argv | semmle.label | argv |
|
||||
| test.cpp:42:38:42:44 | (size_t)... | semmle.label | (size_t)... |
|
||||
@@ -140,8 +142,33 @@ nodes
|
||||
| test.cpp:231:9:231:24 | call to get_tainted_size | semmle.label | call to get_tainted_size |
|
||||
| test.cpp:235:11:235:20 | (size_t)... | semmle.label | (size_t)... |
|
||||
| test.cpp:237:10:237:19 | (size_t)... | semmle.label | (size_t)... |
|
||||
| test.cpp:241:2:241:32 | Chi | semmle.label | Chi |
|
||||
| test.cpp:241:18:241:23 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:241:18:241:31 | (const char *)... | semmle.label | (const char *)... |
|
||||
| test.cpp:249:20:249:25 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:249:20:249:33 | (const char *)... | semmle.label | (const char *)... |
|
||||
| test.cpp:253:11:253:29 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:253:11:253:29 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:253:11:253:29 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:279:17:279:20 | get_size output argument | semmle.label | get_size output argument |
|
||||
| test.cpp:281:11:281:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:281:11:281:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:281:11:281:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:295:18:295:21 | get_size output argument | semmle.label | get_size output argument |
|
||||
| test.cpp:298:10:298:27 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:298:10:298:27 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:298:10:298:27 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:301:19:301:24 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:301:19:301:32 | (const char *)... | semmle.label | (const char *)... |
|
||||
| test.cpp:305:11:305:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:305:11:305:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:305:11:305:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:309:19:309:24 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:309:19:309:32 | (const char *)... | semmle.label | (const char *)... |
|
||||
| test.cpp:314:10:314:27 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:314:10:314:27 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:314:10:314:27 | ... * ... | semmle.label | ... * ... |
|
||||
#select
|
||||
| field_conflation.c:20:3:20:8 | call to malloc | field_conflation.c:12:22:12:27 | call to getenv | field_conflation.c:20:13:20:13 | x | This allocation size is derived from $@ and might overflow | field_conflation.c:12:22:12:27 | call to getenv | user input (getenv) |
|
||||
| test.cpp:42:31:42:36 | call to malloc | test.cpp:39:21:39:24 | argv | test.cpp:42:38:42:44 | tainted | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
||||
| test.cpp:43:31:43:36 | call to malloc | test.cpp:39:21:39:24 | argv | test.cpp:43:38:43:63 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
||||
| test.cpp:45:31:45:36 | call to malloc | test.cpp:39:21:39:24 | argv | test.cpp:45:38:45:63 | ... + ... | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
|
||||
@@ -155,3 +182,8 @@ nodes
|
||||
| test.cpp:221:14:221:19 | call to malloc | test.cpp:227:24:227:29 | call to getenv | test.cpp:221:21:221:21 | s | This allocation size is derived from $@ and might overflow | test.cpp:227:24:227:29 | call to getenv | user input (getenv) |
|
||||
| test.cpp:229:2:229:7 | call to malloc | test.cpp:227:24:227:29 | call to getenv | test.cpp:229:9:229:18 | local_size | This allocation size is derived from $@ and might overflow | test.cpp:227:24:227:29 | call to getenv | user input (getenv) |
|
||||
| test.cpp:231:2:231:7 | call to malloc | test.cpp:201:14:201:19 | call to getenv | test.cpp:231:9:231:24 | call to get_tainted_size | This allocation size is derived from $@ and might overflow | test.cpp:201:14:201:19 | call to getenv | user input (getenv) |
|
||||
| test.cpp:253:4:253:9 | call to malloc | test.cpp:249:20:249:25 | call to getenv | test.cpp:253:11:253:29 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:249:20:249:25 | call to getenv | user input (getenv) |
|
||||
| test.cpp:281:4:281:9 | call to malloc | test.cpp:241:18:241:23 | call to getenv | test.cpp:281:11:281:28 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:241:18:241:23 | call to getenv | user input (getenv) |
|
||||
| test.cpp:298:3:298:8 | call to malloc | test.cpp:241:18:241:23 | call to getenv | test.cpp:298:10:298:27 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:241:18:241:23 | call to getenv | user input (getenv) |
|
||||
| test.cpp:305:4:305:9 | call to malloc | test.cpp:301:19:301:24 | call to getenv | test.cpp:305:11:305:28 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:301:19:301:24 | call to getenv | user input (getenv) |
|
||||
| test.cpp:314:3:314:8 | call to malloc | test.cpp:309:19:309:24 | call to getenv | test.cpp:314:10:314:27 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:309:19:309:24 | call to getenv | user input (getenv) |
|
||||
|
||||
@@ -17,5 +17,5 @@ void test_conflated_fields3(void) {
|
||||
struct XY xy;
|
||||
xy.x = 4;
|
||||
taint_array(&xy);
|
||||
malloc(xy.x); // not tainted [FALSE POSITIVE]
|
||||
malloc(xy.x); // not tainted
|
||||
}
|
||||
|
||||
@@ -236,3 +236,81 @@ void more_cases() {
|
||||
my_func(100); // GOOD
|
||||
my_func(local_size); // GOOD
|
||||
}
|
||||
|
||||
bool get_size(int &out_size) {
|
||||
out_size = atoi(getenv("USER"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void equality_cases() {
|
||||
{
|
||||
int size1 = atoi(getenv("USER"));
|
||||
int size2 = atoi(getenv("USER"));
|
||||
|
||||
if (size1 == 100)
|
||||
{
|
||||
malloc(size2 * sizeof(int)); // BAD
|
||||
}
|
||||
if (size2 == 100)
|
||||
{
|
||||
malloc(size2 * sizeof(int)); // GOOD
|
||||
}
|
||||
}
|
||||
{
|
||||
int size = atoi(getenv("USER"));
|
||||
|
||||
if (size != 100)
|
||||
return;
|
||||
|
||||
malloc(size * sizeof(int)); // GOOD
|
||||
}
|
||||
{
|
||||
int size;
|
||||
|
||||
if ((get_size(size)) && (size == 100))
|
||||
{
|
||||
malloc(size * sizeof(int)); // GOOD
|
||||
}
|
||||
}
|
||||
{
|
||||
int size;
|
||||
|
||||
if ((get_size(size)) && (size != 100))
|
||||
{
|
||||
malloc(size * sizeof(int)); // BAD
|
||||
}
|
||||
}
|
||||
{
|
||||
int size;
|
||||
|
||||
if ((!get_size(size)) || (size != 100))
|
||||
return;
|
||||
|
||||
malloc(size * sizeof(int)); // GOOD
|
||||
}
|
||||
{
|
||||
int size;
|
||||
|
||||
if ((!get_size(size)) || (size == 100))
|
||||
return;
|
||||
|
||||
malloc(size * sizeof(int)); // BAD
|
||||
}
|
||||
{
|
||||
int size = atoi(getenv("USER"));
|
||||
|
||||
if ((size == 50) || (size == 100))
|
||||
{
|
||||
malloc(size * sizeof(int)); // GOOD [FALSE POSITIVE]
|
||||
}
|
||||
}
|
||||
{
|
||||
int size = atoi(getenv("USER"));
|
||||
|
||||
if (size != 50 && size != 100)
|
||||
return;
|
||||
|
||||
malloc(size * sizeof(int)); // GOOD [FALSE POSITIVE]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,5 +5,4 @@
|
||||
| test.c:63:3:63:5 | sc8 | $@ flows to here and is used in arithmetic, potentially causing an underflow. | test.c:62:9:62:16 | - ... | Extreme value |
|
||||
| test.c:75:3:75:5 | sc1 | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:74:9:74:16 | 127 | Extreme value |
|
||||
| test.c:76:3:76:5 | sc1 | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:74:9:74:16 | 127 | Extreme value |
|
||||
| test.c:114:9:114:9 | x | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:108:17:108:23 | 2147483647 | Extreme value |
|
||||
| test.c:124:9:124:9 | x | $@ flows to here and is used in arithmetic, potentially causing an overflow. | test.c:118:17:118:23 | 2147483647 | Extreme value |
|
||||
|
||||
@@ -111,7 +111,7 @@ void test_guards3(int cond) {
|
||||
|
||||
if (x != 0) return;
|
||||
|
||||
return x + 1; // GOOD [FALSE POSITIVE]
|
||||
return x + 1; // GOOD
|
||||
}
|
||||
|
||||
void test_guards4(int cond) {
|
||||
|
||||
@@ -1160,26 +1160,6 @@ class UsingStmt extends Stmt, @using_stmt {
|
||||
* ```
|
||||
*/
|
||||
Expr getAnExpr() { none() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use UsingBlockStmt.getExpr() instead.
|
||||
* Gets the expression directly used by this `using` statement, if any. For
|
||||
* example, `f` on line 2 in
|
||||
*
|
||||
* ```
|
||||
* var f = File.Open("settings.xml");
|
||||
* using (f) {
|
||||
* ...
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
deprecated Expr getExpr() { none() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use UsingBlockStmt.getBody() instead.
|
||||
* Gets the body of this `using` statement.
|
||||
*/
|
||||
deprecated Stmt getBody() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1212,7 +1192,7 @@ class UsingBlockStmt extends UsingStmt, @using_block_stmt {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
override Expr getExpr() { result = this.getChild(0) }
|
||||
Expr getExpr() { result = this.getChild(0) }
|
||||
|
||||
override Expr getAnExpr() {
|
||||
result = this.getAVariableDeclExpr().getInitializer()
|
||||
@@ -1221,7 +1201,7 @@ class UsingBlockStmt extends UsingStmt, @using_block_stmt {
|
||||
}
|
||||
|
||||
/** Gets the body of this `using` statement. */
|
||||
override Stmt getBody() { result.getParent() = this }
|
||||
Stmt getBody() { result.getParent() = this }
|
||||
|
||||
override string toString() { result = "using (...) {...}" }
|
||||
}
|
||||
|
||||
@@ -474,7 +474,8 @@ module Gvn {
|
||||
sourceDecl = any(GenericType t).getSourceDeclaration() and
|
||||
not sourceDecl instanceof PointerType and
|
||||
not sourceDecl instanceof NullableType and
|
||||
not sourceDecl instanceof ArrayType
|
||||
not sourceDecl instanceof ArrayType and
|
||||
not sourceDecl instanceof TupleType
|
||||
}
|
||||
|
||||
cached
|
||||
|
||||
@@ -116,7 +116,7 @@ class XMLFile extends XMLParent, File {
|
||||
XMLFile() { xmlEncoding(this, _) }
|
||||
|
||||
/** Gets a printable representation of this XML file. */
|
||||
override string toString() { result = XMLParent.super.toString() }
|
||||
override string toString() { result = getName() }
|
||||
|
||||
/** Gets the name of this XML file. */
|
||||
override string getName() { result = File.super.getAbsolutePath() }
|
||||
@@ -236,7 +236,7 @@ class XMLElement extends @xmlelement, XMLParent, XMLLocatable {
|
||||
string getAttributeValue(string name) { result = this.getAttribute(name).getValue() }
|
||||
|
||||
/** Gets a printable representation of this XML element. */
|
||||
override string toString() { result = XMLParent.super.toString() }
|
||||
override string toString() { result = getName() }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -66,9 +66,6 @@ abstract class Configuration extends string {
|
||||
*/
|
||||
predicate isBarrier(Node node) { none() }
|
||||
|
||||
/** DEPRECATED: override `isBarrierIn` and `isBarrierOut` instead. */
|
||||
deprecated predicate isBarrierEdge(Node node1, Node node2) { none() }
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isBarrierIn(Node node) { none() }
|
||||
|
||||
|
||||
@@ -66,9 +66,6 @@ abstract class Configuration extends string {
|
||||
*/
|
||||
predicate isBarrier(Node node) { none() }
|
||||
|
||||
/** DEPRECATED: override `isBarrierIn` and `isBarrierOut` instead. */
|
||||
deprecated predicate isBarrierEdge(Node node1, Node node2) { none() }
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isBarrierIn(Node node) { none() }
|
||||
|
||||
|
||||
@@ -66,9 +66,6 @@ abstract class Configuration extends string {
|
||||
*/
|
||||
predicate isBarrier(Node node) { none() }
|
||||
|
||||
/** DEPRECATED: override `isBarrierIn` and `isBarrierOut` instead. */
|
||||
deprecated predicate isBarrierEdge(Node node1, Node node2) { none() }
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isBarrierIn(Node node) { none() }
|
||||
|
||||
|
||||
@@ -66,9 +66,6 @@ abstract class Configuration extends string {
|
||||
*/
|
||||
predicate isBarrier(Node node) { none() }
|
||||
|
||||
/** DEPRECATED: override `isBarrierIn` and `isBarrierOut` instead. */
|
||||
deprecated predicate isBarrierEdge(Node node1, Node node2) { none() }
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isBarrierIn(Node node) { none() }
|
||||
|
||||
|
||||
@@ -66,9 +66,6 @@ abstract class Configuration extends string {
|
||||
*/
|
||||
predicate isBarrier(Node node) { none() }
|
||||
|
||||
/** DEPRECATED: override `isBarrierIn` and `isBarrierOut` instead. */
|
||||
deprecated predicate isBarrierEdge(Node node1, Node node2) { none() }
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isBarrierIn(Node node) { none() }
|
||||
|
||||
|
||||
@@ -79,13 +79,6 @@ abstract class Configuration extends DataFlow::Configuration {
|
||||
defaultTaintBarrier(node)
|
||||
}
|
||||
|
||||
/** DEPRECATED: override `isSanitizerIn` and `isSanitizerOut` instead. */
|
||||
deprecated predicate isSanitizerEdge(DataFlow::Node node1, DataFlow::Node node2) { none() }
|
||||
|
||||
deprecated final override predicate isBarrierEdge(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
isSanitizerEdge(node1, node2)
|
||||
}
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isSanitizerIn(DataFlow::Node node) { none() }
|
||||
|
||||
|
||||
@@ -79,13 +79,6 @@ abstract class Configuration extends DataFlow::Configuration {
|
||||
defaultTaintBarrier(node)
|
||||
}
|
||||
|
||||
/** DEPRECATED: override `isSanitizerIn` and `isSanitizerOut` instead. */
|
||||
deprecated predicate isSanitizerEdge(DataFlow::Node node1, DataFlow::Node node2) { none() }
|
||||
|
||||
deprecated final override predicate isBarrierEdge(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
isSanitizerEdge(node1, node2)
|
||||
}
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isSanitizerIn(DataFlow::Node node) { none() }
|
||||
|
||||
|
||||
@@ -79,13 +79,6 @@ abstract class Configuration extends DataFlow::Configuration {
|
||||
defaultTaintBarrier(node)
|
||||
}
|
||||
|
||||
/** DEPRECATED: override `isSanitizerIn` and `isSanitizerOut` instead. */
|
||||
deprecated predicate isSanitizerEdge(DataFlow::Node node1, DataFlow::Node node2) { none() }
|
||||
|
||||
deprecated final override predicate isBarrierEdge(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
isSanitizerEdge(node1, node2)
|
||||
}
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isSanitizerIn(DataFlow::Node node) { none() }
|
||||
|
||||
|
||||
@@ -79,13 +79,6 @@ abstract class Configuration extends DataFlow::Configuration {
|
||||
defaultTaintBarrier(node)
|
||||
}
|
||||
|
||||
/** DEPRECATED: override `isSanitizerIn` and `isSanitizerOut` instead. */
|
||||
deprecated predicate isSanitizerEdge(DataFlow::Node node1, DataFlow::Node node2) { none() }
|
||||
|
||||
deprecated final override predicate isBarrierEdge(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
isSanitizerEdge(node1, node2)
|
||||
}
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isSanitizerIn(DataFlow::Node node) { none() }
|
||||
|
||||
|
||||
@@ -79,13 +79,6 @@ abstract class Configuration extends DataFlow::Configuration {
|
||||
defaultTaintBarrier(node)
|
||||
}
|
||||
|
||||
/** DEPRECATED: override `isSanitizerIn` and `isSanitizerOut` instead. */
|
||||
deprecated predicate isSanitizerEdge(DataFlow::Node node1, DataFlow::Node node2) { none() }
|
||||
|
||||
deprecated final override predicate isBarrierEdge(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
isSanitizerEdge(node1, node2)
|
||||
}
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isSanitizerIn(DataFlow::Node node) { none() }
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
||||
{
|
||||
Uri uri = Uri.parse(url);
|
||||
// BAD: partial domain match, which allows an attacker to register a domain like myexample.com to circumvent the verification
|
||||
if (uri.getHost() != null && uri.getHost().endsWith("example.com")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Uri uri = Uri.parse(url);
|
||||
// GOOD: full domain match
|
||||
if (uri.getHost() != null && uri.getHost().endsWith(".example.com")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>Apps that rely on URL Parsing to verify that a given URL is pointing to a trust server may be susceptible to many different ways to get URL parsing and verification wrong, which allows an attacker to register a fake site to break the access control.</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>Verify the whole host and domain (FQDN) or check endsWith dot+domain.</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>The following example shows two ways of verifying host domain. In the 'BAD' case,
|
||||
verification is implemented as partial domain match. In the 'GOOD' case, full domain is verified.</p>
|
||||
<sample src="IncorrectURLVerification.java" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
<a href="https://drive.google.com/file/d/0BwMN49Gzo3x6T1N5WGQ4TTNlMHBOb1ZRQTVEWnVBZjFUaE5N/view">Common Android app vulnerabilities from Sebastian Porst of Google</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.bugcrowd.com/resources/webinars/overview-of-common-android-app-vulnerabilities/">Common Android app vulnerabilities from bugcrowd</a>
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
97
java/ql/src/experimental/CWE-939/IncorrectURLVerification.ql
Normal file
97
java/ql/src/experimental/CWE-939/IncorrectURLVerification.ql
Normal file
@@ -0,0 +1,97 @@
|
||||
/**
|
||||
* @id java/incorrect-url-verification
|
||||
* @name Incorrect URL verification
|
||||
* @description Apps that rely on URL parsing to verify that a given URL is pointing to a trusted server are susceptible to wrong ways of URL parsing and verification.
|
||||
* @kind problem
|
||||
* @tags security
|
||||
* external/cwe-939
|
||||
*/
|
||||
|
||||
import java
|
||||
|
||||
/**
|
||||
* The Java class `android.R.string` specific to Android applications, which contains references to application specific resources defined in /res/values/strings.xml.
|
||||
* For example, <resources>...<string name="host">example.com</string>...</resources> in the application com.example.android.web can be referred as R.string.host with the type com.example.android.web.R$string
|
||||
*/
|
||||
class AndroidRString extends RefType {
|
||||
AndroidRString() { this.hasQualifiedName(_, "R$string") }
|
||||
}
|
||||
|
||||
/**
|
||||
* The Java class `android.net.Uri` and `java.net.URL`.
|
||||
*/
|
||||
class Uri extends RefType {
|
||||
Uri() {
|
||||
hasQualifiedName("android.net", "Uri") or
|
||||
hasQualifiedName("java.net", "URL")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The method `getHost()` declared in `android.net.Uri` and `java.net.URL`.
|
||||
*/
|
||||
class UriGetHostMethod extends Method {
|
||||
UriGetHostMethod() {
|
||||
getDeclaringType() instanceof Uri and
|
||||
hasName("getHost") and
|
||||
getNumberOfParameters() = 0
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The method access with incorrect string comparision
|
||||
*/
|
||||
class HostVerificationMethodAccess extends MethodAccess {
|
||||
HostVerificationMethodAccess() {
|
||||
(
|
||||
this.getMethod().hasName("endsWith") or
|
||||
this.getMethod().hasName("contains") or
|
||||
this.getMethod().hasName("indexOf")
|
||||
) and
|
||||
this.getMethod().getNumberOfParameters() = 1 and
|
||||
(
|
||||
this.getArgument(0).(StringLiteral).getRepresentedString().charAt(0) != "." //string constant comparison e.g. uri.getHost().endsWith("example.com")
|
||||
or
|
||||
this
|
||||
.getArgument(0)
|
||||
.(AddExpr)
|
||||
.getLeftOperand()
|
||||
.(VarAccess)
|
||||
.getVariable()
|
||||
.getAnAssignedValue()
|
||||
.(StringLiteral)
|
||||
.getRepresentedString()
|
||||
.charAt(0) != "." //var1+var2, check var1 starts with "." e.g. String domainName = "example"; Uri.parse(url).getHost().endsWith(domainName+".com")
|
||||
or
|
||||
this
|
||||
.getArgument(0)
|
||||
.(AddExpr)
|
||||
.getLeftOperand()
|
||||
.(StringLiteral)
|
||||
.getRepresentedString()
|
||||
.charAt(0) != "." //"."+var2, check string constant "." e.g. String domainName = "example.com"; Uri.parse(url).getHost().endsWith("www."+domainName)
|
||||
or
|
||||
exists(MethodAccess ma, Method m, Field f |
|
||||
this.getArgument(0) = ma and
|
||||
ma.getMethod() = m and
|
||||
m.hasName("getString") and
|
||||
m.getDeclaringType().getQualifiedName() = "android.content.res.Resources" and
|
||||
ma.getArgument(0).(FieldRead).getField() = f and
|
||||
f.getDeclaringType() instanceof AndroidRString
|
||||
) //Check resource properties in /res/values/strings.xml in Android mobile applications using res.getString(R.string.key)
|
||||
or
|
||||
this
|
||||
.getArgument(0)
|
||||
.(VarAccess)
|
||||
.getVariable()
|
||||
.getAnAssignedValue()
|
||||
.(StringLiteral)
|
||||
.getRepresentedString()
|
||||
.charAt(0) != "." //check variable starts with "." e.g. String domainName = "example.com"; Uri.parse(url).getHost().endsWith(domainName)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from UriGetHostMethod um, MethodAccess uma, HostVerificationMethodAccess hma
|
||||
where hma.getQualifier() = uma and uma.getMethod() = um
|
||||
select hma, "Method has potentially $@ ", hma.getArgument(0), "improper URL verification"
|
||||
@@ -22,8 +22,7 @@ class TypeAuthorizedUrl extends Class {
|
||||
}
|
||||
|
||||
/**
|
||||
* The class
|
||||
* `org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry`.
|
||||
* The class `org.springframework.security.config.annotation.web.AbstractRequestMatcherRegistry`.
|
||||
*/
|
||||
class TypeAbstractRequestMatcherRegistry extends Class {
|
||||
TypeAbstractRequestMatcherRegistry() {
|
||||
@@ -34,38 +33,44 @@ class TypeAbstractRequestMatcherRegistry extends Class {
|
||||
}
|
||||
|
||||
/**
|
||||
* The class
|
||||
* `org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest.EndpointRequestMatcher`.
|
||||
* The class `org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest`.
|
||||
*/
|
||||
class TypeEndpointRequestMatcher extends Class {
|
||||
TypeEndpointRequestMatcher() {
|
||||
class TypeEndpointRequest extends Class {
|
||||
TypeEndpointRequest() {
|
||||
this
|
||||
.hasQualifiedName("org.springframework.boot.actuate.autoconfigure.security.servlet",
|
||||
"EndpointRequest$EndpointRequestMatcher")
|
||||
"EndpointRequest")
|
||||
}
|
||||
}
|
||||
|
||||
/** A call to `EndpointRequest.toAnyEndpoint` method. */
|
||||
class ToAnyEndpointCall extends MethodAccess {
|
||||
ToAnyEndpointCall() {
|
||||
getMethod().hasName("toAnyEndpoint") and
|
||||
getMethod().getDeclaringType() instanceof TypeEndpointRequest
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `HttpSecurity.requestMatcher` method with argument of type
|
||||
* `EndpointRequestMatcher`.
|
||||
* A call to `HttpSecurity.requestMatcher` method with argument `RequestMatcher.toAnyEndpoint()`.
|
||||
*/
|
||||
class RequestMatcherCall extends MethodAccess {
|
||||
RequestMatcherCall() {
|
||||
getMethod().hasName("requestMatcher") and
|
||||
getMethod().getDeclaringType() instanceof TypeHttpSecurity and
|
||||
getArgument(0).getType() instanceof TypeEndpointRequestMatcher
|
||||
getArgument(0) instanceof ToAnyEndpointCall
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `HttpSecurity.requestMatchers` method with lambda argument resolving to
|
||||
* `EndpointRequestMatcher` type.
|
||||
* A call to `HttpSecurity.requestMatchers` method with lambda argument
|
||||
* `RequestMatcher.toAnyEndpoint()`.
|
||||
*/
|
||||
class RequestMatchersCall extends MethodAccess {
|
||||
RequestMatchersCall() {
|
||||
getMethod().hasName("requestMatchers") and
|
||||
getMethod().getDeclaringType() instanceof TypeHttpSecurity and
|
||||
getArgument(0).(LambdaExpr).getExprBody().getType() instanceof TypeEndpointRequestMatcher
|
||||
getArgument(0).(LambdaExpr).getExprBody() instanceof ToAnyEndpointCall
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,9 +97,6 @@ class PermitAllCall extends MethodAccess {
|
||||
or
|
||||
// .requestMatchers(matcher -> EndpointRequest).authorizeRequests([...]).[...]
|
||||
authorizeRequestsCall.getQualifier() instanceof RequestMatchersCall
|
||||
or
|
||||
// http.authorizeRequests([...]).[...]
|
||||
authorizeRequestsCall.getQualifier() instanceof VarAccess
|
||||
|
|
||||
// [...].authorizeRequests(r -> r.anyRequest().permitAll()) or
|
||||
// [...].authorizeRequests(r -> r.requestMatchers(EndpointRequest).permitAll())
|
||||
@@ -117,6 +119,22 @@ class PermitAllCall extends MethodAccess {
|
||||
this.getQualifier() = anyRequestCall
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(AuthorizeRequestsCall authorizeRequestsCall |
|
||||
// http.authorizeRequests([...]).[...]
|
||||
authorizeRequestsCall.getQualifier() instanceof VarAccess
|
||||
|
|
||||
// [...].authorizeRequests(r -> r.requestMatchers(EndpointRequest).permitAll())
|
||||
authorizeRequestsCall.getArgument(0).(LambdaExpr).getExprBody() = this and
|
||||
this.getQualifier() instanceof RegistryRequestMatchersCall
|
||||
or
|
||||
// [...].authorizeRequests().requestMatchers(EndpointRequest).permitAll() or
|
||||
authorizeRequestsCall.getNumArgument() = 0 and
|
||||
exists(RegistryRequestMatchersCall registryRequestMatchersCall |
|
||||
registryRequestMatchersCall.getQualifier() = authorizeRequestsCall and
|
||||
this.getQualifier() = registryRequestMatchersCall
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,13 +147,13 @@ class AnyRequestCall extends MethodAccess {
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `AbstractRequestMatcherRegistry.requestMatchers` method with an argument of type
|
||||
* `EndpointRequestMatcher`.
|
||||
* A call to `AbstractRequestMatcherRegistry.requestMatchers` method with an argument
|
||||
* `RequestMatcher.toAnyEndpoint()`.
|
||||
*/
|
||||
class RegistryRequestMatchersCall extends MethodAccess {
|
||||
RegistryRequestMatchersCall() {
|
||||
getMethod().hasName("requestMatchers") and
|
||||
getMethod().getDeclaringType() instanceof TypeAbstractRequestMatcherRegistry and
|
||||
getAnArgument().getType() instanceof TypeEndpointRequestMatcher
|
||||
getAnArgument() instanceof ToAnyEndpointCall
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,9 +66,6 @@ abstract class Configuration extends string {
|
||||
*/
|
||||
predicate isBarrier(Node node) { none() }
|
||||
|
||||
/** DEPRECATED: override `isBarrierIn` and `isBarrierOut` instead. */
|
||||
deprecated predicate isBarrierEdge(Node node1, Node node2) { none() }
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isBarrierIn(Node node) { none() }
|
||||
|
||||
|
||||
@@ -66,9 +66,6 @@ abstract class Configuration extends string {
|
||||
*/
|
||||
predicate isBarrier(Node node) { none() }
|
||||
|
||||
/** DEPRECATED: override `isBarrierIn` and `isBarrierOut` instead. */
|
||||
deprecated predicate isBarrierEdge(Node node1, Node node2) { none() }
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isBarrierIn(Node node) { none() }
|
||||
|
||||
|
||||
@@ -66,9 +66,6 @@ abstract class Configuration extends string {
|
||||
*/
|
||||
predicate isBarrier(Node node) { none() }
|
||||
|
||||
/** DEPRECATED: override `isBarrierIn` and `isBarrierOut` instead. */
|
||||
deprecated predicate isBarrierEdge(Node node1, Node node2) { none() }
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isBarrierIn(Node node) { none() }
|
||||
|
||||
|
||||
@@ -66,9 +66,6 @@ abstract class Configuration extends string {
|
||||
*/
|
||||
predicate isBarrier(Node node) { none() }
|
||||
|
||||
/** DEPRECATED: override `isBarrierIn` and `isBarrierOut` instead. */
|
||||
deprecated predicate isBarrierEdge(Node node1, Node node2) { none() }
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isBarrierIn(Node node) { none() }
|
||||
|
||||
|
||||
@@ -66,9 +66,6 @@ abstract class Configuration extends string {
|
||||
*/
|
||||
predicate isBarrier(Node node) { none() }
|
||||
|
||||
/** DEPRECATED: override `isBarrierIn` and `isBarrierOut` instead. */
|
||||
deprecated predicate isBarrierEdge(Node node1, Node node2) { none() }
|
||||
|
||||
/** Holds if data flow into `node` is prohibited. */
|
||||
predicate isBarrierIn(Node node) { none() }
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user