Merge branch 'main' into rust-improve-cfg

This commit is contained in:
Simon Friis Vindum
2024-09-18 09:51:16 +02:00
16 changed files with 239 additions and 31 deletions

View File

@@ -0,0 +1,4 @@
---
category: breaking
---
* C#: Add support for MaD directly on properties and indexers using *attributes*. Using `Attribute.Getter` or `Attribute.Setter` in the model `ext` field applies the model to the getter or setter for properties and indexers. Prior to this change `Attribute` models unintentionally worked for property setters (if the property is decorated with the matching attribute). That is, a model that uses the `Attribute` feature directly on a property for a property setter needs to be changed to `Attribute.Setter`.

View File

@@ -28,11 +28,14 @@
* types can be short names or fully qualified names (mixing these two options
* is not allowed within a single signature).
* 6. The `ext` column specifies additional API-graph-like edges. Currently
* there are only two valid values: "" and "Attribute". The empty string has no
* effect. "Attribute" applies if `name` and `signature` were left blank and
* acts by selecting an element that is attributed with the attribute type
* selected by the first 4 columns. This can be another member such as a field,
* property, method, or parameter.
* there are only a few valid values: "", "Attribute", "Attribute.Getter" and "Attribute.Setter".
* The empty string has no effect. "Attribute" applies if `name` and `signature` were left blank
* and acts by selecting an element (except for properties and indexers) that is attributed with
* the attribute type selected by the first 4 columns. This can be another member such as
* a field, method, or parameter. "Attribute.Getter" and "Attribute.Setter" work similar to
* "Attribute", except that they can only be applied to properties and indexers.
* "Attribute.Setter" selects the setter element of a property/indexer and "Attribute.Getter"
* selects the getter.
* 7. The `input` column specifies how data enters the element selected by the
* first 6 columns, and the `output` column specifies how data leaves the
* element selected by the first 6 columns. For sinks, an `input` can be either "",
@@ -96,6 +99,7 @@ private import FlowSummaryImpl::Private::External
private import semmle.code.csharp.commons.QualifiedName
private import semmle.code.csharp.dispatch.OverridableCallable
private import semmle.code.csharp.frameworks.System
private import codeql.dataflow.internal.AccessPathSyntax as AccessPathSyntax
private import codeql.mad.ModelValidation as SharedModelVal
/**
@@ -194,8 +198,6 @@ predicate modelCoverage(string namespace, int namespaces, string kind, string pa
/** Provides a query predicate to check the MaD models for validation errors. */
module ModelValidation {
private import codeql.dataflow.internal.AccessPathSyntax as AccessPathSyntax
private predicate getRelevantAccessPath(string path) {
summaryModel(_, _, _, _, _, _, path, _, _, _, _) or
summaryModel(_, _, _, _, _, _, _, path, _, _, _) or
@@ -289,7 +291,7 @@ module ModelValidation {
not signature.regexpMatch("|\\([a-zA-Z0-9_<>\\.\\+\\*,\\[\\]]*\\)") and
result = "Dubious signature \"" + signature + "\" in " + pred + " model."
or
not ext.regexpMatch("|Attribute") and
not ext = ["", "Attribute", "Attribute.Getter", "Attribute.Setter"] and
result = "Unrecognized extra API graph element \"" + ext + "\" in " + pred + " model."
or
invalidProvenance(provenance) and
@@ -406,6 +408,30 @@ Declaration interpretBaseDeclaration(string namespace, string type, string name,
)
}
pragma[inline]
private Declaration interpretExt(Declaration d, ExtPath ext) {
ext = "" and result = d
or
ext.getToken(0) = "Attribute" and
(
not exists(ext.getToken(1)) and
result.(Attributable).getAnAttribute().getType() = d and
not result instanceof Property and
not result instanceof Indexer
or
exists(string accessor | accessor = ext.getToken(1) |
result.(Accessor).getDeclaration().getAnAttribute().getType() = d and
(
result instanceof Getter and
accessor = "Getter"
or
result instanceof Setter and
accessor = "Setter"
)
)
)
}
/** Gets the source/sink/summary/neutral element corresponding to the supplied parameters. */
pragma[nomagic]
Declaration interpretElement(
@@ -425,12 +451,18 @@ Declaration interpretElement(
)
)
|
ext = "" and result = d
or
ext = "Attribute" and result.(Attributable).getAnAttribute().getType() = d
result = interpretExt(d, ext)
)
}
private predicate relevantExt(string ext) {
summaryModel(_, _, _, _, _, ext, _, _, _, _, _) or
sourceModel(_, _, _, _, _, ext, _, _, _, _) or
sinkModel(_, _, _, _, _, ext, _, _, _, _)
}
private class ExtPath = AccessPathSyntax::AccessPath<relevantExt/1>::AccessPath;
private predicate parseSynthField(AccessPathToken c, string name) {
c.getName() = "SyntheticField" and name = c.getAnArgument()
}

