mirror of
https://github.com/github/codeql.git
synced 2026-04-25 16:55:19 +02:00
Merge branch 'main' into rust-cleartext-transmission
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -409,6 +409,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argfile",
|
||||
"chalk-ir",
|
||||
"chrono",
|
||||
"clap",
|
||||
"codeql-extractor",
|
||||
@@ -422,6 +423,7 @@ dependencies = [
|
||||
"ra_ap_hir",
|
||||
"ra_ap_hir_def",
|
||||
"ra_ap_hir_expand",
|
||||
"ra_ap_hir_ty",
|
||||
"ra_ap_ide_db",
|
||||
"ra_ap_intern",
|
||||
"ra_ap_load-cargo",
|
||||
|
||||
@@ -73,6 +73,7 @@ use_repo(
|
||||
tree_sitter_extractors_deps,
|
||||
"vendor_ts__anyhow-1.0.96",
|
||||
"vendor_ts__argfile-0.2.1",
|
||||
"vendor_ts__chalk-ir-0.99.0",
|
||||
"vendor_ts__chrono-0.4.39",
|
||||
"vendor_ts__clap-4.5.31",
|
||||
"vendor_ts__dunce-1.0.5",
|
||||
@@ -94,6 +95,7 @@ use_repo(
|
||||
"vendor_ts__ra_ap_hir-0.0.266",
|
||||
"vendor_ts__ra_ap_hir_def-0.0.266",
|
||||
"vendor_ts__ra_ap_hir_expand-0.0.266",
|
||||
"vendor_ts__ra_ap_hir_ty-0.0.266",
|
||||
"vendor_ts__ra_ap_ide_db-0.0.266",
|
||||
"vendor_ts__ra_ap_intern-0.0.266",
|
||||
"vendor_ts__ra_ap_load-cargo-0.0.266",
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
- description: Security-and-quality queries for GitHub Actions
|
||||
- import: codeql-suites/actions-security-extended.qls
|
||||
- queries: .
|
||||
- apply: security-and-quality-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
|
||||
@@ -1,2 +1,4 @@
|
||||
- description: Extended and experimental security queries for GitHub Actions
|
||||
- import: codeql-suites/actions-code-scanning.qls
|
||||
- queries: .
|
||||
- apply: security-experimental-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
|
||||
@@ -119,9 +119,14 @@ class ConstantMatchingCondition extends ConstantCondition {
|
||||
}
|
||||
|
||||
override predicate isWhiteListed() {
|
||||
exists(SwitchExpr se, int i |
|
||||
se.getCase(i).getPattern() = this.(DiscardExpr) and
|
||||
exists(Switch se, Case c, int i |
|
||||
c = se.getCase(i) and
|
||||
c.getPattern() = this.(DiscardExpr)
|
||||
|
|
||||
i > 0
|
||||
or
|
||||
i = 0 and
|
||||
exists(Expr cond | c.getCondition() = cond and not isConstantCondition(cond, true))
|
||||
)
|
||||
or
|
||||
this = any(PositionalPatternExpr ppe).getPattern(_)
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Increase query precision for `cs/constant-condition` and allow the use of discards in switch/case statements and also take the condition (if any) into account.
|
||||
@@ -9,3 +9,4 @@
|
||||
- cs/inefficient-containskey
|
||||
- cs/call-to-object-tostring
|
||||
- cs/local-not-disposed
|
||||
- cs/constant-condition
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace DisposalTests
|
||||
{
|
||||
public class MyType : IDisposable
|
||||
{
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class Class1 : IDisposable
|
||||
{
|
||||
public void DisposesParameter(IDisposable p1, IDisposable p2)
|
||||
{
|
||||
p1.Dispose();
|
||||
}
|
||||
|
||||
public void CapturesDisposable(MyType p1, MyType p2)
|
||||
{
|
||||
field1 = p1;
|
||||
field2 = p2;
|
||||
}
|
||||
|
||||
public void DisposesSelf()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
MyType field1, field2;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
field1.Dispose();
|
||||
}
|
||||
|
||||
public static void Dispose(IDisposable d)
|
||||
{
|
||||
d.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -1,10 +1,11 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Xml;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml;
|
||||
|
||||
class Test
|
||||
{
|
||||
@@ -48,9 +49,9 @@ class Test
|
||||
}
|
||||
|
||||
// BAD: No Dispose call
|
||||
var c1d = new Timer(TimerProc);
|
||||
var fs = new FileStream("", FileMode.CreateNew, FileAccess.Write);
|
||||
new FileStream("", FileMode.CreateNew, FileAccess.Write).Fluent();
|
||||
var c1d = new Timer(TimerProc); // $ Alert
|
||||
var fs = new FileStream("", FileMode.CreateNew, FileAccess.Write); // $ Alert
|
||||
new FileStream("", FileMode.CreateNew, FileAccess.Write).Fluent(); // $ Alert
|
||||
|
||||
// GOOD: Disposed via wrapper
|
||||
fs = new FileStream("", FileMode.CreateNew, FileAccess.Write);
|
||||
@@ -72,13 +73,10 @@ class Test
|
||||
;
|
||||
|
||||
// GOOD: XmlDocument.Load disposes incoming XmlReader (False positive as this is disposed in library code)
|
||||
var xmlReader = XmlReader.Create(new StringReader("xml"), null);
|
||||
var xmlReader = XmlReader.Create(new StringReader("xml"), null); // $ Alert
|
||||
var xmlDoc = new XmlDocument();
|
||||
xmlDoc.Load(xmlReader);
|
||||
|
||||
// GOOD: Passed to a library (False positive as this is disposed in library code).
|
||||
DisposalTests.Class1.Dispose(new StreamWriter("output.txt"));
|
||||
|
||||
// GOOD: Disposed automatically.
|
||||
using var c2 = new Timer(TimerProc);
|
||||
|
||||
@@ -97,6 +95,15 @@ class Test
|
||||
return null;
|
||||
}
|
||||
|
||||
public void M(IHttpClientFactory factory)
|
||||
{
|
||||
// GOOD: Factory tracks and disposes.
|
||||
HttpClient client1 = factory.CreateClient();
|
||||
|
||||
// BAD: No Dispose call
|
||||
var client2 = new HttpClient(); // $ Alert
|
||||
}
|
||||
|
||||
// GOOD: Escapes
|
||||
IDisposable Create() => new Timer(TimerProc);
|
||||
|
||||
@@ -107,6 +114,15 @@ class Test
|
||||
public void Dispose() { }
|
||||
}
|
||||
|
||||
class Bad
|
||||
{
|
||||
long GetLength(string file)
|
||||
{
|
||||
var stream = new FileStream(file, FileMode.Open); // $ Alert
|
||||
return stream.Length;
|
||||
}
|
||||
}
|
||||
|
||||
static class Extensions
|
||||
{
|
||||
public static FileStream Fluent(this FileStream fs) => fs;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
| NoDisposeCallOnLocalIDisposable.cs:51:19:51:38 | object creation of type Timer | Disposable 'Timer' is created but not disposed. |
|
||||
| NoDisposeCallOnLocalIDisposable.cs:52:18:52:73 | object creation of type FileStream | Disposable 'FileStream' is created but not disposed. |
|
||||
| NoDisposeCallOnLocalIDisposable.cs:53:9:53:64 | object creation of type FileStream | Disposable 'FileStream' is created but not disposed. |
|
||||
| NoDisposeCallOnLocalIDisposable.cs:75:25:75:71 | call to method Create | Disposable 'XmlReader' is created but not disposed. |
|
||||
| NoDisposeCallOnLocalIDisposable.cs:75:42:75:64 | object creation of type StringReader | Disposable 'StringReader' is created but not disposed. |
|
||||
| NoDisposeCallOnLocalIDisposable.cs:80:38:80:67 | object creation of type StreamWriter | Disposable 'StreamWriter' is created but not disposed. |
|
||||
| NoDisposeCallOnLocalIDisposableBad.cs:8:22:8:56 | object creation of type FileStream | Disposable 'FileStream' is created but not disposed. |
|
||||
| NoDisposeCallOnLocalIDisposable.cs:52:19:52:38 | object creation of type Timer | Disposable 'Timer' is created but not disposed. |
|
||||
| NoDisposeCallOnLocalIDisposable.cs:53:18:53:73 | object creation of type FileStream | Disposable 'FileStream' is created but not disposed. |
|
||||
| NoDisposeCallOnLocalIDisposable.cs:54:9:54:64 | object creation of type FileStream | Disposable 'FileStream' is created but not disposed. |
|
||||
| NoDisposeCallOnLocalIDisposable.cs:76:25:76:71 | call to method Create | Disposable 'XmlReader' is created but not disposed. |
|
||||
| NoDisposeCallOnLocalIDisposable.cs:76:42:76:64 | object creation of type StringReader | Disposable 'StringReader' is created but not disposed. |
|
||||
| NoDisposeCallOnLocalIDisposable.cs:104:23:104:38 | object creation of type HttpClient | Disposable 'HttpClient' is created but not disposed. |
|
||||
| NoDisposeCallOnLocalIDisposable.cs:121:22:121:56 | object creation of type FileStream | Disposable 'FileStream' is created but not disposed. |
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
API Abuse/NoDisposeCallOnLocalIDisposable.ql
|
||||
query: API Abuse/NoDisposeCallOnLocalIDisposable.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
class Bad
|
||||
{
|
||||
long GetLength(string file)
|
||||
{
|
||||
var stream = new FileStream(file, FileMode.Open);
|
||||
return stream.Length;
|
||||
}
|
||||
}
|
||||
@@ -1 +1,2 @@
|
||||
semmle-extractor-options: /r:System.Private.Xml.dll /r:System.IO.Compression.dll
|
||||
semmle-extractor-options: /nostdlib /noconfig
|
||||
semmle-extractor-options: --load-sources-from-project:${testdir}/../../../resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.App.csproj
|
||||
|
||||
@@ -35,18 +35,18 @@ class ConstantNullness
|
||||
{
|
||||
void M1(int i)
|
||||
{
|
||||
var j = ((string)null)?.Length; // BAD
|
||||
var s = ((int?)i)?.ToString(); // BAD
|
||||
var j = ((string)null)?.Length; // $ Alert
|
||||
var s = ((int?)i)?.ToString(); // $ Alert
|
||||
var k = s?.Length; // GOOD
|
||||
k = s?.ToLower()?.Length; // GOOD
|
||||
}
|
||||
|
||||
void M2(int i)
|
||||
{
|
||||
var j = (int?)null ?? 0; // BAD
|
||||
var s = "" ?? "a"; // BAD
|
||||
j = (int?)i ?? 1; // BAD
|
||||
s = ""?.CommaJoinWith(s); // BAD
|
||||
var j = (int?)null ?? 0; // $ Alert
|
||||
var s = "" ?? "a"; // $ Alert
|
||||
j = (int?)i ?? 1; // $ Alert
|
||||
s = ""?.CommaJoinWith(s); // $ Alert
|
||||
s = s ?? ""; // GOOD
|
||||
s = (i == 0 ? s : null) ?? s; // GOOD
|
||||
var k = (i == 0 ? s : null)?.Length; // GOOD
|
||||
@@ -59,9 +59,9 @@ class ConstantMatching
|
||||
{
|
||||
switch (1 + 2)
|
||||
{
|
||||
case 2: // BAD
|
||||
case 2: // $ Alert
|
||||
break;
|
||||
case 3: // BAD
|
||||
case 3: // $ Alert
|
||||
break;
|
||||
case int _: // GOOD
|
||||
break;
|
||||
@@ -72,7 +72,7 @@ class ConstantMatching
|
||||
{
|
||||
switch ((object)s)
|
||||
{
|
||||
case int _: // BAD
|
||||
case int _: // $ Alert
|
||||
break;
|
||||
case "": // GOOD
|
||||
break;
|
||||
@@ -92,7 +92,7 @@ class ConstantMatching
|
||||
{
|
||||
return o switch
|
||||
{
|
||||
_ => o.ToString() // BAD
|
||||
_ => o.ToString() // $ Alert
|
||||
};
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ class ConstantMatching
|
||||
return;
|
||||
if (!b2)
|
||||
return;
|
||||
if (b1 && b2) // BAD
|
||||
if (b1 && b2) // $ Alert
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -124,6 +124,35 @@ class ConstantMatching
|
||||
_ => "" // GOOD
|
||||
};
|
||||
}
|
||||
|
||||
string M8(int i)
|
||||
{
|
||||
return i switch
|
||||
{
|
||||
_ when i % 2 == 0 => "even", // GOOD
|
||||
_ => "odd" // GOOD
|
||||
};
|
||||
}
|
||||
|
||||
string M9(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case var _: // $ Alert
|
||||
return "even";
|
||||
}
|
||||
}
|
||||
|
||||
string M10(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case var _ when i % 2 == 0: // GOOD
|
||||
return "even";
|
||||
case var _: // GOOD
|
||||
return "odd";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Assertions
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
| ConstantCondition.cs:95:13:95:13 | _ | Pattern always matches. |
|
||||
| ConstantCondition.cs:114:13:114:14 | access to parameter b1 | Condition always evaluates to 'true'. |
|
||||
| ConstantCondition.cs:114:19:114:20 | access to parameter b2 | Condition always evaluates to 'true'. |
|
||||
| ConstantConditionBad.cs:5:16:5:20 | ... > ... | Condition always evaluates to 'false'. |
|
||||
| ConstantCondition.cs:141:22:141:22 | _ | Pattern always matches. |
|
||||
| ConstantConditionalExpressionCondition.cs:11:22:11:34 | ... == ... | Condition always evaluates to 'true'. |
|
||||
| ConstantConditionalExpressionCondition.cs:12:21:12:25 | false | Condition always evaluates to 'false'. |
|
||||
| ConstantConditionalExpressionCondition.cs:13:21:13:30 | ... == ... | Condition always evaluates to 'true'. |
|
||||
@@ -19,6 +19,7 @@
|
||||
| ConstantIfCondition.cs:11:17:11:29 | ... == ... | Condition always evaluates to 'true'. |
|
||||
| ConstantIfCondition.cs:14:17:14:21 | false | Condition always evaluates to 'false'. |
|
||||
| ConstantIfCondition.cs:17:17:17:26 | ... == ... | Condition always evaluates to 'true'. |
|
||||
| ConstantIfCondition.cs:30:20:30:24 | ... > ... | Condition always evaluates to 'false'. |
|
||||
| ConstantIsNullOrEmpty.cs:10:21:10:54 | call to method IsNullOrEmpty | Condition always evaluates to 'false'. |
|
||||
| ConstantIsNullOrEmpty.cs:46:21:46:46 | call to method IsNullOrEmpty | Condition always evaluates to 'true'. |
|
||||
| ConstantIsNullOrEmpty.cs:50:21:50:44 | call to method IsNullOrEmpty | Condition always evaluates to 'true'. |
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
Bad Practices/Control-Flow/ConstantCondition.ql
|
||||
query: Bad Practices/Control-Flow/ConstantCondition.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
class Bad
|
||||
{
|
||||
public int Max(int a, int b)
|
||||
{
|
||||
return a > a ? a : b;
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,10 @@ namespace ConstantConditionalExpression
|
||||
|
||||
public void Foo()
|
||||
{
|
||||
int i = (ZERO == 1 - 1) ? 0 : 1; // BAD
|
||||
int j = false ? 0 : 1; // BAD
|
||||
int k = " " == " " ? 0 : 1; // BAD
|
||||
int l = (" "[0] == ' ') ? 0 : 1; // BAD: but not flagged
|
||||
int i = (ZERO == 1 - 1) ? 0 : 1; // $ Alert
|
||||
int j = false ? 0 : 1; // $ Alert
|
||||
int k = " " == " " ? 0 : 1; // $ Alert
|
||||
int l = (" "[0] == ' ') ? 0 : 1; // Missing Alert
|
||||
int m = Bar() == 0 ? 0 : 1; // GOOD
|
||||
}
|
||||
|
||||
@@ -21,5 +21,4 @@ namespace ConstantConditionalExpression
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ namespace ConstantForCondition
|
||||
{
|
||||
public void M()
|
||||
{
|
||||
for (int i = 0; false; i++) // GOOD
|
||||
for (int i = 0; false; i++) // $ Alert
|
||||
;
|
||||
for (int i = 0; 0 == 1; i++) // BAD
|
||||
for (int i = 0; 0 == 1; i++) // $ Alert
|
||||
;
|
||||
for (; ; ) // GOOD
|
||||
;
|
||||
|
||||
@@ -8,23 +8,28 @@ namespace ConstantIfCondition
|
||||
|
||||
public void Foo()
|
||||
{
|
||||
if (ZERO == 1 - 1)
|
||||
{ // BAD
|
||||
if (ZERO == 1 - 1) // $ Alert
|
||||
{
|
||||
}
|
||||
if (false)
|
||||
{ // BAD
|
||||
if (false) // $ Alert
|
||||
{
|
||||
}
|
||||
if (" " == " ")
|
||||
{ // BAD
|
||||
if (" " == " ") // $ Alert
|
||||
{
|
||||
}
|
||||
if (" "[0] == ' ')
|
||||
{ // BAD: but not flagged
|
||||
if (" "[0] == ' ') // Missing Alert
|
||||
{
|
||||
}
|
||||
if (Bar() == 0)
|
||||
{ // GOOD
|
||||
if (Bar() == 0) // GOOD
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public int Max(int a, int b)
|
||||
{
|
||||
return a > a ? a : b; // $ Alert
|
||||
}
|
||||
|
||||
public int Bar()
|
||||
{
|
||||
return ZERO;
|
||||
|
||||
@@ -7,17 +7,17 @@ namespace ConstantIsNullOrEmpty
|
||||
static void Main(string[] args)
|
||||
{
|
||||
{
|
||||
if (string.IsNullOrEmpty(nameof(args))) // bad: always false
|
||||
if (string.IsNullOrEmpty(nameof(args))) // $ Alert
|
||||
{
|
||||
}
|
||||
|
||||
string? x = null;
|
||||
if (string.IsNullOrEmpty(x)) // would be nice... bad: always true
|
||||
if (string.IsNullOrEmpty(x)) // Missing Alert (always true)
|
||||
{
|
||||
}
|
||||
|
||||
string y = "";
|
||||
if (string.IsNullOrEmpty(y)) // would be nice... bad: always true
|
||||
if (string.IsNullOrEmpty(y)) // Missing Alert (always true)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -28,12 +28,12 @@ namespace ConstantIsNullOrEmpty
|
||||
}
|
||||
|
||||
string z = " ";
|
||||
if (string.IsNullOrEmpty(z)) // would be nice... bad: always false
|
||||
if (string.IsNullOrEmpty(z)) // Missing Alert (always false)
|
||||
{
|
||||
}
|
||||
|
||||
string a = "a";
|
||||
if (string.IsNullOrEmpty(a)) // would be nice... bad: always false
|
||||
if (string.IsNullOrEmpty(a)) // Missing Alert (always false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -43,18 +43,18 @@ namespace ConstantIsNullOrEmpty
|
||||
{
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(null)) // bad: always true
|
||||
if (string.IsNullOrEmpty(null)) // $ Alert
|
||||
{
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty("")) // bad: always true
|
||||
if (string.IsNullOrEmpty("")) // $ Alert
|
||||
{
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(" ")) // bad: always false
|
||||
if (string.IsNullOrEmpty(" ")) // $ Alert
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ namespace ConstantNullCoalescingLeftHandOperand
|
||||
|
||||
public void Foo()
|
||||
{
|
||||
object i = NULL_OBJECT ?? ""; // BAD
|
||||
object j = null ?? ""; // BAD
|
||||
object i = NULL_OBJECT ?? ""; // $ Alert
|
||||
object j = null ?? ""; // $ Alert
|
||||
object k = Bar() ?? ""; // GOOD
|
||||
}
|
||||
|
||||
|
||||
@@ -9,28 +9,28 @@ namespace ConstantWhileCondition
|
||||
|
||||
public void Foo()
|
||||
{
|
||||
while (ZERO == 1 - 1)
|
||||
{ // BAD
|
||||
while (ZERO == 1 - 1) // $ Alert
|
||||
{
|
||||
break;
|
||||
}
|
||||
while (false)
|
||||
{ // GOOD
|
||||
while (false) // $ Alert
|
||||
{
|
||||
break;
|
||||
}
|
||||
while (true)
|
||||
{ // GOOD
|
||||
while (true) // GOOD
|
||||
{
|
||||
break;
|
||||
}
|
||||
while (" " == " ")
|
||||
{ // BAD
|
||||
while (" " == " ") // $ Alert
|
||||
{
|
||||
break;
|
||||
}
|
||||
while (" "[0] == ' ')
|
||||
{ // BAD: but not flagged
|
||||
while (" "[0] == ' ') // Missing Alert
|
||||
{
|
||||
break;
|
||||
}
|
||||
while (Bar() == 0)
|
||||
{ // GOOD
|
||||
while (Bar() == 0) // GOOD
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added support for the `@tanstack/angular-query-experimental` package.
|
||||
* Improved support for the `@angular/common/http` package, detecting outgoing HTTP requests in more cases.
|
||||
7
javascript/ql/lib/ext/tanstack.model.yml
Normal file
7
javascript/ql/lib/ext/tanstack.model.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/javascript-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["@tanstack/angular-query-experimental", "Member[injectQuery]", "Argument[0].ReturnValue.Member[queryFn].ReturnValue", "ReturnValue.Member[data].Awaited", "taint"]
|
||||
- ["@tanstack/angular-query", "Member[injectQuery]", "Argument[0].ReturnValue.Member[queryFn].ReturnValue", "ReturnValue.Member[data].Awaited", "taint"]
|
||||
@@ -190,13 +190,16 @@ module Angular2 {
|
||||
result.hasUnderlyingType("@angular/common/http", "HttpClient")
|
||||
}
|
||||
|
||||
/** Gets a reference to an `HttpClient` object using the API graph. */
|
||||
API::Node httpClientApiNode() { result = API::Node::ofType("@angular/common/http", "HttpClient") }
|
||||
|
||||
private class AngularClientRequest extends ClientRequest::Range, DataFlow::MethodCallNode {
|
||||
int argumentOffset;
|
||||
|
||||
AngularClientRequest() {
|
||||
this = httpClient().getAMethodCall("request") and argumentOffset = 1
|
||||
this = httpClientApiNode().getMember("request").getACall() and argumentOffset = 1
|
||||
or
|
||||
this = httpClient().getAMethodCall() and
|
||||
this = httpClientApiNode().getAMember().getACall() and
|
||||
not this.getMethodName() = "request" and
|
||||
argumentOffset = 0
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#select
|
||||
| test.jsx:27:29:27:32 | data | test.jsx:5:28:5:63 | fetch(" ... ntent") | test.jsx:27:29:27:32 | data | Cross-site scripting vulnerability due to $@. | test.jsx:5:28:5:63 | fetch(" ... ntent") | user-provided value |
|
||||
| test.ts:21:57:21:76 | response.description | test.ts:8:9:8:79 | this.#h ... query') | test.ts:21:57:21:76 | response.description | Cross-site scripting vulnerability due to $@. | test.ts:8:9:8:79 | this.#h ... query') | user-provided value |
|
||||
| test.ts:24:36:24:90 | `<h2>${ ... o}</p>` | test.ts:8:9:8:79 | this.#h ... query') | test.ts:24:36:24:90 | `<h2>${ ... o}</p>` | Cross-site scripting vulnerability due to $@. | test.ts:8:9:8:79 | this.#h ... query') | user-provided value |
|
||||
| testReactRelay.tsx:7:43:7:58 | commentData.text | testReactRelay.tsx:5:23:5:52 | useFrag ... entRef) | testReactRelay.tsx:7:43:7:58 | commentData.text | Cross-site scripting vulnerability due to $@. | testReactRelay.tsx:5:23:5:52 | useFrag ... entRef) | user-provided value |
|
||||
| testReactRelay.tsx:18:48:18:68 | data.co ... 0].text | testReactRelay.tsx:17:16:17:42 | useLazy ... ry, {}) | testReactRelay.tsx:18:48:18:68 | data.co ... 0].text | Cross-site scripting vulnerability due to $@. | testReactRelay.tsx:17:16:17:42 | useLazy ... ry, {}) | user-provided value |
|
||||
| testReactRelay.tsx:28:17:28:67 | usePrel ... r?.name | testReactRelay.tsx:28:17:28:56 | usePrel ... erence) | testReactRelay.tsx:28:17:28:67 | usePrel ... r?.name | Cross-site scripting vulnerability due to $@. | testReactRelay.tsx:28:17:28:56 | usePrel ... erence) | user-provided value |
|
||||
@@ -20,6 +22,15 @@ edges
|
||||
| test.jsx:6:24:6:38 | response.json() | test.jsx:6:18:6:38 | await r ... .json() | provenance | |
|
||||
| test.jsx:7:12:7:15 | data | test.jsx:15:11:17:5 | data | provenance | |
|
||||
| test.jsx:15:11:17:5 | data | test.jsx:27:29:27:32 | data | provenance | |
|
||||
| test.ts:8:9:8:79 | this.#h ... query') | test.ts:20:28:20:35 | response | provenance | |
|
||||
| test.ts:20:28:20:35 | response | test.ts:21:57:21:64 | response | provenance | |
|
||||
| test.ts:20:28:20:35 | response | test.ts:24:43:24:50 | response | provenance | |
|
||||
| test.ts:20:28:20:35 | response | test.ts:24:67:24:74 | response | provenance | |
|
||||
| test.ts:21:57:21:64 | response | test.ts:21:57:21:76 | response.description | provenance | |
|
||||
| test.ts:24:43:24:50 | response | test.ts:24:43:24:55 | response.name | provenance | |
|
||||
| test.ts:24:43:24:55 | response.name | test.ts:24:36:24:90 | `<h2>${ ... o}</p>` | provenance | |
|
||||
| test.ts:24:67:24:74 | response | test.ts:24:67:24:84 | response.owner.bio | provenance | |
|
||||
| test.ts:24:67:24:84 | response.owner.bio | test.ts:24:36:24:90 | `<h2>${ ... o}</p>` | provenance | |
|
||||
| testReactRelay.tsx:5:9:5:52 | commentData | testReactRelay.tsx:7:43:7:53 | commentData | provenance | |
|
||||
| testReactRelay.tsx:5:23:5:52 | useFrag ... entRef) | testReactRelay.tsx:5:9:5:52 | commentData | provenance | |
|
||||
| testReactRelay.tsx:7:43:7:53 | commentData | testReactRelay.tsx:7:43:7:58 | commentData.text | provenance | |
|
||||
@@ -56,6 +67,15 @@ nodes
|
||||
| test.jsx:7:12:7:15 | data | semmle.label | data |
|
||||
| test.jsx:15:11:17:5 | data | semmle.label | data |
|
||||
| test.jsx:27:29:27:32 | data | semmle.label | data |
|
||||
| test.ts:8:9:8:79 | this.#h ... query') | semmle.label | this.#h ... query') |
|
||||
| test.ts:20:28:20:35 | response | semmle.label | response |
|
||||
| test.ts:21:57:21:64 | response | semmle.label | response |
|
||||
| test.ts:21:57:21:76 | response.description | semmle.label | response.description |
|
||||
| test.ts:24:36:24:90 | `<h2>${ ... o}</p>` | semmle.label | `<h2>${ ... o}</p>` |
|
||||
| test.ts:24:43:24:50 | response | semmle.label | response |
|
||||
| test.ts:24:43:24:55 | response.name | semmle.label | response.name |
|
||||
| test.ts:24:67:24:74 | response | semmle.label | response |
|
||||
| test.ts:24:67:24:84 | response.owner.bio | semmle.label | response.owner.bio |
|
||||
| testReactRelay.tsx:5:9:5:52 | commentData | semmle.label | commentData |
|
||||
| testReactRelay.tsx:5:23:5:52 | useFrag ... entRef) | semmle.label | useFrag ... entRef) |
|
||||
| testReactRelay.tsx:7:43:7:53 | commentData | semmle.label | commentData |
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { QueryClient, injectQuery } from '@tanstack/angular-query-experimental'
|
||||
import { HttpClient } from '@angular/common/http'
|
||||
|
||||
class ServiceOrComponent {
|
||||
query = injectQuery(() => ({
|
||||
queryKey: ['repoData'],
|
||||
queryFn: () =>
|
||||
this.#http.get<Response>('https://api.github.com/repos/tanstack/query'), // $ Source
|
||||
}))
|
||||
|
||||
#http: {
|
||||
get: <T>(url: string) => Promise<T>
|
||||
};
|
||||
|
||||
constructor(http: HttpClient) {
|
||||
this.#http = http;
|
||||
}
|
||||
|
||||
displayRepoDetails() {
|
||||
this.query.data.then(response => {
|
||||
document.getElementById('repoInfo').innerHTML = response.description; // $ Alert
|
||||
|
||||
const detailsElement = document.createElement('div');
|
||||
detailsElement.innerHTML = `<h2>${response.name}</h2><p>${response.owner.bio}</p>`; // $ Alert
|
||||
document.body.appendChild(detailsElement);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
interface Response {
|
||||
name: string;
|
||||
description: string;
|
||||
stargazers_count: number;
|
||||
owner: {
|
||||
bio: string;
|
||||
}
|
||||
}
|
||||
24
misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel
generated
vendored
24
misc/bazel/3rdparty/tree_sitter_extractors_deps/BUILD.bazel
generated
vendored
@@ -55,6 +55,18 @@ alias(
|
||||
tags = ["manual"],
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "chalk-ir-0.99.0",
|
||||
actual = "@vendor_ts__chalk-ir-0.98.0//:chalk_ir",
|
||||
tags = ["manual"],
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "chalk-ir",
|
||||
actual = "@vendor_ts__chalk-ir-0.99.0//:chalk_ir",
|
||||
tags = ["manual"],
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "chrono-0.4.39",
|
||||
actual = "@vendor_ts__chrono-0.4.39//:chrono",
|
||||
@@ -307,6 +319,18 @@ alias(
|
||||
tags = ["manual"],
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "ra_ap_hir_ty-0.0.266",
|
||||
actual = "@vendor_ts__ra_ap_hir_ty-0.0.266//:ra_ap_hir_ty",
|
||||
tags = ["manual"],
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "ra_ap_hir_ty",
|
||||
actual = "@vendor_ts__ra_ap_hir_ty-0.0.266//:ra_ap_hir_ty",
|
||||
tags = ["manual"],
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "ra_ap_ide_db-0.0.266",
|
||||
actual = "@vendor_ts__ra_ap_ide_db-0.0.266//:ra_ap_ide_db",
|
||||
|
||||
4
misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl
generated
vendored
4
misc/bazel/3rdparty/tree_sitter_extractors_deps/defs.bzl
generated
vendored
@@ -327,6 +327,7 @@ _NORMAL_DEPENDENCIES = {
|
||||
_COMMON_CONDITION: {
|
||||
"anyhow": Label("@vendor_ts__anyhow-1.0.96//:anyhow"),
|
||||
"argfile": Label("@vendor_ts__argfile-0.2.1//:argfile"),
|
||||
"chalk-ir": Label("@vendor_ts__chalk-ir-0.99.0//:chalk_ir"),
|
||||
"chrono": Label("@vendor_ts__chrono-0.4.39//:chrono"),
|
||||
"clap": Label("@vendor_ts__clap-4.5.31//:clap"),
|
||||
"dunce": Label("@vendor_ts__dunce-1.0.5//:dunce"),
|
||||
@@ -339,6 +340,7 @@ _NORMAL_DEPENDENCIES = {
|
||||
"ra_ap_hir": Label("@vendor_ts__ra_ap_hir-0.0.266//:ra_ap_hir"),
|
||||
"ra_ap_hir_def": Label("@vendor_ts__ra_ap_hir_def-0.0.266//:ra_ap_hir_def"),
|
||||
"ra_ap_hir_expand": Label("@vendor_ts__ra_ap_hir_expand-0.0.266//:ra_ap_hir_expand"),
|
||||
"ra_ap_hir_ty": Label("@vendor_ts__ra_ap_hir_ty-0.0.266//:ra_ap_hir_ty"),
|
||||
"ra_ap_ide_db": Label("@vendor_ts__ra_ap_ide_db-0.0.266//:ra_ap_ide_db"),
|
||||
"ra_ap_intern": Label("@vendor_ts__ra_ap_intern-0.0.266//:ra_ap_intern"),
|
||||
"ra_ap_load-cargo": Label("@vendor_ts__ra_ap_load-cargo-0.0.266//:ra_ap_load_cargo"),
|
||||
@@ -3476,6 +3478,7 @@ def crate_repositories():
|
||||
return [
|
||||
struct(repo = "vendor_ts__anyhow-1.0.96", is_dev_dep = False),
|
||||
struct(repo = "vendor_ts__argfile-0.2.1", is_dev_dep = False),
|
||||
struct(repo = "vendor_ts__chalk-ir-0.99.0", is_dev_dep = False),
|
||||
struct(repo = "vendor_ts__chrono-0.4.39", is_dev_dep = False),
|
||||
struct(repo = "vendor_ts__clap-4.5.31", is_dev_dep = False),
|
||||
struct(repo = "vendor_ts__dunce-1.0.5", is_dev_dep = False),
|
||||
@@ -3497,6 +3500,7 @@ def crate_repositories():
|
||||
struct(repo = "vendor_ts__ra_ap_hir-0.0.266", is_dev_dep = False),
|
||||
struct(repo = "vendor_ts__ra_ap_hir_def-0.0.266", is_dev_dep = False),
|
||||
struct(repo = "vendor_ts__ra_ap_hir_expand-0.0.266", is_dev_dep = False),
|
||||
struct(repo = "vendor_ts__ra_ap_hir_ty-0.0.266", is_dev_dep = False),
|
||||
struct(repo = "vendor_ts__ra_ap_ide_db-0.0.266", is_dev_dep = False),
|
||||
struct(repo = "vendor_ts__ra_ap_intern-0.0.266", is_dev_dep = False),
|
||||
struct(repo = "vendor_ts__ra_ap_load-cargo-0.0.266", is_dev_dep = False),
|
||||
|
||||
@@ -79,6 +79,11 @@ Element getImmediateParent(Element e) {
|
||||
result = unique(Element x | e = Impl::getImmediateChild(x, _, _) | x)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the immediate child indexed at `index`. Indexes are not guaranteed to be contiguous, but are guaranteed to be distinct.
|
||||
*/
|
||||
Element getImmediateChild(Element e, int index) { result = Impl::getImmediateChild(e, index, _) }
|
||||
|
||||
/**
|
||||
* Gets the immediate child indexed at `index`. Indexes are not guaranteed to be contiguous, but are guaranteed to be distinct. `accessor` is bound the member predicate call resulting in the given child.
|
||||
*/
|
||||
@@ -92,3 +97,10 @@ Element getImmediateChildAndAccessor(Element e, int index, string accessor) {
|
||||
Element getChildAndAccessor(Element e, int index, string accessor) {
|
||||
exists(string partialAccessor | result = Impl::getImmediateChild(e, index, partialAccessor).resolve() and accessor = "get" + partialAccessor)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the child indexed at `index`. Indexes are not guaranteed to be contiguous, but are guaranteed to be distinct. `accessor` is bound the member predicate call resulting in the given child.
|
||||
*/
|
||||
Element getChild(Element e, int index) {
|
||||
result = Impl::getImmediateChild(e, index, _).resolve()
|
||||
}
|
||||
|
||||
@@ -203,7 +203,8 @@ class NotBooleanTestVisitor(ASTVisitor):
|
||||
self.nodes = set()
|
||||
|
||||
def visit_MatchLiteralPattern(self, node):
|
||||
# MatchLiteralPatterns _look_ like boolean tests, but are not.
|
||||
# MatchLiteralPatterns _look_ like boolean tests in that they have both a true ("matched")
|
||||
# and false ("didn't match") successor, but are not.
|
||||
# Thus, without this check, we would interpret
|
||||
#
|
||||
# match x:
|
||||
@@ -212,8 +213,7 @@ class NotBooleanTestVisitor(ASTVisitor):
|
||||
#
|
||||
# (and similarly for True) as if it was a boolean test. This would cause the true edge
|
||||
# (leading to pass) to be pruned later on.
|
||||
if isinstance(node.literal, ast.Name) and node.literal.id in ('True', 'False'):
|
||||
self.nodes.add(node.literal)
|
||||
self.nodes.add(node.literal)
|
||||
|
||||
class NonlocalVisitor(ASTVisitor):
|
||||
def __init__(self):
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
|
||||
- `MatchLiteralPattern`s such as `case None: ...` are now never pruned from the extracted source code. This fixes some situations where code was wrongly identified as unreachable.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
|
||||
- Added the methods `getMinArguments` and `getMaxArguments` to the `Function` class. These return the minimum and maximum positional arguments that the given function accepts.
|
||||
@@ -163,6 +163,24 @@ class Function extends Function_, Scope, AstNode {
|
||||
ret.getValue() = result.getNode()
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the minimum number of positional arguments that can be correctly passed to this function. */
|
||||
int getMinPositionalArguments() {
|
||||
result = count(this.getAnArg()) - count(this.getDefinition().getArgs().getADefault())
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum number of positional arguments that can be correctly passed to this function.
|
||||
*
|
||||
* If the function has a `*vararg` parameter, there is no upper limit on the number of positional
|
||||
* arguments that can be passed to the function. In this case, this method returns a very large
|
||||
* number (currently `INT_MAX`, 2147483647, but this may change in the future).
|
||||
*/
|
||||
int getMaxPositionalArguments() {
|
||||
if exists(this.getVararg())
|
||||
then result = 2147483647 // INT_MAX
|
||||
else result = count(this.getAnArg())
|
||||
}
|
||||
}
|
||||
|
||||
/** A def statement. Note that FunctionDef extends Assign as a function definition binds the newly created function */
|
||||
|
||||
@@ -738,21 +738,9 @@ class PythonFunctionValue extends FunctionValue {
|
||||
else result = "function " + this.getQualifiedName()
|
||||
}
|
||||
|
||||
override int minParameters() {
|
||||
exists(Function f |
|
||||
f = this.getScope() and
|
||||
result = count(f.getAnArg()) - count(f.getDefinition().getArgs().getADefault())
|
||||
)
|
||||
}
|
||||
override int minParameters() { result = this.getScope().getMinPositionalArguments() }
|
||||
|
||||
override int maxParameters() {
|
||||
exists(Function f |
|
||||
f = this.getScope() and
|
||||
if exists(f.getVararg())
|
||||
then result = 2147483647 // INT_MAX
|
||||
else result = count(f.getAnArg())
|
||||
)
|
||||
}
|
||||
override int maxParameters() { result = this.getScope().getMaxPositionalArguments() }
|
||||
|
||||
/** Gets a control flow node corresponding to a return statement in this function */
|
||||
ControlFlowNode getAReturnedNode() { result = this.getScope().getAReturnValueFlowNode() }
|
||||
|
||||
@@ -5,8 +5,11 @@
|
||||
<recommendation>
|
||||
|
||||
<p>To guard against SSRF attacks you should avoid putting user-provided input directly
|
||||
into a request URL. Instead, either maintain a list of authorized URLs on the server and choose
|
||||
from that list based on the input provided, or perform proper validation of the input.
|
||||
into a request URL. On the application level, maintain a list of authorized URLs on the server and choose
|
||||
from that list based on the input provided. If that is not possible, one should verify the IP address for all user-controlled
|
||||
requests to ensure they are not private. This requires saving the verified IP address of each domain,
|
||||
then utilizing a custom HTTP adapter to ensure that future requests to that domain use the verified IP address.
|
||||
On the network level, you can segment the vulnerable application into its own LAN or block access to specific devices.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
|
||||
@@ -4,6 +4,3 @@
|
||||
| test.py:21:5:21:38 | For | This statement is unreachable. |
|
||||
| test.py:28:9:28:21 | ExprStmt | This statement is unreachable. |
|
||||
| test.py:84:5:84:21 | ExceptStmt | This statement is unreachable. |
|
||||
| test.py:158:9:159:16 | Case | This statement is unreachable. |
|
||||
| test.py:162:13:162:16 | Pass | This statement is unreachable. |
|
||||
| test.py:167:13:167:16 | Pass | This statement is unreachable. |
|
||||
|
||||
@@ -14,6 +14,7 @@ ra_ap_base_db = "0.0.266"
|
||||
ra_ap_hir = "0.0.266"
|
||||
ra_ap_hir_def = "0.0.266"
|
||||
ra_ap_ide_db = "0.0.266"
|
||||
ra_ap_hir_ty = "0.0.266"
|
||||
ra_ap_hir_expand = "0.0.266"
|
||||
ra_ap_load-cargo = "0.0.266"
|
||||
ra_ap_paths = "0.0.266"
|
||||
@@ -39,3 +40,4 @@ toml = "0.8.20"
|
||||
tracing = "0.1.41"
|
||||
tracing-flame = "0.2.0"
|
||||
tracing-subscriber = "0.3.19"
|
||||
chalk-ir = "0.99.0"
|
||||
|
||||
1311
rust/extractor/src/crate_graph.rs
Normal file
1311
rust/extractor/src/crate_graph.rs
Normal file
File diff suppressed because it is too large
Load Diff
@@ -83,6 +83,7 @@ pub enum ExtractionStepKind {
|
||||
LoadSource,
|
||||
Parse,
|
||||
Extract,
|
||||
CrateGraph,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
@@ -128,6 +129,10 @@ impl ExtractionStep {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn crate_graph(start: Instant) -> Self {
|
||||
Self::new(start, ExtractionStepKind::CrateGraph, None)
|
||||
}
|
||||
|
||||
pub fn load_source(start: Instant, target: &Path) -> Self {
|
||||
Self::new(
|
||||
start,
|
||||
|
||||
2
rust/extractor/src/generated/.generated.list
generated
2
rust/extractor/src/generated/.generated.list
generated
@@ -1,2 +1,2 @@
|
||||
mod.rs 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7
|
||||
top.rs da0f43b99d3a173520048275597e2b052a7351f6fcb2ad5fc912257976742bb7 da0f43b99d3a173520048275597e2b052a7351f6fcb2ad5fc912257976742bb7
|
||||
top.rs 4b7dee6ebdbb2f8bd2f387cbb71e0481475de0a94c0baaac4699f19551256d65 4b7dee6ebdbb2f8bd2f387cbb71e0481475de0a94c0baaac4699f19551256d65
|
||||
|
||||
48
rust/extractor/src/generated/top.rs
generated
48
rust/extractor/src/generated/top.rs
generated
@@ -22,6 +22,54 @@ impl trap::TrapClass for Element {
|
||||
fn class_name() -> &'static str { "Element" }
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Crate {
|
||||
pub id: trap::TrapId<Crate>,
|
||||
pub name: Option<String>,
|
||||
pub version: Option<String>,
|
||||
pub module: Option<trap::Label<Module>>,
|
||||
pub cfg_options: Vec<String>,
|
||||
pub dependencies: Vec<trap::Label<Crate>>,
|
||||
}
|
||||
|
||||
impl trap::TrapEntry for Crate {
|
||||
fn extract_id(&mut self) -> trap::TrapId<Self> {
|
||||
std::mem::replace(&mut self.id, trap::TrapId::Star)
|
||||
}
|
||||
|
||||
fn emit(self, id: trap::Label<Self>, out: &mut trap::Writer) {
|
||||
out.add_tuple("crates", vec![id.into()]);
|
||||
if let Some(v) = self.name {
|
||||
out.add_tuple("crate_names", vec![id.into(), v.into()]);
|
||||
}
|
||||
if let Some(v) = self.version {
|
||||
out.add_tuple("crate_versions", vec![id.into(), v.into()]);
|
||||
}
|
||||
if let Some(v) = self.module {
|
||||
out.add_tuple("crate_modules", vec![id.into(), v.into()]);
|
||||
}
|
||||
for (i, v) in self.cfg_options.into_iter().enumerate() {
|
||||
out.add_tuple("crate_cfg_options", vec![id.into(), i.into(), v.into()]);
|
||||
}
|
||||
for (i, v) in self.dependencies.into_iter().enumerate() {
|
||||
out.add_tuple("crate_dependencies", vec![id.into(), i.into(), v.into()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl trap::TrapClass for Crate {
|
||||
fn class_name() -> &'static str { "Crate" }
|
||||
}
|
||||
|
||||
impl From<trap::Label<Crate>> for trap::Label<Element> {
|
||||
fn from(value: trap::Label<Crate>) -> Self {
|
||||
// SAFETY: this is safe because in the dbscheme Crate is a subclass of Element
|
||||
unsafe {
|
||||
Self::from_untyped(value.as_untyped())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ExtractorStep {
|
||||
pub id: trap::TrapId<ExtractorStep>,
|
||||
|
||||
@@ -23,6 +23,7 @@ use tracing_subscriber::util::SubscriberInitExt;
|
||||
|
||||
mod archive;
|
||||
mod config;
|
||||
mod crate_graph;
|
||||
mod diagnostics;
|
||||
pub mod generated;
|
||||
mod qltest;
|
||||
@@ -255,6 +256,11 @@ fn main() -> anyhow::Result<()> {
|
||||
if let Some((ref db, ref vfs)) =
|
||||
extractor.load_manifest(manifest, &cargo_config, &load_cargo_config)
|
||||
{
|
||||
let before_crate_graph = Instant::now();
|
||||
crate_graph::extract_crate_graph(extractor.traps, db, vfs);
|
||||
extractor
|
||||
.steps
|
||||
.push(ExtractionStep::crate_graph(before_crate_graph));
|
||||
let semantics = Semantics::new(db);
|
||||
for file in files {
|
||||
match extractor.load_source(file, &semantics, vfs) {
|
||||
|
||||
@@ -74,7 +74,7 @@ macro_rules! trap_key {
|
||||
$(
|
||||
key.push_str(&$x.as_key_part());
|
||||
)*
|
||||
$crate::TrapId::Key(key)
|
||||
trap::TrapId::Key(key)
|
||||
}};
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ impl<T: TrapClass> From<Label<T>> for trap::Arg {
|
||||
}
|
||||
|
||||
pub struct TrapFile {
|
||||
path: PathBuf,
|
||||
pub path: PathBuf,
|
||||
pub writer: Writer,
|
||||
compression: Compression,
|
||||
}
|
||||
@@ -171,6 +171,26 @@ impl TrapFile {
|
||||
);
|
||||
}
|
||||
|
||||
pub fn emit_file_only_location<E: TrapClass>(
|
||||
&mut self,
|
||||
file_label: Label<generated::File>,
|
||||
entity_label: Label<E>,
|
||||
) {
|
||||
let location_label = extractor::location_label(
|
||||
&mut self.writer,
|
||||
trap::Location {
|
||||
file_label: file_label.as_untyped(),
|
||||
start_line: 0,
|
||||
start_column: 0,
|
||||
end_line: 0,
|
||||
end_column: 0,
|
||||
},
|
||||
);
|
||||
self.writer.add_tuple(
|
||||
"locatable_locations",
|
||||
vec![entity_label.into(), location_label.into()],
|
||||
);
|
||||
}
|
||||
pub fn emit_diagnostic(
|
||||
&mut self,
|
||||
severity: DiagnosticSeverity,
|
||||
|
||||
14
rust/ql/.generated.list
generated
14
rust/ql/.generated.list
generated
@@ -43,6 +43,7 @@ lib/codeql/rust/elements/ConstArg.qll f37b34417503bbd2f3ce09b3211d8fa71f6a954970
|
||||
lib/codeql/rust/elements/ConstBlockPat.qll a25f42b84dbeb33e10955735ef53b8bb7e3258522d6d1a9068f19adaf1af89d9 eeb816d2b54db77a1e7bb70e90b68d040a0cd44e9d44455a223311c3615c5e6e
|
||||
lib/codeql/rust/elements/ConstParam.qll 248db1e3abef6943326c42478a15f148f8cdaa25649ef5578064b15924c53351 28babba3aea28a65c3fe3b3db6cb9c86f70d7391e9d6ef9188eb2e4513072f9f
|
||||
lib/codeql/rust/elements/ContinueExpr.qll 9f27c5d5c819ad0ebc5bd10967ba8d33a9dc95b9aae278fcfb1fcf9216bda79c 0dc061445a6b89854fdce92aaf022fdc76b724511a50bb777496ce75c9ecb262
|
||||
lib/codeql/rust/elements/Crate.qll 67a3b953a04244e2fcebe7a18be13bc7fdb8781669819e473823a9168f3f5412 aef65281efbc8c7e7b3747693626718ca25b3d9a90aa42221de00998eca44efe
|
||||
lib/codeql/rust/elements/DynTraitTypeRepr.qll 5953263ec1e77613170c13b5259b22a71c206a7e08841d2fa1a0b373b4014483 d4380c6cc460687dcd8598df27cad954ef4f508f1117a82460d15d295a7b64ab
|
||||
lib/codeql/rust/elements/Element.qll 0b62d139fef54ed2cf2e2334806aa9bfbc036c9c2085d558f15a42cc3fa84c48 24b999b93df79383ef27ede46e38da752868c88a07fe35fcff5d526684ba7294
|
||||
lib/codeql/rust/elements/Enum.qll 2f122b042519d55e221fceac72fce24b30d4caf1947b25e9b68ee4a2095deb11 83a47445145e4fda8c3631db602a42dbb7a431f259eddf5c09dccd86f6abdd0e
|
||||
@@ -254,6 +255,7 @@ lib/codeql/rust/elements/internal/ConstImpl.qll 7aac2b441a41f21b7d788e3eb042554f
|
||||
lib/codeql/rust/elements/internal/ConstParamConstructor.qll f6645f952aac87c7e00e5e9661275312a1df47172088b4de6b5a253d5c4ed048 eda737470a7b89cf6a02715c9147d074041d6d00fd50d5b2d70266add6e4b571
|
||||
lib/codeql/rust/elements/internal/ConstParamImpl.qll 909d85d857dfb973cd8e148744d3a88506d113d193d35ab0243be745d004ad45 c9e18170c5b4e4d5fca9f175bb139a248055b608ceafdd90c7182d06d67c3cba
|
||||
lib/codeql/rust/elements/internal/ContinueExprConstructor.qll cd93f1b35ccdb031d7e8deba92f6a76187f6009c454f3ea07e89ba459de57ca6 6f658e7d580c4c9068b01d6dd6f72888b8800860668a6653f8c3b27dc9996935
|
||||
lib/codeql/rust/elements/internal/CrateConstructor.qll 2a3710ed6ff4ffdbc773ac16e2cf176415be8908e1d59fd0702bdeddbae096f4 f75a069b0ef71e54089001eb3a34b8a9e4ce8e4f65ffa71b669b38cf86e0af40
|
||||
lib/codeql/rust/elements/internal/DynTraitTypeReprConstructor.qll 6964e6c80fb7f5e283c1d15562cef18ed097452b7fcbc04eff780c7646675c7a f03c4830bf1b958fdfb6563136fa21c911b2e41ce1d1caee14ec572c7232866d
|
||||
lib/codeql/rust/elements/internal/DynTraitTypeReprImpl.qll fa2dc41b441c2e8d663644ca8ae53f473ac54b3c977490b5173787cffe4a62b1 118945a547627b639574c5f8e58bf7dbf5f3882c6d74ebf363c28c8fb88799d3
|
||||
lib/codeql/rust/elements/internal/EnumConstructor.qll eca1a13937faacb1db50e4cf69d175f992f2204a5aaed9144bb6f3cb63814ac5 1bafba78b2729fdb052a25a1ba3f4f70871564aa4df632b4a1d467858a437924
|
||||
@@ -501,6 +503,7 @@ lib/codeql/rust/elements/internal/generated/ConstArg.qll e2451cac6ee464f5b64883d
|
||||
lib/codeql/rust/elements/internal/generated/ConstBlockPat.qll 7526d83ee9565d74776f42db58b1a2efff6fb324cfc7137f51f2206fee815d79 0ab3c22908ff790e7092e576a5df3837db33c32a7922a513a0f5e495729c1ac5
|
||||
lib/codeql/rust/elements/internal/generated/ConstParam.qll 310342603959a4d521418caec45b585b97e3a5bf79368769c7150f52596a7266 a5dd92f0b24d7dbdaea2daedba3c8d5f700ec7d3ace81ca368600da2ad610082
|
||||
lib/codeql/rust/elements/internal/generated/ContinueExpr.qll e2010feb14fb6edeb83a991d9357e50edb770172ddfde2e8670b0d3e68169f28 48d09d661e1443002f6d22b8710e22c9c36d9daa9cde09c6366a61e960d717cb
|
||||
lib/codeql/rust/elements/internal/generated/Crate.qll 6d28f07d4ddaf077119590a007a8cfad0c86cf0efabbde689fb4092577b883df d43013163916aa83f281314a72d02d7566e1f505aa36cfd8060a760b06b02683
|
||||
lib/codeql/rust/elements/internal/generated/DynTraitTypeRepr.qll a9d540717af1f00dbea1c683fd6b846cddfb2968c7f3e021863276f123337787 1972efb9bca7aae9a9708ca6dcf398e5e8c6d2416a07d525dba1649b80fbe4d1
|
||||
lib/codeql/rust/elements/internal/generated/Element.qll fb483b636180c699181c8aff83bc471b2c416206694f7028c671015918547663 542d1b9ae80c997974c94db3655887186df3921a8fa3f565eaf292dcfdac3c4c
|
||||
lib/codeql/rust/elements/internal/generated/Enum.qll 4f4cbc9cd758c20d476bc767b916c62ba434d1750067d0ffb63e0821bb95ec86 3da735d54022add50cec0217bbf8ec4cf29b47f4851ee327628bcdd6454989d0
|
||||
@@ -574,7 +577,7 @@ lib/codeql/rust/elements/internal/generated/ParamList.qll c808c9d84dd7800573832b
|
||||
lib/codeql/rust/elements/internal/generated/ParenExpr.qll bc0731505bfe88516205ec360582a4222d2681d11342c93e15258590ddee82f2 d4bd6e0c80cf1d63746c88d4bcb3a01d4c75732e5da09e3ebd9437ced227fb60
|
||||
lib/codeql/rust/elements/internal/generated/ParenPat.qll 4f168ef5d5bb87a903251cc31b2e44a759b099ec69c90af31783fbb15778c940 0e34f94a45a13396fd57d94c245dc64d1adde2ab0e22b56946f7e94c04e297fc
|
||||
lib/codeql/rust/elements/internal/generated/ParenTypeRepr.qll 40ab5c592e7699c621787793743e33988de71ff42ca27599f5ab3ddb70e3f7d8 12c0a6eed2202ee3e892f61da3b3ce77ac3190854cdf3097e8d2be98aa3cb91d
|
||||
lib/codeql/rust/elements/internal/generated/ParentChild.qll 2992505ffc3279d58f2d03e89ec0f7d23aedebb3c3baf990bfbda894a6cc10e8 2f6b721e8244b444b47d41c2303fea166debee208544389c4dd9f2be0d62fe43
|
||||
lib/codeql/rust/elements/internal/generated/ParentChild.qll eec4e7672ef5f07752044348d45882f0a849b295dfb17169e910ed0bfca3c162 29a9cc9b2870b1c6240cc53a9a70c4623381219a8f88ea1656b6828d16ef51c7
|
||||
lib/codeql/rust/elements/internal/generated/ParenthesizedArgList.qll c5fa328ea60d3a3333d7c7bb3480969c1873166c7ac8ebb9d0afad7a8099d1a8 2dbbb6200d96f7db7dea4a55bdeab8d67b14d39a43e0bd54ada019f7e466f163
|
||||
lib/codeql/rust/elements/internal/generated/Pat.qll 3605ac062be2f294ee73336e9669027b8b655f4ad55660e1eab35266275154ee 7f9400db2884d336dd1d21df2a8093759c2a110be9bf6482ce8e80ae0fd74ed4
|
||||
lib/codeql/rust/elements/internal/generated/Path.qll 8e47e91aff3f8c60f1ee8cb3887b8e4936c38e4665d052f2c92a939a969aac29 2c28beb89cabd7c7c91a5bc65c874f414cb96bbefde37b25811b61089a8a0053
|
||||
@@ -589,7 +592,7 @@ lib/codeql/rust/elements/internal/generated/PtrTypeRepr.qll 51d1e9e683fc79dddbff
|
||||
lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll e5b8e69519012bbaae29dcb82d53f7f7ecce368c0358ec27ef6180b228a0057f e5b8e69519012bbaae29dcb82d53f7f7ecce368c0358ec27ef6180b228a0057f
|
||||
lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9
|
||||
lib/codeql/rust/elements/internal/generated/RangePat.qll 80826a6a6868a803aa2372e31c52a03e1811a3f1f2abdb469f91ca0bfdd9ecb6 34ee1e208c1690cba505dff2c588837c0cd91e185e2a87d1fe673191962276a9
|
||||
lib/codeql/rust/elements/internal/generated/Raw.qll cfbf960b83fc7f659214a48ced60001366410322a116de255678dec9d765d8dd c0d1ee182ccb916dedf33a272fb37ac394e0fac95ef4fadb8a93c7db8d11feb5
|
||||
lib/codeql/rust/elements/internal/generated/Raw.qll 4b60a7c36b770156d3710d811247bc1607c851a926d1546271f166af5b68c01f f65ba77cb2135b4a0d37d8c3e19e49f368426b14c7e48730f3fb9e65f9d7b9c5
|
||||
lib/codeql/rust/elements/internal/generated/RecordExpr.qll 2131b2cb336caa76170082e69776011bf02576bbfdd34ba68ca84af24209250a 39a2e3ec32352b594c43cc1295e0e8b3f9808173322d3d73cb7d48ef969d5565
|
||||
lib/codeql/rust/elements/internal/generated/RecordExprField.qll 7e9f8663d3b74ebbc9603b10c9912f082febba6bd73d344b100bbd3edf837802 fbe6b578e7fd5d5a6f21bbb8c388957ab7210a6a249ec71510a50fb35b319ea1
|
||||
lib/codeql/rust/elements/internal/generated/RecordExprFieldList.qll 179a97211fe7aa6265085d4d54115cdbc0e1cd7c9b2135591e8f36d6432f13d3 dd44bbbc1e83a1ed3a587afb729d7debf7aeb7b63245de181726af13090e50c0
|
||||
@@ -615,8 +618,8 @@ lib/codeql/rust/elements/internal/generated/Static.qll 0b336767104d2b852b9acd234
|
||||
lib/codeql/rust/elements/internal/generated/Stmt.qll 8473ff532dd5cc9d7decaddcd174b94d610f6ca0aec8e473cc051dad9f3db917 6ef7d2b5237c2dbdcacbf7d8b39109d4dc100229f2b28b5c9e3e4fbf673ba72b
|
||||
lib/codeql/rust/elements/internal/generated/StmtList.qll a667193e32341e17400867c6e359878c4e645ef9f5f4d97676afc0283a33a026 a320ed678ee359302e2fc1b70a9476705cd616fcfa44a499d32f0c7715627f73
|
||||
lib/codeql/rust/elements/internal/generated/Struct.qll 4d57f0db12dc7ad3e31e750a24172ef1505406b4dab16386af0674bd18bf8f4b 1a73c83df926b996f629316f74c61ea775be04532ab61b56af904223354f033e
|
||||
lib/codeql/rust/elements/internal/generated/Synth.qll a00cdbb2ba5213976055f2339ae8bb01a42fdae22c355f171aa2ddfbbd7ec200 f49fbdcc7ab69258e3a86039a95d17b069e64922cc6a32a872dc696067b65507
|
||||
lib/codeql/rust/elements/internal/generated/SynthConstructors.qll 0d7929ad8c03e683500c64d1cfff73da518be9836a5d32e44d2f311fb4ae1b96 0d7929ad8c03e683500c64d1cfff73da518be9836a5d32e44d2f311fb4ae1b96
|
||||
lib/codeql/rust/elements/internal/generated/Synth.qll 554d5979ddb7afa42aa4d373cafcffd086e017104130f4a661264ee1c7b54653 059fa863ddab905050e1bbb4669722a14721b40b193bb91f1642da9a36d09018
|
||||
lib/codeql/rust/elements/internal/generated/SynthConstructors.qll f6321ef2a74bb3c869cb3d3fc7753ec90d03bf2c620597f7f1fea636309a3575 f6321ef2a74bb3c869cb3d3fc7753ec90d03bf2c620597f7f1fea636309a3575
|
||||
lib/codeql/rust/elements/internal/generated/Token.qll 77a91a25ca5669703cf3a4353b591cef4d72caa6b0b9db07bb9e005d69c848d1 2fdffc4882ed3a6ca9ac6d1fb5f1ac5a471ca703e2ffdc642885fa558d6e373b
|
||||
lib/codeql/rust/elements/internal/generated/TokenTree.qll 8577c2b097c1be2f0f7daa5acfcf146f78674a424d99563e08a84dd3e6d91b46 d2f30764e84dbfc0a6a5d3d8a5f935cd432413688cb32da9c94e420fbc10665c
|
||||
lib/codeql/rust/elements/internal/generated/Trait.qll 8fa41b50fa0f68333534f2b66bb4ec8e103ff09ac8fa5c2cc64bc04beafec205 ce1c9aa6d0e2f05d28aab8e1165c3b9fb8e24681ade0cf6a9df2e8617abeae7e
|
||||
@@ -652,7 +655,7 @@ lib/codeql/rust/elements/internal/generated/WhileExpr.qll 7edf1f23fbf953a2baabcd
|
||||
lib/codeql/rust/elements/internal/generated/WildcardPat.qll d74b70b57a0a66bfae017a329352a5b27a6b9e73dd5521d627f680e810c6c59e 4b913b548ba27ff3c82fcd32cf996ff329cb57d176d3bebd0fcef394486ea499
|
||||
lib/codeql/rust/elements/internal/generated/YeetExpr.qll cac328200872a35337b4bcb15c851afb4743f82c080f9738d295571eb01d7392 94af734eea08129b587fed849b643e7572800e8330c0b57d727d41abda47930b
|
||||
lib/codeql/rust/elements/internal/generated/YieldExpr.qll 37e5f0c1e373a22bbc53d8b7f2c0e1f476e5be5080b8437c5e964f4e83fad79a 4a9a68643401637bf48e5c2b2f74a6bf0ddcb4ff76f6bffb61d436b685621e85
|
||||
lib/codeql/rust/elements.qll fd66034a77b69f4741ca1488e8d04879da800bfa8d55492747c2b49d71a8067b fd66034a77b69f4741ca1488e8d04879da800bfa8d55492747c2b49d71a8067b
|
||||
lib/codeql/rust/elements.qll 041993d344a4c10b301ac607075254175f1a1f927328de4f40f4df0260d0dece 041993d344a4c10b301ac607075254175f1a1f927328de4f40f4df0260d0dece
|
||||
test/extractor-tests/generated/Abi/Abi.ql 7f6e7dc4af86eca3ebdc79b10373988cd0871bd78b51997d3cffd969105e5fdd 2f936b6ca005c6157c755121584410c03e4a3949c23bee302fbe05ee10ce118f
|
||||
test/extractor-tests/generated/Abi/Abi_getAbiString.ql a496762fcec5a0887b87023bbf93e9b650f02e20113e25c44d6e4281ae8f5335 14109c7ce11ba25e3cd6e7f1b3fcb4cb00622f2a4eac91bfe43145c5f366bc52
|
||||
test/extractor-tests/generated/ArgList/ArgList.ql e412927756e72165d0e7c5c9bd3fca89d08197bbf760db8fb7683c64bb2229bc 043dba8506946fbb87753e22c387987d7eded6ddb963aa067f9e60ef9024d684
|
||||
@@ -750,6 +753,7 @@ test/extractor-tests/generated/ConstParam/ConstParam_getTypeRepr.ql f25a4695e06a
|
||||
test/extractor-tests/generated/ContinueExpr/ContinueExpr.ql 971ccb238aec663855745fa2669d5f8973a4e6c76bacdf0deaf23522ec1cf80c 4e3ceb4c4cd833ad8311bb02e5cda18163082e341cd8a3def60734a53cca8929
|
||||
test/extractor-tests/generated/ContinueExpr/ContinueExpr_getAttr.ql acb261869d3b3c65e364e7b6fbd7afdf5305806d4417b05044beed9a81e66ea4 af35ce0aee87ddc7a0cd34be4a480c619940d036d5cecce0e4e1fcd75b7c553e
|
||||
test/extractor-tests/generated/ContinueExpr/ContinueExpr_getLifetime.ql 39dae9872d92fa9b15343c93da545c2b0e15b4f27f2296c200fd4611b68858d5 52a209022e3b83260b4ef5513ffbcc1ca1f7c21bad2c721a0d3698793d2161d2
|
||||
test/extractor-tests/generated/Crate/MISSING_SOURCE.txt b6cf5771fdbbe981aeb3f443ec7a40517b6e99ffc9817fd8872c2e344240dae1 b6cf5771fdbbe981aeb3f443ec7a40517b6e99ffc9817fd8872c2e344240dae1
|
||||
test/extractor-tests/generated/DynTraitTypeRepr/DynTraitTypeRepr.ql 513d64b564f359e1022ae6f3d6d4a8ad637f595f01f29a6c2a167d1c2e8f1f99 0c7a7af6ee1005126b9ab77b2a7732821f85f1d2d426312c98206cbbedc19bb2
|
||||
test/extractor-tests/generated/DynTraitTypeRepr/DynTraitTypeRepr_getTypeBoundList.ql b20720ff0b147d55cea6f2de44d5bf297e79991eaf103938ccd7ab9d129e9656 eb8c9db2581cea00c29d7772de0b0a125be02c37092217a419f1a2b6a9711a6c
|
||||
test/extractor-tests/generated/Enum/Enum.ql ed518d828d8e2e4790849284de1d0d5e728dbc2fe5e9f187e8ebfa2d503efd5a 7092b963eb133371e1cbc09d45f8c2308d7093523140b351d67073a8d258643e
|
||||
|
||||
4
rust/ql/.gitattributes
generated
vendored
4
rust/ql/.gitattributes
generated
vendored
@@ -45,6 +45,7 @@
|
||||
/lib/codeql/rust/elements/ConstBlockPat.qll linguist-generated
|
||||
/lib/codeql/rust/elements/ConstParam.qll linguist-generated
|
||||
/lib/codeql/rust/elements/ContinueExpr.qll linguist-generated
|
||||
/lib/codeql/rust/elements/Crate.qll linguist-generated
|
||||
/lib/codeql/rust/elements/DynTraitTypeRepr.qll linguist-generated
|
||||
/lib/codeql/rust/elements/Element.qll linguist-generated
|
||||
/lib/codeql/rust/elements/Enum.qll linguist-generated
|
||||
@@ -256,6 +257,7 @@
|
||||
/lib/codeql/rust/elements/internal/ConstParamConstructor.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/ConstParamImpl.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/ContinueExprConstructor.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/CrateConstructor.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/DynTraitTypeReprConstructor.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/DynTraitTypeReprImpl.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/EnumConstructor.qll linguist-generated
|
||||
@@ -503,6 +505,7 @@
|
||||
/lib/codeql/rust/elements/internal/generated/ConstBlockPat.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/ConstParam.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/ContinueExpr.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/Crate.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/DynTraitTypeRepr.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/Element.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/generated/Enum.qll linguist-generated
|
||||
@@ -752,6 +755,7 @@
|
||||
/test/extractor-tests/generated/ContinueExpr/ContinueExpr.ql linguist-generated
|
||||
/test/extractor-tests/generated/ContinueExpr/ContinueExpr_getAttr.ql linguist-generated
|
||||
/test/extractor-tests/generated/ContinueExpr/ContinueExpr_getLifetime.ql linguist-generated
|
||||
/test/extractor-tests/generated/Crate/MISSING_SOURCE.txt linguist-generated
|
||||
/test/extractor-tests/generated/DynTraitTypeRepr/DynTraitTypeRepr.ql linguist-generated
|
||||
/test/extractor-tests/generated/DynTraitTypeRepr/DynTraitTypeRepr_getTypeBoundList.ql linguist-generated
|
||||
/test/extractor-tests/generated/Enum/Enum.ql linguist-generated
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"attributes": {
|
||||
"durations": {
|
||||
"crateGraph": {
|
||||
"ms": "__REDACTED__",
|
||||
"pretty": "__REDACTED__"
|
||||
},
|
||||
"extract": {
|
||||
"ms": "__REDACTED__",
|
||||
"pretty": "__REDACTED__"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import rust
|
||||
|
||||
from Function f
|
||||
where exists(f.getLocation().getFile().getRelativePath())
|
||||
where f.fromSource()
|
||||
select f
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
| Cargo.toml:0:0:0:0 | LoadManifest(Cargo.toml) |
|
||||
| file://:0:0:0:0 | CrateGraph |
|
||||
| file://:0:0:0:0 | FindManifests |
|
||||
| src/directory_module/mod.rs:0:0:0:0 | Extract(src/directory_module/mod.rs) |
|
||||
| src/directory_module/mod.rs:0:0:0:0 | LoadSource(src/directory_module/mod.rs) |
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
| file://:0:0:0:0 | CrateGraph |
|
||||
| file://:0:0:0:0 | FindManifests |
|
||||
| rust-project.json:0:0:0:0 | LoadManifest(rust-project.json) |
|
||||
| src/directory_module/mod.rs:0:0:0:0 | Extract(src/directory_module/mod.rs) |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
| Elements extracted | 66 |
|
||||
| Elements extracted | 67 |
|
||||
| Elements unextracted | 0 |
|
||||
| Extraction errors | 0 |
|
||||
| Extraction warnings | 1 |
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"attributes": {
|
||||
"durations": {
|
||||
"crateGraph": {
|
||||
"ms": "__REDACTED__",
|
||||
"pretty": "__REDACTED__"
|
||||
},
|
||||
"extract": {
|
||||
"ms": "__REDACTED__",
|
||||
"pretty": "__REDACTED__"
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
{
|
||||
"attributes": {
|
||||
"durations": {
|
||||
"crateGraph": {
|
||||
"ms": "__REDACTED__",
|
||||
"pretty": "__REDACTED__"
|
||||
},
|
||||
"extract": {
|
||||
"ms": "__REDACTED__",
|
||||
"pretty": "__REDACTED__"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import rust
|
||||
|
||||
from Function f
|
||||
where exists(f.getLocation().getFile().getRelativePath())
|
||||
where f.fromSource()
|
||||
select f
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
| exe/src/main.rs:0:0:0:0 | Extract(exe/src/main.rs) |
|
||||
| exe/src/main.rs:0:0:0:0 | LoadSource(exe/src/main.rs) |
|
||||
| exe/src/main.rs:0:0:0:0 | Parse(exe/src/main.rs) |
|
||||
| file://:0:0:0:0 | CrateGraph |
|
||||
| file://:0:0:0:0 | FindManifests |
|
||||
| lib/src/a_module/mod.rs:0:0:0:0 | Extract(lib/src/a_module/mod.rs) |
|
||||
| lib/src/a_module/mod.rs:0:0:0:0 | LoadSource(lib/src/a_module/mod.rs) |
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
| exe/src/main.rs:0:0:0:0 | Extract(exe/src/main.rs) |
|
||||
| exe/src/main.rs:0:0:0:0 | LoadSource(exe/src/main.rs) |
|
||||
| exe/src/main.rs:0:0:0:0 | Parse(exe/src/main.rs) |
|
||||
| file://:0:0:0:0 | CrateGraph |
|
||||
| file://:0:0:0:0 | FindManifests |
|
||||
| lib/src/a_module/mod.rs:0:0:0:0 | Extract(lib/src/a_module/mod.rs) |
|
||||
| lib/src/a_module/mod.rs:0:0:0:0 | LoadSource(lib/src/a_module/mod.rs) |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
| Elements extracted | 86 |
|
||||
| Elements extracted | 87 |
|
||||
| Elements unextracted | 0 |
|
||||
| Extraction errors | 0 |
|
||||
| Extraction warnings | 0 |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
| Elements extracted | 86 |
|
||||
| Elements extracted | 87 |
|
||||
| Elements unextracted | 0 |
|
||||
| Extraction errors | 0 |
|
||||
| Extraction warnings | 0 |
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import rust
|
||||
|
||||
from Function f
|
||||
where f.fromSource()
|
||||
select f
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import rust
|
||||
|
||||
from Function f
|
||||
where f.fromSource()
|
||||
select f
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import rust
|
||||
|
||||
from Function f
|
||||
where f.fromSource()
|
||||
select f
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import rust
|
||||
|
||||
from Function f
|
||||
where exists(f.getLocation().getFile().getRelativePath())
|
||||
where f.fromSource()
|
||||
select f
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import rust
|
||||
|
||||
from Function f
|
||||
where exists(f.getLocation().getFile().getRelativePath())
|
||||
where f.fromSource()
|
||||
select f
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import rust
|
||||
|
||||
from Function f
|
||||
where exists(f.getLocation().getFile().getRelativePath())
|
||||
where f.fromSource()
|
||||
select f
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import rust
|
||||
|
||||
from Function f
|
||||
where exists(f.getLocation().getFile().getRelativePath())
|
||||
where f.fromSource()
|
||||
select f
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
| Cargo.toml:0:0:0:0 | LoadManifest(Cargo.toml) |
|
||||
| exe/src/main.rs:0:0:0:0 | Extract(exe/src/main.rs) |
|
||||
| exe/src/main.rs:0:0:0:0 | Parse(exe/src/main.rs) |
|
||||
| file://:0:0:0:0 | CrateGraph |
|
||||
| file://:0:0:0:0 | FindManifests |
|
||||
| lib/src/lib.rs:0:0:0:0 | Extract(lib/src/lib.rs) |
|
||||
| lib/src/lib.rs:0:0:0:0 | Parse(lib/src/lib.rs) |
|
||||
|
||||
@@ -55,7 +55,8 @@ class File extends Container, Impl::File {
|
||||
|
|
||||
node.getFile() = this and
|
||||
line = [/*loc.getStartLine(), */ loc.getEndLine()] and // ignore start locations for now as we're getting them wrong for things with a comment attached
|
||||
not loc instanceof EmptyLocation
|
||||
not loc instanceof EmptyLocation and
|
||||
line > 0
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -152,6 +152,29 @@ class ModeledRemoteSource extends RemoteSource::Range {
|
||||
ModeledRemoteSource() { sourceNode(this, "remote") }
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow sink that is used in a query.
|
||||
*
|
||||
* Extend this class to refine existing API models. If you want to model new APIs,
|
||||
* extend `QuerySink::Range` instead.
|
||||
*/
|
||||
final class QuerySink = QuerySink::Range;
|
||||
|
||||
/**
|
||||
* Provides a class for modeling new query sinks.
|
||||
*/
|
||||
module QuerySink {
|
||||
/**
|
||||
* A data flow sink that is used in a query.
|
||||
*/
|
||||
abstract class Range extends DataFlow::Node {
|
||||
/**
|
||||
* Gets a string that describes the type of this sink (usually the query it applies to).
|
||||
*/
|
||||
abstract string getSinkType();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow node that constructs a SQL statement (for later execution).
|
||||
*
|
||||
|
||||
@@ -1,4 +1,22 @@
|
||||
/** Provides classes and predicates for defining flow sinks. */
|
||||
/**
|
||||
* Provides classes and predicates for defining flow sinks.
|
||||
*
|
||||
* Flow sinks defined here feed into data flow configurations as follows:
|
||||
*
|
||||
* ```text
|
||||
* data from *.model.yml | QL extensions of FlowSink::Range
|
||||
* v v
|
||||
* FlowSink (associated with a models-as-data kind string)
|
||||
* v
|
||||
* sinkNode predicate | other QL defined sinks, for example using concepts
|
||||
* v v
|
||||
* various Sink classes for specific data flow configurations <- extending QuerySink
|
||||
* ```
|
||||
*
|
||||
* New sinks should be defined using models-as-data, QL extensions of
|
||||
* `FlowSink::Range`, or concepts. Data flow configurations should use the
|
||||
* `sinkNode` predicate and/or concepts to define their sinks.
|
||||
*/
|
||||
|
||||
private import rust
|
||||
private import internal.FlowSummaryImpl as Impl
|
||||
@@ -12,7 +30,7 @@ private module Sinks {
|
||||
|
||||
/** Provides the `Range` class used to define the extent of `FlowSink`. */
|
||||
module FlowSink {
|
||||
/** A flow source. */
|
||||
/** A flow sink. */
|
||||
abstract class Range extends Impl::Public::SinkElement {
|
||||
bindingset[this]
|
||||
Range() { any() }
|
||||
|
||||
@@ -1,4 +1,28 @@
|
||||
/** Provides classes and predicates for defining flow sources. */
|
||||
/**
|
||||
* Provides classes and predicates for defining flow sources.
|
||||
*
|
||||
* Flow sources defined here feed into the `ActiveThreatModelSource` class and
|
||||
* ultimately reach data flow configurations as follows:
|
||||
*
|
||||
* ```text
|
||||
* data from *.model.yml | QL extensions of FlowSource::Range
|
||||
* v v
|
||||
* FlowSource (associated with a models-as-data kind string)
|
||||
* v
|
||||
* sourceNode predicate | (theoretically other QL defined sources)
|
||||
* v v
|
||||
* ThreatModelSource (associated with a threat model source type)
|
||||
* v
|
||||
* ActiveThreatModelSource (just the enabled sources)
|
||||
* v
|
||||
* various Source classes for specific data flow configurations
|
||||
* ```
|
||||
*
|
||||
* New sources should be defined using models-as-data or QL extensions of
|
||||
* `FlowSource::Range`. Data flow configurations on the other hand should use
|
||||
* `ActiveThreatModelSource` to match sources enabled in the user
|
||||
* configuration.
|
||||
*/
|
||||
|
||||
private import rust
|
||||
private import internal.FlowSummaryImpl as Impl
|
||||
|
||||
1
rust/ql/lib/codeql/rust/elements.qll
generated
1
rust/ql/lib/codeql/rust/elements.qll
generated
@@ -48,6 +48,7 @@ import codeql.rust.elements.ConstArg
|
||||
import codeql.rust.elements.ConstBlockPat
|
||||
import codeql.rust.elements.ConstParam
|
||||
import codeql.rust.elements.ContinueExpr
|
||||
import codeql.rust.elements.Crate
|
||||
import codeql.rust.elements.DynTraitTypeRepr
|
||||
import codeql.rust.elements.Element
|
||||
import codeql.rust.elements.Enum
|
||||
|
||||
10
rust/ql/lib/codeql/rust/elements/Crate.qll
generated
Normal file
10
rust/ql/lib/codeql/rust/elements/Crate.qll
generated
Normal file
@@ -0,0 +1,10 @@
|
||||
// generated by codegen, do not edit
|
||||
/**
|
||||
* This module provides the public class `Crate`.
|
||||
*/
|
||||
|
||||
private import internal.CrateImpl
|
||||
import codeql.rust.elements.Element
|
||||
import codeql.rust.elements.Module
|
||||
|
||||
final class Crate = Impl::Crate;
|
||||
14
rust/ql/lib/codeql/rust/elements/internal/CrateConstructor.qll
generated
Normal file
14
rust/ql/lib/codeql/rust/elements/internal/CrateConstructor.qll
generated
Normal file
@@ -0,0 +1,14 @@
|
||||
// generated by codegen, remove this comment if you wish to edit this file
|
||||
/**
|
||||
* This module defines the hook used internally to tweak the characteristic predicate of
|
||||
* `Crate` synthesized instances.
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
|
||||
private import codeql.rust.elements.internal.generated.Raw
|
||||
|
||||
/**
|
||||
* The characteristic predicate of `Crate` synthesized instances.
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
predicate constructCrate(Raw::Crate id) { any() }
|
||||
29
rust/ql/lib/codeql/rust/elements/internal/CrateImpl.qll
Normal file
29
rust/ql/lib/codeql/rust/elements/internal/CrateImpl.qll
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* This module provides a hand-modifiable wrapper around the generated class `Crate`.
|
||||
*
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
|
||||
private import codeql.rust.elements.internal.generated.Crate
|
||||
|
||||
/**
|
||||
* INTERNAL: This module contains the customizable definition of `Crate` and should not
|
||||
* be referenced directly.
|
||||
*/
|
||||
module Impl {
|
||||
class Crate extends Generated::Crate {
|
||||
override string toString() { result = strictconcat(int i | | this.toStringPart(i) order by i) }
|
||||
|
||||
private string toStringPart(int i) {
|
||||
i = 0 and result = "Crate("
|
||||
or
|
||||
i = 1 and result = this.getName()
|
||||
or
|
||||
i = 2 and result = "@"
|
||||
or
|
||||
i = 3 and result = this.getVersion()
|
||||
or
|
||||
i = 4 and result = ")"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,9 @@ module Impl {
|
||||
* Gets the primary file where this element occurs.
|
||||
*/
|
||||
File getFile() { result = this.getLocation().getFile() }
|
||||
|
||||
/** Holds if this element is from source code. */
|
||||
predicate fromSource() { exists(this.getFile().getRelativePath()) }
|
||||
}
|
||||
|
||||
/** Gets the non-synthesized location of `l`, if any. */
|
||||
|
||||
@@ -236,13 +236,11 @@ module Impl {
|
||||
this instanceof VariableScope or
|
||||
this instanceof VariableAccessCand or
|
||||
this instanceof LetStmt or
|
||||
getImmediateChildAndAccessor(this, _, _) instanceof RelevantElement
|
||||
getImmediateChild(this, _) instanceof RelevantElement
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private RelevantElement getChild(int index) {
|
||||
result = getImmediateChildAndAccessor(this, index, _)
|
||||
}
|
||||
private RelevantElement getChild(int index) { result = getImmediateChild(this, index) }
|
||||
|
||||
pragma[nomagic]
|
||||
private RelevantElement getImmediateChildMin(int index) {
|
||||
|
||||
94
rust/ql/lib/codeql/rust/elements/internal/generated/Crate.qll
generated
Normal file
94
rust/ql/lib/codeql/rust/elements/internal/generated/Crate.qll
generated
Normal file
@@ -0,0 +1,94 @@
|
||||
// generated by codegen, do not edit
|
||||
/**
|
||||
* This module provides the generated definition of `Crate`.
|
||||
* INTERNAL: Do not import directly.
|
||||
*/
|
||||
|
||||
private import codeql.rust.elements.internal.generated.Synth
|
||||
private import codeql.rust.elements.internal.generated.Raw
|
||||
import codeql.rust.elements.Crate
|
||||
import codeql.rust.elements.internal.ElementImpl::Impl as ElementImpl
|
||||
import codeql.rust.elements.Module
|
||||
|
||||
private class CrateAlias = Crate;
|
||||
|
||||
/**
|
||||
* INTERNAL: This module contains the fully generated definition of `Crate` and should not
|
||||
* be referenced directly.
|
||||
*/
|
||||
module Generated {
|
||||
/**
|
||||
* INTERNAL: Do not reference the `Generated::Crate` class directly.
|
||||
* Use the subclass `Crate`, where the following predicates are available.
|
||||
*/
|
||||
class Crate extends Synth::TCrate, ElementImpl::Element {
|
||||
override string getAPrimaryQlClass() { result = "Crate" }
|
||||
|
||||
/**
|
||||
* Gets the name of this crate, if it exists.
|
||||
*/
|
||||
string getName() { result = Synth::convertCrateToRaw(this).(Raw::Crate).getName() }
|
||||
|
||||
/**
|
||||
* Holds if `getName()` exists.
|
||||
*/
|
||||
final predicate hasName() { exists(this.getName()) }
|
||||
|
||||
/**
|
||||
* Gets the version of this crate, if it exists.
|
||||
*/
|
||||
string getVersion() { result = Synth::convertCrateToRaw(this).(Raw::Crate).getVersion() }
|
||||
|
||||
/**
|
||||
* Holds if `getVersion()` exists.
|
||||
*/
|
||||
final predicate hasVersion() { exists(this.getVersion()) }
|
||||
|
||||
/**
|
||||
* Gets the module of this crate, if it exists.
|
||||
*/
|
||||
Module getModule() {
|
||||
result = Synth::convertModuleFromRaw(Synth::convertCrateToRaw(this).(Raw::Crate).getModule())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `getModule()` exists.
|
||||
*/
|
||||
final predicate hasModule() { exists(this.getModule()) }
|
||||
|
||||
/**
|
||||
* Gets the `index`th cfg option of this crate (0-based).
|
||||
*/
|
||||
string getCfgOption(int index) {
|
||||
result = Synth::convertCrateToRaw(this).(Raw::Crate).getCfgOption(index)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets any of the cfg options of this crate.
|
||||
*/
|
||||
final string getACfgOption() { result = this.getCfgOption(_) }
|
||||
|
||||
/**
|
||||
* Gets the number of cfg options of this crate.
|
||||
*/
|
||||
final int getNumberOfCfgOptions() { result = count(int i | exists(this.getCfgOption(i))) }
|
||||
|
||||
/**
|
||||
* Gets the `index`th dependency of this crate (0-based).
|
||||
*/
|
||||
CrateAlias getDependency(int index) {
|
||||
result =
|
||||
Synth::convertCrateFromRaw(Synth::convertCrateToRaw(this).(Raw::Crate).getDependency(index))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets any of the dependencies of this crate.
|
||||
*/
|
||||
final CrateAlias getADependency() { result = this.getDependency(_) }
|
||||
|
||||
/**
|
||||
* Gets the number of dependencies of this crate.
|
||||
*/
|
||||
final int getNumberOfDependencies() { result = count(int i | exists(this.getDependency(i))) }
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,19 @@ private module Impl {
|
||||
none()
|
||||
}
|
||||
|
||||
private Element getImmediateChildOfCrate(Crate e, int index, string partialPredicateCall) {
|
||||
exists(int b, int bElement, int n |
|
||||
b = 0 and
|
||||
bElement = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfElement(e, i, _)) | i) and
|
||||
n = bElement and
|
||||
(
|
||||
none()
|
||||
or
|
||||
result = getImmediateChildOfElement(e, index - b, partialPredicateCall)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private Element getImmediateChildOfExtractorStep(
|
||||
ExtractorStep e, int index, string partialPredicateCall
|
||||
) {
|
||||
@@ -4050,6 +4063,8 @@ private module Impl {
|
||||
// * none() simplifies generation, as we can append `or ...` without a special case for the first item
|
||||
none()
|
||||
or
|
||||
result = getImmediateChildOfCrate(e, index, partialAccessor)
|
||||
or
|
||||
result = getImmediateChildOfExtractorStep(e, index, partialAccessor)
|
||||
or
|
||||
result = getImmediateChildOfFormat(e, index, partialAccessor)
|
||||
@@ -4388,6 +4403,11 @@ Element getImmediateParent(Element e) {
|
||||
result = unique(Element x | e = Impl::getImmediateChild(x, _, _) | x)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the immediate child indexed at `index`. Indexes are not guaranteed to be contiguous, but are guaranteed to be distinct.
|
||||
*/
|
||||
Element getImmediateChild(Element e, int index) { result = Impl::getImmediateChild(e, index, _) }
|
||||
|
||||
/**
|
||||
* Gets the immediate child indexed at `index`. Indexes are not guaranteed to be contiguous, but are guaranteed to be distinct. `accessor` is bound the member predicate call resulting in the given child.
|
||||
*/
|
||||
@@ -4407,3 +4427,8 @@ Element getChildAndAccessor(Element e, int index, string accessor) {
|
||||
accessor = "get" + partialAccessor
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the child indexed at `index`. Indexes are not guaranteed to be contiguous, but are guaranteed to be distinct. `accessor` is bound the member predicate call resulting in the given child.
|
||||
*/
|
||||
Element getChild(Element e, int index) { result = Impl::getImmediateChild(e, index, _).resolve() }
|
||||
|
||||
@@ -12,6 +12,38 @@ module Raw {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
class Crate extends @crate, Element {
|
||||
override string toString() { result = "Crate" }
|
||||
|
||||
/**
|
||||
* Gets the name of this crate, if it exists.
|
||||
*/
|
||||
string getName() { crate_names(this, result) }
|
||||
|
||||
/**
|
||||
* Gets the version of this crate, if it exists.
|
||||
*/
|
||||
string getVersion() { crate_versions(this, result) }
|
||||
|
||||
/**
|
||||
* Gets the module of this crate, if it exists.
|
||||
*/
|
||||
Module getModule() { crate_modules(this, result) }
|
||||
|
||||
/**
|
||||
* Gets the `index`th cfg option of this crate (0-based).
|
||||
*/
|
||||
string getCfgOption(int index) { crate_cfg_options(this, index, result) }
|
||||
|
||||
/**
|
||||
* Gets the `index`th dependency of this crate (0-based).
|
||||
*/
|
||||
Crate getDependency(int index) { crate_dependencies(this, index, result) }
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
|
||||
@@ -162,6 +162,10 @@ module Synth {
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
TContinueExpr(Raw::ContinueExpr id) { constructContinueExpr(id) } or
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
TCrate(Raw::Crate id) { constructCrate(id) } or
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
@@ -1061,6 +1065,12 @@ module Synth {
|
||||
*/
|
||||
TContinueExpr convertContinueExprFromRaw(Raw::Element e) { result = TContinueExpr(e) }
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* Converts a raw element to a synthesized `TCrate`, if possible.
|
||||
*/
|
||||
TCrate convertCrateFromRaw(Raw::Element e) { result = TCrate(e) }
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* Converts a raw element to a synthesized `TDynTraitTypeRepr`, if possible.
|
||||
@@ -2050,6 +2060,8 @@ module Synth {
|
||||
* Converts a raw DB element to a synthesized `TElement`, if possible.
|
||||
*/
|
||||
TElement convertElementFromRaw(Raw::Element e) {
|
||||
result = convertCrateFromRaw(e)
|
||||
or
|
||||
result = convertExtractorStepFromRaw(e)
|
||||
or
|
||||
result = convertLocatableFromRaw(e)
|
||||
@@ -2633,6 +2645,12 @@ module Synth {
|
||||
*/
|
||||
Raw::Element convertContinueExprToRaw(TContinueExpr e) { e = TContinueExpr(result) }
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* Converts a synthesized `TCrate` to a raw DB element, if possible.
|
||||
*/
|
||||
Raw::Element convertCrateToRaw(TCrate e) { e = TCrate(result) }
|
||||
|
||||
/**
|
||||
* INTERNAL: Do not use.
|
||||
* Converts a synthesized `TDynTraitTypeRepr` to a raw DB element, if possible.
|
||||
@@ -3620,6 +3638,8 @@ module Synth {
|
||||
* Converts a synthesized `TElement` to a raw DB element, if possible.
|
||||
*/
|
||||
Raw::Element convertElementToRaw(TElement e) {
|
||||
result = convertCrateToRaw(e)
|
||||
or
|
||||
result = convertExtractorStepToRaw(e)
|
||||
or
|
||||
result = convertLocatableToRaw(e)
|
||||
|
||||
@@ -40,6 +40,7 @@ import codeql.rust.elements.internal.ConstArgConstructor
|
||||
import codeql.rust.elements.internal.ConstBlockPatConstructor
|
||||
import codeql.rust.elements.internal.ConstParamConstructor
|
||||
import codeql.rust.elements.internal.ContinueExprConstructor
|
||||
import codeql.rust.elements.internal.CrateConstructor
|
||||
import codeql.rust.elements.internal.DynTraitTypeReprConstructor
|
||||
import codeql.rust.elements.internal.EnumConstructor
|
||||
import codeql.rust.elements.internal.ExprStmtConstructor
|
||||
|
||||
@@ -24,7 +24,9 @@ query predicate multipleLocations(Locatable e) { strictcount(e.getLocation()) >
|
||||
/**
|
||||
* Holds if `e` does not have a `Location`.
|
||||
*/
|
||||
query predicate noLocation(Locatable e) { not exists(e.getLocation()) }
|
||||
query predicate noLocation(Locatable e) {
|
||||
not exists(e.getLocation()) and not e.(AstNode).getParentNode*() = any(Crate c).getModule()
|
||||
}
|
||||
|
||||
private predicate multiplePrimaryQlClasses(Element e) {
|
||||
strictcount(string cls | cls = e.getAPrimaryQlClass() and cls != "VariableAccess") > 1
|
||||
@@ -38,7 +40,7 @@ query predicate multiplePrimaryQlClasses(Element e, string s) {
|
||||
s = strictconcat(e.getPrimaryQlClasses(), ", ")
|
||||
}
|
||||
|
||||
private Element getParent(Element child) { child = getChildAndAccessor(result, _, _) }
|
||||
private Element getParent(Element child) { child = getChild(result, _) }
|
||||
|
||||
private predicate multipleParents(Element child) { strictcount(getParent(child)) > 1 }
|
||||
|
||||
@@ -54,8 +56,8 @@ query predicate multipleParents(Element child, string childClass, Element parent
|
||||
|
||||
/** Holds if `parent` has multiple children at the same index. */
|
||||
query predicate multipleChildren(Element parent, int index, Element child1, Element child2) {
|
||||
child1 = getChildAndAccessor(parent, index, _) and
|
||||
child2 = getChildAndAccessor(parent, index, _) and
|
||||
child1 = getChild(parent, index) and
|
||||
child2 = getChild(parent, index) and
|
||||
child1 != child2
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import rust
|
||||
private import codeql.rust.dataflow.DataFlow
|
||||
private import codeql.rust.dataflow.internal.DataFlowImpl
|
||||
private import codeql.rust.security.SensitiveData
|
||||
private import codeql.rust.Concepts
|
||||
|
||||
/**
|
||||
* Provides default sources, sinks and barriers for detecting cleartext logging
|
||||
@@ -21,7 +22,9 @@ module CleartextLogging {
|
||||
/**
|
||||
* A data flow sink for cleartext logging vulnerabilities.
|
||||
*/
|
||||
abstract class Sink extends DataFlow::Node { }
|
||||
abstract class Sink extends QuerySink::Range {
|
||||
override string getSinkType() { result = "CleartextLogging" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A barrier for cleartext logging vulnerabilities.
|
||||
|
||||
@@ -23,7 +23,9 @@ module SqlInjection {
|
||||
/**
|
||||
* A data flow sink for SQL injection vulnerabilities.
|
||||
*/
|
||||
abstract class Sink extends DataFlow::Node { }
|
||||
abstract class Sink extends QuerySink::Range {
|
||||
override string getSinkType() { result = "SqlInjection" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A barrier for SQL injection vulnerabilities.
|
||||
|
||||
@@ -43,7 +43,7 @@ module NormalHashFunction {
|
||||
* data" vulnerabilities that applies to data that does not require computationally expensive
|
||||
* hashing. That is, a broken or weak hashing algorithm.
|
||||
*/
|
||||
abstract class Sink extends DataFlow::Node {
|
||||
abstract class Sink extends QuerySink::Range {
|
||||
/**
|
||||
* Gets the name of the weak hashing algorithm.
|
||||
*/
|
||||
@@ -76,6 +76,8 @@ module NormalHashFunction {
|
||||
class WeakHashingOperationInputAsSink extends Sink {
|
||||
Cryptography::HashingAlgorithm algorithm;
|
||||
|
||||
override string getSinkType() { result = "WeakSensitiveDataHashing" }
|
||||
|
||||
WeakHashingOperationInputAsSink() {
|
||||
exists(Cryptography::CryptographicOperation operation |
|
||||
algorithm.isWeak() and
|
||||
@@ -114,7 +116,9 @@ module ComputationallyExpensiveHashFunction {
|
||||
* hashing. That is, a broken or weak hashing algorithm or one that is not computationally
|
||||
* expensive enough for password hashing.
|
||||
*/
|
||||
abstract class Sink extends DataFlow::Node {
|
||||
abstract class Sink extends QuerySink::Range {
|
||||
override string getSinkType() { result = "WeakSensitiveDataHashing" }
|
||||
|
||||
/**
|
||||
* Gets the name of the weak hashing algorithm.
|
||||
*/
|
||||
|
||||
@@ -8,11 +8,14 @@ private import rust
|
||||
private import codeql.rust.dataflow.DataFlow
|
||||
private import codeql.rust.controlflow.CfgNodes
|
||||
private import codeql.rust.dataflow.FlowSink
|
||||
private import codeql.rust.Concepts
|
||||
|
||||
/**
|
||||
* A data flow sink for regular expression injection vulnerabilities.
|
||||
*/
|
||||
abstract class RegexInjectionSink extends DataFlow::Node { }
|
||||
abstract class RegexInjectionSink extends QuerySink::Range {
|
||||
override string getSinkType() { result = "RegexInjection" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A barrier for regular expression injection vulnerabilities.
|
||||
|
||||
@@ -120,11 +120,48 @@ locatable_locations(
|
||||
// from schema
|
||||
|
||||
@element =
|
||||
@extractor_step
|
||||
@crate
|
||||
| @extractor_step
|
||||
| @locatable
|
||||
| @unextracted
|
||||
;
|
||||
|
||||
crates(
|
||||
unique int id: @crate
|
||||
);
|
||||
|
||||
#keyset[id]
|
||||
crate_names(
|
||||
int id: @crate ref,
|
||||
string name: string ref
|
||||
);
|
||||
|
||||
#keyset[id]
|
||||
crate_versions(
|
||||
int id: @crate ref,
|
||||
string version: string ref
|
||||
);
|
||||
|
||||
#keyset[id]
|
||||
crate_modules(
|
||||
int id: @crate ref,
|
||||
int module: @module ref
|
||||
);
|
||||
|
||||
#keyset[id, index]
|
||||
crate_cfg_options(
|
||||
int id: @crate ref,
|
||||
int index: int ref,
|
||||
string cfg_option: string ref
|
||||
);
|
||||
|
||||
#keyset[id, index]
|
||||
crate_dependencies(
|
||||
int id: @crate ref,
|
||||
int index: int ref,
|
||||
int dependency: @crate ref
|
||||
);
|
||||
|
||||
extractor_steps(
|
||||
unique int id: @extractor_step,
|
||||
string action: string ref,
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
|
||||
import rust
|
||||
import codeql.rust.dataflow.DataFlow
|
||||
import codeql.rust.Concepts
|
||||
import Stats
|
||||
|
||||
from string kind, int num
|
||||
where num = strictcount(DataFlow::Node n | getAQuerySinkKind(n) = kind)
|
||||
where num = strictcount(QuerySink s | s.getSinkType() = kind)
|
||||
select kind, num
|
||||
|
||||
@@ -11,7 +11,8 @@
|
||||
|
||||
import rust
|
||||
import codeql.rust.dataflow.DataFlow
|
||||
import codeql.rust.Concepts
|
||||
import Stats
|
||||
|
||||
from DataFlow::Node n
|
||||
select n, "Sink for " + strictconcat(getAQuerySinkKind(n), ", ") + "."
|
||||
from QuerySink s
|
||||
select s, "Sink for " + concat(s.getSinkType(), ", ") + "."
|
||||
|
||||
@@ -9,8 +9,12 @@ private import codeql.rust.dataflow.internal.TaintTrackingImpl
|
||||
private import codeql.rust.internal.AstConsistency as AstConsistency
|
||||
private import codeql.rust.controlflow.internal.CfgConsistency as CfgConsistency
|
||||
private import codeql.rust.dataflow.internal.DataFlowConsistency as DataFlowConsistency
|
||||
private import codeql.rust.security.SqlInjectionExtensions
|
||||
private import codeql.rust.Concepts
|
||||
// import all query extensions files, so that all extensions of `QuerySink` are found
|
||||
private import codeql.rust.security.CleartextLoggingExtensions
|
||||
private import codeql.rust.security.SqlInjectionExtensions
|
||||
private import codeql.rust.security.WeakSensitiveDataHashingExtensions
|
||||
private import codeql.rust.security.regex.RegexInjectionExtensions
|
||||
|
||||
/**
|
||||
* Gets a count of the total number of lines of code in the database.
|
||||
@@ -55,16 +59,7 @@ int getTaintEdgesCount() {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a kind of query for which `n` is a sink (if any).
|
||||
*/
|
||||
string getAQuerySinkKind(DataFlow::Node n) {
|
||||
n instanceof SqlInjection::Sink and result = "SqlInjection"
|
||||
or
|
||||
n instanceof CleartextLogging::Sink and result = "CleartextLogging"
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a count of the total number of query sinks in the database.
|
||||
*/
|
||||
int getQuerySinksCount() { result = count(DataFlow::Node n | exists(getAQuerySinkKind(n))) }
|
||||
int getQuerySinksCount() { result = count(QuerySink s) }
|
||||
|
||||
@@ -14,9 +14,17 @@ import codeql.rust.Diagnostics
|
||||
import Stats
|
||||
import TaintReach
|
||||
|
||||
class CrateElement extends Element {
|
||||
CrateElement() {
|
||||
this instanceof Crate or
|
||||
this.(AstNode).getParentNode*() = any(Crate c).getModule()
|
||||
}
|
||||
}
|
||||
|
||||
from string key, int value
|
||||
where
|
||||
key = "Elements extracted" and value = count(Element e | not e instanceof Unextracted)
|
||||
key = "Elements extracted" and
|
||||
value = count(Element e | not e instanceof Unextracted and not e instanceof CrateElement)
|
||||
or
|
||||
key = "Elements unextracted" and value = count(Unextracted e)
|
||||
or
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
private import rust
|
||||
|
||||
predicate toBeTested(Element e) { any() }
|
||||
predicate toBeTested(Element e) { not e instanceof CrateElement }
|
||||
|
||||
class CrateElement extends Element {
|
||||
CrateElement() {
|
||||
this instanceof Crate or
|
||||
any(Crate c).getModule() = this.(AstNode).getParentNode*()
|
||||
}
|
||||
}
|
||||
|
||||
117
rust/ql/test/extractor-tests/crate_graph/crates.expected
Normal file
117
rust/ql/test/extractor-tests/crate_graph/crates.expected
Normal file
@@ -0,0 +1,117 @@
|
||||
#-----| Crate(allocator_api2@0.2.21)
|
||||
|
||||
#-----| Crate(core@0.0.0)
|
||||
#-----| -> Crate(rand@0.8.5)
|
||||
#-----| -> Crate(rand_xorshift@0.3.0)
|
||||
|
||||
#-----| Crate(compiler_builtins@0.1.140)
|
||||
#-----| -> Crate(core@0.0.0)
|
||||
|
||||
#-----| Crate(cfg_if@1.0.0)
|
||||
#-----| -> Crate(core@0.0.0)
|
||||
#-----| -> Crate(compiler_builtins@0.1.140)
|
||||
|
||||
#-----| Crate(std@0.0.0)
|
||||
#-----| -> Crate(core@0.0.0)
|
||||
#-----| -> Crate(compiler_builtins@0.1.140)
|
||||
#-----| -> Crate(cfg_if@1.0.0)
|
||||
#-----| -> Crate(alloc@0.0.0)
|
||||
#-----| -> Crate(hashbrown@0.15.2)
|
||||
#-----| -> Crate(libc@0.2.169)
|
||||
#-----| -> Crate(rand@0.8.5)
|
||||
#-----| -> Crate(rand_xorshift@0.3.0)
|
||||
#-----| -> Crate(rustc_demangle@0.1.24)
|
||||
#-----| -> Crate(panic_abort@0.0.0)
|
||||
#-----| -> Crate(unwind@0.0.0)
|
||||
#-----| -> Crate(panic_unwind@0.0.0)
|
||||
#-----| -> Crate(std_detect@0.1.5)
|
||||
|
||||
#-----| Crate(unicode_width@0.1.14)
|
||||
#-----| -> Crate(core@0.0.0)
|
||||
#-----| -> Crate(compiler_builtins@0.1.140)
|
||||
#-----| -> Crate(std@0.0.0)
|
||||
|
||||
#-----| Crate(getopts@0.2.21)
|
||||
#-----| -> Crate(core@0.0.0)
|
||||
#-----| -> Crate(std@0.0.0)
|
||||
#-----| -> Crate(unicode_width@0.1.14)
|
||||
|
||||
#-----| Crate(alloc@0.0.0)
|
||||
#-----| -> Crate(core@0.0.0)
|
||||
#-----| -> Crate(compiler_builtins@0.1.140)
|
||||
#-----| -> Crate(rand@0.8.5)
|
||||
#-----| -> Crate(rand_xorshift@0.3.0)
|
||||
|
||||
#-----| Crate(hashbrown@0.15.2)
|
||||
#-----| -> Crate(allocator_api2@0.2.21)
|
||||
#-----| -> Crate(core@0.0.0)
|
||||
#-----| -> Crate(compiler_builtins@0.1.140)
|
||||
#-----| -> Crate(alloc@0.0.0)
|
||||
|
||||
#-----| Crate(libc@0.2.169)
|
||||
#-----| -> Crate(core@0.0.0)
|
||||
|
||||
#-----| Crate(rand_core@0.6.4)
|
||||
|
||||
#-----| Crate(rand@0.8.5)
|
||||
#-----| -> Crate(rand_core@0.6.4)
|
||||
|
||||
#-----| Crate(rand_xorshift@0.3.0)
|
||||
#-----| -> Crate(rand_core@0.6.4)
|
||||
|
||||
#-----| Crate(rustc_demangle@0.1.24)
|
||||
#-----| -> Crate(core@0.0.0)
|
||||
#-----| -> Crate(compiler_builtins@0.1.140)
|
||||
|
||||
#-----| Crate(panic_abort@0.0.0)
|
||||
#-----| -> Crate(core@0.0.0)
|
||||
#-----| -> Crate(compiler_builtins@0.1.140)
|
||||
#-----| -> Crate(cfg_if@1.0.0)
|
||||
#-----| -> Crate(alloc@0.0.0)
|
||||
#-----| -> Crate(libc@0.2.169)
|
||||
|
||||
#-----| Crate(unwind@0.0.0)
|
||||
#-----| -> Crate(core@0.0.0)
|
||||
#-----| -> Crate(compiler_builtins@0.1.140)
|
||||
#-----| -> Crate(cfg_if@1.0.0)
|
||||
#-----| -> Crate(libc@0.2.169)
|
||||
|
||||
#-----| Crate(panic_unwind@0.0.0)
|
||||
#-----| -> Crate(core@0.0.0)
|
||||
#-----| -> Crate(compiler_builtins@0.1.140)
|
||||
#-----| -> Crate(cfg_if@1.0.0)
|
||||
#-----| -> Crate(alloc@0.0.0)
|
||||
#-----| -> Crate(libc@0.2.169)
|
||||
#-----| -> Crate(unwind@0.0.0)
|
||||
|
||||
#-----| Crate(proc_macro@0.0.0)
|
||||
#-----| -> Crate(core@0.0.0)
|
||||
#-----| -> Crate(std@0.0.0)
|
||||
|
||||
#-----| Crate(std_detect@0.1.5)
|
||||
#-----| -> Crate(core@0.0.0)
|
||||
#-----| -> Crate(compiler_builtins@0.1.140)
|
||||
#-----| -> Crate(cfg_if@1.0.0)
|
||||
#-----| -> Crate(alloc@0.0.0)
|
||||
#-----| -> Crate(libc@0.2.169)
|
||||
|
||||
#-----| Crate(test@0.0.0)
|
||||
#-----| -> Crate(core@0.0.0)
|
||||
#-----| -> Crate(std@0.0.0)
|
||||
#-----| -> Crate(getopts@0.2.21)
|
||||
#-----| -> Crate(libc@0.2.169)
|
||||
|
||||
#-----| Crate(test@0.0.1)
|
||||
#-----| -> Crate(core@0.0.0)
|
||||
#-----| -> Crate(std@0.0.0)
|
||||
#-----| -> Crate(alloc@0.0.0)
|
||||
#-----| -> Crate(proc_macro@0.0.0)
|
||||
#-----| -> Crate(test@0.0.0)
|
||||
|
||||
#-----| Crate(main@0.0.1)
|
||||
#-----| -> Crate(core@0.0.0)
|
||||
#-----| -> Crate(std@0.0.0)
|
||||
#-----| -> Crate(alloc@0.0.0)
|
||||
#-----| -> Crate(proc_macro@0.0.0)
|
||||
#-----| -> Crate(test@0.0.0)
|
||||
#-----| -> Crate(test@0.0.1)
|
||||
11
rust/ql/test/extractor-tests/crate_graph/crates.ql
Normal file
11
rust/ql/test/extractor-tests/crate_graph/crates.ql
Normal file
@@ -0,0 +1,11 @@
|
||||
/**
|
||||
* @id crate-graph
|
||||
* @name Crate Graph
|
||||
* @kind graph
|
||||
*/
|
||||
|
||||
import rust
|
||||
|
||||
query predicate nodes(Crate c) { any() }
|
||||
|
||||
query predicate edges(Crate c1, Crate c2) { c1.getADependency() = c2 }
|
||||
3
rust/ql/test/extractor-tests/crate_graph/main.rs
Normal file
3
rust/ql/test/extractor-tests/crate_graph/main.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
println! {"Hello world"}
|
||||
}
|
||||
42
rust/ql/test/extractor-tests/crate_graph/module.rs
Normal file
42
rust/ql/test/extractor-tests/crate_graph/module.rs
Normal file
@@ -0,0 +1,42 @@
|
||||
use std::fmt;
|
||||
|
||||
pub enum X {
|
||||
A,
|
||||
B,
|
||||
}
|
||||
|
||||
pub struct X_List {
|
||||
x: X,
|
||||
tail: Option<Box<X_List>>,
|
||||
}
|
||||
|
||||
pub fn length(list: X_List) -> usize {
|
||||
match list {
|
||||
X_List { x: _, tail: None } => 1,
|
||||
X_List {
|
||||
x: _,
|
||||
tail: Some(tail),
|
||||
} => 1 + length(*tail),
|
||||
}
|
||||
}
|
||||
pub trait AsString {
|
||||
fn as_string(&self) -> &str;
|
||||
}
|
||||
|
||||
impl AsString for X {
|
||||
fn as_string(&self) -> &str {
|
||||
match self {
|
||||
X::A => "a",
|
||||
X::B => "b",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for X {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.as_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub const X_A: X = X::A;
|
||||
pub static X_B: X = X::B;
|
||||
38
rust/ql/test/extractor-tests/crate_graph/modules.expected
Normal file
38
rust/ql/test/extractor-tests/crate_graph/modules.expected
Normal file
@@ -0,0 +1,38 @@
|
||||
#-----| Const
|
||||
|
||||
#-----| Static
|
||||
|
||||
#-----| enum X
|
||||
|
||||
#-----| fn as_string
|
||||
|
||||
#-----| fn as_string
|
||||
|
||||
#-----| fn fmt
|
||||
|
||||
#-----| fn length
|
||||
|
||||
#-----| impl ...::Display for ...::X { ... }
|
||||
#-----| -> fn fmt
|
||||
|
||||
#-----| impl AsString for ...::X { ... }
|
||||
#-----| -> fn as_string
|
||||
|
||||
lib.rs:
|
||||
# 0| mod crate
|
||||
#-----| -> mod module
|
||||
|
||||
#-----| mod module
|
||||
#-----| -> Const
|
||||
#-----| -> Static
|
||||
#-----| -> enum X
|
||||
#-----| -> fn length
|
||||
#-----| -> impl ...::Display for ...::X { ... }
|
||||
#-----| -> impl AsString for ...::X { ... }
|
||||
#-----| -> struct X_List
|
||||
#-----| -> trait AsString
|
||||
|
||||
#-----| struct X_List
|
||||
|
||||
#-----| trait AsString
|
||||
#-----| -> fn as_string
|
||||
45
rust/ql/test/extractor-tests/crate_graph/modules.ql
Normal file
45
rust/ql/test/extractor-tests/crate_graph/modules.ql
Normal file
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* @id module-graph
|
||||
* @name Module and Item Graph
|
||||
* @kind graph
|
||||
*/
|
||||
|
||||
import rust
|
||||
|
||||
predicate nodes(Item i) { i instanceof RelevantNode }
|
||||
|
||||
class RelevantNode extends Item {
|
||||
RelevantNode() {
|
||||
this.getParentNode*() =
|
||||
any(Crate m | m.getName() = "test" and m.getVersion() = "0.0.1").getModule()
|
||||
}
|
||||
}
|
||||
|
||||
predicate edges(RelevantNode container, RelevantNode element) {
|
||||
element = container.(Module).getItemList().getAnItem() or
|
||||
element = container.(Impl).getAssocItemList().getAnAssocItem() or
|
||||
element = container.(Trait).getAssocItemList().getAnAssocItem()
|
||||
}
|
||||
|
||||
query predicate nodes(RelevantNode node, string attr, string val) {
|
||||
nodes(node) and
|
||||
(
|
||||
attr = "semmle.label" and
|
||||
val = node.toString()
|
||||
or
|
||||
attr = "semmle.order" and
|
||||
val =
|
||||
any(int i | node = rank[i](RelevantNode n | nodes(n) | n order by n.toString())).toString()
|
||||
)
|
||||
}
|
||||
|
||||
query predicate edges(RelevantNode pred, RelevantNode succ, string attr, string val) {
|
||||
edges(pred, succ) and
|
||||
(
|
||||
attr = "semmle.label" and
|
||||
val = ""
|
||||
or
|
||||
attr = "semmle.order" and
|
||||
val = any(int i | succ = rank[i](Item s | edges(pred, s) | s order by s.toString())).toString()
|
||||
)
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user