Skip to content

Commit 65f8f56

Browse files
authored
Merge branch 'main' into incomplete-url-string-sanitization
2 parents bf888f0 + 496aab7 commit 65f8f56

File tree

180 files changed

+9958
-1006
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

180 files changed

+9958
-1006
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ If you have an idea for a query that you would like to share with other CodeQL u
3636

3737
For details, see the [guide on query metadata](docs/query-metadata-style-guide.md).
3838

39-
Make sure the `select` statement is compatible with the query `@kind`. See [About CodeQL queries](https://help.semmle.com/QL/learn-ql/writing-queries/introduction-to-queries.html#select-clause) on help.semmle.com.
39+
Make sure the `select` statement is compatible with the query `@kind`. See [About CodeQL queries](https://codeql.github.com/docs/writing-codeql-queries/about-codeql-queries/#select-clause) on codeql.github.com.
4040

4141
3. **Formatting**
4242

config/identical-files.json

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@
2727
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll",
2828
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl4.qll",
2929
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll",
30-
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll"
30+
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl2.qll",
31+
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForLibraries.qll"
3132
],
3233
"DataFlow Java/C++/C#/Python Common": [
3334
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll",
@@ -54,7 +55,8 @@
5455
"python/ql/lib/semmle/python/dataflow/new/internal/tainttracking2/TaintTrackingImpl.qll",
5556
"python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingImpl.qll",
5657
"python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingImpl.qll",
57-
"ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll"
58+
"ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
59+
"ruby/ql/lib/codeql/ruby/dataflow/internal/tainttrackingforlibraries/TaintTrackingImpl.qll"
5860
],
5961
"DataFlow Java/C++/C#/Python Consistency checks": [
6062
"java/ql/lib/semmle/code/java/dataflow/internal/DataFlowImplConsistency.qll",
@@ -480,11 +482,12 @@
480482
"python/ql/lib/semmle/python/security/performance/ReDoSUtil.qll",
481483
"ruby/ql/lib/codeql/ruby/security/performance/ReDoSUtil.qll"
482484
],
483-
"ReDoS Exponential Python/JS": [
485+
"ReDoS Exponential Python/JS/Ruby": [
484486
"javascript/ql/lib/semmle/javascript/security/performance/ExponentialBackTracking.qll",
485-
"python/ql/lib/semmle/python/security/performance/ExponentialBackTracking.qll"
487+
"python/ql/lib/semmle/python/security/performance/ExponentialBackTracking.qll",
488+
"ruby/ql/lib/codeql/ruby/security/performance/ExponentialBackTracking.qll"
486489
],
487-
"ReDoS Polynomial Python/JS": [
490+
"ReDoS Polynomial Python/JS/Ruby": [
488491
"javascript/ql/lib/semmle/javascript/security/performance/SuperlinearBackTracking.qll",
489492
"python/ql/lib/semmle/python/security/performance/SuperlinearBackTracking.qll",
490493
"ruby/ql/lib/codeql/ruby/security/performance/SuperlinearBackTracking.qll"
@@ -520,12 +523,34 @@
520523
"javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qll",
521524
"ruby/ql/src/queries/security/cwe-020/IncompleteUrlSubstringSanitization.qll"
522525
],
526+
"Concepts Python/Ruby/JS": [
527+
"python/ql/lib/semmle/python/internal/ConceptsShared.qll",
528+
"ruby/ql/lib/codeql/ruby/internal/ConceptsShared.qll",
529+
"javascript/ql/lib/semmle/javascript/internal/ConceptsShared.qll"
530+
],
523531
"Hostname Regexp queries": [
524532
"javascript/ql/src/Security/CWE-020/HostnameRegexpShared.qll",
533+
"python/ql/src/Security/CWE-020/HostnameRegexpShared.qll",
525534
"ruby/ql/src/queries/security/cwe-020/HostnameRegexpShared.qll"
526535
],
527536
"ApiGraphModels": [
528537
"javascript/ql/lib/semmle/javascript/frameworks/data/internal/ApiGraphModels.qll",
529538
"ruby/ql/lib/codeql/ruby/frameworks/data/internal/ApiGraphModels.qll"
539+
],
540+
"TaintedFormatStringQuery Ruby/JS": [
541+
"javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatStringQuery.qll",
542+
"ruby/ql/lib/codeql/ruby/security/TaintedFormatStringQuery.qll"
543+
],
544+
"TaintedFormatStringCustomizations Ruby/JS": [
545+
"javascript/ql/lib/semmle/javascript/security/dataflow/TaintedFormatStringCustomizations.qll",
546+
"ruby/ql/lib/codeql/ruby/security/TaintedFormatStringCustomizations.qll"
547+
],
548+
"HttpToFileAccessQuery JS/Ruby": [
549+
"javascript/ql/lib/semmle/javascript/security/dataflow/HttpToFileAccessQuery.qll",
550+
"ruby/ql/lib/codeql/ruby/security/HttpToFileAccessQuery.qll"
551+
],
552+
"HttpToFileAccessCustomizations JS/Ruby": [
553+
"javascript/ql/lib/semmle/javascript/security/dataflow/HttpToFileAccessCustomizations.qll",
554+
"ruby/ql/lib/codeql/ruby/security/HttpToFileAccessCustomizations.qll"
530555
]
531556
}

cpp/ql/lib/semmle/code/cpp/Location.qll

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,24 @@ class Location extends @location {
7373

7474
/** Holds if `this` comes on a line strictly before `l`. */
7575
pragma[inline]
76-
predicate isBefore(Location l) {
77-
this.getFile() = l.getFile() and this.getEndLine() < l.getStartLine()
76+
predicate isBefore(Location l) { this.isBefore(l, false) }
77+
78+
/**
79+
* Holds if `this` comes strictly before `l`. The boolean `sameLine` is
80+
* true if `l` is on the same line as `this`, but starts at a later column.
81+
* Otherwise, `sameLine` is false.
82+
*/
83+
pragma[inline]
84+
predicate isBefore(Location l, boolean sameLine) {
85+
this.getFile() = l.getFile() and
86+
(
87+
sameLine = false and
88+
this.getEndLine() < l.getStartLine()
89+
or
90+
sameLine = true and
91+
this.getEndLine() = l.getStartLine() and
92+
this.getEndColumn() < l.getStartColumn()
93+
)
7894
}
7995

8096
/** Holds if location `l` is completely contained within this one. */

cpp/ql/lib/semmle/code/cpp/Type.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ class Type extends Locatable, @type {
9494
* The result of this predicate will be the type itself, except in the case of a TypedefType or a Decltype,
9595
* in which case the result will be type which results from (possibly recursively) resolving typedefs.
9696
*/
97+
pragma[nomagic]
9798
Type getUnderlyingType() { result = this }
9899

99100
/**

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ Instruction getInstructionBackEdgeSuccessor(Instruction instruction, EdgeKind ki
349349

350350
/** Holds if `goto` jumps strictly forward in the program text. */
351351
private predicate isStrictlyForwardGoto(GotoStmt goto) {
352-
goto.getLocation().isBefore(goto.getTarget().getLocation())
352+
goto.getLocation().isBefore(goto.getTarget().getLocation(), _)
353353
}
354354

355355
Locatable getInstructionAst(TStageInstruction instr) {

cpp/ql/lib/semmle/code/cpp/models/interfaces/FormattingFunction.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ abstract class FormattingFunction extends ArrayFunction, TaintFunction {
9292
* snapshots there may be multiple results where we can't tell which is correct for a
9393
* particular function.
9494
*/
95+
pragma[nomagic]
9596
Type getWideCharType() {
9697
result = getFormatCharType() and
9798
result.getSize() > 1
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* @name Extraction errors
3+
* @description List all extraction errors for files in the source code directory.
4+
* @kind diagnostic
5+
* @id cpp/diagnostics/extraction-errors
6+
*/
7+
8+
import cpp
9+
import ExtractionErrors
10+
11+
// NOTE:
12+
// This file looks like the other `diagnostics/extraction-errors` queries in other CodeQL supported
13+
// languages. However, since this diagnostic query is located in the `Internal` subdirectory it will not
14+
// appear in the Code Scanning suite. The related query `cpp/diagnostics/extraction-warnings` is,
15+
// however, included as a public diagnostics query.
16+
from ExtractionError error
17+
where
18+
error instanceof ExtractionUnknownError or
19+
exists(error.getFile().getRelativePath())
20+
select error, "Extraction failed in " + error.getFile() + " with error " + error.getErrorMessage(),
21+
error.getSeverity()
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/**
2+
* Provides a common hierarchy of all types of errors that can occur during extraction.
3+
*/
4+
5+
import cpp
6+
7+
/*
8+
* A note about how the C/C++ extractor emits diagnostics:
9+
* When the extractor frontend encounters an error, it emits a diagnostic message,
10+
* that includes a message, location and severity.
11+
* However, that process is best-effort and may fail (e.g. due to lack of memory).
12+
* Thus, if the extractor emitted at least one diagnostic of severity discretionary
13+
* error (or higher), it *also* emits a simple "There was an error during this compilation"
14+
* error diagnostic, without location information.
15+
* In the common case, this means that a compilation during which one or more errors happened also gets
16+
* the catch-all diagnostic.
17+
* This diagnostic has the empty string as file path.
18+
* We filter out these useless diagnostics if there is at least one error-level diagnostic
19+
* for the affected compilation in the database.
20+
* Otherwise, we show it to indicate that something went wrong and that we
21+
* don't know what exactly happened.
22+
*/
23+
24+
/**
25+
* An error that, if present, leads to a file being marked as non-successfully extracted.
26+
*/
27+
class ReportableError extends Diagnostic {
28+
ReportableError() {
29+
(
30+
this instanceof CompilerDiscretionaryError or
31+
this instanceof CompilerError or
32+
this instanceof CompilerCatastrophe
33+
) and
34+
// Filter for the catch-all diagnostic, see note above.
35+
not this.getFile().getAbsolutePath() = ""
36+
}
37+
}
38+
39+
private newtype TExtractionError =
40+
TReportableError(ReportableError err) or
41+
TCompilationFailed(Compilation c, File f) {
42+
f = c.getAFileCompiled() and not c.normalTermination()
43+
} or
44+
// Show the catch-all diagnostic (see note above) only if we haven't seen any other error-level diagnostic
45+
// for that compilation
46+
TUnknownError(CompilerError err) {
47+
not exists(ReportableError e | e.getCompilation() = err.getCompilation())
48+
}
49+
50+
/**
51+
* Superclass for the extraction error hierarchy.
52+
*/
53+
class ExtractionError extends TExtractionError {
54+
/** Gets the string representation of the error. */
55+
string toString() { none() }
56+
57+
/** Gets the error message for this error. */
58+
string getErrorMessage() { none() }
59+
60+
/** Gets the file this error occured in. */
61+
File getFile() { none() }
62+
63+
/** Gets the location this error occured in. */
64+
Location getLocation() { none() }
65+
66+
/** Gets the SARIF severity of this error. */
67+
int getSeverity() {
68+
// Unfortunately, we can't distinguish between errors and fatal errors in SARIF,
69+
// so all errors have severity 2.
70+
result = 2
71+
}
72+
}
73+
74+
/**
75+
* An unrecoverable extraction error, where extraction was unable to finish.
76+
* This can be caused by a multitude of reasons, for example:
77+
* - hitting a frontend assertion
78+
* - crashing due to dereferencing an invalid pointer
79+
* - stack overflow
80+
* - out of memory
81+
*/
82+
class ExtractionUnrecoverableError extends ExtractionError, TCompilationFailed {
83+
Compilation c;
84+
File f;
85+
86+
ExtractionUnrecoverableError() { this = TCompilationFailed(c, f) }
87+
88+
override string toString() {
89+
result = "Unrecoverable extraction error while compiling " + f.toString()
90+
}
91+
92+
override string getErrorMessage() { result = "unrecoverable compilation failure." }
93+
94+
override File getFile() { result = f }
95+
96+
override Location getLocation() { result = f.getLocation() }
97+
}
98+
99+
/**
100+
* A recoverable extraction error.
101+
* These are compiler errors from the frontend.
102+
* Upon encountering one of these, we still continue extraction, but the
103+
* database will be incomplete for that file.
104+
*/
105+
class ExtractionRecoverableError extends ExtractionError, TReportableError {
106+
ReportableError err;
107+
108+
ExtractionRecoverableError() { this = TReportableError(err) }
109+
110+
override string toString() { result = "Recoverable extraction error: " + err }
111+
112+
override string getErrorMessage() { result = err.getFullMessage() }
113+
114+
override File getFile() { result = err.getFile() }
115+
116+
override Location getLocation() { result = err.getLocation() }
117+
}
118+
119+
/**
120+
* An unknown error happened during extraction.
121+
* These are only displayed if we know that we encountered an error during extraction,
122+
* but, for some reason, failed to emit a proper diagnostic with location information
123+
* and error message.
124+
*/
125+
class ExtractionUnknownError extends ExtractionError, TUnknownError {
126+
CompilerError err;
127+
128+
ExtractionUnknownError() { this = TUnknownError(err) }
129+
130+
override string toString() { result = "Unknown extraction error: " + err }
131+
132+
override string getErrorMessage() { result = err.getFullMessage() }
133+
134+
override File getFile() { result = err.getFile() }
135+
136+
override Location getLocation() { result = err.getLocation() }
137+
}

0 commit comments

Comments
 (0)