View File

@@ -12,6 +12,12 @@ namespace My.Qltest
object fieldWrite = new object();
TaggedField = fieldWrite;
object propertyWrite = new object();
TaggedPropertySetter = propertyWrite;
object indexerWrite = new object();
this[0] = indexerWrite;
}
object SinkMethod()
@@ -34,7 +40,21 @@ namespace My.Qltest
[SinkAttribute]
object TaggedField;
[SinkPropertyAttribute]
object TaggedPropertySetter { get; set; }
[SinkIndexerAttribute]
object this[int index]
{
get { return null; }
set { }
}
}
class SinkAttribute : System.Attribute { }
}
class SinkPropertyAttribute : System.Attribute { }
class SinkIndexerAttribute : System.Attribute { }
}

View File

@@ -18,14 +18,17 @@ namespace My.Qltest
x = TaggedSrcField;
x = SrcTwoArg("", "");
x = TaggedSrcPropertyGetter;
x = this[0];
}
[SourceAttribute()]
[SourceAttribute]
void Tagged1(object taggedMethodParam)
{
}
void Tagged2([SourceAttribute()] object taggedSrcParam)
void Tagged2([SourceAttribute] object taggedSrcParam)
{
}
@@ -49,14 +52,20 @@ namespace My.Qltest
void SrcArg(object src) { }
[SourceAttribute()]
[SourceAttribute]
object TaggedSrcMethod() { return null; }
[SourceAttribute()]
[SourceAttribute]
object TaggedSrcField;
object SrcTwoArg(string s1, string s2) { return null; }
[SourceAttribute]
object TaggedSrcPropertyGetter { get; }
[SourceAttribute]
object this[int i] => null;
}
class SourceAttribute : System.Attribute { }
}
}

View File

@@ -4,5 +4,7 @@ invalidModelRow
| Sinks.cs:11:13:11:41 | this access | file-content-store |
| Sinks.cs:11:30:11:40 | access to local variable argToTagged | file-content-store |
| Sinks.cs:14:27:14:36 | access to local variable fieldWrite | sql-injection |
| Sinks.cs:20:20:20:22 | access to local variable res | js-injection |
| Sinks.cs:27:20:27:25 | access to local variable resTag | html-injection |
| Sinks.cs:17:36:17:48 | access to local variable propertyWrite | sql-injection |
| Sinks.cs:20:23:20:34 | access to local variable indexerWrite | sql-injection |
| Sinks.cs:26:20:26:22 | access to local variable res | js-injection |
| Sinks.cs:33:20:33:25 | access to local variable resTag | html-injection |

View File

@@ -9,3 +9,5 @@ extensions:
- ["My.Qltest", "SinkAttribute", false, "", "", "Attribute", "ReturnValue", "html-injection", "manual"]
- ["My.Qltest", "SinkAttribute", false, "", "", "Attribute", "Argument", "file-content-store", "manual"]
- ["My.Qltest", "SinkAttribute", false, "", "", "Attribute", "", "sql-injection", "manual"]
- ["My.Qltest", "SinkPropertyAttribute", false, "", "", "Attribute.Setter", "Argument[0]", "sql-injection", "manual"]
- ["My.Qltest", "SinkIndexerAttribute", false, "", "", "Attribute.Setter", "Argument[1]", "sql-injection", "manual"]

View File

@@ -9,9 +9,11 @@ invalidModelRow
| Sources.cs:17:17:17:33 | call to method TaggedSrcMethod | local |
| Sources.cs:18:17:18:30 | access to field TaggedSrcField | local |
| Sources.cs:20:17:20:33 | call to method SrcTwoArg | local |
| Sources.cs:24:14:24:20 | this | local |
| Sources.cs:24:29:24:45 | taggedMethodParam | local |
| Sources.cs:28:49:28:62 | taggedSrcParam | local |
| Sources.cs:40:45:40:45 | p | local |
| Sources.cs:47:50:47:50 | p | local |
| Sources.cs:53:16:53:30 | this | local |
| Sources.cs:22:17:22:39 | access to property TaggedSrcPropertyGetter | local |
| Sources.cs:23:17:23:23 | access to indexer | local |
| Sources.cs:27:14:27:20 | this | local |
| Sources.cs:27:29:27:45 | taggedMethodParam | local |
| Sources.cs:31:47:31:60 | taggedSrcParam | local |
| Sources.cs:43:45:43:45 | p | local |
| Sources.cs:50:50:50:50 | p | local |
| Sources.cs:56:16:56:30 | this | local |

View File

@@ -17,4 +17,5 @@ extensions:
- ["My.Qltest", "SourceAttribute", false, "", "", "Attribute", "ReturnValue", "local", "manual"]
- ["My.Qltest", "SourceAttribute", false, "", "", "Attribute", "Parameter", "local", "manual"]
- ["My.Qltest", "SourceAttribute", false, "", "", "Attribute", "", "local", "manual"]
- ["My.Qltest", "A", false, "SrcTwoArg", "(System.String,System.String)", "", "ReturnValue", "local", "manual"]
- ["My.Qltest", "SourceAttribute", false, "", "", "Attribute.Getter", "ReturnValue", "local", "manual"]
- ["My.Qltest", "A", false, "SrcTwoArg", "(System.String,System.String)", "", "ReturnValue", "local", "manual"]

View File

@@ -147,7 +147,14 @@ private module CaptureInput implements VariableCapture::InputSig<Location> {
}
class Callable extends J::Callable {
predicate isConstructor() { this instanceof Constructor }
predicate isConstructor() {
// InstanceInitializers are called from constructors and are equally likely
// to capture variables for the purpose of field initialization, so we treat
// them as constructors for the heuristic identification of whether to allow
// this-to-this summaries.
this instanceof Constructor or
this instanceof InstanceInitializer
}
}
}

View File

@@ -248,4 +248,35 @@ public class B {
sink(l.get(0)); // $ hasValueFlow=src
sink(l2.get(0)); // $ hasValueFlow=src
}
void testInstanceInitializer() {
// Tests capture in the instance initializer ("<obinit>")
String s = source("init");
class MyLocal3 {
String f = s;
void run() {
sink(this.f); // $ hasValueFlow=init
}
}
new MyLocal3().run();
}
void testConstructorIndirection() {
// Tests capture in nested constructor call
String s = source("init");
class MyLocal4 {
String f;
MyLocal4() {
this(42);
}
MyLocal4(int i) {
f = s;
}
String get() {
return this.f;
}
}
sink(new MyLocal4().get()); // $ hasValueFlow=init
sink(new MyLocal4(1).get()); // $ hasValueFlow=init
}
}

View File

@@ -254,6 +254,46 @@ edges
| B.java:247:5:247:18 | new MyLocal2(...) [pre constructor] : MyLocal2 [String s] : String | B.java:247:5:247:18 | new MyLocal2(...) : MyLocal2 [List<String> l, <element>] : String | provenance | MaD:2 |
| B.java:248:10:248:10 | l : ArrayList [<element>] : String | B.java:248:10:248:17 | get(...) | provenance | MaD:3 |
| B.java:249:10:249:11 | l2 : ArrayList [<element>] : String | B.java:249:10:249:18 | get(...) | provenance | MaD:3 |
| B.java:254:16:254:29 | source(...) : String | B.java:261:5:261:18 | String s : String | provenance | |
| B.java:255:11:255:18 | parameter this : MyLocal3 [String s] : String | B.java:255:11:255:18 | this <.method> : MyLocal3 [String s] : String | provenance | |
| B.java:255:11:255:18 | parameter this : MyLocal3 [String s] : String | B.java:256:18:256:18 | this : MyLocal3 [String s] : String | provenance | |
| B.java:255:11:255:18 | this <.method> : MyLocal3 [String s] : String | B.java:255:11:255:18 | parameter this : MyLocal3 [String s] : String | provenance | |
| B.java:255:11:255:18 | this <.method> : MyLocal3 [String s] : String | B.java:255:11:255:18 | this <.method> [post update] : MyLocal3 [f] : String | provenance | |
| B.java:255:11:255:18 | this <.method> [post update] : MyLocal3 [f] : String | B.java:255:11:255:18 | parameter this [Return] : MyLocal3 [f] : String | provenance | |
| B.java:256:7:256:19 | this <.field> [post update] : MyLocal3 [f] : String | B.java:255:11:255:18 | parameter this [Return] : MyLocal3 [f] : String | provenance | |
| B.java:256:18:256:18 | s : String | B.java:256:7:256:19 | this <.field> [post update] : MyLocal3 [f] : String | provenance | |
| B.java:256:18:256:18 | this : MyLocal3 [String s] : String | B.java:256:18:256:18 | s : String | provenance | |
| B.java:257:12:257:14 | parameter this : MyLocal3 [f] : String | B.java:258:14:258:17 | this : MyLocal3 [f] : String | provenance | |
| B.java:258:14:258:17 | this : MyLocal3 [f] : String | B.java:258:14:258:19 | this.f | provenance | |
| B.java:261:5:261:18 | String s : String | B.java:261:5:261:18 | new MyLocal3(...) [pre constructor] : MyLocal3 [String s] : String | provenance | |
| B.java:261:5:261:18 | new MyLocal3(...) : MyLocal3 [f] : String | B.java:257:12:257:14 | parameter this : MyLocal3 [f] : String | provenance | |
| B.java:261:5:261:18 | new MyLocal3(...) [pre constructor] : MyLocal3 [String s] : String | B.java:255:11:255:18 | parameter this : MyLocal3 [String s] : String | provenance | |
| B.java:261:5:261:18 | new MyLocal3(...) [pre constructor] : MyLocal3 [String s] : String | B.java:261:5:261:18 | new MyLocal3(...) : MyLocal3 [f] : String | provenance | |
| B.java:266:16:266:29 | source(...) : String | B.java:279:10:279:23 | String s : String | provenance | |
| B.java:266:16:266:29 | source(...) : String | B.java:280:10:280:24 | String s : String | provenance | |
| B.java:269:7:269:14 | parameter this : MyLocal4 [String s] : String | B.java:270:9:270:17 | this <constr(this)> : MyLocal4 [String s] : String | provenance | |
| B.java:270:9:270:17 | this <constr(this)> : MyLocal4 [String s] : String | B.java:270:9:270:17 | this <constr(this)> [post update] : MyLocal4 [f] : String | provenance | |
| B.java:270:9:270:17 | this <constr(this)> : MyLocal4 [String s] : String | B.java:272:7:272:14 | parameter this : MyLocal4 [String s] : String | provenance | |
| B.java:270:9:270:17 | this <constr(this)> [post update] : MyLocal4 [f] : String | B.java:269:7:269:14 | parameter this [Return] : MyLocal4 [f] : String | provenance | |
| B.java:272:7:272:14 | parameter this : MyLocal4 [String s] : String | B.java:273:13:273:13 | this : MyLocal4 [String s] : String | provenance | |
| B.java:273:9:273:9 | this <.field> [post update] : MyLocal4 [f] : String | B.java:272:7:272:14 | parameter this [Return] : MyLocal4 [f] : String | provenance | |
| B.java:273:13:273:13 | s : String | B.java:273:9:273:9 | this <.field> [post update] : MyLocal4 [f] : String | provenance | |
| B.java:273:13:273:13 | this : MyLocal4 [String s] : String | B.java:273:13:273:13 | s : String | provenance | |
| B.java:275:14:275:16 | parameter this : MyLocal4 [f] : String | B.java:276:16:276:19 | this : MyLocal4 [f] : String | provenance | |
| B.java:276:16:276:19 | this : MyLocal4 [f] : String | B.java:276:16:276:21 | this.f : String | provenance | |
| B.java:279:10:279:23 | String s : String | B.java:279:10:279:23 | new MyLocal4(...) : MyLocal4 [String s] : String | provenance | |
| B.java:279:10:279:23 | String s : String | B.java:279:10:279:23 | new MyLocal4(...) [pre constructor] : MyLocal4 [String s] : String | provenance | |
| B.java:279:10:279:23 | String s : String | B.java:280:10:280:24 | String s : String | provenance | |
| B.java:279:10:279:23 | new MyLocal4(...) : MyLocal4 [String s] : String | B.java:279:10:279:23 | String s : String | provenance | |
| B.java:279:10:279:23 | new MyLocal4(...) : MyLocal4 [f] : String | B.java:275:14:275:16 | parameter this : MyLocal4 [f] : String | provenance | |
| B.java:279:10:279:23 | new MyLocal4(...) : MyLocal4 [f] : String | B.java:279:10:279:29 | get(...) | provenance | |
| B.java:279:10:279:23 | new MyLocal4(...) [pre constructor] : MyLocal4 [String s] : String | B.java:269:7:269:14 | parameter this : MyLocal4 [String s] : String | provenance | |
| B.java:279:10:279:23 | new MyLocal4(...) [pre constructor] : MyLocal4 [String s] : String | B.java:279:10:279:23 | new MyLocal4(...) : MyLocal4 [f] : String | provenance | |
| B.java:280:10:280:24 | String s : String | B.java:280:10:280:24 | new MyLocal4(...) [pre constructor] : MyLocal4 [String s] : String | provenance | |
| B.java:280:10:280:24 | new MyLocal4(...) : MyLocal4 [f] : String | B.java:275:14:275:16 | parameter this : MyLocal4 [f] : String | provenance | |
| B.java:280:10:280:24 | new MyLocal4(...) : MyLocal4 [f] : String | B.java:280:10:280:30 | get(...) | provenance | |
| B.java:280:10:280:24 | new MyLocal4(...) [pre constructor] : MyLocal4 [String s] : String | B.java:272:7:272:14 | parameter this : MyLocal4 [String s] : String | provenance | |
| B.java:280:10:280:24 | new MyLocal4(...) [pre constructor] : MyLocal4 [String s] : String | B.java:280:10:280:24 | new MyLocal4(...) : MyLocal4 [f] : String | provenance | |
nodes
| B.java:11:5:11:6 | l1 [post update] : ArrayList [<element>] : String | semmle.label | l1 [post update] : ArrayList [<element>] : String |
| B.java:11:12:11:22 | source(...) : String | semmle.label | source(...) : String |
@@ -511,6 +551,45 @@ nodes
| B.java:248:10:248:17 | get(...) | semmle.label | get(...) |
| B.java:249:10:249:11 | l2 : ArrayList [<element>] : String | semmle.label | l2 : ArrayList [<element>] : String |
| B.java:249:10:249:18 | get(...) | semmle.label | get(...) |
| B.java:254:16:254:29 | source(...) : String | semmle.label | source(...) : String |
| B.java:255:11:255:18 | parameter this : MyLocal3 [String s] : String | semmle.label | parameter this : MyLocal3 [String s] : String |
| B.java:255:11:255:18 | parameter this : MyLocal3 [String s] : String | semmle.label | parameter this : MyLocal3 [String s] : String |
| B.java:255:11:255:18 | parameter this [Return] : MyLocal3 [f] : String | semmle.label | parameter this [Return] : MyLocal3 [f] : String |
| B.java:255:11:255:18 | parameter this [Return] : MyLocal3 [f] : String | semmle.label | parameter this [Return] : MyLocal3 [f] : String |
| B.java:255:11:255:18 | this <.method> : MyLocal3 [String s] : String | semmle.label | this <.method> : MyLocal3 [String s] : String |
| B.java:255:11:255:18 | this <.method> [post update] : MyLocal3 [f] : String | semmle.label | this <.method> [post update] : MyLocal3 [f] : String |
| B.java:256:7:256:19 | this <.field> [post update] : MyLocal3 [f] : String | semmle.label | this <.field> [post update] : MyLocal3 [f] : String |
| B.java:256:18:256:18 | s : String | semmle.label | s : String |
| B.java:256:18:256:18 | this : MyLocal3 [String s] : String | semmle.label | this : MyLocal3 [String s] : String |
| B.java:257:12:257:14 | parameter this : MyLocal3 [f] : String | semmle.label | parameter this : MyLocal3 [f] : String |
| B.java:258:14:258:17 | this : MyLocal3 [f] : String | semmle.label | this : MyLocal3 [f] : String |
| B.java:258:14:258:19 | this.f | semmle.label | this.f |
| B.java:261:5:261:18 | String s : String | semmle.label | String s : String |
| B.java:261:5:261:18 | new MyLocal3(...) : MyLocal3 [f] : String | semmle.label | new MyLocal3(...) : MyLocal3 [f] : String |
| B.java:261:5:261:18 | new MyLocal3(...) [pre constructor] : MyLocal3 [String s] : String | semmle.label | new MyLocal3(...) [pre constructor] : MyLocal3 [String s] : String |
| B.java:266:16:266:29 | source(...) : String | semmle.label | source(...) : String |
| B.java:269:7:269:14 | parameter this : MyLocal4 [String s] : String | semmle.label | parameter this : MyLocal4 [String s] : String |
| B.java:269:7:269:14 | parameter this [Return] : MyLocal4 [f] : String | semmle.label | parameter this [Return] : MyLocal4 [f] : String |
| B.java:270:9:270:17 | this <constr(this)> : MyLocal4 [String s] : String | semmle.label | this <constr(this)> : MyLocal4 [String s] : String |
| B.java:270:9:270:17 | this <constr(this)> [post update] : MyLocal4 [f] : String | semmle.label | this <constr(this)> [post update] : MyLocal4 [f] : String |
| B.java:272:7:272:14 | parameter this : MyLocal4 [String s] : String | semmle.label | parameter this : MyLocal4 [String s] : String |
| B.java:272:7:272:14 | parameter this [Return] : MyLocal4 [f] : String | semmle.label | parameter this [Return] : MyLocal4 [f] : String |
| B.java:273:9:273:9 | this <.field> [post update] : MyLocal4 [f] : String | semmle.label | this <.field> [post update] : MyLocal4 [f] : String |
| B.java:273:13:273:13 | s : String | semmle.label | s : String |
| B.java:273:13:273:13 | this : MyLocal4 [String s] : String | semmle.label | this : MyLocal4 [String s] : String |
| B.java:275:14:275:16 | parameter this : MyLocal4 [f] : String | semmle.label | parameter this : MyLocal4 [f] : String |
| B.java:276:16:276:19 | this : MyLocal4 [f] : String | semmle.label | this : MyLocal4 [f] : String |
| B.java:276:16:276:21 | this.f : String | semmle.label | this.f : String |
| B.java:279:10:279:23 | String s : String | semmle.label | String s : String |
| B.java:279:10:279:23 | String s : String | semmle.label | String s : String |
| B.java:279:10:279:23 | new MyLocal4(...) : MyLocal4 [String s] : String | semmle.label | new MyLocal4(...) : MyLocal4 [String s] : String |
| B.java:279:10:279:23 | new MyLocal4(...) : MyLocal4 [f] : String | semmle.label | new MyLocal4(...) : MyLocal4 [f] : String |
| B.java:279:10:279:23 | new MyLocal4(...) [pre constructor] : MyLocal4 [String s] : String | semmle.label | new MyLocal4(...) [pre constructor] : MyLocal4 [String s] : String |
| B.java:279:10:279:29 | get(...) | semmle.label | get(...) |
| B.java:280:10:280:24 | String s : String | semmle.label | String s : String |
| B.java:280:10:280:24 | new MyLocal4(...) : MyLocal4 [f] : String | semmle.label | new MyLocal4(...) : MyLocal4 [f] : String |
| B.java:280:10:280:24 | new MyLocal4(...) [pre constructor] : MyLocal4 [String s] : String | semmle.label | new MyLocal4(...) [pre constructor] : MyLocal4 [String s] : String |
| B.java:280:10:280:30 | get(...) | semmle.label | get(...) |
subpaths
| B.java:13:5:13:6 | l1 : ArrayList [<element>] : String | B.java:13:16:13:16 | e : String | B.java:13:16:13:29 | parameter this [Return] : new Consumer<String>(...) { ... } [List<String> l2, <element>] : String | B.java:13:16:13:29 | ...->... [post update] : new Consumer<String>(...) { ... } [List<String> l2, <element>] : String |
| B.java:30:14:30:24 | source(...) : String | B.java:22:26:22:26 | x : String | B.java:22:26:22:71 | parameter this [Return] : new Consumer<String>(...) { ... } [B other, bf1] : String | B.java:30:5:30:5 | f [post update] : new Consumer<String>(...) { ... } [B other, bf1] : String |
@@ -530,4 +609,11 @@ subpaths
| B.java:178:10:178:11 | m2 : MyLocal [List<String> l, <element>] : String | B.java:169:14:169:16 | parameter this : MyLocal [List<String> l, <element>] : String | B.java:170:16:170:23 | get(...) : String | B.java:178:10:178:17 | get(...) |
| B.java:247:5:247:18 | new MyLocal2(...) : MyLocal2 [List<String> l, <element>] : String | B.java:240:12:240:14 | parameter this : MyLocal2 [List<String> l, <element>] : String | B.java:240:12:240:14 | parameter this [Return] : MyLocal2 [List<String> l2, <element>] : String | B.java:247:5:247:18 | new MyLocal2(...) [post update] : MyLocal2 [List<String> l2, <element>] : String |
| B.java:247:5:247:18 | new MyLocal2(...) [pre constructor] : MyLocal2 [String s] : String | B.java:235:7:235:14 | parameter this : MyLocal2 [String s] : String | B.java:235:7:235:14 | parameter this [Return] : MyLocal2 [List<String> l, <element>] : String | B.java:247:5:247:18 | new MyLocal2(...) : MyLocal2 [List<String> l, <element>] : String |
| B.java:255:11:255:18 | this <.method> : MyLocal3 [String s] : String | B.java:255:11:255:18 | parameter this : MyLocal3 [String s] : String | B.java:255:11:255:18 | parameter this [Return] : MyLocal3 [f] : String | B.java:255:11:255:18 | this <.method> [post update] : MyLocal3 [f] : String |
| B.java:261:5:261:18 | new MyLocal3(...) [pre constructor] : MyLocal3 [String s] : String | B.java:255:11:255:18 | parameter this : MyLocal3 [String s] : String | B.java:255:11:255:18 | parameter this [Return] : MyLocal3 [f] : String | B.java:261:5:261:18 | new MyLocal3(...) : MyLocal3 [f] : String |
| B.java:270:9:270:17 | this <constr(this)> : MyLocal4 [String s] : String | B.java:272:7:272:14 | parameter this : MyLocal4 [String s] : String | B.java:272:7:272:14 | parameter this [Return] : MyLocal4 [f] : String | B.java:270:9:270:17 | this <constr(this)> [post update] : MyLocal4 [f] : String |
| B.java:279:10:279:23 | new MyLocal4(...) : MyLocal4 [f] : String | B.java:275:14:275:16 | parameter this : MyLocal4 [f] : String | B.java:276:16:276:21 | this.f : String | B.java:279:10:279:29 | get(...) |
| B.java:279:10:279:23 | new MyLocal4(...) [pre constructor] : MyLocal4 [String s] : String | B.java:269:7:269:14 | parameter this : MyLocal4 [String s] : String | B.java:269:7:269:14 | parameter this [Return] : MyLocal4 [f] : String | B.java:279:10:279:23 | new MyLocal4(...) : MyLocal4 [f] : String |
| B.java:280:10:280:24 | new MyLocal4(...) : MyLocal4 [f] : String | B.java:275:14:275:16 | parameter this : MyLocal4 [f] : String | B.java:276:16:276:21 | this.f : String | B.java:280:10:280:30 | get(...) |
| B.java:280:10:280:24 | new MyLocal4(...) [pre constructor] : MyLocal4 [String s] : String | B.java:272:7:272:14 | parameter this : MyLocal4 [String s] : String | B.java:272:7:272:14 | parameter this [Return] : MyLocal4 [f] : String | B.java:280:10:280:24 | new MyLocal4(...) : MyLocal4 [f] : String |
testFailures

View File

@@ -2,6 +2,7 @@ load("//misc/bazel:pkg.bzl", "codeql_pkg_files")
codeql_pkg_files(
name = "tools",
srcs = glob(["*.cmd"]),
exes = glob(["*.sh"]),
visibility = ["//rust:__pkg__"],
)

5
rust/tools/autobuild.cmd Normal file
View File

@@ -0,0 +1,5 @@
@echo off
type NUL && "%CODEQL_DIST%\codeql.exe" database index-files --working-dir=. --language=rust --include-extension=.rs "%CODEQL_EXTRACTOR_RUST_WIP_DATABASE%"
exit /b %ERRORLEVEL%

View File

@@ -2,5 +2,4 @@
exec "${CODEQL_DIST}/codeql" database index-files \
--working-dir=. --language=rust --include-extension=.rs \
${CODEQL_VERBOSITY:+"--verbosity=${CODEQL_VERBOSITY}"} \
"${CODEQL_EXTRACTOR_RUST_WIP_DATABASE}"

View File

@@ -0,0 +1,5 @@
@echo off
type NUL && "%CODEQL_EXTRACTOR_RUST_ROOT%\tools\%CODEQL_PLATFORM%\extractor" @"%1"
exit /b %ERRORLEVEL%

View File

@@ -585,11 +585,13 @@ module Flow<LocationSig Location, InputSig<Location> Input> implements OutputSig
2 <= strictcount(CapturedVariable v | captureAccess(v, c))
or
// Constructors that capture a variable may assign it to a field, which also
// entails a this-to-this summary.
captureAccess(_, c) and c.isConstructor()
// entails a this-to-this summary. If there are multiple constructors, then
// they might call each other, so if one constructor captures a variable we
// allow this-to-this summaries for all of them.
exists(ClosureExpr ce | ce.hasBody(c) and c.isConstructor() and hasConstructorCapture(ce, _))
}
/** Holds if the constructor, if any, for the closure defined by `ce` captures `v`. */
/** Holds if a constructor, if any, for the closure defined by `ce` captures `v`. */
private predicate hasConstructorCapture(ClosureExpr ce, CapturedVariable v) {
exists(Callable c | ce.hasBody(c) and c.isConstructor() and captureAccess(v, c))
}