Merge branch 'main' into redsun82/rust-less-canonical-paths

This commit is contained in:
Paolo Tranquilli
2024-12-03 12:19:08 +01:00
100 changed files with 2843 additions and 787 deletions

View File

@@ -1,4 +1,5 @@
{
"image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04",
"extensions": [
"rust-lang.rust-analyzer",
"bungcip.better-toml",

View File

@@ -42,3 +42,6 @@ MODULE.bazel @github/codeql-ci-reviewers
# Misc
/misc/scripts/accept-expected-changes-from-ci.py @RasmusWL
/misc/scripts/generate-code-scanning-query-list.py @RasmusWL
# .devcontainer
/.devcontainer/ @github/codeql-ci-reviewers

View File

@@ -545,7 +545,7 @@ module ProductFlow {
private predicate outImpl1(Flow1::PathNode pred1, Flow1::PathNode succ1, DataFlowCall call) {
Flow1::PathGraph::edges(pred1, succ1, _, _) and
exists(ReturnKindExt returnKind |
succ1.getNode() = returnKind.getAnOutNode(call) and
succ1.getNode() = getAnOutNodeExt(call, returnKind) and
returnKind = getParamReturnPosition(_, pred1.asParameterReturnNode()).getKind()
)
}
@@ -573,7 +573,7 @@ module ProductFlow {
private predicate outImpl2(Flow2::PathNode pred2, Flow2::PathNode succ2, DataFlowCall call) {
Flow2::PathGraph::edges(pred2, succ2, _, _) and
exists(ReturnKindExt returnKind |
succ2.getNode() = returnKind.getAnOutNode(call) and
succ2.getNode() = getAnOutNodeExt(call, returnKind) and
returnKind = getParamReturnPosition(_, pred2.asParameterReturnNode()).getKind()
)
}

View File

@@ -61,5 +61,21 @@
],
"env": {}
},
{
"name": "C#: Tracing Debug",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "dotnet: build",
"program": "${workspaceFolder}/extractor/Semmle.Extraction.CSharp.Driver/bin/Debug/net9.0/Semmle.Extraction.CSharp.Driver.dll",
// Set the path to the folder that should be extracted:
"cwd": "${workspaceFolder}/ql/test/library-tests/dataflow/local",
"args": [
"LocalDataFlow.cs"
],
"env": {},
"stopAtEntry": true,
"justMyCode": false,
"suppressJITOptimizations": true
},
]
}

View File

@@ -13,6 +13,8 @@ JsonToItemsTaskFactory,,,11,,,,,,,,,,,,,,,,,,,1,10
Microsoft.Android.Build,,1,14,,,,,,,,,,,,,1,,,,,,12,2
Microsoft.Apple.Build,,,7,,,,,,,,,,,,,,,,,,,7,
Microsoft.ApplicationBlocks.Data,28,,,,,,,,,,,,28,,,,,,,,,,
Microsoft.AspNetCore.Components,,2,1,,,,,,,,,,,,,,,,2,,,1,
Microsoft.AspNetCore.WebUtilities,,,2,,,,,,,,,,,,,,,,,,,2,
Microsoft.CSharp,,,2,,,,,,,,,,,,,,,,,,,2,
Microsoft.Diagnostics.Tools.Pgo,,,25,,,,,,,,,,,,,,,,,,,2,23
Microsoft.DotNet.Build.Tasks,,,10,,,,,,,,,,,,,,,,,,,8,2
@@ -44,5 +46,5 @@ MySql.Data.MySqlClient,48,,,,,,,,,,,,48,,,,,,,,,,
Newtonsoft.Json,,,91,,,,,,,,,,,,,,,,,,,73,18
ServiceStack,194,,7,27,,,,,75,,,,92,,,,,,,,,7,
SourceGenerators,,,5,,,,,,,,,,,,,,,,,,,,5
System,54,47,10818,,6,5,5,,,4,1,,33,2,,6,15,17,4,3,,5511,5307
System,54,47,10819,,6,5,5,,,4,1,,33,2,,6,15,17,4,3,,5512,5307
Windows.Security.Cryptography.Core,1,,,,,,,1,,,,,,,,,,,,,,,
1 package sink source summary sink:code-injection sink:encryption-decryptor sink:encryption-encryptor sink:encryption-keyprop sink:encryption-symmetrickey sink:file-content-store sink:html-injection sink:js-injection sink:log-injection sink:sql-injection source:commandargs source:database source:environment source:file source:file-write source:remote source:stdin source:windows-registry summary:taint summary:value
13 Microsoft.Android.Build 1 14 1 12 2
14 Microsoft.Apple.Build 7 7
15 Microsoft.ApplicationBlocks.Data 28 28
16 Microsoft.AspNetCore.Components 2 1 2 1
17 Microsoft.AspNetCore.WebUtilities 2 2
18 Microsoft.CSharp 2 2
19 Microsoft.Diagnostics.Tools.Pgo 25 2 23
20 Microsoft.DotNet.Build.Tasks 10 8 2
46 Newtonsoft.Json 91 73 18
47 ServiceStack 194 7 27 75 92 7
48 SourceGenerators 5 5
49 System 54 47 10818 10819 6 5 5 4 1 33 2 6 15 17 4 3 5511 5512 5307
50 Windows.Security.Cryptography.Core 1 1

View File

@@ -8,7 +8,7 @@ C# framework & library support
Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE-079` :sub:`Cross-site scripting`
`ServiceStack <https://servicestack.net/>`_,"``ServiceStack.*``, ``ServiceStack``",,7,194,
System,"``System.*``, ``System``",47,10818,54,5
Others,"``Amazon.Lambda.APIGatewayEvents``, ``Amazon.Lambda.Core``, ``Dapper``, ``ILCompiler``, ``ILLink.RoslynAnalyzer``, ``ILLink.Shared``, ``ILLink.Tasks``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``JsonToItemsTaskFactory``, ``Microsoft.Android.Build``, ``Microsoft.Apple.Build``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.CSharp``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.DotNet.Build.Tasks``, ``Microsoft.DotNet.PlatformAbstractions``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.Diagnostics.Metrics``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.JSInterop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NET.Sdk.WebAssembly``, ``Microsoft.NET.WebAssembly.Webcil``, ``Microsoft.VisualBasic``, ``Microsoft.WebAssembly.Build.Tasks``, ``Microsoft.Win32``, ``Mono.Linker``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``SourceGenerators``, ``Windows.Security.Cryptography.Core``",57,2068,150,2
Totals,,104,12893,398,7
System,"``System.*``, ``System``",47,10819,54,5
Others,"``Amazon.Lambda.APIGatewayEvents``, ``Amazon.Lambda.Core``, ``Dapper``, ``ILCompiler``, ``ILLink.RoslynAnalyzer``, ``ILLink.Shared``, ``ILLink.Tasks``, ``Internal.IL``, ``Internal.Pgo``, ``Internal.TypeSystem``, ``JsonToItemsTaskFactory``, ``Microsoft.Android.Build``, ``Microsoft.Apple.Build``, ``Microsoft.ApplicationBlocks.Data``, ``Microsoft.AspNetCore.Components``, ``Microsoft.AspNetCore.WebUtilities``, ``Microsoft.CSharp``, ``Microsoft.Diagnostics.Tools.Pgo``, ``Microsoft.DotNet.Build.Tasks``, ``Microsoft.DotNet.PlatformAbstractions``, ``Microsoft.EntityFrameworkCore``, ``Microsoft.Extensions.Caching.Distributed``, ``Microsoft.Extensions.Caching.Memory``, ``Microsoft.Extensions.Configuration``, ``Microsoft.Extensions.DependencyInjection``, ``Microsoft.Extensions.DependencyModel``, ``Microsoft.Extensions.Diagnostics.Metrics``, ``Microsoft.Extensions.FileProviders``, ``Microsoft.Extensions.FileSystemGlobbing``, ``Microsoft.Extensions.Hosting``, ``Microsoft.Extensions.Http``, ``Microsoft.Extensions.Logging``, ``Microsoft.Extensions.Options``, ``Microsoft.Extensions.Primitives``, ``Microsoft.Interop``, ``Microsoft.JSInterop``, ``Microsoft.NET.Build.Tasks``, ``Microsoft.NET.Sdk.WebAssembly``, ``Microsoft.NET.WebAssembly.Webcil``, ``Microsoft.VisualBasic``, ``Microsoft.WebAssembly.Build.Tasks``, ``Microsoft.Win32``, ``Mono.Linker``, ``MySql.Data.MySqlClient``, ``Newtonsoft.Json``, ``SourceGenerators``, ``Windows.Security.Cryptography.Core``",59,2071,150,2
Totals,,106,12897,398,7

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* .NET 9 is now required to build the C# extractor.

View File

@@ -731,11 +731,9 @@ module LocalFlow {
or
node2 = node1.(LocalFunctionCreationNode).getAnAccess(true)
or
node1 =
unique(FlowSummaryNode n1 |
FlowSummaryImpl::Private::Steps::summaryLocalStep(n1.getSummaryNode(),
node2.(FlowSummaryNode).getSummaryNode(), true, _)
)
FlowSummaryImpl::Private::Steps::summaryLocalMustFlowStep(node1
.(FlowSummaryNode)
.getSummaryNode(), node2.(FlowSummaryNode).getSummaryNode())
}
}

View File

@@ -52,6 +52,7 @@ class ICryptoTransform extends ValueOrRefType {
}
from UnsafeField field
where field.fromSource()
select field,
"Static field '" + field.getName() +
"' contains a 'System.Security.Cryptography.ICryptoTransform' that could be used in an unsafe way."

View File

@@ -68,15 +68,25 @@ module CallTargetStats implements StatsSig {
)
}
private predicate isInitializedWithCollectionInitializer(PropertyCall c) {
private predicate isInitializedWithObjectOrCollectionInitializer(PropertyCall c) {
exists(Property p, AssignExpr assign |
p = c.getProperty() and
assign = c.getParent() and
assign.getLValue() = c and
assign.getRValue() instanceof CollectionInitializer
assign.getRValue() instanceof ObjectOrCollectionInitializer
)
}
private predicate isEventFieldAccess(EventCall c) {
exists(Event e | c.getEvent() = e |
forall(Accessor a | e.getAnAccessor() = a | a.isCompilerGenerated())
)
}
private predicate isTypeParameterInstantiation(ObjectCreation e) {
e.getType() instanceof TypeParameter
}
additional predicate isNotOkCall(Call c) {
not exists(c.getTarget()) and
not c instanceof DelegateCall and
@@ -84,8 +94,10 @@ module CallTargetStats implements StatsSig {
not isNoSetterPropertyCallInConstructor(c) and
not isNoSetterPropertyInitialization(c) and
not isAnonymousObjectMemberDeclaration(c) and
not isInitializedWithCollectionInitializer(c) and
not c.getParent+() instanceof NameOfExpr
not isInitializedWithObjectOrCollectionInitializer(c) and
not c.getParent+() instanceof NameOfExpr and
not isEventFieldAccess(c) and
not isTypeParameterInstantiation(c)
}
int getNumberOfNotOk() { result = count(Call c | isNotOkCall(c)) }

View File

@@ -0,0 +1,4 @@
| Quality.cs:26:19:26:26 | access to indexer | Call without target $@. | Quality.cs:26:19:26:26 | access to indexer | access to indexer |
| Quality.cs:29:21:29:27 | access to indexer | Call without target $@. | Quality.cs:29:21:29:27 | access to indexer | access to indexer |
| Quality.cs:32:9:32:21 | access to indexer | Call without target $@. | Quality.cs:32:9:32:21 | access to indexer | access to indexer |
| Quality.cs:34:21:34:25 | object creation of type null | Call without target $@. | Quality.cs:34:21:34:25 | object creation of type null | object creation of type null |

View File

@@ -4,4 +4,12 @@
| Quality.cs:15:24:15:34 | access to property MyProperty3 | Call without target $@. | Quality.cs:15:24:15:34 | access to property MyProperty3 | access to property MyProperty3 |
| Quality.cs:15:24:15:46 | access to property MyProperty2 | Call without target $@. | Quality.cs:15:24:15:46 | access to property MyProperty2 | access to property MyProperty2 |
| Quality.cs:19:13:19:23 | access to property MyProperty4 | Call without target $@. | Quality.cs:19:13:19:23 | access to property MyProperty4 | access to property MyProperty4 |
| Quality.cs:24:16:24:26 | access to property MyProperty2 | Call without target $@. | Quality.cs:24:16:24:26 | access to property MyProperty2 | access to property MyProperty2 |
| Quality.cs:20:13:20:23 | access to property MyProperty6 | Call without target $@. | Quality.cs:20:13:20:23 | access to property MyProperty6 | access to property MyProperty6 |
| Quality.cs:23:9:23:14 | access to event Event1 | Call without target $@. | Quality.cs:23:9:23:14 | access to event Event1 | access to event Event1 |
| Quality.cs:23:9:23:30 | delegate call | Call without target $@. | Quality.cs:23:9:23:30 | delegate call | delegate call |
| Quality.cs:26:19:26:26 | access to indexer | Call without target $@. | Quality.cs:26:19:26:26 | access to indexer | access to indexer |
| Quality.cs:29:21:29:27 | access to indexer | Call without target $@. | Quality.cs:29:21:29:27 | access to indexer | access to indexer |
| Quality.cs:32:9:32:21 | access to indexer | Call without target $@. | Quality.cs:32:9:32:21 | access to indexer | access to indexer |
| Quality.cs:34:21:34:25 | object creation of type null | Call without target $@. | Quality.cs:34:21:34:25 | object creation of type null | object creation of type null |
| Quality.cs:38:16:38:26 | access to property MyProperty2 | Call without target $@. | Quality.cs:38:16:38:26 | access to property MyProperty2 | access to property MyProperty2 |
| Quality.cs:50:20:50:26 | object creation of type T | Call without target $@. | Quality.cs:50:20:50:26 | object creation of type T | object creation of type T |

View File

@@ -16,8 +16,22 @@ public class Test
new Test()
{
MyProperty4 = { 1, 2, 3 }
MyProperty4 = { 1, 2, 3 },
MyProperty6 = { [1] = "" }
};
Event1.Invoke(this, 5);
var str = "abcd";
var sub = str[..3]; // TODO: this is not an indexer call, but rather a `str.Substring(0, 3)` call.
Span<int> sp = null;
var slice = sp[..3]; // TODO: this is not an indexer call, but rather a `sp.Slice(0, 3)` call.
Span<byte> guidBytes = stackalloc byte[16];
guidBytes[08] = 1; // TODO: this indexer call has no target, because the target is a `ref` returning getter.
new MyList([new(), new Test()]); // TODO: the `new()` call has no target, which is unexpected, as we know at compile time, that this is a `new Test()` call.
}
public int MyProperty1 { get; }
@@ -25,4 +39,20 @@ public class Test
public Test MyProperty3 { get; set; }
public List<int> MyProperty4 { get; }
static int MyProperty5 { get; }
public Dictionary<int, string> MyProperty6 { get; }
public event EventHandler<int> Event1;
class Gen<T> where T : new()
{
public static T Factory()
{
return new T();
}
}
class MyList
{
public MyList(IEnumerable<Test> init) { }
}
}

View File

@@ -0,0 +1,4 @@
---
category: fix
---
* Fixed a bug which meant that promoted fields and methods were missing when the embedded parent was not promoted due to a name clash.

View File

@@ -496,14 +496,15 @@ class StructType extends @structtype, CompositeType {
Field getFieldOfEmbedded(Field embeddedParent, string name, int depth, boolean isEmbedded) {
// embeddedParent is a field of 'this' at depth 'depth - 1'
this.hasFieldCand(_, embeddedParent, depth - 1, true) and
// embeddedParent's type has the result field
exists(StructType embeddedType, Type fieldType |
fieldType = embeddedParent.getType().getUnderlyingType() and
pragma[only_bind_into](embeddedType) =
[fieldType, fieldType.(PointerType).getBaseType().getUnderlyingType()]
|
result = embeddedType.getOwnField(name, isEmbedded)
)
// embeddedParent's type has the result field. Note that it is invalid Go
// to have an embedded field with a named type whose underlying type is a
// pointer, so we don't have to have
// `lookThroughPointerType(embeddedParent.getType().getUnderlyingType())`.
result =
lookThroughPointerType(embeddedParent.getType())
.getUnderlyingType()
.(StructType)
.getOwnField(name, isEmbedded)
}
/**
@@ -523,8 +524,12 @@ class StructType extends @structtype, CompositeType {
private predicate hasFieldCand(string name, Field f, int depth, boolean isEmbedded) {
f = this.getOwnField(name, isEmbedded) and depth = 0
or
not this.hasOwnField(_, name, _, _) and
f = this.getFieldOfEmbedded(_, name, depth, isEmbedded)
f = this.getFieldOfEmbedded(_, name, depth, isEmbedded) and
// If this is a cyclic field and this is not the first time we see this embedded field
// then don't include it as a field candidate to avoid non-termination.
not exists(Type t | lookThroughPointerType(t) = lookThroughPointerType(f.getType()) |
this.hasOwnField(_, name, t, _)
)
}
private predicate hasMethodCand(string name, Method m, int depth) {
@@ -541,15 +546,7 @@ class StructType extends @structtype, CompositeType {
predicate hasField(string name, Type tp) {
exists(int mindepth |
mindepth = min(int depth | this.hasFieldCand(name, _, depth, _)) and
tp = unique(Field f | f = this.getFieldCand(name, mindepth, _)).getType()
)
}
private Field getFieldCand(string name, int depth, boolean isEmbedded) {
result = this.getOwnField(name, isEmbedded) and depth = 0
or
exists(Type embedded | this.hasEmbeddedField(embedded, depth - 1) |
result = embedded.getUnderlyingType().(StructType).getOwnField(name, isEmbedded)
tp = unique(Field f | this.hasFieldCand(name, f, mindepth, _)).getType()
)
}
@@ -564,9 +561,9 @@ class StructType extends @structtype, CompositeType {
* The depth of a field `f` declared in this type is zero.
*/
Field getFieldAtDepth(string name, int depth) {
depth = min(int depthCand | exists(this.getFieldCand(name, depthCand, _))) and
result = this.getFieldCand(name, depth, _) and
strictcount(this.getFieldCand(name, depth, _)) = 1
depth = min(int depthCand | this.hasFieldCand(name, _, depthCand, _)) and
this.hasFieldCand(name, result, depth, _) and
strictcount(Field f | this.hasFieldCand(name, f, depth, _)) = 1
}
Method getMethodAtDepth(string name, int depth) {

View File

@@ -13,8 +13,8 @@
| depth.go:19:2:19:2 | f | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
| embedded.go:4:2:4:2 | A | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
| embedded.go:8:3:8:5 | Baz | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
| embedded.go:13:2:13:4 | Qux | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
| embedded.go:14:2:14:4 | Baz | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
| embedded.go:12:2:12:4 | Qux | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
| embedded.go:13:2:13:4 | Baz | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
| generic.go:4:2:4:11 | valueField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
| generic.go:5:2:5:13 | pointerField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
| generic.go:6:2:6:11 | arrayField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
@@ -26,6 +26,7 @@
| generic.go:21:2:21:9 | mapField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
| generic.go:25:2:25:12 | structField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
| generic.go:29:2:29:13 | pointerField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
| main.go:18:7:18:15 | NameClash | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
| pkg1/embedding.go:19:23:19:26 | base | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/embedding.go:22:27:22:30 | base | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/embedding.go:25:24:25:31 | embedder | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
@@ -36,20 +37,22 @@
| pkg1/promotedStructs.go:14:2:14:7 | PField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/promotedStructs.go:22:22:22:22 | S | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/promotedStructs.go:25:22:25:22 | P | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:4:2:4:2 | f | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:5:2:5:4 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:6:2:6:4 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:10:2:10:4 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:11:2:11:4 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:15:3:15:5 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:16:3:16:5 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:20:3:20:5 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:21:2:21:4 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:25:2:25:4 | val | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:26:2:26:5 | flag | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:30:2:30:5 | flag | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:6:2:6:2 | f | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:7:2:7:4 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:8:2:8:4 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:12:2:12:4 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:13:2:13:4 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:17:3:17:5 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:18:3:18:5 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:22:3:22:5 | Foo | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:23:2:23:4 | Bar | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:27:2:27:4 | val | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:28:2:28:5 | flag | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:32:2:32:5 | flag | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg1/tst.go:62:7:62:15 | NameClash | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 |
| pkg2/tst.go:4:2:4:2 | g | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 |
| pkg2/tst.go:8:2:8:2 | g | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 |
| pkg2/tst.go:17:2:17:8 | NCField | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 |
| struct_tags.go:4:2:4:7 | field1 | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
| struct_tags.go:5:2:5:7 | field2 | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |
| struct_tags.go:9:2:9:7 | field1 | package github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types |

View File

@@ -18,10 +18,11 @@
| depth.go:19:2:19:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.c | f |
| depth.go:19:2:19:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.d | f |
| embedded.go:4:2:4:2 | A | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.Baz | A |
| embedded.go:4:2:4:2 | A | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | A |
| embedded.go:4:2:4:2 | A | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.Qux | A |
| embedded.go:8:3:8:5 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.Qux | Baz |
| embedded.go:13:2:13:4 | Qux | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | Qux |
| embedded.go:14:2:14:4 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | Baz |
| embedded.go:12:2:12:4 | Qux | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | Qux |
| embedded.go:13:2:13:4 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz | Baz |
| generic.go:4:2:4:11 | valueField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct1 | valueField |
| generic.go:5:2:5:13 | pointerField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct1 | pointerField |
| generic.go:6:2:6:11 | arrayField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct1 | arrayField |
@@ -33,6 +34,7 @@
| generic.go:21:2:21:9 | mapField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct2 | mapField |
| generic.go:25:2:25:12 | structField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct2b | structField |
| generic.go:29:2:29:13 | pointerField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.CircularGenericStruct2 | pointerField |
| main.go:18:7:18:15 | NameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsNameClash | NameClash |
| pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder | base |
| pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder2 | base |
| pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder3 | base |
@@ -49,27 +51,31 @@
| pkg1/promotedStructs.go:14:2:14:7 | PField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedP | PField |
| pkg1/promotedStructs.go:22:22:22:22 | S | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedS | S |
| pkg1/promotedStructs.go:25:22:25:22 | P | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedP | P |
| pkg1/tst.go:4:2:4:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | f |
| pkg1/tst.go:5:2:5:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | Foo |
| pkg1/tst.go:6:2:6:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | Bar |
| pkg1/tst.go:10:2:10:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | Foo |
| pkg1/tst.go:11:2:11:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | Bar |
| pkg1/tst.go:15:3:15:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | Foo |
| pkg1/tst.go:16:3:16:5 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | Bar |
| pkg1/tst.go:20:3:20:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | Foo |
| pkg1/tst.go:21:2:21:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | Bar |
| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | val |
| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | val |
| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | val |
| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | val |
| pkg1/tst.go:26:2:26:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | flag |
| pkg1/tst.go:26:2:26:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | flag |
| pkg1/tst.go:30:2:30:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Bar | flag |
| pkg1/tst.go:30:2:30:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | flag |
| pkg1/tst.go:6:2:6:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | f |
| pkg1/tst.go:7:2:7:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | Foo |
| pkg1/tst.go:8:2:8:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | Bar |
| pkg1/tst.go:12:2:12:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | Foo |
| pkg1/tst.go:13:2:13:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | Bar |
| pkg1/tst.go:17:3:17:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | Foo |
| pkg1/tst.go:18:3:18:5 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | Bar |
| pkg1/tst.go:22:3:22:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | Foo |
| pkg1/tst.go:23:2:23:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | Bar |
| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | val |
| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | val |
| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | val |
| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | val |
| pkg1/tst.go:28:2:28:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | flag |
| pkg1/tst.go:28:2:28:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | flag |
| pkg1/tst.go:32:2:32:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Bar | flag |
| pkg1/tst.go:32:2:32:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 | flag |
| pkg1/tst.go:62:7:62:15 | NameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.NameClash | NameClash |
| pkg2/tst.go:4:2:4:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.G | g |
| pkg2/tst.go:4:2:4:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.T | g |
| pkg2/tst.go:8:2:8:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.G | g |
| pkg2/tst.go:8:2:8:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.T | g |
| pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsNameClash | NCField |
| pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.NameClash | NCField |
| pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.NameClash | NCField |
| struct_tags.go:4:2:4:7 | field1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.S1 | field1 |
| struct_tags.go:5:2:5:7 | field2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.S1 | field2 |
| struct_tags.go:9:2:9:7 | field1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.S2 | field1 |

View File

@@ -18,10 +18,11 @@
| depth.go:19:2:19:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | c | f |
| depth.go:19:2:19:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | d | f |
| embedded.go:4:2:4:2 | A | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | Baz | A |
| embedded.go:4:2:4:2 | A | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsBaz | A |
| embedded.go:4:2:4:2 | A | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | Qux | A |
| embedded.go:8:3:8:5 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | Qux | Baz |
| embedded.go:13:2:13:4 | Qux | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsBaz | Qux |
| embedded.go:14:2:14:4 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsBaz | Baz |
| embedded.go:12:2:12:4 | Qux | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsBaz | Qux |
| embedded.go:13:2:13:4 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsBaz | Baz |
| generic.go:4:2:4:11 | valueField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct1 | valueField |
| generic.go:5:2:5:13 | pointerField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct1 | pointerField |
| generic.go:6:2:6:11 | arrayField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct1 | arrayField |
@@ -33,6 +34,7 @@
| generic.go:21:2:21:9 | mapField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct2 | mapField |
| generic.go:25:2:25:12 | structField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | GenericStruct2b | structField |
| generic.go:29:2:29:13 | pointerField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | CircularGenericStruct2 | pointerField |
| main.go:18:7:18:15 | NameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsNameClash | NameClash |
| pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder | base |
| pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder2 | base |
| pkg1/embedding.go:19:23:19:26 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | embedder3 | base |
@@ -49,27 +51,31 @@
| pkg1/promotedStructs.go:14:2:14:7 | PField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | SEmbedP | PField |
| pkg1/promotedStructs.go:22:22:22:22 | S | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | SEmbedS | S |
| pkg1/promotedStructs.go:25:22:25:22 | P | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | SEmbedP | P |
| pkg1/tst.go:4:2:4:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | f |
| pkg1/tst.go:5:2:5:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | Foo |
| pkg1/tst.go:6:2:6:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | Bar |
| pkg1/tst.go:10:2:10:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T2 | Foo |
| pkg1/tst.go:11:2:11:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T2 | Bar |
| pkg1/tst.go:15:3:15:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | Foo |
| pkg1/tst.go:16:3:16:5 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | Bar |
| pkg1/tst.go:20:3:20:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | Foo |
| pkg1/tst.go:21:2:21:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | Bar |
| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | val |
| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | val |
| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | val |
| pkg1/tst.go:25:2:25:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | val |
| pkg1/tst.go:26:2:26:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | flag |
| pkg1/tst.go:26:2:26:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | flag |
| pkg1/tst.go:30:2:30:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Bar | flag |
| pkg1/tst.go:30:2:30:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T2 | flag |
| pkg1/tst.go:6:2:6:2 | f | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | f |
| pkg1/tst.go:7:2:7:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | Foo |
| pkg1/tst.go:8:2:8:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | Bar |
| pkg1/tst.go:12:2:12:4 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T2 | Foo |
| pkg1/tst.go:13:2:13:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T2 | Bar |
| pkg1/tst.go:17:3:17:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | Foo |
| pkg1/tst.go:18:3:18:5 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | Bar |
| pkg1/tst.go:22:3:22:5 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | Foo |
| pkg1/tst.go:23:2:23:4 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | Bar |
| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | val |
| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | val |
| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | val |
| pkg1/tst.go:27:2:27:4 | val | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | val |
| pkg1/tst.go:28:2:28:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | flag |
| pkg1/tst.go:28:2:28:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | flag |
| pkg1/tst.go:32:2:32:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Bar | flag |
| pkg1/tst.go:32:2:32:5 | flag | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T2 | flag |
| pkg1/tst.go:62:7:62:15 | NameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | NameClash | NameClash |
| pkg2/tst.go:4:2:4:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | G | g |
| pkg2/tst.go:4:2:4:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | T | g |
| pkg2/tst.go:8:2:8:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | G | g |
| pkg2/tst.go:8:2:8:2 | g | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | T | g |
| pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsNameClash | NCField |
| pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | NameClash | NCField |
| pkg2/tst.go:17:2:17:8 | NCField | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | NameClash | NCField |
| struct_tags.go:4:2:4:7 | field1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | S1 | field1 |
| struct_tags.go:5:2:5:7 | field2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | S1 | field2 |
| struct_tags.go:9:2:9:7 | field1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | S2 | field1 |

View File

@@ -1,2 +1,2 @@
failures
testFailures
failures

View File

@@ -1,4 +1,6 @@
| * EmbedsNameClash | 1 |
| * Foo | 1 |
| * NameClash | 1 |
| * P | 1 |
| * S | 1 |
| * SEmbedP | 1 |
@@ -19,10 +21,12 @@
| AExtended | 2 |
| B | 2 |
| C | 2 |
| EmbedsNameClash | 1 |
| Foo | 1 |
| GenericInterface | 1 |
| MixedExportedAndNot | 2 |
| MyInterface | 17 |
| NameClash | 1 |
| S | 1 |
| SEmbedS | 1 |
| T | 1 |

View File

@@ -30,6 +30,7 @@
| interface.go:95:6:95:8 | i18 | StringA | func() string |
| interface.go:101:6:101:8 | i19 | StringB | func() string |
| interface.go:105:6:105:8 | i20 | StringB | func() string |
| main.go:17:6:17:20 | EmbedsNameClash | NCMethod | func() |
| pkg1/embedding.go:19:6:19:13 | embedder | f | func() int |
| pkg1/embedding.go:22:6:22:16 | ptrembedder | f | func() int |
| pkg1/embedding.go:22:6:22:16 | ptrembedder | g | func() int |
@@ -51,8 +52,9 @@
| pkg1/interfaces.go:35:6:35:24 | MixedExportedAndNot | Exported | func() |
| pkg1/interfaces.go:35:6:35:24 | MixedExportedAndNot | notExported | func() |
| pkg1/promotedStructs.go:22:6:22:12 | SEmbedS | SMethod | func() interface { } |
| pkg1/tst.go:3:6:3:6 | T | half | func() Foo |
| pkg1/tst.go:14:6:14:7 | T3 | half | func() Foo |
| pkg1/tst.go:19:6:19:7 | T4 | half | func() Foo |
| pkg1/tst.go:5:6:5:6 | T | half | func() Foo |
| pkg1/tst.go:16:6:16:7 | T3 | half | func() Foo |
| pkg1/tst.go:21:6:21:7 | T4 | half | func() Foo |
| pkg1/tst.go:61:6:61:14 | NameClash | NCMethod | func() |
| pkg2/tst.go:11:6:11:24 | MixedExportedAndNot | Exported | func() |
| pkg2/tst.go:11:6:11:24 | MixedExportedAndNot | notExported | func() |

View File

@@ -59,9 +59,12 @@
| pkg1/promotedStructs.go:8:12:8:18 | SMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedS | SMethod |
| pkg1/promotedStructs.go:17:13:17:19 | PMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.P | PMethod |
| pkg1/promotedStructs.go:17:13:17:19 | PMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedP | PMethod |
| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | half |
| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | half |
| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | half |
| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | half |
| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo | half |
| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T | half |
| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 | half |
| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 | half |
| pkg2/tst.go:12:2:12:9 | Exported | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.MixedExportedAndNot | Exported |
| pkg2/tst.go:13:2:13:12 | notExported | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.MixedExportedAndNot | notExported |
| pkg2/tst.go:20:20:20:27 | NCMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsNameClash | NCMethod |
| pkg2/tst.go:20:20:20:27 | NCMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.NameClash | NCMethod |
| pkg2/tst.go:20:20:20:27 | NCMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.NameClash | NCMethod |

View File

@@ -59,9 +59,12 @@
| pkg1/promotedStructs.go:8:12:8:18 | SMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | SEmbedS | SMethod |
| pkg1/promotedStructs.go:17:13:17:19 | PMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | P | PMethod |
| pkg1/promotedStructs.go:17:13:17:19 | PMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | SEmbedP | PMethod |
| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | half |
| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | half |
| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | half |
| pkg1/tst.go:33:16:33:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | half |
| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | Foo | half |
| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T | half |
| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T3 | half |
| pkg1/tst.go:35:16:35:19 | half | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | T4 | half |
| pkg2/tst.go:12:2:12:9 | Exported | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | MixedExportedAndNot | Exported |
| pkg2/tst.go:13:2:13:12 | notExported | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | MixedExportedAndNot | notExported |
| pkg2/tst.go:20:20:20:27 | NCMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types | EmbedsNameClash | NCMethod |
| pkg2/tst.go:20:20:20:27 | NCMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1 | NameClash | NCMethod |
| pkg2/tst.go:20:20:20:27 | NCMethod | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2 | NameClash | NCMethod |

View File

@@ -1,11 +1,13 @@
| * Foo | half | pkg1/tst.go:33:16:33:19 | half |
| * EmbedsNameClash | NCMethod | pkg2/tst.go:20:20:20:27 | NCMethod |
| * Foo | half | pkg1/tst.go:35:16:35:19 | half |
| * NameClash | NCMethod | pkg2/tst.go:20:20:20:27 | NCMethod |
| * P | PMethod | pkg1/promotedStructs.go:17:13:17:19 | PMethod |
| * S | SMethod | pkg1/promotedStructs.go:8:12:8:18 | SMethod |
| * SEmbedP | PMethod | pkg1/promotedStructs.go:17:13:17:19 | PMethod |
| * SEmbedS | SMethod | pkg1/promotedStructs.go:8:12:8:18 | SMethod |
| * T | half | pkg1/tst.go:33:16:33:19 | half |
| * T3 | half | pkg1/tst.go:33:16:33:19 | half |
| * T4 | half | pkg1/tst.go:33:16:33:19 | half |
| * T | half | pkg1/tst.go:35:16:35:19 | half |
| * T3 | half | pkg1/tst.go:35:16:35:19 | half |
| * T4 | half | pkg1/tst.go:35:16:35:19 | half |
| * base | f | pkg1/embedding.go:10:13:10:13 | f |
| * base | g | pkg1/embedding.go:14:14:14:14 | g |
| * embedder | f | pkg1/embedding.go:10:13:10:13 | f |
@@ -29,7 +31,8 @@
| B | n | pkg1/interfaces.go:9:2:9:2 | n |
| C | n | pkg1/interfaces.go:13:2:13:2 | n |
| C | o | pkg1/interfaces.go:14:2:14:2 | o |
| Foo | half | pkg1/tst.go:33:16:33:19 | half |
| EmbedsNameClash | NCMethod | pkg2/tst.go:20:20:20:27 | NCMethod |
| Foo | half | pkg1/tst.go:35:16:35:19 | half |
| GenericInterface | GetT | generic.go:33:2:33:5 | GetT |
| MixedExportedAndNot | Exported | pkg1/interfaces.go:36:2:36:9 | Exported |
| MixedExportedAndNot | Exported | pkg2/tst.go:12:2:12:9 | Exported |
@@ -52,11 +55,12 @@
| MyInterface | dummy18 | generic.go:62:2:62:8 | dummy18 |
| MyInterface | dummy19 | generic.go:63:2:63:8 | dummy19 |
| MyInterface | dummy20 | generic.go:64:2:64:8 | dummy20 |
| NameClash | NCMethod | pkg2/tst.go:20:20:20:27 | NCMethod |
| S | SMethod | pkg1/promotedStructs.go:8:12:8:18 | SMethod |
| SEmbedS | SMethod | pkg1/promotedStructs.go:8:12:8:18 | SMethod |
| T | half | pkg1/tst.go:33:16:33:19 | half |
| T3 | half | pkg1/tst.go:33:16:33:19 | half |
| T4 | half | pkg1/tst.go:33:16:33:19 | half |
| T | half | pkg1/tst.go:35:16:35:19 | half |
| T3 | half | pkg1/tst.go:35:16:35:19 | half |
| T4 | half | pkg1/tst.go:35:16:35:19 | half |
| base | f | pkg1/embedding.go:10:13:10:13 | f |
| embedder | f | pkg1/embedding.go:10:13:10:13 | f |
| embedder2 | f | pkg1/embedding.go:10:13:10:13 | f |

View File

@@ -9,7 +9,7 @@
| depth.go:18:6:18:6 | d | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.d |
| embedded.go:3:6:3:8 | Baz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.Baz |
| embedded.go:7:6:7:8 | Qux | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.Qux |
| embedded.go:12:6:12:14 | EmbedsBaz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz |
| embedded.go:11:6:11:14 | EmbedsBaz | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsBaz |
| generic.go:3:6:3:19 | GenericStruct1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.GenericStruct1 |
| generic.go:11:6:11:27 | CircularGenericStruct1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.CircularGenericStruct1 |
| generic.go:15:6:15:31 | UsesCircularGenericStruct1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.UsesCircularGenericStruct1 |
@@ -77,6 +77,7 @@
| interface.go:136:6:136:21 | testComparable21 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable21 |
| interface.go:137:6:137:21 | testComparable22 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable22 |
| interface.go:138:6:138:21 | testComparable23 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.testComparable23 |
| main.go:17:6:17:20 | EmbedsNameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.EmbedsNameClash |
| pkg1/embedding.go:8:6:8:9 | base | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.base |
| pkg1/embedding.go:19:6:19:13 | embedder | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.embedder |
| pkg1/embedding.go:22:6:22:16 | ptrembedder | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.ptrembedder |
@@ -95,14 +96,16 @@
| pkg1/promotedStructs.go:13:6:13:6 | P | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.P |
| pkg1/promotedStructs.go:22:6:22:12 | SEmbedS | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedS |
| pkg1/promotedStructs.go:25:6:25:12 | SEmbedP | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.SEmbedP |
| pkg1/tst.go:3:6:3:6 | T | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T |
| pkg1/tst.go:9:6:9:7 | T2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 |
| pkg1/tst.go:14:6:14:7 | T3 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 |
| pkg1/tst.go:19:6:19:7 | T4 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 |
| pkg1/tst.go:24:6:24:8 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo |
| pkg1/tst.go:29:6:29:8 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Bar |
| pkg1/tst.go:5:6:5:6 | T | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T |
| pkg1/tst.go:11:6:11:7 | T2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T2 |
| pkg1/tst.go:16:6:16:7 | T3 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T3 |
| pkg1/tst.go:21:6:21:7 | T4 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.T4 |
| pkg1/tst.go:26:6:26:8 | Foo | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Foo |
| pkg1/tst.go:31:6:31:8 | Bar | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.Bar |
| pkg1/tst.go:61:6:61:14 | NameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1.NameClash |
| pkg2/tst.go:3:6:3:6 | T | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.T |
| pkg2/tst.go:7:6:7:6 | G | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.G |
| pkg2/tst.go:11:6:11:24 | MixedExportedAndNot | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.MixedExportedAndNot |
| pkg2/tst.go:16:6:16:14 | NameClash | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2.NameClash |
| struct_tags.go:3:6:3:7 | S1 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.S1 |
| struct_tags.go:8:6:8:7 | S2 | github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types.S2 |

View File

@@ -4,18 +4,19 @@
| depth.go:22:1:25:1 | function declaration | 0 |
| generic.go:70:1:72:1 | function declaration | 1 |
| generic.go:74:1:80:1 | function declaration | 1 |
| main.go:5:1:5:30 | function declaration | 1 |
| main.go:7:1:9:1 | function declaration | 2 |
| main.go:11:1:11:14 | function declaration | 0 |
| main.go:9:1:9:30 | function declaration | 1 |
| main.go:11:1:13:1 | function declaration | 2 |
| main.go:15:1:15:14 | function declaration | 0 |
| pkg1/embedding.go:10:1:12:1 | function declaration | 0 |
| pkg1/embedding.go:14:1:16:1 | function declaration | 0 |
| pkg1/embedding.go:30:1:32:1 | function declaration | 0 |
| pkg1/embedding.go:40:1:61:1 | function declaration | 0 |
| pkg1/promotedStructs.go:8:1:10:1 | function declaration | 0 |
| pkg1/promotedStructs.go:17:1:19:1 | function declaration | 0 |
| pkg1/tst.go:33:1:35:1 | function declaration | 0 |
| pkg1/tst.go:37:1:37:26 | function declaration | 1 |
| pkg1/tst.go:39:1:57:1 | function declaration | 2 |
| pkg1/tst.go:35:1:37:1 | function declaration | 0 |
| pkg1/tst.go:39:1:39:26 | function declaration | 1 |
| pkg1/tst.go:41:1:59:1 | function declaration | 2 |
| pkg2/tst.go:20:1:20:32 | function declaration | 0 |
| promoted.go:7:1:10:1 | function declaration | 1 |
| promoted.go:12:1:15:1 | function declaration | 1 |
| promoted.go:17:1:20:1 | function declaration | 1 |

View File

@@ -4,18 +4,19 @@
| depth.go:22:1:25:1 | function declaration | 0 |
| generic.go:70:1:72:1 | function declaration | 1 |
| generic.go:74:1:80:1 | function declaration | 0 |
| main.go:5:1:5:30 | function declaration | 0 |
| main.go:7:1:9:1 | function declaration | 2 |
| main.go:11:1:11:14 | function declaration | 0 |
| main.go:9:1:9:30 | function declaration | 0 |
| main.go:11:1:13:1 | function declaration | 2 |
| main.go:15:1:15:14 | function declaration | 0 |
| pkg1/embedding.go:10:1:12:1 | function declaration | 1 |
| pkg1/embedding.go:14:1:16:1 | function declaration | 1 |
| pkg1/embedding.go:30:1:32:1 | function declaration | 1 |
| pkg1/embedding.go:40:1:61:1 | function declaration | 0 |
| pkg1/promotedStructs.go:8:1:10:1 | function declaration | 1 |
| pkg1/promotedStructs.go:17:1:19:1 | function declaration | 1 |
| pkg1/tst.go:33:1:35:1 | function declaration | 1 |
| pkg1/tst.go:37:1:37:26 | function declaration | 0 |
| pkg1/tst.go:39:1:57:1 | function declaration | 0 |
| pkg1/tst.go:35:1:37:1 | function declaration | 1 |
| pkg1/tst.go:39:1:39:26 | function declaration | 0 |
| pkg1/tst.go:41:1:59:1 | function declaration | 0 |
| pkg2/tst.go:20:1:20:32 | function declaration | 0 |
| promoted.go:7:1:10:1 | function declaration | 0 |
| promoted.go:12:1:15:1 | function declaration | 0 |
| promoted.go:17:1:20:1 | function declaration | 0 |

View File

@@ -1,2 +1,2 @@
failures
testFailures
failures

View File

@@ -20,8 +20,9 @@
| embedded.go:3:6:3:8 | Baz | embedded.go:3:10:5:1 | struct type | A | string |
| embedded.go:7:6:7:8 | Qux | embedded.go:7:10:9:1 | struct type | A | string |
| embedded.go:7:6:7:8 | Qux | embedded.go:7:10:9:1 | struct type | Baz | * Baz |
| embedded.go:12:6:12:14 | EmbedsBaz | embedded.go:12:16:15:1 | struct type | Baz | string |
| embedded.go:12:6:12:14 | EmbedsBaz | embedded.go:12:16:15:1 | struct type | Qux | Qux |
| embedded.go:11:6:11:14 | EmbedsBaz | embedded.go:11:16:14:1 | struct type | A | string |
| embedded.go:11:6:11:14 | EmbedsBaz | embedded.go:11:16:14:1 | struct type | Baz | string |
| embedded.go:11:6:11:14 | EmbedsBaz | embedded.go:11:16:14:1 | struct type | Qux | Qux |
| generic.go:3:6:3:19 | GenericStruct1 | generic.go:3:28:9:1 | struct type | arrayField | [10]T |
| generic.go:3:6:3:19 | GenericStruct1 | generic.go:3:28:9:1 | struct type | mapField | [string]T |
| generic.go:3:6:3:19 | GenericStruct1 | generic.go:3:28:9:1 | struct type | pointerField | * T |
@@ -33,6 +34,8 @@
| generic.go:19:6:19:19 | GenericStruct2 | generic.go:19:42:22:1 | struct type | structField | GenericStruct1 |
| generic.go:24:6:24:20 | GenericStruct2b | generic.go:24:39:26:1 | struct type | structField | GenericStruct2 |
| generic.go:28:6:28:27 | CircularGenericStruct2 | generic.go:28:39:30:1 | struct type | pointerField | * CircularGenericStruct2 |
| main.go:17:6:17:20 | EmbedsNameClash | main.go:17:22:19:1 | struct type | NCField | string |
| main.go:17:6:17:20 | EmbedsNameClash | main.go:17:22:19:1 | struct type | NameClash | NameClash |
| pkg1/embedding.go:19:6:19:13 | embedder | pkg1/embedding.go:19:15:19:28 | struct type | base | base |
| pkg1/embedding.go:22:6:22:16 | ptrembedder | pkg1/embedding.go:22:18:22:32 | struct type | base | * base |
| pkg1/embedding.go:25:6:25:14 | embedder2 | pkg1/embedding.go:25:16:25:33 | struct type | base | base |
@@ -51,27 +54,30 @@
| pkg1/promotedStructs.go:22:6:22:12 | SEmbedS | pkg1/promotedStructs.go:22:14:22:24 | struct type | SField | string |
| pkg1/promotedStructs.go:25:6:25:12 | SEmbedP | pkg1/promotedStructs.go:25:14:25:24 | struct type | P | P |
| pkg1/promotedStructs.go:25:6:25:12 | SEmbedP | pkg1/promotedStructs.go:25:14:25:24 | struct type | PField | string |
| pkg1/tst.go:3:6:3:6 | T | pkg1/tst.go:3:8:7:1 | struct type | Bar | Bar |
| pkg1/tst.go:3:6:3:6 | T | pkg1/tst.go:3:8:7:1 | struct type | Foo | Foo |
| pkg1/tst.go:3:6:3:6 | T | pkg1/tst.go:3:8:7:1 | struct type | f | int |
| pkg1/tst.go:3:6:3:6 | T | pkg1/tst.go:3:8:7:1 | struct type | val | int |
| pkg1/tst.go:9:6:9:7 | T2 | pkg1/tst.go:9:9:12:1 | struct type | Bar | Bar |
| pkg1/tst.go:9:6:9:7 | T2 | pkg1/tst.go:9:9:12:1 | struct type | Foo | Foo |
| pkg1/tst.go:9:6:9:7 | T2 | pkg1/tst.go:9:9:12:1 | struct type | flag | bool |
| pkg1/tst.go:14:6:14:7 | T3 | pkg1/tst.go:14:9:17:1 | struct type | Bar | * Bar |
| pkg1/tst.go:14:6:14:7 | T3 | pkg1/tst.go:14:9:17:1 | struct type | Foo | * Foo |
| pkg1/tst.go:14:6:14:7 | T3 | pkg1/tst.go:14:9:17:1 | struct type | val | int |
| pkg1/tst.go:19:6:19:7 | T4 | pkg1/tst.go:19:9:22:1 | struct type | Bar | Bar |
| pkg1/tst.go:19:6:19:7 | T4 | pkg1/tst.go:19:9:22:1 | struct type | Foo | * Foo |
| pkg1/tst.go:19:6:19:7 | T4 | pkg1/tst.go:19:9:22:1 | struct type | flag | bool |
| pkg1/tst.go:19:6:19:7 | T4 | pkg1/tst.go:19:9:22:1 | struct type | val | int |
| pkg1/tst.go:24:6:24:8 | Foo | pkg1/tst.go:24:10:27:1 | struct type | flag | bool |
| pkg1/tst.go:24:6:24:8 | Foo | pkg1/tst.go:24:10:27:1 | struct type | val | int |
| pkg1/tst.go:29:6:29:8 | Bar | pkg1/tst.go:29:10:31:1 | struct type | flag | bool |
| pkg1/tst.go:5:6:5:6 | T | pkg1/tst.go:5:8:9:1 | struct type | Bar | Bar |
| pkg1/tst.go:5:6:5:6 | T | pkg1/tst.go:5:8:9:1 | struct type | Foo | Foo |
| pkg1/tst.go:5:6:5:6 | T | pkg1/tst.go:5:8:9:1 | struct type | f | int |
| pkg1/tst.go:5:6:5:6 | T | pkg1/tst.go:5:8:9:1 | struct type | val | int |
| pkg1/tst.go:11:6:11:7 | T2 | pkg1/tst.go:11:9:14:1 | struct type | Bar | Bar |
| pkg1/tst.go:11:6:11:7 | T2 | pkg1/tst.go:11:9:14:1 | struct type | Foo | Foo |
| pkg1/tst.go:11:6:11:7 | T2 | pkg1/tst.go:11:9:14:1 | struct type | flag | bool |
| pkg1/tst.go:16:6:16:7 | T3 | pkg1/tst.go:16:9:19:1 | struct type | Bar | * Bar |
| pkg1/tst.go:16:6:16:7 | T3 | pkg1/tst.go:16:9:19:1 | struct type | Foo | * Foo |
| pkg1/tst.go:16:6:16:7 | T3 | pkg1/tst.go:16:9:19:1 | struct type | val | int |
| pkg1/tst.go:21:6:21:7 | T4 | pkg1/tst.go:21:9:24:1 | struct type | Bar | Bar |
| pkg1/tst.go:21:6:21:7 | T4 | pkg1/tst.go:21:9:24:1 | struct type | Foo | * Foo |
| pkg1/tst.go:21:6:21:7 | T4 | pkg1/tst.go:21:9:24:1 | struct type | flag | bool |
| pkg1/tst.go:21:6:21:7 | T4 | pkg1/tst.go:21:9:24:1 | struct type | val | int |
| pkg1/tst.go:26:6:26:8 | Foo | pkg1/tst.go:26:10:29:1 | struct type | flag | bool |
| pkg1/tst.go:26:6:26:8 | Foo | pkg1/tst.go:26:10:29:1 | struct type | val | int |
| pkg1/tst.go:31:6:31:8 | Bar | pkg1/tst.go:31:10:33:1 | struct type | flag | bool |
| pkg1/tst.go:61:6:61:14 | NameClash | pkg1/tst.go:61:16:63:1 | struct type | NCField | string |
| pkg1/tst.go:61:6:61:14 | NameClash | pkg1/tst.go:61:16:63:1 | struct type | NameClash | NameClash |
| pkg2/tst.go:3:6:3:6 | T | pkg2/tst.go:3:8:5:1 | struct type | g | int |
| pkg2/tst.go:3:6:3:6 | T | pkg2/tst.go:7:8:9:1 | struct type | g | int |
| pkg2/tst.go:7:6:7:6 | G | pkg2/tst.go:3:8:5:1 | struct type | g | int |
| pkg2/tst.go:7:6:7:6 | G | pkg2/tst.go:7:8:9:1 | struct type | g | int |
| pkg2/tst.go:16:6:16:14 | NameClash | pkg2/tst.go:16:16:18:1 | struct type | NCField | string |
| struct_tags.go:3:6:3:7 | S1 | struct_tags.go:3:9:6:1 | struct type | field1 | int |
| struct_tags.go:3:6:3:7 | S1 | struct_tags.go:3:9:6:1 | struct type | field2 | int |
| struct_tags.go:8:6:8:7 | S2 | struct_tags.go:8:9:11:1 | struct type | field1 | int |

View File

@@ -9,7 +9,7 @@
| depth.go:18:6:18:6 | d | d |
| embedded.go:3:6:3:8 | Baz | Baz |
| embedded.go:7:6:7:8 | Qux | Qux |
| embedded.go:12:6:12:14 | EmbedsBaz | EmbedsBaz |
| embedded.go:11:6:11:14 | EmbedsBaz | EmbedsBaz |
| generic.go:3:6:3:19 | GenericStruct1 | GenericStruct1 |
| generic.go:11:6:11:27 | CircularGenericStruct1 | CircularGenericStruct1 |
| generic.go:15:6:15:31 | UsesCircularGenericStruct1 | UsesCircularGenericStruct1 |
@@ -77,6 +77,7 @@
| interface.go:136:6:136:21 | testComparable21 | testComparable21 |
| interface.go:137:6:137:21 | testComparable22 | testComparable22 |
| interface.go:138:6:138:21 | testComparable23 | testComparable23 |
| main.go:17:6:17:20 | EmbedsNameClash | EmbedsNameClash |
| pkg1/embedding.go:8:6:8:9 | base | base |
| pkg1/embedding.go:19:6:19:13 | embedder | embedder |
| pkg1/embedding.go:22:6:22:16 | ptrembedder | ptrembedder |
@@ -95,14 +96,16 @@
| pkg1/promotedStructs.go:13:6:13:6 | P | P |
| pkg1/promotedStructs.go:22:6:22:12 | SEmbedS | SEmbedS |
| pkg1/promotedStructs.go:25:6:25:12 | SEmbedP | SEmbedP |
| pkg1/tst.go:3:6:3:6 | T | T |
| pkg1/tst.go:9:6:9:7 | T2 | T2 |
| pkg1/tst.go:14:6:14:7 | T3 | T3 |
| pkg1/tst.go:19:6:19:7 | T4 | T4 |
| pkg1/tst.go:24:6:24:8 | Foo | Foo |
| pkg1/tst.go:29:6:29:8 | Bar | Bar |
| pkg1/tst.go:5:6:5:6 | T | T |
| pkg1/tst.go:11:6:11:7 | T2 | T2 |
| pkg1/tst.go:16:6:16:7 | T3 | T3 |
| pkg1/tst.go:21:6:21:7 | T4 | T4 |
| pkg1/tst.go:26:6:26:8 | Foo | Foo |
| pkg1/tst.go:31:6:31:8 | Bar | Bar |
| pkg1/tst.go:61:6:61:14 | NameClash | NameClash |
| pkg2/tst.go:3:6:3:6 | T | T |
| pkg2/tst.go:7:6:7:6 | G | G |
| pkg2/tst.go:11:6:11:24 | MixedExportedAndNot | MixedExportedAndNot |
| pkg2/tst.go:16:6:16:14 | NameClash | NameClash |
| struct_tags.go:3:6:3:7 | S1 | S1 |
| struct_tags.go:8:6:8:7 | S2 | S2 |

View File

@@ -8,7 +8,6 @@ type Qux struct {
*Baz
}
// EmbedsBaz should have a field A but does not
type EmbedsBaz struct {
Qux
Baz string

View File

@@ -1,6 +1,10 @@
package main
import "regexp"
import (
"regexp"
"github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg1"
)
func test(r *regexp.Regexp) {}
@@ -9,3 +13,7 @@ func swap(x int, y int) (int, int) {
}
func main() {}
type EmbedsNameClash struct {
pkg1.NameClash
}

View File

@@ -1,5 +1,7 @@
package pkg1
import "github.com/github/codeql-go/ql/test/library-tests/semmle/go/Types/pkg2"
type T struct {
f int
Foo
@@ -55,3 +57,7 @@ func test(t T, t2 T2) {
// methods of T2
// illegal: t2.half()
}
type NameClash struct {
pkg2.NameClash
}

View File

@@ -12,3 +12,9 @@ type MixedExportedAndNot interface {
Exported()
notExported()
}
type NameClash struct {
NCField string
}
func (t NameClash) NCMethod() {}

View File

@@ -160,11 +160,8 @@ predicate localMustFlowStep(Node node1, Node node2) {
or
node2.asExpr().(AssignExpr).getSource() = node1.asExpr()
or
node1 =
unique(FlowSummaryNode n1 |
FlowSummaryImpl::Private::Steps::summaryLocalStep(n1.getSummaryNode(),
node2.(FlowSummaryNode).getSummaryNode(), true, _)
)
FlowSummaryImpl::Private::Steps::summaryLocalMustFlowStep(node1.(FlowSummaryNode).getSummaryNode(),
node2.(FlowSummaryNode).getSummaryNode())
}
import Cached

View File

@@ -0,0 +1,6 @@
---
category: majorAnalysis
---
* The `js/incomplete-sanitization` query now also checks regular expressions constructed using `new RegExp(..)`. Previously it only checked regular expression literals.
* Regular expression-based sanitisers implemented with `new RegExp(..)` are now detected in more cases.
* Regular expression related queries now account for unknown flags.

View File

@@ -117,6 +117,12 @@ class StringReplaceCall extends DataFlow::MethodCallNode {
*/
predicate isGlobal() { this.getRegExp().isGlobal() or this.getMethodName() = "replaceAll" }
/**
* Holds if this is a global replacement, that is, the first argument is a regular expression
* with the `g` flag or unknown flags, or this is a call to `.replaceAll()`.
*/
predicate maybeGlobal() { this.getRegExp().maybeGlobal() or this.getMethodName() = "replaceAll" }
/**
* Holds if this call to `replace` replaces `old` with `new`.
*/

View File

@@ -1685,6 +1685,9 @@ class RegExpCreationNode extends DataFlow::SourceNode {
/** Holds if the constructed predicate has the `g` flag. */
predicate isGlobal() { RegExp::isGlobal(this.getFlags()) }
/** Holds if the constructed predicate has the `g` flag or unknown flags. */
predicate maybeGlobal() { RegExp::maybeGlobal(this.tryGetFlags()) }
/** Gets a data flow node referring to this regular expression. */
private DataFlow::SourceNode getAReference(DataFlow::TypeTracker t) {
t.start() and

View File

@@ -74,7 +74,7 @@ private StringReplaceCall getAStringReplaceMethodCall(StringReplaceCall n) {
module HtmlSanitization {
private predicate fixedGlobalReplacement(StringReplaceCallSequence chain) {
forall(StringReplaceCall member | member = chain.getAMember() |
member.isGlobal() and member.getArgument(0) instanceof DataFlow::RegExpLiteralNode
member.maybeGlobal() and member.getArgument(0) instanceof DataFlow::RegExpCreationNode
)
}

View File

@@ -36,9 +36,12 @@ module CleartextLogging {
*/
class MaskingReplacer extends Barrier, StringReplaceCall {
MaskingReplacer() {
this.isGlobal() and
this.maybeGlobal() and
exists(this.getRawReplacement().getStringValue()) and
any(RegExpDot term).getLiteral() = this.getRegExp().asExpr()
exists(DataFlow::RegExpCreationNode regexpObj |
this.(StringReplaceCall).getRegExp() = regexpObj and
regexpObj.getRoot() = any(RegExpDot term).getRootTerm()
)
}
}

View File

@@ -46,7 +46,7 @@ class Configuration extends TaintTracking::Configuration {
// Replacing with "_" is likely to be exploitable
not replace.getRawReplacement().getStringValue() = "_" and
(
replace.isGlobal()
replace.maybeGlobal()
or
// Non-global replace with a non-empty string can also prevent __proto__ by
// inserting a chunk of text that doesn't fit anywhere in __proto__

View File

@@ -76,7 +76,7 @@ module RegExpInjection {
*/
class MetacharEscapeSanitizer extends Sanitizer, StringReplaceCall {
MetacharEscapeSanitizer() {
this.isGlobal() and
this.maybeGlobal() and
(
RegExp::alwaysMatchesMetaCharacter(this.getRegExp().getRoot(), ["{", "[", "+"])
or

View File

@@ -221,10 +221,10 @@ module TaintedPath {
this instanceof StringReplaceCall and
input = this.getReceiver() and
output = this and
not exists(RegExpLiteral literal, RegExpTerm term |
this.(StringReplaceCall).getRegExp().asExpr() = literal and
this.(StringReplaceCall).isGlobal() and
literal.getRoot() = term
not exists(DataFlow::RegExpCreationNode regexp, RegExpTerm term |
this.(StringReplaceCall).getRegExp() = regexp and
this.(StringReplaceCall).maybeGlobal() and
regexp.getRoot() = term
|
term.getAMatchedString() = "/" or
term.getAMatchedString() = "." or
@@ -305,9 +305,9 @@ module TaintedPath {
input = this.getReceiver() and
output = this and
this.isGlobal() and
exists(RegExpLiteral literal, RegExpTerm term |
this.getRegExp().asExpr() = literal and
literal.getRoot() = term and
exists(DataFlow::RegExpCreationNode regexp, RegExpTerm term |
this.getRegExp() = regexp and
regexp.getRoot() = term and
not term.getAMatchedString() = "/"
|
term.getAMatchedString() = "." or

View File

@@ -245,7 +245,7 @@ module UnsafeShellCommandConstruction {
class ReplaceQuotesSanitizer extends Sanitizer, StringReplaceCall {
ReplaceQuotesSanitizer() {
this.getAReplacedString() = "'" and
this.isGlobal() and
this.maybeGlobal() and
this.getRawReplacement().mayHaveStringValue(["'\\''", ""])
}
}

View File

@@ -36,7 +36,7 @@ module Shared {
*/
class MetacharEscapeSanitizer extends Sanitizer, StringReplaceCall {
MetacharEscapeSanitizer() {
this.isGlobal() and
this.maybeGlobal() and
(
RegExp::alwaysMatchesMetaCharacter(this.getRegExp().getRoot(), ["<", "'", "\""])
or

View File

@@ -23,7 +23,7 @@ string metachar() { result = "'\"\\&<>\n\r\t*|{}[]%$".charAt(_) }
/** Gets a string matched by `e` in a `replace` call. */
string getAMatchedString(DataFlow::Node e) {
result = e.(DataFlow::RegExpLiteralNode).getRoot().getAMatchedString()
result = e.(DataFlow::RegExpCreationNode).getRoot().getAMatchedString()
or
result = e.getStringValue()
}
@@ -52,8 +52,8 @@ predicate isSimpleAlt(RegExpAlt t) { forall(RegExpTerm ch | ch = t.getAChild() |
* Holds if `mce` is of the form `x.replace(re, new)`, where `re` is a global
* regular expression and `new` prefixes the matched string with a backslash.
*/
predicate isBackslashEscape(StringReplaceCall mce, DataFlow::RegExpLiteralNode re) {
mce.isGlobal() and
predicate isBackslashEscape(StringReplaceCall mce, DataFlow::RegExpCreationNode re) {
mce.maybeGlobal() and
re = mce.getRegExp() and
(
// replacement with `\$&`, `\$1` or similar
@@ -72,7 +72,7 @@ predicate allBackslashesEscaped(DataFlow::Node nd) {
nd instanceof JsonStringifyCall
or
// check whether `nd` itself escapes backslashes
exists(DataFlow::RegExpLiteralNode rel | isBackslashEscape(nd, rel) |
exists(DataFlow::RegExpCreationNode rel | isBackslashEscape(nd, rel) |
// if it's a complex regexp, we conservatively assume that it probably escapes backslashes
not isSimple(rel.getRoot()) or
getAMatchedString(rel) = "\\"
@@ -143,12 +143,21 @@ predicate whitelistedRemoval(StringReplaceCall repl) {
)
}
/**
* Gets a nice string representation of the pattern or value of the node.
*/
string getPatternOrValueString(DataFlow::Node node) {
if node instanceof DataFlow::RegExpConstructorInvokeNode
then result = "/" + node.(DataFlow::RegExpConstructorInvokeNode).getRoot() + "/"
else result = node.toString()
}
from StringReplaceCall repl, DataFlow::Node old, string msg
where
(old = repl.getArgument(0) or old = repl.getRegExp()) and
(
not repl.isGlobal() and
msg = "This replaces only the first occurrence of " + old + "." and
not repl.maybeGlobal() and
msg = "This replaces only the first occurrence of " + getPatternOrValueString(old) + "." and
// only flag if this is likely to be a sanitizer or URL encoder or decoder
exists(string m | m = getAMatchedString(old) |
// sanitizer

View File

@@ -65,8 +65,8 @@ predicate isCaseSensitiveMiddleware(
arg = call.getArgument(0) and
regexp.getAReference().flowsTo(arg) and
exists(string flags |
flags = regexp.getFlags() and
not RegExp::isIgnoreCase(flags)
flags = regexp.tryGetFlags() and
not RegExp::maybeIgnoreCase(flags)
)
)
}

View File

@@ -1517,6 +1517,207 @@ nodes
| TaintedPath.js:198:35:198:38 | path |
| TaintedPath.js:198:35:198:38 | path |
| TaintedPath.js:198:35:198:38 | path |
| TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:24:202:30 | req.url |
| TaintedPath.js:202:24:202:30 | req.url |
| TaintedPath.js:202:24:202:30 | req.url |
| TaintedPath.js:202:24:202:30 | req.url |
| TaintedPath.js:202:24:202:30 | req.url |
| TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:24:211:30 | req.url |
| TaintedPath.js:211:24:211:30 | req.url |
| TaintedPath.js:211:24:211:30 | req.url |
| TaintedPath.js:211:24:211:30 | req.url |
| TaintedPath.js:211:24:211:30 | req.url |
| TaintedPath.js:213:29:213:32 | path |
| TaintedPath.js:213:29:213:32 | path |
| TaintedPath.js:213:29:213:32 | path |
| TaintedPath.js:213:29:213:32 | path |
| TaintedPath.js:213:29:213:32 | path |
| TaintedPath.js:213:29:213:32 | path |
| TaintedPath.js:213:29:213:32 | path |
| TaintedPath.js:213:29:213:32 | path |
| TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:216:31:216:34 | path |
| TaintedPath.js:216:31:216:34 | path |
| TaintedPath.js:216:31:216:34 | path |
| TaintedPath.js:216:31:216:34 | path |
| TaintedPath.js:216:31:216:34 | path |
| TaintedPath.js:216:31:216:34 | path |
| TaintedPath.js:216:31:216:34 | path |
| TaintedPath.js:216:31:216:34 | path |
| TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| examples/TaintedPath.js:8:7:8:52 | filePath |
| examples/TaintedPath.js:8:7:8:52 | filePath |
| examples/TaintedPath.js:8:7:8:52 | filePath |
@@ -6680,6 +6881,262 @@ edges
| TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:195:14:195:37 | url.par ... , true) |
| TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:195:14:195:37 | url.par ... , true) |
| TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:195:14:195:37 | url.par ... , true) |
| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:202:7:202:48 | path | TaintedPath.js:206:29:206:32 | path |
| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:37 | url.par ... , true) | TaintedPath.js:202:14:202:43 | url.par ... ).query |
| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:43 | url.par ... ).query | TaintedPath.js:202:14:202:48 | url.par ... ry.path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:14:202:48 | url.par ... ry.path | TaintedPath.js:202:7:202:48 | path |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:202:14:202:37 | url.par ... , true) |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:206:29:206:32 | path | TaintedPath.js:206:29:206:85 | path.re ... '), '') |
| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path |
| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path |
| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path |
| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path |
| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path |
| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path |
| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path |
| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:213:29:213:32 | path |
| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path |
| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path |
| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path |
| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path |
| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path |
| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path |
| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path |
| TaintedPath.js:211:7:211:48 | path | TaintedPath.js:216:31:216:34 | path |
| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:37 | url.par ... , true) | TaintedPath.js:211:14:211:43 | url.par ... ).query |
| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:43 | url.par ... ).query | TaintedPath.js:211:14:211:48 | url.par ... ry.path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:14:211:48 | url.par ... ry.path | TaintedPath.js:211:7:211:48 | path |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:211:14:211:37 | url.par ... , true) |
| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:213:29:213:32 | path | TaintedPath.js:213:29:213:68 | path.re ... '), '') |
| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| TaintedPath.js:216:31:216:34 | path | TaintedPath.js:216:31:216:69 | path.re ... '), '') |
| examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath |
| examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath |
| examples/TaintedPath.js:8:7:8:52 | filePath | examples/TaintedPath.js:11:36:11:43 | filePath |
@@ -10499,6 +10956,9 @@ edges
| TaintedPath.js:196:31:196:34 | path | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:196:31:196:34 | path | This path depends on a $@. | TaintedPath.js:195:24:195:30 | req.url | user-provided value |
| TaintedPath.js:197:45:197:48 | path | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:197:45:197:48 | path | This path depends on a $@. | TaintedPath.js:195:24:195:30 | req.url | user-provided value |
| TaintedPath.js:198:35:198:38 | path | TaintedPath.js:195:24:195:30 | req.url | TaintedPath.js:198:35:198:38 | path | This path depends on a $@. | TaintedPath.js:195:24:195:30 | req.url | user-provided value |
| TaintedPath.js:206:29:206:85 | path.re ... '), '') | TaintedPath.js:202:24:202:30 | req.url | TaintedPath.js:206:29:206:85 | path.re ... '), '') | This path depends on a $@. | TaintedPath.js:202:24:202:30 | req.url | user-provided value |
| TaintedPath.js:213:29:213:68 | path.re ... '), '') | TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:213:29:213:68 | path.re ... '), '') | This path depends on a $@. | TaintedPath.js:211:24:211:30 | req.url | user-provided value |
| TaintedPath.js:216:31:216:69 | path.re ... '), '') | TaintedPath.js:211:24:211:30 | req.url | TaintedPath.js:216:31:216:69 | path.re ... '), '') | This path depends on a $@. | TaintedPath.js:211:24:211:30 | req.url | user-provided value |
| examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | examples/TaintedPath.js:8:28:8:34 | req.url | examples/TaintedPath.js:11:29:11:43 | ROOT + filePath | This path depends on a $@. | examples/TaintedPath.js:8:28:8:34 | req.url | user-provided value |
| express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | express.js:8:20:8:32 | req.query.bar | This path depends on a $@. | express.js:8:20:8:32 | req.query.bar | user-provided value |
| handlebars.js:11:32:11:39 | filePath | handlebars.js:29:46:29:60 | req.params.path | handlebars.js:11:32:11:39 | filePath | This path depends on a $@. | handlebars.js:29:46:29:60 | req.params.path | user-provided value |

View File

@@ -197,3 +197,25 @@ var server = http.createServer(function(req, res) {
cp.execFileSync("foobar", ["args"], {cwd: path}); // NOT OK
cp.execFileSync("foobar", {cwd: path}); // NOT OK
});
var server = http.createServer(function(req, res) {
let path = url.parse(req.url, true).query.path;
// Removal of forward-slash or dots.
res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", 'g'), ''))); // OK
res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", ''), ''))); // NOT OK.
res.write(fs.readFileSync(path.replace(new RegExp("[\\]\\[*,;'\"`<>\\?/]", unknownFlags()), ''))); // OK -- Might be okay depending on what unknownFlags evaluates to.
});
var server = http.createServer(function(req, res) {
let path = url.parse(req.url, true).query.path;
res.write(fs.readFileSync(path.replace(new RegExp("[.]", 'g'), ''))); // NOT OK (can be absolute)
if (!pathModule.isAbsolute(path)) {
res.write(fs.readFileSync(path.replace(new RegExp("[.]", ''), ''))); // NOT OK
res.write(fs.readFileSync(path.replace(new RegExp("[.]", 'g'), ''))); // OK
res.write(fs.readFileSync(path.replace(new RegExp("[.]", unknownFlags()), ''))); // OK
}
});

View File

@@ -319,6 +319,15 @@ nodes
| lib/lib.js:626:29:626:32 | name |
| lib/lib.js:629:25:629:28 | name |
| lib/lib.js:629:25:629:28 | name |
| lib/lib.js:632:38:632:41 | name |
| lib/lib.js:632:38:632:41 | name |
| lib/lib.js:633:6:633:68 | sanitized |
| lib/lib.js:633:18:633:68 | "'" + n ... ) + "'" |
| lib/lib.js:633:24:633:27 | name |
| lib/lib.js:633:24:633:62 | name.re ... '\\\\''") |
| lib/lib.js:633:24:633:62 | name.re ... '\\\\''") |
| lib/lib.js:634:22:634:30 | sanitized |
| lib/lib.js:634:22:634:30 | sanitized |
| lib/subLib2/compiled-file.ts:3:26:3:29 | name |
| lib/subLib2/compiled-file.ts:3:26:3:29 | name |
| lib/subLib2/compiled-file.ts:4:25:4:28 | name |
@@ -749,6 +758,14 @@ edges
| lib/lib.js:608:42:608:45 | name | lib/lib.js:629:25:629:28 | name |
| lib/lib.js:608:42:608:45 | name | lib/lib.js:629:25:629:28 | name |
| lib/lib.js:608:42:608:45 | name | lib/lib.js:629:25:629:28 | name |
| lib/lib.js:632:38:632:41 | name | lib/lib.js:633:24:633:27 | name |
| lib/lib.js:632:38:632:41 | name | lib/lib.js:633:24:633:27 | name |
| lib/lib.js:633:6:633:68 | sanitized | lib/lib.js:634:22:634:30 | sanitized |
| lib/lib.js:633:6:633:68 | sanitized | lib/lib.js:634:22:634:30 | sanitized |
| lib/lib.js:633:18:633:68 | "'" + n ... ) + "'" | lib/lib.js:633:6:633:68 | sanitized |
| lib/lib.js:633:24:633:27 | name | lib/lib.js:633:24:633:62 | name.re ... '\\\\''") |
| lib/lib.js:633:24:633:27 | name | lib/lib.js:633:24:633:62 | name.re ... '\\\\''") |
| lib/lib.js:633:24:633:62 | name.re ... '\\\\''") | lib/lib.js:633:18:633:68 | "'" + n ... ) + "'" |
| lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name |
| lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name |
| lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name |
@@ -879,6 +896,8 @@ edges
| lib/lib.js:609:10:609:25 | "rm -rf " + name | lib/lib.js:608:42:608:45 | name | lib/lib.js:609:22:609:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:608:42:608:45 | name | library input | lib/lib.js:609:2:609:26 | cp.exec ... + name) | shell command |
| lib/lib.js:626:17:626:32 | "rm -rf " + name | lib/lib.js:608:42:608:45 | name | lib/lib.js:626:29:626:32 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:608:42:608:45 | name | library input | lib/lib.js:626:9:626:33 | cp.exec ... + name) | shell command |
| lib/lib.js:629:13:629:28 | "rm -rf " + name | lib/lib.js:608:42:608:45 | name | lib/lib.js:629:25:629:28 | name | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:608:42:608:45 | name | library input | lib/lib.js:629:5:629:29 | cp.exec ... + name) | shell command |
| lib/lib.js:633:18:633:68 | "'" + n ... ) + "'" | lib/lib.js:632:38:632:41 | name | lib/lib.js:633:24:633:62 | name.re ... '\\\\''") | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:632:38:632:41 | name | library input | lib/lib.js:634:2:634:31 | cp.exec ... itized) | shell command |
| lib/lib.js:634:10:634:30 | "rm -rf ... nitized | lib/lib.js:632:38:632:41 | name | lib/lib.js:634:22:634:30 | sanitized | This string concatenation which depends on $@ is later used in a $@. | lib/lib.js:632:38:632:41 | name | library input | lib/lib.js:634:2:634:31 | cp.exec ... itized) | shell command |
| lib/subLib2/compiled-file.ts:4:13:4:28 | "rm -rf " + name | lib/subLib2/compiled-file.ts:3:26:3:29 | name | lib/subLib2/compiled-file.ts:4:25:4:28 | name | This string concatenation which depends on $@ is later used in a $@. | lib/subLib2/compiled-file.ts:3:26:3:29 | name | library input | lib/subLib2/compiled-file.ts:4:5:4:29 | cp.exec ... + name) | shell command |
| lib/subLib2/special-file.js:4:10:4:25 | "rm -rf " + name | lib/subLib2/special-file.js:3:28:3:31 | name | lib/subLib2/special-file.js:4:22:4:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/subLib2/special-file.js:3:28:3:31 | name | library input | lib/subLib2/special-file.js:4:2:4:26 | cp.exec ... + name) | shell command |
| lib/subLib3/my-file.ts:4:10:4:25 | "rm -rf " + name | lib/subLib3/my-file.ts:3:28:3:31 | name | lib/subLib3/my-file.ts:4:22:4:25 | name | This string concatenation which depends on $@ is later used in a $@. | lib/subLib3/my-file.ts:3:28:3:31 | name | library input | lib/subLib3/my-file.ts:4:2:4:26 | cp.exec ... + name) | shell command |

View File

@@ -628,3 +628,14 @@ module.exports.veryIndeirect = function (name) {
cp.exec("rm -rf " + name); // NOT OK
}
module.exports.sanitizer = function (name) {
var sanitized = "'" + name.replace(new RegExp("\'"), "'\\''") + "'"
cp.exec("rm -rf " + sanitized); // NOT OK
var sanitized = "'" + name.replace(new RegExp("\'", 'g'), "'\\''") + "'"
cp.exec("rm -rf " + sanitized); // OK
var sanitized = "'" + name.replace(new RegExp("\'", unknownFlags()), "'\\''") + "'"
cp.exec("rm -rf " + sanitized); // OK -- Most likely should be okay and not flagged to reduce false positives.
}

View File

@@ -1148,6 +1148,12 @@ nodes
| tst.js:501:33:501:63 | decodeU ... n.hash) |
| tst.js:501:43:501:62 | window.location.hash |
| tst.js:501:43:501:62 | window.location.hash |
| tst.js:508:7:508:39 | target |
| tst.js:508:16:508:39 | documen ... .search |
| tst.js:508:16:508:39 | documen ... .search |
| tst.js:509:18:509:23 | target |
| tst.js:509:18:509:54 | target. ... "), '') |
| tst.js:509:18:509:54 | target. ... "), '') |
| typeahead.js:20:13:20:45 | target |
| typeahead.js:20:22:20:45 | documen ... .search |
| typeahead.js:20:22:20:45 | documen ... .search |
@@ -2331,6 +2337,11 @@ edges
| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) |
| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) |
| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) |
| tst.js:508:7:508:39 | target | tst.js:509:18:509:23 | target |
| tst.js:508:16:508:39 | documen ... .search | tst.js:508:7:508:39 | target |
| tst.js:508:16:508:39 | documen ... .search | tst.js:508:7:508:39 | target |
| tst.js:509:18:509:23 | target | tst.js:509:18:509:54 | target. ... "), '') |
| tst.js:509:18:509:23 | target | tst.js:509:18:509:54 | target. ... "), '') |
| typeahead.js:20:13:20:45 | target | typeahead.js:21:12:21:17 | target |
| typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:20:13:20:45 | target |
| typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:20:13:20:45 | target |
@@ -2623,6 +2634,7 @@ edges
| tst.js:491:23:491:45 | locatio ... bstr(1) | tst.js:491:23:491:35 | location.hash | tst.js:491:23:491:45 | locatio ... bstr(1) | Cross-site scripting vulnerability due to $@. | tst.js:491:23:491:35 | location.hash | user-provided value |
| tst.js:494:18:494:40 | locatio ... bstr(1) | tst.js:494:18:494:30 | location.hash | tst.js:494:18:494:40 | locatio ... bstr(1) | Cross-site scripting vulnerability due to $@. | tst.js:494:18:494:30 | location.hash | user-provided value |
| tst.js:501:33:501:63 | decodeU ... n.hash) | tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) | Cross-site scripting vulnerability due to $@. | tst.js:501:43:501:62 | window.location.hash | user-provided value |
| tst.js:509:18:509:54 | target. ... "), '') | tst.js:508:16:508:39 | documen ... .search | tst.js:509:18:509:54 | target. ... "), '') | Cross-site scripting vulnerability due to $@. | tst.js:508:16:508:39 | documen ... .search | user-provided value |
| typeahead.js:25:18:25:20 | val | typeahead.js:20:22:20:45 | documen ... .search | typeahead.js:25:18:25:20 | val | Cross-site scripting vulnerability due to $@. | typeahead.js:20:22:20:45 | documen ... .search | user-provided value |
| v-html.vue:2:8:2:23 | v-html=tainted | v-html.vue:6:42:6:58 | document.location | v-html.vue:2:8:2:23 | v-html=tainted | Cross-site scripting vulnerability due to $@. | v-html.vue:6:42:6:58 | document.location | user-provided value |
| various-concat-obfuscations.js:4:4:4:31 | "<div>" ... </div>" | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | various-concat-obfuscations.js:4:4:4:31 | "<div>" ... </div>" | Cross-site scripting vulnerability due to $@. | various-concat-obfuscations.js:2:16:2:39 | documen ... .search | user-provided value |

View File

@@ -1160,6 +1160,12 @@ nodes
| tst.js:501:33:501:63 | decodeU ... n.hash) |
| tst.js:501:43:501:62 | window.location.hash |
| tst.js:501:43:501:62 | window.location.hash |
| tst.js:508:7:508:39 | target |
| tst.js:508:16:508:39 | documen ... .search |
| tst.js:508:16:508:39 | documen ... .search |
| tst.js:509:18:509:23 | target |
| tst.js:509:18:509:54 | target. ... "), '') |
| tst.js:509:18:509:54 | target. ... "), '') |
| typeahead.js:9:28:9:30 | loc |
| typeahead.js:9:28:9:30 | loc |
| typeahead.js:9:28:9:30 | loc |
@@ -2393,6 +2399,11 @@ edges
| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) |
| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) |
| tst.js:501:43:501:62 | window.location.hash | tst.js:501:33:501:63 | decodeU ... n.hash) |
| tst.js:508:7:508:39 | target | tst.js:509:18:509:23 | target |
| tst.js:508:16:508:39 | documen ... .search | tst.js:508:7:508:39 | target |
| tst.js:508:16:508:39 | documen ... .search | tst.js:508:7:508:39 | target |
| tst.js:509:18:509:23 | target | tst.js:509:18:509:54 | target. ... "), '') |
| tst.js:509:18:509:23 | target | tst.js:509:18:509:54 | target. ... "), '') |
| typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc |
| typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc |
| typeahead.js:9:28:9:30 | loc | typeahead.js:10:16:10:18 | loc |

View File

@@ -503,3 +503,10 @@ function Foo() {
};
Object.assign(this, obj);
}
function nonGlobalSanitizer() {
var target = document.location.search
$("#foo").html(target.replace(new RegExp("<|>"), '')); // NOT OK
$("#foo").html(target.replace(new RegExp("<|>", unknownFlags()), '')); // OK -- most likely good. We don't know what the flags are.
$("#foo").html(target.replace(new RegExp("<|>", "g"), '')); // OK
}

View File

@@ -6,3 +6,4 @@
| tst.js:60:7:60:28 | s.repla ... '%25') | This replacement may double-escape '%' characters from $@. | tst.js:59:7:59:28 | s.repla ... '%26') | here |
| tst.js:68:10:70:38 | s.repla ... &amp;") | This replacement may double-escape '&' characters from $@. | tst.js:68:10:69:39 | s.repla ... apos;") | here |
| tst.js:79:10:79:66 | s.repla ... &amp;") | This replacement may double-escape '&' characters from $@. | tst.js:79:10:79:43 | s.repla ... epl[c]) | here |
| tst.js:99:10:101:49 | s.repla ... &amp;") | This replacement may double-escape '&' characters from $@. | tst.js:99:10:100:51 | s.repla ... apos;") | here |

View File

@@ -94,3 +94,21 @@ function testWithCapturedVar(x) {
function encodeDecodeEncode(s) {
return goodEncode(goodDecode(goodEncode(s)));
}
function badEncode(s) {
return s.replace(new RegExp("\"", "g"), "&quot;")
.replace(new RegExp("\'", "g"), "&apos;")
.replace(new RegExp("&", "g"), "&amp;"); // NOT OK
}
function goodEncode(s) {
return s.replace(new RegExp("\"", ""), "&quot;")
.replace(new RegExp("\'", ""), "&apos;")
.replace(new RegExp("&", ""), "&amp;"); // OK
}
function goodEncode(s) {
return s.replace(new RegExp("\"", unknownFlags()), "&quot;")
.replace(new RegExp("\'", unknownFlags()), "&apos;")
.replace(new RegExp("&", unknownFlags()), "&amp;"); // OK
}

View File

@@ -65,3 +65,9 @@
| tst.js:305:10:305:34 | s().rep ... ]/g,'') | This HTML sanitizer does not sanitize double quotes |
| tst.js:309:10:318:3 | s().rep ... ;";\\n\\t}) | This HTML sanitizer does not sanitize single quotes |
| tst.js:320:9:329:3 | s().rep ... ;";\\n\\t}) | This HTML sanitizer does not sanitize single quotes |
| tst.js:333:2:333:40 | s().rep ... g"),'') | This HTML sanitizer does not sanitize ampersands |
| tst.js:333:2:333:40 | s().rep ... g"),'') | This HTML sanitizer does not sanitize double quotes |
| tst.js:333:2:333:40 | s().rep ... g"),'') | This HTML sanitizer does not sanitize single quotes |
| tst.js:337:2:337:46 | s().rep ... ()),'') | This HTML sanitizer does not sanitize ampersands |
| tst.js:337:2:337:46 | s().rep ... ()),'') | This HTML sanitizer does not sanitize double quotes |
| tst.js:337:2:337:46 | s().rep ... ()),'') | This HTML sanitizer does not sanitize single quotes |

View File

@@ -39,3 +39,4 @@
| tst-multi-character-sanitization.js:145:13:145:90 | content ... /g, '') | This string may still contain $@, which may cause an HTML element injection vulnerability. | tst-multi-character-sanitization.js:145:30:145:30 | < | <script |
| tst-multi-character-sanitization.js:148:3:148:99 | n.clone ... gi, '') | This string may still contain $@, which may cause an HTML element injection vulnerability. | tst-multi-character-sanitization.js:148:41:148:41 | < | <script |
| tst-multi-character-sanitization.js:152:3:152:99 | n.clone ... gi, '') | This string may still contain $@, which may cause an HTML element injection vulnerability. | tst-multi-character-sanitization.js:152:41:152:41 | < | <script |
| tst.js:341:9:341:44 | p.repla ... "), "") | This string may still contain $@, which may cause a path injection vulnerability. | tst.js:341:31:341:33 | \\. | ../ |

View File

@@ -29,3 +29,9 @@
| tst.js:149:2:149:24 | x.repla ... replace | This replaces only the first occurrence of "\\n". |
| tst.js:193:9:193:17 | s.replace | This replaces only the first occurrence of /'/. |
| tst.js:202:10:202:18 | p.replace | This replaces only the first occurrence of "/../". |
| tst.js:341:9:341:17 | p.replace | This replaces only the first occurrence of /\\.\\.//. |
| tst.js:345:9:345:17 | s.replace | This does not escape backslash characters in the input. |
| tst.js:349:9:349:17 | s.replace | This replaces only the first occurrence of /'/. |
| tst.js:353:9:353:17 | s.replace | This does not escape backslash characters in the input. |
| tst.js:362:2:362:10 | x.replace | This replaces only the first occurrence of /\n/. |
| tst.js:363:2:363:24 | x.repla ... replace | This replaces only the first occurrence of /\n/. |

View File

@@ -327,4 +327,41 @@ function incompleteComplexSanitizers() {
if (str === "\"")
return "&quot;";
}) + '"';
}
}
function typicalBadHtmlSanitizers(s) {
s().replace(new RegExp("[<>]", "g"),''); // NOT OK
}
function typicalBadHtmlSanitizers(s) {
s().replace(new RegExp("[<>]", unknown()),''); // NOT OK
}
function bad18NewRegExp(p) {
return p.replace(new RegExp("\\.\\./"), ""); // NOT OK
}
function bad4NewRegExpG(s) {
return s.replace(new RegExp("\'","g"), "\\$&"); // NOT OK
}
function bad4NewRegExp(s) {
return s.replace(new RegExp("\'"), "\\$&"); // NOT OK
}
function bad4NewRegExpUnknown(s) {
return s.replace(new RegExp("\'", unknownFlags()), "\\$&"); // NOT OK
}
function newlinesNewReGexp(s) {
require("child_process").execSync("which emacs").toString().replace(new RegExp("\n"), ""); // OK
x.replace(new RegExp("\n", "g"), "").replace(x, y); // OK
x.replace(x, y).replace(new RegExp("\n", "g"), ""); // OK
x.replace(new RegExp("\n"), "").replace(x, y); // NOT OK
x.replace(x, y).replace(new RegExp("\n"), ""); // NOT OK
x.replace(new RegExp("\n", unknownFlags()), "").replace(x, y); // OK
x.replace(x, y).replace(new RegExp("\n", unknownFlags()), ""); // OK
}

View File

@@ -2,6 +2,7 @@
| tst.js:14:5:14:28 | new Reg ... (.*)?') | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/FOO/1' will bypass the middleware. | tst.js:14:5:14:28 | new Reg ... (.*)?') | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | case-insensitive path |
| tst.js:41:9:41:25 | /\\/foo\\/([0-9]+)/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/FOO/1' will bypass the middleware. | tst.js:41:9:41:25 | /\\/foo\\/([0-9]+)/ | pattern | tst.js:60:1:61:2 | app.get ... ware\\n}) | case-insensitive path |
| tst.js:64:5:64:28 | new Reg ... (.*)?') | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAR/1' will bypass the middleware. | tst.js:64:5:64:28 | new Reg ... (.*)?') | pattern | tst.js:73:1:74:2 | app.get ... ware\\n}) | case-insensitive path |
| tst.js:64:5:64:28 | new Reg ... (.*)?') | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAR/1' will bypass the middleware. | tst.js:64:5:64:28 | new Reg ... (.*)?') | pattern | tst.js:107:1:108:2 | app.get ... ware\\n}) | case-insensitive path |
| tst.js:76:9:76:20 | /\\/baz\\/bla/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAZ/BLA' will bypass the middleware. | tst.js:76:9:76:20 | /\\/baz\\/bla/ | pattern | tst.js:77:1:79:2 | app.get ... });\\n}) | case-insensitive path |
| tst.js:86:9:86:30 | /\\/[Bb] ... 3\\/[a]/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/BAZ3/A' will bypass the middleware. | tst.js:86:9:86:30 | /\\/[Bb] ... 3\\/[a]/ | pattern | tst.js:87:1:89:2 | app.get ... });\\n}) | case-insensitive path |
| tst.js:91:9:91:40 | /\\/summ ... ntGame/ | This route uses a case-sensitive path $@, but is guarding a $@. A path such as '/CURRENTGAME' will bypass the middleware. | tst.js:91:9:91:40 | /\\/summ ... ntGame/ | pattern | tst.js:93:1:95:2 | app.get ... O");\\n}) | case-insensitive path |

View File

@@ -93,3 +93,16 @@ app.use(/\/summonerByName|\/currentGame/,apiLimit1, apiLimit2);
app.get('/currentGame', function (req, res) {
res.send("FOO");
});
app.get(
new RegExp('^/bar(.*)?', unknownFlag()), // OK - Might be OK if the unknown flag evaluates to case insensitive one
unknown(),
function(req, res, next) {
if (req.params.blah) {
next();
}
}
);
app.get('/bar/*', (req, res) => { // OK - not a middleware
});

View File

@@ -139,6 +139,10 @@ nodes
| passwords.js:176:17:176:26 | myPasscode |
| passwords.js:176:17:176:26 | myPasscode |
| passwords.js:176:17:176:26 | myPasscode |
| passwords.js:182:14:182:21 | password |
| passwords.js:182:14:182:21 | password |
| passwords.js:182:14:182:51 | passwor ... ), "*") |
| passwords.js:182:14:182:51 | passwor ... ), "*") |
| passwords_in_browser1.js:2:13:2:20 | password |
| passwords_in_browser1.js:2:13:2:20 | password |
| passwords_in_browser1.js:2:13:2:20 | password |
@@ -285,6 +289,10 @@ edges
| passwords.js:170:11:170:18 | password | passwords.js:170:11:170:39 | passwor ... g, "*") |
| passwords.js:173:17:173:26 | myPassword | passwords.js:173:17:173:26 | myPassword |
| passwords.js:176:17:176:26 | myPasscode | passwords.js:176:17:176:26 | myPasscode |
| passwords.js:182:14:182:21 | password | passwords.js:182:14:182:51 | passwor ... ), "*") |
| passwords.js:182:14:182:21 | password | passwords.js:182:14:182:51 | passwor ... ), "*") |
| passwords.js:182:14:182:21 | password | passwords.js:182:14:182:51 | passwor ... ), "*") |
| passwords.js:182:14:182:21 | password | passwords.js:182:14:182:51 | passwor ... ), "*") |
| passwords_in_browser1.js:2:13:2:20 | password | passwords_in_browser1.js:2:13:2:20 | password |
| passwords_in_browser2.js:2:13:2:20 | password | passwords_in_browser2.js:2:13:2:20 | password |
| passwords_in_server_1.js:6:13:6:20 | password | passwords_in_server_1.js:6:13:6:20 | password |
@@ -332,6 +340,7 @@ edges
| passwords.js:170:11:170:39 | passwor ... g, "*") | passwords.js:170:11:170:18 | password | passwords.js:170:11:170:39 | passwor ... g, "*") | This logs sensitive data returned by $@ as clear text. | passwords.js:170:11:170:18 | password | an access to password |
| passwords.js:173:17:173:26 | myPassword | passwords.js:173:17:173:26 | myPassword | passwords.js:173:17:173:26 | myPassword | This logs sensitive data returned by $@ as clear text. | passwords.js:173:17:173:26 | myPassword | an access to myPassword |
| passwords.js:176:17:176:26 | myPasscode | passwords.js:176:17:176:26 | myPasscode | passwords.js:176:17:176:26 | myPasscode | This logs sensitive data returned by $@ as clear text. | passwords.js:176:17:176:26 | myPasscode | an access to myPasscode |
| passwords.js:182:14:182:51 | passwor ... ), "*") | passwords.js:182:14:182:21 | password | passwords.js:182:14:182:51 | passwor ... ), "*") | This logs sensitive data returned by $@ as clear text. | passwords.js:182:14:182:21 | password | an access to password |
| passwords_in_server_1.js:6:13:6:20 | password | passwords_in_server_1.js:6:13:6:20 | password | passwords_in_server_1.js:6:13:6:20 | password | This logs sensitive data returned by $@ as clear text. | passwords_in_server_1.js:6:13:6:20 | password | an access to password |
| passwords_in_server_2.js:3:13:3:20 | password | passwords_in_server_2.js:3:13:3:20 | password | passwords_in_server_2.js:3:13:3:20 | password | This logs sensitive data returned by $@ as clear text. | passwords_in_server_2.js:3:13:3:20 | password | an access to password |
| passwords_in_server_3.js:2:13:2:20 | password | passwords_in_server_3.js:2:13:2:20 | password | passwords_in_server_3.js:2:13:2:20 | password | This logs sensitive data returned by $@ as clear text. | passwords_in_server_3.js:2:13:2:20 | password | an access to password |

View File

@@ -174,4 +174,12 @@ const debug = require('debug')('test');
const myPasscode = foo();
console.log(myPasscode); // NOT OK
});
});
(function () {
console.log(password.replace(/./g, "*")); // OK
console.log(password.replace(new RegExp(".", "g"), "*")); // OK
console.log(password.replace(new RegExp("."), "*")); // NOT OK
console.log(password.replace(new RegExp(".", unknownFlags()), "*")); // OK -- Most likely not a problem.
console.log(password.replace(new RegExp("pre_._suf", "g"), "*")); // OK
})();

View File

@@ -130,6 +130,9 @@
| polynomial-redos.js:133:22:133:23 | f+ | Strings starting with 'f' and with many repetitions of 'f' can start matching anywhere after the start of the preceeding ff+G |
| polynomial-redos.js:136:25:136:26 | h+ | Strings starting with 'h' and with many repetitions of 'h' can start matching anywhere after the start of the preceeding hh+I |
| polynomial-redos.js:138:322:138:323 | .* | Strings starting with 'AAAAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' can start matching anywhere after the start of the preceeding (AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)(AA\|BB)C.*X |
| polynomial-redos.js:140:33:140:34 | h+ | Strings starting with 'h' and with many repetitions of 'h' can start matching anywhere after the start of the preceeding hh+I |
| polynomial-redos.js:141:33:141:34 | h+ | Strings starting with 'h' and with many repetitions of 'h' can start matching anywhere after the start of the preceeding hh+I |
| polynomial-redos.js:142:33:142:34 | h+ | Strings starting with 'h' and with many repetitions of 'h' can start matching anywhere after the start of the preceeding hh+I |
| regexplib/address.js:27:3:27:5 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*\\(?0\\d{4}\\)?(\\s*\|-)\\d{3}(\\s*\|-)\\d{3}\\s*) |
| regexplib/address.js:27:48:27:50 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*\\(?0\\d{3}\\)?(\\s*\|-)\\d{3}(\\s*\|-)\\d{4}\\s*) |
| regexplib/address.js:27:93:27:95 | \\s* | Strings with many repetitions of '\\t' can start matching anywhere after the start of the preceeding (\\s*(7\|8)(\\d{7}\|\\d{3}(\\-\|\\s{1})\\d{4})\\s*) |

View File

@@ -249,6 +249,12 @@ nodes
| polynomial-redos.js:136:5:136:13 | modified3 |
| polynomial-redos.js:138:5:138:11 | tainted |
| polynomial-redos.js:138:5:138:11 | tainted |
| polynomial-redos.js:140:2:140:10 | modified3 |
| polynomial-redos.js:140:2:140:10 | modified3 |
| polynomial-redos.js:141:2:141:10 | modified3 |
| polynomial-redos.js:141:2:141:10 | modified3 |
| polynomial-redos.js:142:2:142:10 | modified3 |
| polynomial-redos.js:142:2:142:10 | modified3 |
edges
| lib/closure.js:3:21:3:21 | x | lib/closure.js:4:16:4:16 | x |
| lib/closure.js:3:21:3:21 | x | lib/closure.js:4:16:4:16 | x |
@@ -489,6 +495,12 @@ edges
| polynomial-redos.js:132:18:132:50 | tainted ... g, "e") | polynomial-redos.js:132:6:132:50 | modified2 |
| polynomial-redos.js:135:9:135:47 | modified3 | polynomial-redos.js:136:5:136:13 | modified3 |
| polynomial-redos.js:135:9:135:47 | modified3 | polynomial-redos.js:136:5:136:13 | modified3 |
| polynomial-redos.js:135:9:135:47 | modified3 | polynomial-redos.js:140:2:140:10 | modified3 |
| polynomial-redos.js:135:9:135:47 | modified3 | polynomial-redos.js:140:2:140:10 | modified3 |
| polynomial-redos.js:135:9:135:47 | modified3 | polynomial-redos.js:141:2:141:10 | modified3 |
| polynomial-redos.js:135:9:135:47 | modified3 | polynomial-redos.js:141:2:141:10 | modified3 |
| polynomial-redos.js:135:9:135:47 | modified3 | polynomial-redos.js:142:2:142:10 | modified3 |
| polynomial-redos.js:135:9:135:47 | modified3 | polynomial-redos.js:142:2:142:10 | modified3 |
| polynomial-redos.js:135:21:135:27 | tainted | polynomial-redos.js:135:21:135:47 | tainted ... /g, "") |
| polynomial-redos.js:135:21:135:47 | tainted ... /g, "") | polynomial-redos.js:135:9:135:47 | modified3 |
#select
@@ -590,3 +602,6 @@ edges
| polynomial-redos.js:133:2:133:32 | modifie ... g, "b") | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:133:2:133:10 | modified2 | This $@ that depends on $@ may run slow on strings starting with 'f' and with many repetitions of 'f'. | polynomial-redos.js:133:22:133:23 | f+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:136:5:136:35 | modifie ... g, "b") | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:136:5:136:13 | modified3 | This $@ that depends on $@ may run slow on strings starting with 'h' and with many repetitions of 'h'. | polynomial-redos.js:136:25:136:26 | h+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:138:5:138:326 | tainted ... )C.*X/) | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:138:5:138:11 | tainted | This $@ that depends on $@ may run slow on strings starting with 'AAAAAAAAAAAAAAAAAAAAAABBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC' and with many repetitions of 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC'. | polynomial-redos.js:138:322:138:323 | .* | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:140:2:140:48 | modifie ... ), "b") | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:140:2:140:10 | modified3 | This $@ that depends on $@ may run slow on strings starting with 'h' and with many repetitions of 'h'. | polynomial-redos.js:140:33:140:34 | h+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:141:2:141:59 | modifie ... ), "b") | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:141:2:141:10 | modified3 | This $@ that depends on $@ may run slow on strings starting with 'h' and with many repetitions of 'h'. | polynomial-redos.js:141:33:141:34 | h+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |
| polynomial-redos.js:142:2:142:47 | modifie ... ), "b") | polynomial-redos.js:5:16:5:32 | req.query.tainted | polynomial-redos.js:142:2:142:10 | modified3 | This $@ that depends on $@ may run slow on strings starting with 'h' and with many repetitions of 'h'. | polynomial-redos.js:142:33:142:34 | h+ | regular expression | polynomial-redos.js:5:16:5:32 | req.query.tainted | a user-provided value |

View File

@@ -136,4 +136,8 @@ app.use(function(req, res) {
modified3.replace(/hh+I/g, "b"); // NOT OK
tainted.match(/(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)(AA|BB)C.*X/); // NOT OK
modified3.replace(new RegExp("hh+I", "g"), "b"); // NOT OK
modified3.replace(new RegExp("hh+I", unknownFlags()), "b"); // NOT OK
modified3.replace(new RegExp("hh+I", ""), "b"); // NOT OK
});

View File

@@ -64,6 +64,14 @@ nodes
| RegExpInjection.js:93:20:93:31 | process.argv |
| RegExpInjection.js:93:20:93:31 | process.argv |
| RegExpInjection.js:93:20:93:34 | process.argv[1] |
| RegExpInjection.js:97:7:97:32 | input |
| RegExpInjection.js:97:15:97:32 | req.param("input") |
| RegExpInjection.js:97:15:97:32 | req.param("input") |
| RegExpInjection.js:99:7:99:106 | sanitized |
| RegExpInjection.js:99:19:99:23 | input |
| RegExpInjection.js:99:19:99:106 | input.r ... "\\\\$&") |
| RegExpInjection.js:100:14:100:22 | sanitized |
| RegExpInjection.js:100:14:100:22 | sanitized |
| tst.js:5:9:5:29 | data |
| tst.js:5:16:5:29 | req.query.data |
| tst.js:5:16:5:29 | req.query.data |
@@ -133,6 +141,13 @@ edges
| RegExpInjection.js:93:20:93:31 | process.argv | RegExpInjection.js:93:20:93:34 | process.argv[1] |
| RegExpInjection.js:93:20:93:34 | process.argv[1] | RegExpInjection.js:93:16:93:49 | `^${pro ... r.app$` |
| RegExpInjection.js:93:20:93:34 | process.argv[1] | RegExpInjection.js:93:16:93:49 | `^${pro ... r.app$` |
| RegExpInjection.js:97:7:97:32 | input | RegExpInjection.js:99:19:99:23 | input |
| RegExpInjection.js:97:15:97:32 | req.param("input") | RegExpInjection.js:97:7:97:32 | input |
| RegExpInjection.js:97:15:97:32 | req.param("input") | RegExpInjection.js:97:7:97:32 | input |
| RegExpInjection.js:99:7:99:106 | sanitized | RegExpInjection.js:100:14:100:22 | sanitized |
| RegExpInjection.js:99:7:99:106 | sanitized | RegExpInjection.js:100:14:100:22 | sanitized |
| RegExpInjection.js:99:19:99:23 | input | RegExpInjection.js:99:19:99:106 | input.r ... "\\\\$&") |
| RegExpInjection.js:99:19:99:106 | input.r ... "\\\\$&") | RegExpInjection.js:99:7:99:106 | sanitized |
| tst.js:5:9:5:29 | data | tst.js:6:21:6:24 | data |
| tst.js:5:16:5:29 | req.query.data | tst.js:5:9:5:29 | data |
| tst.js:5:16:5:29 | req.query.data | tst.js:5:9:5:29 | data |
@@ -157,4 +172,5 @@ edges
| RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | RegExpInjection.js:82:15:82:32 | req.param("input") | RegExpInjection.js:87:14:87:55 | "^.*\\.( ... + ")$" | This regular expression is constructed from a $@. | RegExpInjection.js:82:15:82:32 | req.param("input") | user-provided value |
| RegExpInjection.js:91:16:91:50 | `^${pro ... r.app$` | RegExpInjection.js:91:20:91:30 | process.env | RegExpInjection.js:91:16:91:50 | `^${pro ... r.app$` | This regular expression is constructed from a $@. | RegExpInjection.js:91:20:91:30 | process.env | environment variable |
| RegExpInjection.js:93:16:93:49 | `^${pro ... r.app$` | RegExpInjection.js:93:20:93:31 | process.argv | RegExpInjection.js:93:16:93:49 | `^${pro ... r.app$` | This regular expression is constructed from a $@. | RegExpInjection.js:93:20:93:31 | process.argv | command-line argument |
| RegExpInjection.js:100:14:100:22 | sanitized | RegExpInjection.js:97:15:97:32 | req.param("input") | RegExpInjection.js:100:14:100:22 | sanitized | This regular expression is constructed from a $@. | RegExpInjection.js:97:15:97:32 | req.param("input") | user-provided value |
| tst.js:6:16:6:35 | "^"+ data.name + "$" | tst.js:5:16:5:29 | req.query.data | tst.js:6:16:6:35 | "^"+ data.name + "$" | This regular expression is constructed from a $@. | tst.js:5:16:5:29 | req.query.data | user-provided value |

View File

@@ -92,3 +92,16 @@ app.get("argv", function(req, res) {
new RegExp(`^${process.argv[1]}/Foo/bar.app$`); // NOT OK
});
app.get("argv", function(req, res) {
var input = req.param("input");
var sanitized = input.replace(new RegExp("[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]"), "\\$&");
new RegExp(sanitized); // NOT OK
var sanitized = input.replace(new RegExp("[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]", "g"), "\\$&");
new RegExp(sanitized); // OK
var sanitized = input.replace(new RegExp("[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]", unknownFlags()), "\\$&");
new RegExp(sanitized); // OK -- Most likely not a problem.
});

View File

@@ -190,6 +190,11 @@ nodes
| tst.js:105:5:105:17 | object[taint] |
| tst.js:105:5:105:17 | object[taint] |
| tst.js:105:12:105:16 | taint |
| tst.js:130:5:130:53 | obj[req ... ), '')] |
| tst.js:130:5:130:53 | obj[req ... ), '')] |
| tst.js:130:9:130:19 | req.query.x |
| tst.js:130:9:130:19 | req.query.x |
| tst.js:130:9:130:52 | req.que ... '), '') |
edges
| lib.js:1:38:1:40 | obj | lib.js:6:7:6:9 | obj |
| lib.js:1:38:1:40 | obj | lib.js:6:7:6:9 | obj |
@@ -366,6 +371,10 @@ edges
| tst.js:102:24:102:37 | req.query.data | tst.js:102:17:102:38 | String( ... y.data) |
| tst.js:105:12:105:16 | taint | tst.js:105:5:105:17 | object[taint] |
| tst.js:105:12:105:16 | taint | tst.js:105:5:105:17 | object[taint] |
| tst.js:130:9:130:19 | req.query.x | tst.js:130:9:130:52 | req.que ... '), '') |
| tst.js:130:9:130:19 | req.query.x | tst.js:130:9:130:52 | req.que ... '), '') |
| tst.js:130:9:130:52 | req.que ... '), '') | tst.js:130:5:130:53 | obj[req ... ), '')] |
| tst.js:130:9:130:52 | req.que ... '), '') | tst.js:130:5:130:53 | obj[req ... ), '')] |
#select
| lib.js:6:7:6:9 | obj | lib.js:1:43:1:46 | path | lib.js:6:7:6:9 | obj | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:1:43:1:46 | path | library input |
| lib.js:15:3:15:14 | obj[path[0]] | lib.js:14:38:14:41 | path | lib.js:15:3:15:14 | obj[path[0]] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | lib.js:14:38:14:41 | path | library input |
@@ -394,3 +403,4 @@ edges
| tst.js:94:5:94:37 | obj[req ... ', '')] | tst.js:94:9:94:19 | req.query.x | tst.js:94:5:94:37 | obj[req ... ', '')] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:94:9:94:19 | req.query.x | user controlled input |
| tst.js:97:5:97:46 | obj[req ... g, '')] | tst.js:97:9:97:19 | req.query.x | tst.js:97:5:97:46 | obj[req ... g, '')] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:97:9:97:19 | req.query.x | user controlled input |
| tst.js:105:5:105:17 | object[taint] | tst.js:102:24:102:37 | req.query.data | tst.js:105:5:105:17 | object[taint] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:102:24:102:37 | req.query.data | user controlled input |
| tst.js:130:5:130:53 | obj[req ... ), '')] | tst.js:130:9:130:19 | req.query.x | tst.js:130:5:130:53 | obj[req ... ), '')] | This assignment may alter Object.prototype if a malicious '__proto__' string is injected from $@. | tst.js:130:9:130:19 | req.query.x | user controlled input |

View File

@@ -123,3 +123,10 @@ app.get('/assign', (req, res) => {
Object.assign(dest, plainObj[taint]);
dest[taint] = taint; // OK - 'dest' is not Object.prototype itself (but possibly a copy)
});
app.get('/foo', (req, res) => {
let obj = {};
obj[req.query.x.replace(new RegExp('_', 'g'), '')].x = 'foo'; // OK
obj[req.query.x.replace(new RegExp('_', ''), '')].x = 'foo'; // NOT OK
obj[req.query.x.replace(new RegExp('_', unknownFlags()), '')].x = 'foo'; // OK
});

View File

@@ -0,0 +1,37 @@
/**
* @name Predicates starting with "get" or "as" should return a value
* @description Checks if predicates that start with "get" or "as" actually return a value.
* @kind problem
* @problem.severity warning
* @id ql/predicates-get-should-return-value
* @tags correctness
* maintainability
* @precision high
*/
import ql
import codeql_ql.ast.Ast
/**
* Identifies predicates whose names start with "get", "as" followed by an uppercase letter.
* This ensures that only predicates like "getValue" are matched, excluding names like "getter".
*/
predicate isGetPredicate(Predicate pred, string prefix) {
prefix = pred.getName().regexpCapture("(get|as)[A-Z].*", 1)
}
/**
* Checks if a predicate has a return type. This is phrased negatively to not flag unresolved aliases.
*/
predicate hasNoReturnType(Predicate pred) {
not exists(pred.getReturnTypeExpr()) and
not pred.(ClasslessPredicate).getAlias() instanceof PredicateExpr
or
hasNoReturnType(pred.(ClasslessPredicate).getAlias().(PredicateExpr).getResolvedPredicate())
}
from Predicate pred, string prefix
where
isGetPredicate(pred, prefix) and
hasNoReturnType(pred)
select pred, "This predicate starts with '" + prefix + "' but does not return a value."

View File

@@ -0,0 +1,6 @@
| test.qll:4:11:4:18 | ClasslessPredicate getValue | This predicate starts with 'get' but does not return a value. |
| test.qll:25:11:25:28 | ClasslessPredicate getImplementation2 | This predicate starts with 'get' but does not return a value. |
| test.qll:28:11:28:19 | ClasslessPredicate getAlias2 | This predicate starts with 'get' but does not return a value. |
| test.qll:31:11:31:17 | ClasslessPredicate asValue | This predicate starts with 'as' but does not return a value. |
| test.qll:48:11:48:19 | ClasslessPredicate getAlias4 | This predicate starts with 'get' but does not return a value. |
| test.qll:61:11:61:22 | ClasslessPredicate getDistance2 | This predicate starts with 'get' but does not return a value. |

View File

@@ -0,0 +1 @@
queries/style/ValidatePredicateGetReturns.ql

View File

@@ -0,0 +1,67 @@
import ql
// NOT OK -- Predicate starts with "get" but does not return a value
predicate getValue() { none() }
// OK -- starts with get and returns a value
string getData() { result = "data" }
// OK -- starts with get but followed by a lowercase letter, probably should be ignored
predicate getterFunction() { none() }
// OK -- starts with get and returns a value
string getImplementation() { result = "implementation" }
// OK -- is an alias
predicate getAlias = getImplementation/0;
// OK -- Starts with "get" but followed by a lowercase letter, probably be ignored
predicate getvalue() { none() }
// OK -- Does not start with "get", should be ignored
predicate retrieveValue() { none() }
// NOT OK -- starts with get and does not return value
predicate getImplementation2() { none() }
// NOT OK -- is an alias for a predicate which does not have a return value
predicate getAlias2 = getImplementation2/0;
// NOT OK -- starts with as and does not return value
predicate asValue() { none() }
// OK -- starts with as but followed by a lowercase letter, probably should be ignored
predicate assessment() { none() }
// OK -- starts with as and returns a value
string asString() { result = "string" }
// OK -- starts with get and returns a value
HiddenType getInjectableCompositeActionNode() {
exists(HiddenType hidden | result = hidden.toString())
}
// OK
predicate implementation4() { none() }
// NOT OK -- is an alias
predicate getAlias4 = implementation4/0;
// OK -- is an alias
predicate alias5 = implementation4/0;
int root() { none() }
predicate edge(int x, int y) { none() }
// OK -- Higher-order predicate
int getDistance(int x) = shortestDistances(root/0, edge/2)(_, x, result)
// NOT OK -- Higher-order predicate that does not return a value even though has 'get' in the name
predicate getDistance2(int x, int y) = shortestDistances(root/0, edge/2)(_, x, y)
// OK
predicate unresolvedAlias = unresolved/0;
// OK -- unresolved alias
predicate getUnresolvedAlias = unresolved/0;

View File

@@ -175,11 +175,9 @@ module LocalFlow {
or
node1 = node2.(ImplicitBlockArgumentNode).getParameterNode(true)
or
node1 =
unique(FlowSummaryNode n1 |
FlowSummaryImpl::Private::Steps::summaryLocalStep(n1.getSummaryNode(),
node2.(FlowSummaryNode).getSummaryNode(), true, _)
)
FlowSummaryImpl::Private::Steps::summaryLocalMustFlowStep(node1
.(FlowSummaryNode)
.getSummaryNode(), node2.(FlowSummaryNode).getSummaryNode())
}
}

View File

@@ -198,8 +198,11 @@ fn canonicalize_if_on_windows(path: &Path) -> Option<PathBuf> {
}
pub(crate) fn path_to_file_id(path: &Path, vfs: &Vfs) -> Option<FileId> {
// There seems to be some flaky inconsistencies around UNC paths on Windows, so if we fail to
// find the file id for a UNC path like that, we try to canonicalize it using dunce then.
// There seems to be some flaky inconsistencies around paths on Windows, where sometimes paths
// are registered in `vfs` without the `//?/` long path prefix. Then it happens that paths with
// that prefix are not found. To work around that, on Windows after failing to find `path` as
// is, we then try to canonicalize it using dunce. Dunce will be able to losslessly convert a
// `//?/` path into its equivalent one in `vfs` without the prefix, if there is one.
iter::once(path.to_path_buf())
.chain(canonicalize_if_on_windows(path))
.filter_map(|p| {

View File

@@ -5,12 +5,4 @@
* @id rust/diagnostics/data-flow-consistency
*/
import codeql.rust.dataflow.DataFlow::DataFlow as DataFlow
private import rust
private import codeql.rust.dataflow.internal.DataFlowImpl
private import codeql.rust.dataflow.internal.TaintTrackingImpl
private import codeql.dataflow.internal.DataFlowImplConsistency
private module Input implements InputSig<Location, RustDataFlow> { }
import MakeConsistency<Location, RustDataFlow, RustTaintTracking, Input>
import codeql.rust.dataflow.internal.DataFlowConsistency

View File

@@ -21,6 +21,11 @@ query predicate multipleToStrings(Element e, string cls, string s) {
*/
query predicate multipleLocations(Locatable e) { strictcount(e.getLocation()) > 1 }
/**
* Holds if `e` does not have a `Location`.
*/
query predicate noLocation(Locatable e) { not exists(e.getLocation()) }
private predicate multiplePrimaryQlClasses(Element e) {
strictcount(string cls | cls = e.getAPrimaryQlClass() and cls != "VariableAccess") > 1
}
@@ -58,6 +63,9 @@ int getAstInconsistencyCounts(string type) {
type = "Multiple locations" and
result = count(Element e | multipleLocations(e) | e)
or
type = "No location" and
result = count(Element e | noLocation(e) | e)
or
type = "Multiple primary QL classes" and
result = count(Element e | multiplePrimaryQlClasses(e) | e)
or

View File

@@ -15,7 +15,14 @@ private import DataFlowImpl::Node as Node
module DataFlow {
final class Node = Node::Node;
final class ParameterNode = Node::ParameterNode;
/**
* The value of a parameter at function entry, viewed as a node in a data
* flow graph.
*/
final class ParameterNode extends Node instanceof Node::SourceParameterNode {
/** Gets the parameter that this node corresponds to. */
ParamBase getParameter() { result = super.getParameter().getParamBase() }
}
final class PostUpdateNode = Node::PostUpdateNode;

View File

@@ -0,0 +1,69 @@
/** Provides classes and predicates for defining flow summaries. */
private import rust
private import internal.FlowSummaryImpl as Impl
private import codeql.rust.elements.internal.CallExprBaseImpl::Impl as CallExprBaseImpl
// import all instances below
private module Summaries {
private import codeql.rust.Frameworks
// TODO: Use models-as-data when it's available
private class UnwrapSummary extends SummarizedCallable::Range {
UnwrapSummary() { this = "lang:core::_::<crate::option::Option>::unwrap" }
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
input = "Argument[self].Variant[crate::std::option::Option::Some(0)]" and
output = "ReturnValue" and
preservesValue = true
}
}
}
/** Provides the `Range` class used to define the extent of `LibraryCallable`. */
module LibraryCallable {
/** A callable defined in library code, identified by a unique string. */
abstract class Range extends string {
bindingset[this]
Range() { any() }
/** Gets a call to this library callable. */
CallExprBase getACall() {
exists(Resolvable r, string crate |
r = CallExprBaseImpl::getCallResolvable(result) and
this = crate + r.getResolvedPath()
|
crate = r.getResolvedCrateOrigin() + "::_::"
or
not r.hasResolvedCrateOrigin() and
crate = ""
)
}
}
}
final class LibraryCallable = LibraryCallable::Range;
/** Provides the `Range` class used to define the extent of `SummarizedCallable`. */
module SummarizedCallable {
/** A callable with a flow summary, identified by a unique string. */
abstract class Range extends LibraryCallable::Range, Impl::Public::SummarizedCallable {
bindingset[this]
Range() { any() }
override predicate propagatesFlow(
string input, string output, boolean preservesValue, string model
) {
this.propagatesFlow(input, output, preservesValue) and model = ""
}
/**
* Holds if data may flow from `input` to `output` through this callable.
*
* `preservesValue` indicates whether this is a value-preserving step or a taint-step.
*/
abstract predicate propagatesFlow(string input, string output, boolean preservesValue);
}
}
final class SummarizedCallable = SummarizedCallable::Range;

View File

@@ -0,0 +1,17 @@
import codeql.rust.dataflow.DataFlow::DataFlow as DataFlow
private import rust
private import codeql.rust.dataflow.internal.DataFlowImpl
private import codeql.rust.dataflow.internal.TaintTrackingImpl
private import codeql.dataflow.internal.DataFlowImplConsistency
private module Input implements InputSig<Location, RustDataFlow> {
predicate uniqueNodeLocationExclude(RustDataFlow::Node n) {
// Exclude nodes where the missing location can be explained by the
// underlying AST node not having a location.
not exists(n.asExpr().getLocation())
}
predicate missingLocationExclude(RustDataFlow::Node n) { not exists(n.asExpr().getLocation()) }
}
import MakeConsistency<Location, RustDataFlow, RustTaintTracking, Input>

View File

@@ -11,8 +11,8 @@ private import SsaImpl as SsaImpl
private import codeql.rust.controlflow.ControlFlowGraph
private import codeql.rust.controlflow.CfgNodes
private import codeql.rust.dataflow.Ssa
private newtype TReturnKind = TNormalReturnKind()
private import codeql.rust.dataflow.FlowSummary
private import FlowSummaryImpl as FlowSummaryImpl
/**
* A return kind. A return kind describes how a value can be returned from a
@@ -35,8 +35,13 @@ final class DataFlowCallable extends TDataFlowCallable {
*/
CfgScope asCfgScope() { this = TCfgScope(result) }
/**
* Gets the underlying library callable, if any.
*/
LibraryCallable asLibraryCallable() { this = TLibraryCallable(result) }
/** Gets a textual representation of this callable. */
string toString() { result = this.asCfgScope().toString() }
string toString() { result = [this.asCfgScope().toString(), this.asLibraryCallable().toString()] }
/** Gets the location of this callable. */
Location getLocation() { result = this.asCfgScope().getLocation() }
@@ -54,11 +59,31 @@ final class DataFlowCall extends TDataFlowCall {
CallExprBaseCfgNode asCallBaseExprCfgNode() { result = call }
DataFlowCallable getEnclosingCallable() {
result = TCfgScope(call.getExpr().getEnclosingCfgScope())
predicate isSummaryCall(
FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver
) {
this = TSummaryCall(c, receiver)
}
string toString() { result = this.asCallBaseExprCfgNode().toString() }
DataFlowCallable getEnclosingCallable() {
result = TCfgScope(call.getExpr().getEnclosingCfgScope())
or
exists(FlowSummaryImpl::Public::SummarizedCallable c |
this.isSummaryCall(c, _) and
result = TLibraryCallable(c)
)
}
string toString() {
result = this.asCallBaseExprCfgNode().toString()
or
exists(
FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver
|
this.isSummaryCall(c, receiver) and
result = "[summary] call to " + receiver + " in " + c
)
}
Location getLocation() { result = this.asCallBaseExprCfgNode().getLocation() }
}
@@ -148,6 +173,26 @@ module Node {
override Location getLocation() { none() }
}
/** A data flow node used to model flow summaries. */
class FlowSummaryNode extends Node, TFlowSummaryNode {
FlowSummaryImpl::Private::SummaryNode getSummaryNode() { this = TFlowSummaryNode(result) }
/** Gets the summarized callable that this node belongs to. */
FlowSummaryImpl::Public::SummarizedCallable getSummarizedCallable() {
result = this.getSummaryNode().getSummarizedCallable()
}
override CfgScope getCfgScope() { none() }
override DataFlowCallable getEnclosingCallable() {
result.asLibraryCallable() = this.getSummarizedCallable()
}
override EmptyLocation getLocation() { any() }
override string toString() { result = this.getSummaryNode().toString() }
}
/** A data flow node that corresponds directly to a CFG node for an AST node. */
abstract class AstCfgFlowNode extends Node {
AstCfgNode n;
@@ -189,17 +234,62 @@ module Node {
* The value of a parameter at function entry, viewed as a node in a data
* flow graph.
*/
final class ParameterNode extends AstCfgFlowNode, TParameterNode {
abstract class ParameterNode extends Node {
abstract predicate isParameterOf(DataFlowCallable c, ParameterPosition pos);
}
final class SourceParameterNode extends AstCfgFlowNode, ParameterNode, TSourceParameterNode {
override ParamBaseCfgNode n;
ParameterNode() { this = TParameterNode(n) }
SourceParameterNode() { this = TSourceParameterNode(n) }
override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
n.getAstNode() = pos.getParameterIn(c.asCfgScope().(Callable).getParamList())
}
/** Gets the parameter in the CFG that this node corresponds to. */
ParamBaseCfgNode getParameter() { result = n }
}
final class ArgumentNode extends ExprNode {
ArgumentNode() { isArgumentForCall(n, _, _) }
/** A parameter for a library callable with a flow summary. */
final class SummaryParameterNode extends ParameterNode, FlowSummaryNode {
private ParameterPosition pos_;
SummaryParameterNode() {
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), pos_)
}
override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
this.getSummarizedCallable() = c.asLibraryCallable() and pos = pos_
}
}
abstract class ArgumentNode extends Node {
abstract predicate isArgumentOf(DataFlowCall call, RustDataFlow::ArgumentPosition pos);
}
final class ExprArgumentNode extends ArgumentNode, ExprNode {
private CallExprBaseCfgNode call_;
private RustDataFlow::ArgumentPosition pos_;
ExprArgumentNode() { isArgumentForCall(n, call_, pos_) }
override predicate isArgumentOf(DataFlowCall call, RustDataFlow::ArgumentPosition pos) {
call.asCallBaseExprCfgNode() = call_ and pos = pos_
}
}
final class SummaryArgumentNode extends FlowSummaryNode, ArgumentNode {
private FlowSummaryImpl::Private::SummaryNode receiver;
private RustDataFlow::ArgumentPosition pos_;
SummaryArgumentNode() {
FlowSummaryImpl::Private::summaryArgumentNode(receiver, this.getSummaryNode(), pos_)
}
override predicate isArgumentOf(DataFlowCall call, RustDataFlow::ArgumentPosition pos) {
call.isSummaryCall(_, receiver) and pos = pos_
}
}
/** An SSA node. */
@@ -222,23 +312,52 @@ module Node {
}
/** A data flow node that represents a value returned by a callable. */
final class ReturnNode extends ExprNode {
ReturnNode() { this.getCfgNode().getASuccessor() instanceof AnnotatedExitCfgNode }
abstract class ReturnNode extends Node {
abstract ReturnKind getKind();
}
ReturnKind getKind() { any() }
final class ExprReturnNode extends ExprNode, ReturnNode {
ExprReturnNode() { this.getCfgNode().getASuccessor() instanceof AnnotatedExitCfgNode }
override ReturnKind getKind() { result = TNormalReturnKind() }
}
final class SummaryReturnNode extends FlowSummaryNode, ReturnNode {
private ReturnKind rk;
SummaryReturnNode() { FlowSummaryImpl::Private::summaryReturnNode(this.getSummaryNode(), rk) }
override ReturnKind getKind() { result = rk }
}
/** A data-flow node that represents the output of a call. */
abstract class OutNode extends Node, ExprNode {
abstract class OutNode extends Node {
/** Gets the underlying call for this node. */
abstract DataFlowCall getCall();
abstract DataFlowCall getCall(ReturnKind kind);
}
final private class ExprOutNode extends ExprNode, OutNode {
ExprOutNode() { this.asExpr() instanceof CallExprBaseCfgNode }
/** Gets the underlying call CFG node that includes this out node. */
override DataFlowCall getCall() { result.asCallBaseExprCfgNode() = this.getCfgNode() }
override DataFlowCall getCall(ReturnKind kind) {
result.asCallBaseExprCfgNode() = this.getCfgNode() and
kind = TNormalReturnKind()
}
}
final class SummaryOutNode extends FlowSummaryNode, OutNode {
private DataFlowCall call;
private ReturnKind kind_;
SummaryOutNode() {
exists(FlowSummaryImpl::Private::SummaryNode receiver |
call.isSummaryCall(_, receiver) and
FlowSummaryImpl::Private::summaryOutNode(receiver, this.getSummaryNode(), kind_)
)
}
override DataFlowCall getCall(ReturnKind kind) { result = call and kind = kind_ }
}
/**
@@ -252,19 +371,35 @@ module Node {
* Nodes corresponding to AST elements, for example `ExprNode`, usually refer
* to the value before the update.
*/
final class PostUpdateNode extends Node, TArgumentPostUpdateNode {
abstract class PostUpdateNode extends Node {
/** Gets the node before the state update. */
abstract Node getPreUpdateNode();
override string toString() { result = "[post] " + this.getPreUpdateNode().toString() }
}
final class ExprPostUpdateNode extends PostUpdateNode, TExprPostUpdateNode {
private ExprCfgNode n;
PostUpdateNode() { this = TArgumentPostUpdateNode(n) }
ExprPostUpdateNode() { this = TExprPostUpdateNode(n) }
/** Gets the node before the state update. */
Node getPreUpdateNode() { result = TExprNode(n) }
override Node getPreUpdateNode() { result = TExprNode(n) }
final override CfgScope getCfgScope() { result = n.getScope() }
override CfgScope getCfgScope() { result = n.getScope() }
final override Location getLocation() { result = n.getLocation() }
override Location getLocation() { result = n.getLocation() }
}
final override string toString() { result = n.toString() }
final class SummaryPostUpdateNode extends FlowSummaryNode, PostUpdateNode {
private FlowSummaryNode pre;
SummaryPostUpdateNode() {
FlowSummaryImpl::Private::summaryPostUpdateNode(this.getSummaryNode(), pre.getSummaryNode())
}
override Node getPreUpdateNode() { result = pre }
final override string toString() { result = PostUpdateNode.super.toString() }
}
final class CastNode = NaNode;
@@ -277,7 +412,7 @@ module SsaFlow {
private module SsaFlow = SsaImpl::DataFlowIntegration;
private Node::ParameterNode toParameterNode(ParamCfgNode p) {
result.(Node::ParameterNode).getParameter() = p
result.(Node::SourceParameterNode).getParameter() = p
}
/** Converts a control flow node into an SSA control flow node. */
@@ -286,6 +421,9 @@ module SsaFlow {
or
result.(SsaFlow::ExprNode).getExpr() = n.asExpr()
or
result.(SsaFlow::ExprPostUpdateNode).getExpr() =
n.(Node::PostUpdateNode).getPreUpdateNode().asExpr()
or
n = toParameterNode(result.(SsaFlow::ParameterNode).getParameter())
}
@@ -313,6 +451,15 @@ private ExprCfgNode getALastEvalNode(ExprCfgNode e) {
}
module LocalFlow {
predicate flowSummaryLocalStep(
Node::FlowSummaryNode nodeFrom, Node::FlowSummaryNode nodeTo,
FlowSummaryImpl::Public::SummarizedCallable c, string model
) {
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.getSummaryNode(),
nodeTo.getSummaryNode(), true, model) and
c = nodeFrom.getSummarizedCallable()
}
pragma[nomagic]
predicate localFlowStepCommon(Node nodeFrom, Node nodeTo) {
nodeFrom.getCfgNode() = getALastEvalNode(nodeTo.getCfgNode())
@@ -326,9 +473,7 @@ module LocalFlow {
nodeFrom.(Node::AstCfgFlowNode).getCfgNode() =
nodeTo.(Node::SsaNode).getDefinitionExt().(Ssa::WriteDefinition).getControlFlowNode()
or
nodeFrom.(Node::ParameterNode).getParameter().(ParamCfgNode).getPat() = nodeTo.asPat()
or
SsaFlow::localFlowStep(_, nodeFrom, nodeTo, _)
nodeFrom.(Node::SourceParameterNode).getParameter().(ParamCfgNode).getPat() = nodeTo.asPat()
or
exists(AssignmentExprCfgNode a |
a.getRhs() = nodeFrom.getCfgNode() and
@@ -394,7 +539,7 @@ abstract class Content extends TContent {
}
/** A canonical path pointing to an enum variant. */
private class VariantCanonicalPath extends MkVariantCanonicalPath {
class VariantCanonicalPath extends MkVariantCanonicalPath {
CrateOriginOption crate;
string path;
string name;
@@ -404,6 +549,8 @@ private class VariantCanonicalPath extends MkVariantCanonicalPath {
/** Gets the underlying variant. */
Variant getVariant() { variantHasExtendedCanonicalPath(_, result, crate, path, name) }
string getExtendedCanonicalPath() { result = path + "::" + name }
string toString() { result = name }
Location getLocation() { result = this.getVariant().getLocation() }
@@ -449,6 +596,54 @@ private class VariantFieldContent extends VariantContent, TVariantFieldContent {
}
}
/** A canonical path pointing to a struct. */
private class StructCanonicalPath extends MkStructCanonicalPath {
CrateOriginOption crate;
string path;
StructCanonicalPath() { this = MkStructCanonicalPath(crate, path) }
/** Gets the underlying struct. */
Struct getStruct() { hasExtendedCanonicalPath(result, crate, path) }
string toString() { result = this.getStruct().getName().getText() }
Location getLocation() { result = this.getStruct().getLocation() }
}
/** Content stored in a field on a struct. */
private class StructFieldContent extends Content, TStructFieldContent {
private StructCanonicalPath s;
private string field_;
StructFieldContent() { this = TStructFieldContent(s, field_) }
StructCanonicalPath getStructCanonicalPath(string field) { result = s and field = field_ }
override string toString() { result = s.toString() + "." + field_.toString() }
}
/**
* Content stored at a position in a tuple.
*
* NOTE: Unlike `struct`s and `enum`s tuples are structural and not nominal,
* hence we don't store a canonical path for them.
*/
private class TuplePositionContent extends Content, TTuplePositionContent {
private int pos;
TuplePositionContent() { this = TTuplePositionContent(pos) }
int getPosition() { result = pos }
override string toString() { result = "tuple." + pos.toString() }
}
/** Holds if `access` indexes a tuple at an index corresponding to `c`. */
private predicate fieldTuplePositionContent(FieldExprCfgNode access, TuplePositionContent c) {
access.getNameRef().getText().toInt() = c.getPosition()
}
/** A value that represents a set of `Content`s. */
abstract class ContentSet extends TContentSet {
/** Gets a textual representation of this element. */
@@ -513,19 +708,23 @@ module RustDataFlow implements InputSig<Location> {
/** Holds if `p` is a parameter of `c` at the position `pos`. */
predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos) {
p.getCfgNode().getAstNode() = pos.getParameterIn(c.asCfgScope().(Callable).getParamList())
p.isParameterOf(c, pos)
}
/** Holds if `n` is an argument of `c` at the position `pos`. */
predicate isArgumentNode(ArgumentNode n, DataFlowCall call, ArgumentPosition pos) {
isArgumentForCall(n.getCfgNode(), call.asCallBaseExprCfgNode(), pos)
n.isArgumentOf(call, pos)
}
DataFlowCallable nodeGetEnclosingCallable(Node node) { result = node.getEnclosingCallable() }
DataFlowType getNodeType(Node node) { any() }
predicate nodeIsHidden(Node node) { node instanceof Node::SsaNode }
predicate nodeIsHidden(Node node) {
node instanceof Node::SsaNode
or
node instanceof Node::FlowSummaryNode
}
class DataFlowExpr = ExprCfgNode;
@@ -541,15 +740,15 @@ module RustDataFlow implements InputSig<Location> {
/** Gets a viable implementation of the target of the given `Call`. */
DataFlowCallable viableCallable(DataFlowCall call) {
result.asCfgScope() = call.asCallBaseExprCfgNode().getCallExprBase().getStaticTarget()
or
result.asLibraryCallable().getACall() = call.asCallBaseExprCfgNode().getCallExprBase()
}
/**
* Gets a node that can read the value returned from `call` with return kind
* `kind`.
*/
OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
call = result.getCall() and exists(kind)
}
OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) { call = result.getCall(kind) }
// NOTE: For now we use the type `Unit` and do not benefit from type
// information in the data flow analysis.
@@ -586,8 +785,21 @@ module RustDataFlow implements InputSig<Location> {
* are the value-preserving intra-callable flow steps.
*/
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) {
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo) and
(
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
or
exists(SsaImpl::DefinitionExt def, boolean isUseStep |
SsaFlow::localFlowStep(def, nodeFrom, nodeTo, isUseStep)
|
isUseStep = false
or
isUseStep = true and
not FlowSummaryImpl::Private::Steps::prohibitsUseUseFlow(nodeFrom, _)
)
) and
model = ""
or
LocalFlow::flowSummaryLocalStep(nodeFrom, nodeTo, _, model)
}
/**
@@ -595,7 +807,18 @@ module RustDataFlow implements InputSig<Location> {
* that does not follow a call edge. For example, a step through a global
* variable.
*/
predicate jumpStep(Node node1, Node node2) { none() }
predicate jumpStep(Node node1, Node node2) {
FlowSummaryImpl::Private::Steps::summaryJumpStep(node1.(Node::FlowSummaryNode).getSummaryNode(),
node2.(Node::FlowSummaryNode).getSummaryNode())
}
/** Holds if path `p` resolves to struct `s`. */
private predicate pathResolveToStructCanonicalPath(PathAstNode p, StructCanonicalPath s) {
exists(CrateOriginOption crate, string path |
resolveExtendedCanonicalPath(p, crate, path) and
s = MkStructCanonicalPath(crate, path)
)
}
/** Holds if path `p` resolves to variant `v`. */
private predicate pathResolveToVariantCanonicalPath(PathAstNode p, VariantCanonicalPath v) {
@@ -627,6 +850,12 @@ module RustDataFlow implements InputSig<Location> {
pathResolveToVariantCanonicalPath(p, v)
}
/** Holds if `p` destructs a struct `s`. */
pragma[nomagic]
private predicate structDestruction(RecordPat p, StructCanonicalPath s) {
pathResolveToStructCanonicalPath(p, s)
}
/**
* Holds if data can flow from `node1` to `node2` via a read of `c`. Thus,
* `node1` references an object with a content `c.getAReadContent()` whose
@@ -643,11 +872,28 @@ module RustDataFlow implements InputSig<Location> {
or
exists(RecordPatCfgNode pat, string field |
pat = node1.asPat() and
recordVariantDestruction(pat.getPat(),
c.(VariantFieldContent).getVariantCanonicalPath(field)) and
(
// Pattern destructs a struct-like variant.
recordVariantDestruction(pat.getPat(),
c.(VariantFieldContent).getVariantCanonicalPath(field))
or
// Pattern destructs a struct.
structDestruction(pat.getPat(), c.(StructFieldContent).getStructCanonicalPath(field))
) and
node2.asPat() = pat.getFieldPat(field)
)
or
exists(FieldExprCfgNode access |
// Read of a tuple entry
fieldTuplePositionContent(access, c) and
// TODO: Handle read of a struct field.
node1.asExpr() = access.getExpr() and
node2.asExpr() = access
)
)
or
FlowSummaryImpl::Private::Steps::summaryReadStep(node1.(Node::FlowSummaryNode).getSummaryNode(),
cs, node2.(Node::FlowSummaryNode).getSummaryNode())
}
/** Holds if `ce` constructs an enum value of type `v`. */
@@ -662,6 +908,21 @@ module RustDataFlow implements InputSig<Location> {
pathResolveToVariantCanonicalPath(re, v)
}
/** Holds if `re` constructs a struct value of type `s`. */
pragma[nomagic]
private predicate structConstruction(RecordExpr re, StructCanonicalPath s) {
pathResolveToStructCanonicalPath(re, s)
}
private predicate tupleAssignment(Node node1, Node node2, TuplePositionContent c) {
exists(AssignmentExprCfgNode assignment, FieldExprCfgNode access |
assignment.getLhs() = access and
fieldTuplePositionContent(access, c) and
node1.asExpr() = assignment.getRhs() and
node2.asExpr() = access.getExpr()
)
}
/**
* Holds if data can flow from `node1` to `node2` via a store into `c`. Thus,
* `node2` references an object with a content `c.getAStoreContent()` that
@@ -669,24 +930,37 @@ module RustDataFlow implements InputSig<Location> {
*/
predicate storeStep(Node node1, ContentSet cs, Node node2) {
exists(Content c | c = cs.(SingletonContentSet).getContent() |
node2.asExpr() =
any(CallExprCfgNode call, int pos |
tupleVariantConstruction(call.getCallExpr(),
c.(VariantPositionContent).getVariantCanonicalPath(pos)) and
node1.asExpr() = call.getArgument(pos)
|
call
)
exists(CallExprCfgNode call, int pos |
tupleVariantConstruction(call.getCallExpr(),
c.(VariantPositionContent).getVariantCanonicalPath(pos)) and
node1.asExpr() = call.getArgument(pos) and
node2.asExpr() = call
)
or
node2.asExpr() =
any(RecordExprCfgNode re, string field |
exists(RecordExprCfgNode re, string field |
(
// Expression is for a struct-like enum variant.
recordVariantConstruction(re.getRecordExpr(),
c.(VariantFieldContent).getVariantCanonicalPath(field)) and
node1.asExpr() = re.getFieldExpr(field)
|
re
)
c.(VariantFieldContent).getVariantCanonicalPath(field))
or
// Expression is for a struct.
structConstruction(re.getRecordExpr(),
c.(StructFieldContent).getStructCanonicalPath(field))
) and
node1.asExpr() = re.getFieldExpr(field) and
node2.asExpr() = re
)
or
exists(TupleExprCfgNode tuple |
node1.asExpr() = tuple.getField(c.(TuplePositionContent).getPosition()) and
node2.asExpr() = tuple
)
or
tupleAssignment(node1, node2.(PostUpdateNode).getPreUpdateNode(), c)
)
or
FlowSummaryImpl::Private::Steps::summaryStoreStep(node1.(Node::FlowSummaryNode).getSummaryNode(),
cs, node2.(Node::FlowSummaryNode).getSummaryNode())
}
/**
@@ -694,13 +968,21 @@ module RustDataFlow implements InputSig<Location> {
* any value stored inside `f` is cleared at the pre-update node associated with `x`
* in `x.f = newValue`.
*/
predicate clearsContent(Node n, ContentSet c) { none() }
predicate clearsContent(Node n, ContentSet cs) {
tupleAssignment(_, n, cs.(SingletonContentSet).getContent())
or
FlowSummaryImpl::Private::Steps::summaryClearsContent(n.(Node::FlowSummaryNode).getSummaryNode(),
cs)
}
/**
* Holds if the value that is being tracked is expected to be stored inside content `c`
* at node `n`.
*/
predicate expectsContent(Node n, ContentSet c) { none() }
predicate expectsContent(Node n, ContentSet cs) {
FlowSummaryImpl::Private::Steps::summaryExpectsContent(n.(Node::FlowSummaryNode)
.getSummaryNode(), cs)
}
class NodeRegion instanceof Void {
string toString() { result = "NodeRegion" }
@@ -720,7 +1002,12 @@ module RustDataFlow implements InputSig<Location> {
* One example would be to allow flow like `p.foo = p.bar;`, which is disallowed
* by default as a heuristic.
*/
predicate allowParameterReturnInSelf(ParameterNode p) { none() }
predicate allowParameterReturnInSelf(ParameterNode p) {
exists(DataFlowCallable c, ParameterPosition pos |
p.isParameterOf(c, pos) and
FlowSummaryImpl::Private::summaryAllowParameterReturnInSelf(c.asLibraryCallable(), pos)
)
}
/**
* Holds if the value of `node2` is given by `node1`.
@@ -733,6 +1020,10 @@ module RustDataFlow implements InputSig<Location> {
*/
predicate localMustFlowStep(Node node1, Node node2) {
SsaFlow::localMustFlowStep(_, node1, node2)
or
FlowSummaryImpl::Private::Steps::summaryLocalMustFlowStep(node1
.(Node::FlowSummaryNode)
.getSummaryNode(), node2.(Node::FlowSummaryNode).getSummaryNode())
}
class LambdaCallKind = Void;
@@ -762,30 +1053,54 @@ private module Cached {
cached
newtype TNode =
TExprNode(ExprCfgNode n) or
TParameterNode(ParamBaseCfgNode p) or
TSourceParameterNode(ParamBaseCfgNode p) or
TPatNode(PatCfgNode p) or
TArgumentPostUpdateNode(ExprCfgNode e) { isArgumentForCall(e, _, _) } or
TSsaNode(SsaImpl::DataFlowIntegration::SsaNode node)
TExprPostUpdateNode(ExprCfgNode e) {
isArgumentForCall(e, _, _) or e = any(FieldExprCfgNode access).getExpr()
} or
TSsaNode(SsaImpl::DataFlowIntegration::SsaNode node) or
TFlowSummaryNode(FlowSummaryImpl::Private::SummaryNode sn)
cached
newtype TDataFlowCall = TCall(CallExprBaseCfgNode c)
newtype TDataFlowCall =
TCall(CallExprBaseCfgNode c) or
TSummaryCall(
FlowSummaryImpl::Public::SummarizedCallable c, FlowSummaryImpl::Private::SummaryNode receiver
) {
FlowSummaryImpl::Private::summaryCallbackRange(c, receiver)
}
cached
newtype TDataFlowCallable = TCfgScope(CfgScope scope)
newtype TDataFlowCallable =
TCfgScope(CfgScope scope) or
TLibraryCallable(LibraryCallable c)
/** This is the local flow predicate that is exposed. */
cached
predicate localFlowStepImpl(Node::Node nodeFrom, Node::Node nodeTo) {
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
or
SsaFlow::localFlowStep(_, nodeFrom, nodeTo, _)
or
// Simple flow through library code is included in the exposed local
// step relation, even though flow is technically inter-procedural
FlowSummaryImpl::Private::Steps::summaryThroughStepValue(nodeFrom, nodeTo, _)
}
cached
newtype TParameterPosition =
TPositionalParameterPosition(int i) {
i in [0 .. max([any(ParamList l).getNumberOfParams(), any(ArgList l).getNumberOfArgs()]) - 1]
or
FlowSummaryImpl::ParsePositions::isParsedArgumentPosition(_, i)
or
FlowSummaryImpl::ParsePositions::isParsedParameterPosition(_, i)
} or
TSelfParameterPosition()
cached
newtype TReturnKind = TNormalReturnKind()
cached
newtype TVariantCanonicalPath =
MkVariantCanonicalPath(CrateOriginOption crate, string path, string name) {
@@ -802,6 +1117,12 @@ private module Cached {
name = ["Ok", "Err"]
}
cached
newtype TStructCanonicalPath =
MkStructCanonicalPath(CrateOriginOption crate, string path) {
exists(Struct s | hasExtendedCanonicalPath(s, crate, path))
}
cached
newtype TContent =
TVariantPositionContent(VariantCanonicalPath v, int pos) {
@@ -817,6 +1138,16 @@ private module Cached {
} or
TVariantFieldContent(VariantCanonicalPath v, string field) {
field = v.getVariant().getFieldList().(RecordFieldList).getAField().getName().getText()
} or
TTuplePositionContent(int pos) {
pos in [0 .. max([
any(TuplePat pat).getNumberOfFields(),
any(FieldExpr access).getNameRef().getText().toInt()
]
)]
} or
TStructFieldContent(StructCanonicalPath s, string field) {
field = s.getStruct().getFieldList().(RecordFieldList).getAField().getName().getText()
}
cached

View File

@@ -0,0 +1,103 @@
/**
* Provides classes and predicates for defining flow summaries.
*/
private import rust
private import codeql.dataflow.internal.FlowSummaryImpl
private import codeql.dataflow.internal.AccessPathSyntax as AccessPath
private import codeql.rust.dataflow.internal.DataFlowImpl
private import codeql.rust.dataflow.FlowSummary
module Input implements InputSig<Location, RustDataFlow> {
class SummarizedCallableBase = string;
RustDataFlow::ArgumentPosition callbackSelfParameterPosition() { none() }
ReturnKind getStandardReturnValueKind() { result = TNormalReturnKind() }
string encodeParameterPosition(ParameterPosition pos) { result = pos.toString() }
predicate encodeArgumentPosition = encodeParameterPosition/1;
string encodeContent(ContentSet cs, string arg) {
exists(Content c | cs = TSingletonContentSet(c) |
exists(VariantCanonicalPath v | result = "Variant" |
exists(int pos |
c = TVariantPositionContent(v, pos) and
arg = v.getExtendedCanonicalPath() + "(" + pos + ")"
)
or
exists(string field |
c = TVariantFieldContent(v, field) and
arg = v.getExtendedCanonicalPath() + "::" + field
)
)
)
}
string encodeReturn(ReturnKind rk, string arg) { none() }
string encodeWithoutContent(ContentSet c, string arg) {
result = "Without" + encodeContent(c, arg)
}
string encodeWithContent(ContentSet c, string arg) { result = "With" + encodeContent(c, arg) }
bindingset[token]
ParameterPosition decodeUnknownParameterPosition(AccessPath::AccessPathTokenBase token) {
// needed to support `Argument[x..y]` ranges
token.getName() = "Argument" and
result.getPosition() = AccessPath::parseInt(token.getAnArgument())
}
bindingset[token]
RustDataFlow::ArgumentPosition decodeUnknownArgumentPosition(AccessPath::AccessPathTokenBase token) {
// needed to support `Parameter[x..y]` ranges
token.getName() = "Parameter" and
result.getPosition() = AccessPath::parseInt(token.getAnArgument())
}
bindingset[token]
ContentSet decodeUnknownContent(AccessPath::AccessPathTokenBase token) { none() }
bindingset[token]
ContentSet decodeUnknownWithContent(AccessPath::AccessPathTokenBase token) { none() }
}
private import Make<Location, RustDataFlow, Input> as Impl
private module StepsInput implements Impl::Private::StepsInputSig {
DataFlowCall getACall(Public::SummarizedCallable sc) {
result.asCallBaseExprCfgNode().getCallExprBase() = sc.(LibraryCallable).getACall()
}
}
module Private {
import Impl::Private
module Steps = Impl::Private::Steps<StepsInput>;
}
module Public = Impl::Public;
module ParsePositions {
private import Private
private predicate isParamBody(string body) {
body = any(AccessPathToken tok).getAnArgument("Parameter")
}
private predicate isArgBody(string body) {
body = any(AccessPathToken tok).getAnArgument("Argument")
}
predicate isParsedParameterPosition(string c, int i) {
isParamBody(c) and
i = AccessPath::parseInt(c)
}
predicate isParsedArgumentPosition(string c, int i) {
isArgBody(c) and
i = AccessPath::parseInt(c)
}
}

View File

@@ -18,7 +18,7 @@ module Impl {
private import codeql.rust.elements.internal.PathExprImpl::Impl
pragma[nomagic]
private Resolvable getCallResolvable(CallExprBase call) {
Resolvable getCallResolvable(CallExprBase call) {
result = call.(MethodCallExpr)
or
result = call.(CallExpr).getFunction().(PathExpr)

View File

@@ -5,17 +5,10 @@
* @id rust/diagnostics/data-flow-consistency-counts
*/
private import rust
private import codeql.rust.dataflow.internal.DataFlowImpl
private import codeql.rust.dataflow.internal.TaintTrackingImpl
private import codeql.dataflow.internal.DataFlowImplConsistency
private module Input implements InputSig<Location, RustDataFlow> { }
import codeql.rust.dataflow.internal.DataFlowConsistency as Consistency
// see also `rust/diagnostics/data-flow-consistency`, which lists the
// individual inconsistency results.
from string type, int num
where
num =
MakeConsistency<Location, RustDataFlow, RustTaintTracking, Input>::getInconsistencyCounts(type)
where num = Consistency::getInconsistencyCounts(type)
select type, num

View File

@@ -7,7 +7,7 @@ private import codeql.rust.dataflow.internal.DataFlowImpl
private import codeql.rust.dataflow.internal.TaintTrackingImpl
private import codeql.rust.AstConsistency as AstConsistency
private import codeql.rust.controlflow.internal.CfgConsistency as CfgConsistency
private import codeql.dataflow.internal.DataFlowImplConsistency as DataFlowImplConsistency
private import codeql.rust.dataflow.internal.DataFlowConsistency as DataFlowConsistency
/**
* Gets a count of the total number of lines of code in the database.
@@ -35,15 +35,9 @@ int getTotalCfgInconsistencies() {
result = sum(string type | | CfgConsistency::getCfgInconsistencyCounts(type))
}
private module Input implements DataFlowImplConsistency::InputSig<Location, RustDataFlow> { }
/**
* Gets a count of the total number of data flow inconsistencies in the database.
*/
int getTotalDataFlowInconsistencies() {
result =
sum(string type |
|
DataFlowImplConsistency::MakeConsistency<Location, RustDataFlow, RustTaintTracking, Input>::getInconsistencyCounts(type)
)
result = sum(string type | | DataFlowConsistency::getInconsistencyCounts(type))
}

View File

@@ -0,0 +1,42 @@
noLocation
| file://:0:0:0:0 | ... .parent(...) |
| file://:0:0:0:0 | ... .unwrap(...) |
| file://:0:0:0:0 | ...: ... |
| file://:0:0:0:0 | ...::Path |
| file://:0:0:0:0 | ...::path |
| file://:0:0:0:0 | ArgList |
| file://:0:0:0:0 | ArgList |
| file://:0:0:0:0 | MacroItems |
| file://:0:0:0:0 | ParamList |
| file://:0:0:0:0 | Path |
| file://:0:0:0:0 | Path |
| file://:0:0:0:0 | Path |
| file://:0:0:0:0 | Path |
| file://:0:0:0:0 | Path |
| file://:0:0:0:0 | Path |
| file://:0:0:0:0 | Path |
| file://:0:0:0:0 | Path |
| file://:0:0:0:0 | Path |
| file://:0:0:0:0 | Path |
| file://:0:0:0:0 | RefType |
| file://:0:0:0:0 | RefType |
| file://:0:0:0:0 | RetType |
| file://:0:0:0:0 | StmtList |
| file://:0:0:0:0 | Use |
| file://:0:0:0:0 | UseTree |
| file://:0:0:0:0 | fn get_parent |
| file://:0:0:0:0 | get_parent |
| file://:0:0:0:0 | parent |
| file://:0:0:0:0 | path |
| file://:0:0:0:0 | path |
| file://:0:0:0:0 | path |
| file://:0:0:0:0 | path |
| file://:0:0:0:0 | path |
| file://:0:0:0:0 | path |
| file://:0:0:0:0 | path |
| file://:0:0:0:0 | path |
| file://:0:0:0:0 | std |
| file://:0:0:0:0 | std |
| file://:0:0:0:0 | std |
| file://:0:0:0:0 | unwrap |
| file://:0:0:0:0 | { ... } |

View File

@@ -1,11 +0,0 @@
uniqueNodeLocation
| file://:0:0:0:0 | ... .parent(...) | Node should have one location but has 0. |
| file://:0:0:0:0 | ... .parent(...) | Node should have one location but has 0. |
| file://:0:0:0:0 | ... .unwrap(...) | Node should have one location but has 0. |
| file://:0:0:0:0 | ...: ... | Node should have one location but has 0. |
| file://:0:0:0:0 | path | Node should have one location but has 0. |
| file://:0:0:0:0 | path | Node should have one location but has 0. |
| file://:0:0:0:0 | path | Node should have one location but has 0. |
| file://:0:0:0:0 | { ... } | Node should have one location but has 0. |
missingLocation
| Nodes without location: 8 |

View File

@@ -54,269 +54,378 @@ localStep
| main.rs:53:5:53:5 | [SSA] i | main.rs:54:10:54:10 | i |
| main.rs:53:5:53:5 | i | main.rs:53:5:53:5 | [SSA] i |
| main.rs:53:9:53:17 | source(...) | main.rs:53:5:53:5 | i |
| main.rs:61:9:61:9 | [SSA] i | main.rs:62:11:62:11 | i |
| main.rs:61:9:61:9 | i | main.rs:61:9:61:9 | [SSA] i |
| main.rs:61:13:61:31 | ...::new(...) | main.rs:61:9:61:9 | i |
| main.rs:66:9:66:9 | [SSA] a | main.rs:67:10:67:10 | a |
| main.rs:66:9:66:9 | a | main.rs:66:9:66:9 | [SSA] a |
| main.rs:66:13:66:26 | TupleExpr | main.rs:66:9:66:9 | a |
| main.rs:67:10:67:10 | a | main.rs:68:10:68:10 | a |
| main.rs:78:9:78:9 | [SSA] p | main.rs:83:10:83:10 | p |
| main.rs:78:9:78:9 | p | main.rs:78:9:78:9 | [SSA] p |
| main.rs:78:13:82:5 | Point {...} | main.rs:78:9:78:9 | p |
| main.rs:83:10:83:10 | p | main.rs:84:10:84:10 | p |
| main.rs:84:10:84:10 | p | main.rs:85:10:85:10 | p |
| main.rs:92:9:92:9 | [SSA] p | main.rs:97:38:97:38 | p |
| main.rs:92:9:92:9 | p | main.rs:92:9:92:9 | [SSA] p |
| main.rs:92:13:96:5 | Point {...} | main.rs:92:9:92:9 | p |
| main.rs:97:20:97:20 | [SSA] a | main.rs:98:10:98:10 | a |
| main.rs:97:20:97:20 | a | main.rs:97:20:97:20 | [SSA] a |
| main.rs:97:26:97:26 | [SSA] b | main.rs:99:10:99:10 | b |
| main.rs:97:26:97:26 | b | main.rs:97:26:97:26 | [SSA] b |
| main.rs:97:32:97:32 | [SSA] c | main.rs:100:10:100:10 | c |
| main.rs:97:32:97:32 | c | main.rs:97:32:97:32 | [SSA] c |
| main.rs:97:38:97:38 | p | main.rs:97:9:97:34 | Point {...} |
| main.rs:104:9:104:10 | [SSA] s1 | main.rs:106:11:106:12 | s1 |
| main.rs:104:9:104:10 | s1 | main.rs:104:9:104:10 | [SSA] s1 |
| main.rs:104:14:104:37 | ...::Some(...) | main.rs:104:9:104:10 | s1 |
| main.rs:105:9:105:10 | [SSA] s2 | main.rs:110:11:110:12 | s2 |
| main.rs:105:9:105:10 | s2 | main.rs:105:9:105:10 | [SSA] s2 |
| main.rs:105:14:105:28 | ...::Some(...) | main.rs:105:9:105:10 | s2 |
| main.rs:106:11:106:12 | s1 | main.rs:107:9:107:23 | ...::Some(...) |
| main.rs:106:11:106:12 | s1 | main.rs:108:9:108:20 | ...::None |
| main.rs:107:22:107:22 | [SSA] n | main.rs:107:33:107:33 | n |
| main.rs:107:22:107:22 | n | main.rs:107:22:107:22 | [SSA] n |
| main.rs:107:28:107:34 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } |
| main.rs:108:25:108:31 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } |
| main.rs:110:5:113:5 | match s2 { ... } | main.rs:103:37:114:1 | { ... } |
| main.rs:110:11:110:12 | s2 | main.rs:111:9:111:23 | ...::Some(...) |
| main.rs:110:11:110:12 | s2 | main.rs:112:9:112:20 | ...::None |
| main.rs:111:22:111:22 | [SSA] n | main.rs:111:33:111:33 | n |
| main.rs:111:22:111:22 | n | main.rs:111:22:111:22 | [SSA] n |
| main.rs:111:28:111:34 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } |
| main.rs:112:25:112:31 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } |
| main.rs:117:9:117:10 | [SSA] s1 | main.rs:119:11:119:12 | s1 |
| main.rs:117:9:117:10 | s1 | main.rs:117:9:117:10 | [SSA] s1 |
| main.rs:117:14:117:29 | Some(...) | main.rs:117:9:117:10 | s1 |
| main.rs:118:9:118:10 | [SSA] s2 | main.rs:123:11:123:12 | s2 |
| main.rs:118:9:118:10 | s2 | main.rs:118:9:118:10 | [SSA] s2 |
| main.rs:118:14:118:20 | Some(...) | main.rs:118:9:118:10 | s2 |
| main.rs:119:11:119:12 | s1 | main.rs:120:9:120:15 | Some(...) |
| main.rs:119:11:119:12 | s1 | main.rs:121:9:121:12 | None |
| main.rs:120:14:120:14 | [SSA] n | main.rs:120:25:120:25 | n |
| main.rs:120:14:120:14 | n | main.rs:120:14:120:14 | [SSA] n |
| main.rs:120:20:120:26 | sink(...) | main.rs:119:5:122:5 | match s1 { ... } |
| main.rs:121:17:121:23 | sink(...) | main.rs:119:5:122:5 | match s1 { ... } |
| main.rs:123:5:126:5 | match s2 { ... } | main.rs:116:39:127:1 | { ... } |
| main.rs:123:11:123:12 | s2 | main.rs:124:9:124:15 | Some(...) |
| main.rs:123:11:123:12 | s2 | main.rs:125:9:125:12 | None |
| main.rs:124:14:124:14 | [SSA] n | main.rs:124:25:124:25 | n |
| main.rs:124:14:124:14 | n | main.rs:124:14:124:14 | [SSA] n |
| main.rs:124:20:124:26 | sink(...) | main.rs:123:5:126:5 | match s2 { ... } |
| main.rs:125:17:125:23 | sink(...) | main.rs:123:5:126:5 | match s2 { ... } |
| main.rs:135:9:135:10 | [SSA] s1 | main.rs:137:11:137:12 | s1 |
| main.rs:135:9:135:10 | s1 | main.rs:135:9:135:10 | [SSA] s1 |
| main.rs:135:14:135:39 | ...::A(...) | main.rs:135:9:135:10 | s1 |
| main.rs:136:9:136:10 | [SSA] s2 | main.rs:144:11:144:12 | s2 |
| main.rs:136:9:136:10 | s2 | main.rs:136:9:136:10 | [SSA] s2 |
| main.rs:136:14:136:30 | ...::B(...) | main.rs:136:9:136:10 | s2 |
| main.rs:137:11:137:12 | s1 | main.rs:138:9:138:25 | ...::A(...) |
| main.rs:137:11:137:12 | s1 | main.rs:139:9:139:25 | ...::B(...) |
| main.rs:137:11:137:12 | s1 | main.rs:141:11:141:12 | s1 |
| main.rs:138:24:138:24 | [SSA] n | main.rs:138:35:138:35 | n |
| main.rs:138:24:138:24 | n | main.rs:138:24:138:24 | [SSA] n |
| main.rs:138:30:138:36 | sink(...) | main.rs:137:5:140:5 | match s1 { ... } |
| main.rs:139:24:139:24 | [SSA] n | main.rs:139:35:139:35 | n |
| main.rs:139:24:139:24 | n | main.rs:139:24:139:24 | [SSA] n |
| main.rs:139:30:139:36 | sink(...) | main.rs:137:5:140:5 | match s1 { ... } |
| main.rs:141:11:141:12 | s1 | main.rs:142:10:142:46 | ... \| ... |
| main.rs:142:10:142:46 | ... \| ... | main.rs:142:10:142:26 | ...::A(...) |
| main.rs:142:10:142:46 | ... \| ... | main.rs:142:30:142:46 | ...::B(...) |
| main.rs:142:10:142:46 | [SSA] [match(true)] phi | main.rs:142:57:142:57 | n |
| main.rs:142:25:142:25 | [SSA] [input] [match(true)] phi | main.rs:142:10:142:46 | [SSA] [match(true)] phi |
| main.rs:142:25:142:25 | [SSA] n | main.rs:142:25:142:25 | [SSA] [input] [match(true)] phi |
| main.rs:142:25:142:25 | n | main.rs:142:25:142:25 | [SSA] n |
| main.rs:142:45:142:45 | [SSA] [input] [match(true)] phi | main.rs:142:10:142:46 | [SSA] [match(true)] phi |
| main.rs:142:45:142:45 | [SSA] n | main.rs:142:45:142:45 | [SSA] [input] [match(true)] phi |
| main.rs:142:45:142:45 | n | main.rs:142:45:142:45 | [SSA] n |
| main.rs:142:52:142:58 | sink(...) | main.rs:141:5:143:5 | match s1 { ... } |
| main.rs:144:5:147:5 | match s2 { ... } | main.rs:134:48:148:1 | { ... } |
| main.rs:144:11:144:12 | s2 | main.rs:145:9:145:25 | ...::A(...) |
| main.rs:144:11:144:12 | s2 | main.rs:146:9:146:25 | ...::B(...) |
| main.rs:145:24:145:24 | [SSA] n | main.rs:145:35:145:35 | n |
| main.rs:145:24:145:24 | n | main.rs:145:24:145:24 | [SSA] n |
| main.rs:145:30:145:36 | sink(...) | main.rs:144:5:147:5 | match s2 { ... } |
| main.rs:146:24:146:24 | [SSA] n | main.rs:146:35:146:35 | n |
| main.rs:146:24:146:24 | n | main.rs:146:24:146:24 | [SSA] n |
| main.rs:146:30:146:36 | sink(...) | main.rs:144:5:147:5 | match s2 { ... } |
| main.rs:153:9:153:10 | [SSA] s1 | main.rs:155:11:155:12 | s1 |
| main.rs:153:9:153:10 | s1 | main.rs:153:9:153:10 | [SSA] s1 |
| main.rs:153:14:153:26 | A(...) | main.rs:153:9:153:10 | s1 |
| main.rs:154:9:154:10 | [SSA] s2 | main.rs:162:11:162:12 | s2 |
| main.rs:154:9:154:10 | s2 | main.rs:154:9:154:10 | [SSA] s2 |
| main.rs:154:14:154:17 | B(...) | main.rs:154:9:154:10 | s2 |
| main.rs:155:11:155:12 | s1 | main.rs:156:9:156:12 | A(...) |
| main.rs:155:11:155:12 | s1 | main.rs:157:9:157:12 | B(...) |
| main.rs:155:11:155:12 | s1 | main.rs:159:11:159:12 | s1 |
| main.rs:156:11:156:11 | [SSA] n | main.rs:156:22:156:22 | n |
| main.rs:156:11:156:11 | n | main.rs:156:11:156:11 | [SSA] n |
| main.rs:156:17:156:23 | sink(...) | main.rs:155:5:158:5 | match s1 { ... } |
| main.rs:157:11:157:11 | [SSA] n | main.rs:157:22:157:22 | n |
| main.rs:157:11:157:11 | n | main.rs:157:11:157:11 | [SSA] n |
| main.rs:157:17:157:23 | sink(...) | main.rs:155:5:158:5 | match s1 { ... } |
| main.rs:159:11:159:12 | s1 | main.rs:160:10:160:20 | ... \| ... |
| main.rs:160:10:160:20 | ... \| ... | main.rs:160:10:160:13 | A(...) |
| main.rs:160:10:160:20 | ... \| ... | main.rs:160:17:160:20 | B(...) |
| main.rs:160:10:160:20 | [SSA] [match(true)] phi | main.rs:160:31:160:31 | n |
| main.rs:160:12:160:12 | [SSA] [input] [match(true)] phi | main.rs:160:10:160:20 | [SSA] [match(true)] phi |
| main.rs:160:12:160:12 | [SSA] n | main.rs:160:12:160:12 | [SSA] [input] [match(true)] phi |
| main.rs:160:12:160:12 | n | main.rs:160:12:160:12 | [SSA] n |
| main.rs:160:19:160:19 | [SSA] [input] [match(true)] phi | main.rs:160:10:160:20 | [SSA] [match(true)] phi |
| main.rs:160:19:160:19 | [SSA] n | main.rs:160:19:160:19 | [SSA] [input] [match(true)] phi |
| main.rs:160:19:160:19 | n | main.rs:160:19:160:19 | [SSA] n |
| main.rs:160:26:160:32 | sink(...) | main.rs:159:5:161:5 | match s1 { ... } |
| main.rs:162:5:165:5 | match s2 { ... } | main.rs:152:50:166:1 | { ... } |
| main.rs:162:11:162:12 | s2 | main.rs:163:9:163:12 | A(...) |
| main.rs:162:11:162:12 | s2 | main.rs:164:9:164:12 | B(...) |
| main.rs:163:11:163:11 | [SSA] n | main.rs:163:22:163:22 | n |
| main.rs:163:11:163:11 | n | main.rs:163:11:163:11 | [SSA] n |
| main.rs:163:17:163:23 | sink(...) | main.rs:162:5:165:5 | match s2 { ... } |
| main.rs:164:11:164:11 | [SSA] n | main.rs:164:22:164:22 | n |
| main.rs:164:11:164:11 | n | main.rs:164:11:164:11 | [SSA] n |
| main.rs:164:17:164:23 | sink(...) | main.rs:162:5:165:5 | match s2 { ... } |
| main.rs:174:9:174:10 | [SSA] s1 | main.rs:178:11:178:12 | s1 |
| main.rs:174:9:174:10 | s1 | main.rs:174:9:174:10 | [SSA] s1 |
| main.rs:174:14:176:5 | ...::C {...} | main.rs:174:9:174:10 | s1 |
| main.rs:177:9:177:10 | [SSA] s2 | main.rs:185:11:185:12 | s2 |
| main.rs:177:9:177:10 | s2 | main.rs:177:9:177:10 | [SSA] s2 |
| main.rs:177:14:177:43 | ...::D {...} | main.rs:177:9:177:10 | s2 |
| main.rs:178:11:178:12 | s1 | main.rs:179:9:179:38 | ...::C {...} |
| main.rs:178:11:178:12 | s1 | main.rs:180:9:180:38 | ...::D {...} |
| main.rs:178:11:178:12 | s1 | main.rs:182:11:182:12 | s1 |
| main.rs:179:36:179:36 | [SSA] n | main.rs:179:48:179:48 | n |
| main.rs:179:36:179:36 | n | main.rs:179:36:179:36 | [SSA] n |
| main.rs:179:43:179:49 | sink(...) | main.rs:178:5:181:5 | match s1 { ... } |
| main.rs:180:36:180:36 | [SSA] n | main.rs:180:48:180:48 | n |
| main.rs:180:36:180:36 | n | main.rs:180:36:180:36 | [SSA] n |
| main.rs:180:43:180:49 | sink(...) | main.rs:178:5:181:5 | match s1 { ... } |
| main.rs:182:11:182:12 | s1 | main.rs:183:10:183:72 | ... \| ... |
| main.rs:183:10:183:72 | ... \| ... | main.rs:183:10:183:39 | ...::C {...} |
| main.rs:183:10:183:72 | ... \| ... | main.rs:183:43:183:72 | ...::D {...} |
| main.rs:183:10:183:72 | [SSA] [match(true)] phi | main.rs:183:83:183:83 | n |
| main.rs:183:37:183:37 | [SSA] [input] [match(true)] phi | main.rs:183:10:183:72 | [SSA] [match(true)] phi |
| main.rs:183:37:183:37 | [SSA] n | main.rs:183:37:183:37 | [SSA] [input] [match(true)] phi |
| main.rs:183:37:183:37 | n | main.rs:183:37:183:37 | [SSA] n |
| main.rs:183:70:183:70 | [SSA] [input] [match(true)] phi | main.rs:183:10:183:72 | [SSA] [match(true)] phi |
| main.rs:183:70:183:70 | [SSA] n | main.rs:183:70:183:70 | [SSA] [input] [match(true)] phi |
| main.rs:183:70:183:70 | n | main.rs:183:70:183:70 | [SSA] n |
| main.rs:183:78:183:84 | sink(...) | main.rs:182:5:184:5 | match s1 { ... } |
| main.rs:185:5:188:5 | match s2 { ... } | main.rs:173:49:189:1 | { ... } |
| main.rs:185:11:185:12 | s2 | main.rs:186:9:186:38 | ...::C {...} |
| main.rs:185:11:185:12 | s2 | main.rs:187:9:187:38 | ...::D {...} |
| main.rs:186:36:186:36 | [SSA] n | main.rs:186:48:186:48 | n |
| main.rs:186:36:186:36 | n | main.rs:186:36:186:36 | [SSA] n |
| main.rs:186:43:186:49 | sink(...) | main.rs:185:5:188:5 | match s2 { ... } |
| main.rs:187:36:187:36 | [SSA] n | main.rs:187:48:187:48 | n |
| main.rs:187:36:187:36 | n | main.rs:187:36:187:36 | [SSA] n |
| main.rs:187:43:187:49 | sink(...) | main.rs:185:5:188:5 | match s2 { ... } |
| main.rs:194:9:194:10 | [SSA] s1 | main.rs:198:11:198:12 | s1 |
| main.rs:194:9:194:10 | s1 | main.rs:194:9:194:10 | [SSA] s1 |
| main.rs:194:14:196:5 | C {...} | main.rs:194:9:194:10 | s1 |
| main.rs:197:9:197:10 | [SSA] s2 | main.rs:205:11:205:12 | s2 |
| main.rs:197:9:197:10 | s2 | main.rs:197:9:197:10 | [SSA] s2 |
| main.rs:197:14:197:29 | D {...} | main.rs:197:9:197:10 | s2 |
| main.rs:198:11:198:12 | s1 | main.rs:199:9:199:24 | C {...} |
| main.rs:198:11:198:12 | s1 | main.rs:200:9:200:24 | D {...} |
| main.rs:198:11:198:12 | s1 | main.rs:202:11:202:12 | s1 |
| main.rs:199:22:199:22 | [SSA] n | main.rs:199:34:199:34 | n |
| main.rs:199:22:199:22 | n | main.rs:199:22:199:22 | [SSA] n |
| main.rs:199:29:199:35 | sink(...) | main.rs:198:5:201:5 | match s1 { ... } |
| main.rs:200:22:200:22 | [SSA] n | main.rs:200:34:200:34 | n |
| main.rs:200:22:200:22 | n | main.rs:200:22:200:22 | [SSA] n |
| main.rs:200:29:200:35 | sink(...) | main.rs:198:5:201:5 | match s1 { ... } |
| main.rs:202:11:202:12 | s1 | main.rs:203:10:203:44 | ... \| ... |
| main.rs:203:10:203:44 | ... \| ... | main.rs:203:10:203:25 | C {...} |
| main.rs:203:10:203:44 | ... \| ... | main.rs:203:29:203:44 | D {...} |
| main.rs:203:10:203:44 | [SSA] [match(true)] phi | main.rs:203:55:203:55 | n |
| main.rs:203:23:203:23 | [SSA] [input] [match(true)] phi | main.rs:203:10:203:44 | [SSA] [match(true)] phi |
| main.rs:203:23:203:23 | [SSA] n | main.rs:203:23:203:23 | [SSA] [input] [match(true)] phi |
| main.rs:203:23:203:23 | n | main.rs:203:23:203:23 | [SSA] n |
| main.rs:203:42:203:42 | [SSA] [input] [match(true)] phi | main.rs:203:10:203:44 | [SSA] [match(true)] phi |
| main.rs:203:42:203:42 | [SSA] n | main.rs:203:42:203:42 | [SSA] [input] [match(true)] phi |
| main.rs:203:42:203:42 | n | main.rs:203:42:203:42 | [SSA] n |
| main.rs:203:50:203:56 | sink(...) | main.rs:202:5:204:5 | match s1 { ... } |
| main.rs:205:5:208:5 | match s2 { ... } | main.rs:193:51:209:1 | { ... } |
| main.rs:205:11:205:12 | s2 | main.rs:206:9:206:24 | C {...} |
| main.rs:205:11:205:12 | s2 | main.rs:207:9:207:24 | D {...} |
| main.rs:206:22:206:22 | [SSA] n | main.rs:206:34:206:34 | n |
| main.rs:206:22:206:22 | n | main.rs:206:22:206:22 | [SSA] n |
| main.rs:206:29:206:35 | sink(...) | main.rs:205:5:208:5 | match s2 { ... } |
| main.rs:207:22:207:22 | [SSA] n | main.rs:207:34:207:34 | n |
| main.rs:207:22:207:22 | n | main.rs:207:22:207:22 | [SSA] n |
| main.rs:207:29:207:35 | sink(...) | main.rs:205:5:208:5 | match s2 { ... } |
| main.rs:212:9:212:9 | [SSA] a | main.rs:213:5:213:5 | a |
| main.rs:212:9:212:9 | a | main.rs:212:9:212:9 | [SSA] a |
| main.rs:212:13:212:17 | { ... } | main.rs:212:9:212:9 | a |
| main.rs:212:15:212:15 | 0 | main.rs:212:13:212:17 | { ... } |
| main.rs:213:5:213:5 | a | main.rs:211:31:214:1 | { ... } |
| main.rs:216:22:216:22 | [SSA] b | main.rs:218:12:218:12 | b |
| main.rs:216:22:216:22 | b | main.rs:216:22:216:22 | [SSA] b |
| main.rs:216:22:216:28 | ...: bool | main.rs:216:22:216:22 | b |
| main.rs:217:9:217:9 | [SSA] a | main.rs:223:5:223:5 | a |
| main.rs:217:9:217:9 | a | main.rs:217:9:217:9 | [SSA] a |
| main.rs:217:13:222:5 | 'block: { ... } | main.rs:217:9:217:9 | a |
| main.rs:219:13:219:26 | break ''block 1 | main.rs:217:13:222:5 | 'block: { ... } |
| main.rs:219:26:219:26 | 1 | main.rs:219:13:219:26 | break ''block 1 |
| main.rs:221:9:221:9 | 2 | main.rs:217:13:222:5 | 'block: { ... } |
| main.rs:223:5:223:5 | a | main.rs:216:38:224:1 | { ... } |
| main.rs:226:22:226:22 | [SSA] b | main.rs:228:12:228:12 | b |
| main.rs:226:22:226:22 | b | main.rs:226:22:226:22 | [SSA] b |
| main.rs:226:22:226:28 | ...: bool | main.rs:226:22:226:22 | b |
| main.rs:227:9:227:9 | [SSA] a | main.rs:233:5:233:5 | a |
| main.rs:227:9:227:9 | a | main.rs:227:9:227:9 | [SSA] a |
| main.rs:227:13:232:5 | 'block: { ... } | main.rs:227:9:227:9 | a |
| main.rs:229:13:229:26 | break ''block 1 | main.rs:227:13:232:5 | 'block: { ... } |
| main.rs:229:26:229:26 | 1 | main.rs:229:13:229:26 | break ''block 1 |
| main.rs:231:9:231:22 | break ''block 2 | main.rs:227:13:232:5 | 'block: { ... } |
| main.rs:231:22:231:22 | 2 | main.rs:231:9:231:22 | break ''block 2 |
| main.rs:233:5:233:5 | a | main.rs:226:38:234:1 | { ... } |
| main.rs:58:9:58:9 | [SSA] a | main.rs:59:5:59:5 | a |
| main.rs:58:9:58:9 | a | main.rs:58:9:58:9 | [SSA] a |
| main.rs:58:13:58:17 | { ... } | main.rs:58:9:58:9 | a |
| main.rs:58:15:58:15 | 0 | main.rs:58:13:58:17 | { ... } |
| main.rs:59:5:59:5 | a | main.rs:57:31:60:1 | { ... } |
| main.rs:62:22:62:22 | [SSA] b | main.rs:64:12:64:12 | b |
| main.rs:62:22:62:22 | b | main.rs:62:22:62:22 | [SSA] b |
| main.rs:62:22:62:28 | ...: bool | main.rs:62:22:62:22 | b |
| main.rs:63:9:63:9 | [SSA] a | main.rs:69:5:69:5 | a |
| main.rs:63:9:63:9 | a | main.rs:63:9:63:9 | [SSA] a |
| main.rs:63:13:68:5 | 'block: { ... } | main.rs:63:9:63:9 | a |
| main.rs:65:13:65:26 | break ''block 1 | main.rs:63:13:68:5 | 'block: { ... } |
| main.rs:65:26:65:26 | 1 | main.rs:65:13:65:26 | break ''block 1 |
| main.rs:67:9:67:9 | 2 | main.rs:63:13:68:5 | 'block: { ... } |
| main.rs:69:5:69:5 | a | main.rs:62:38:70:1 | { ... } |
| main.rs:72:22:72:22 | [SSA] b | main.rs:74:12:74:12 | b |
| main.rs:72:22:72:22 | b | main.rs:72:22:72:22 | [SSA] b |
| main.rs:72:22:72:28 | ...: bool | main.rs:72:22:72:22 | b |
| main.rs:73:9:73:9 | [SSA] a | main.rs:79:5:79:5 | a |
| main.rs:73:9:73:9 | a | main.rs:73:9:73:9 | [SSA] a |
| main.rs:73:13:78:5 | 'block: { ... } | main.rs:73:9:73:9 | a |
| main.rs:75:13:75:26 | break ''block 1 | main.rs:73:13:78:5 | 'block: { ... } |
| main.rs:75:26:75:26 | 1 | main.rs:75:13:75:26 | break ''block 1 |
| main.rs:77:9:77:22 | break ''block 2 | main.rs:73:13:78:5 | 'block: { ... } |
| main.rs:77:22:77:22 | 2 | main.rs:77:9:77:22 | break ''block 2 |
| main.rs:79:5:79:5 | a | main.rs:72:38:80:1 | { ... } |
| main.rs:86:9:86:9 | [SSA] i | main.rs:87:11:87:11 | i |
| main.rs:86:9:86:9 | i | main.rs:86:9:86:9 | [SSA] i |
| main.rs:86:13:86:31 | ...::new(...) | main.rs:86:9:86:9 | i |
| main.rs:94:9:94:9 | [SSA] a | main.rs:95:10:95:10 | a |
| main.rs:94:9:94:9 | a | main.rs:94:9:94:9 | [SSA] a |
| main.rs:94:13:94:26 | TupleExpr | main.rs:94:9:94:9 | a |
| main.rs:95:10:95:10 | [post] a | main.rs:96:10:96:10 | a |
| main.rs:95:10:95:10 | a | main.rs:96:10:96:10 | a |
| main.rs:100:9:100:9 | [SSA] a | main.rs:101:24:101:24 | a |
| main.rs:100:9:100:9 | a | main.rs:100:9:100:9 | [SSA] a |
| main.rs:100:13:100:30 | TupleExpr | main.rs:100:9:100:9 | a |
| main.rs:101:10:101:11 | [SSA] a0 | main.rs:102:10:102:11 | a0 |
| main.rs:101:10:101:11 | a0 | main.rs:101:10:101:11 | [SSA] a0 |
| main.rs:101:14:101:15 | [SSA] a1 | main.rs:103:10:103:11 | a1 |
| main.rs:101:14:101:15 | a1 | main.rs:101:14:101:15 | [SSA] a1 |
| main.rs:101:18:101:19 | [SSA] a2 | main.rs:104:10:104:11 | a2 |
| main.rs:101:18:101:19 | a2 | main.rs:101:18:101:19 | [SSA] a2 |
| main.rs:101:24:101:24 | a | main.rs:101:9:101:20 | TuplePat |
| main.rs:108:9:108:13 | [SSA] a | main.rs:109:10:109:10 | a |
| main.rs:108:9:108:13 | a | main.rs:108:9:108:13 | [SSA] a |
| main.rs:108:17:108:31 | TupleExpr | main.rs:108:9:108:13 | a |
| main.rs:109:10:109:10 | [post] a | main.rs:110:10:110:10 | a |
| main.rs:109:10:109:10 | a | main.rs:110:10:110:10 | a |
| main.rs:110:10:110:10 | [post] a | main.rs:111:5:111:5 | a |
| main.rs:110:10:110:10 | a | main.rs:111:5:111:5 | a |
| main.rs:111:5:111:5 | [post] a | main.rs:112:5:112:5 | a |
| main.rs:111:5:111:5 | a | main.rs:112:5:112:5 | a |
| main.rs:111:11:111:20 | source(...) | main.rs:111:5:111:7 | a.0 |
| main.rs:112:5:112:5 | [post] a | main.rs:113:10:113:10 | a |
| main.rs:112:5:112:5 | a | main.rs:113:10:113:10 | a |
| main.rs:112:11:112:11 | 2 | main.rs:112:5:112:7 | a.1 |
| main.rs:113:10:113:10 | [post] a | main.rs:114:10:114:10 | a |
| main.rs:113:10:113:10 | a | main.rs:114:10:114:10 | a |
| main.rs:118:9:118:9 | [SSA] a | main.rs:119:14:119:14 | a |
| main.rs:118:9:118:9 | a | main.rs:118:9:118:9 | [SSA] a |
| main.rs:118:13:118:27 | TupleExpr | main.rs:118:9:118:9 | a |
| main.rs:119:9:119:9 | [SSA] b | main.rs:120:10:120:10 | b |
| main.rs:119:9:119:9 | b | main.rs:119:9:119:9 | [SSA] b |
| main.rs:119:13:119:18 | TupleExpr | main.rs:119:9:119:9 | b |
| main.rs:120:10:120:10 | [post] b | main.rs:121:10:121:10 | b |
| main.rs:120:10:120:10 | b | main.rs:121:10:121:10 | b |
| main.rs:121:10:121:10 | [post] b | main.rs:122:10:122:10 | b |
| main.rs:121:10:121:10 | b | main.rs:122:10:122:10 | b |
| main.rs:134:9:134:9 | [SSA] p | main.rs:138:10:138:10 | p |
| main.rs:134:9:134:9 | p | main.rs:134:9:134:9 | [SSA] p |
| main.rs:134:13:137:5 | Point {...} | main.rs:134:9:134:9 | p |
| main.rs:138:10:138:10 | [post] p | main.rs:139:10:139:10 | p |
| main.rs:138:10:138:10 | p | main.rs:139:10:139:10 | p |
| main.rs:143:9:143:13 | [SSA] p | main.rs:147:10:147:10 | p |
| main.rs:143:9:143:13 | p | main.rs:143:9:143:13 | [SSA] p |
| main.rs:143:17:146:5 | Point {...} | main.rs:143:9:143:13 | p |
| main.rs:147:10:147:10 | [post] p | main.rs:148:5:148:5 | p |
| main.rs:147:10:147:10 | p | main.rs:148:5:148:5 | p |
| main.rs:148:5:148:5 | [post] p | main.rs:149:10:149:10 | p |
| main.rs:148:5:148:5 | p | main.rs:149:10:149:10 | p |
| main.rs:148:11:148:20 | source(...) | main.rs:148:5:148:7 | p.y |
| main.rs:153:9:153:9 | [SSA] p | main.rs:157:32:157:32 | p |
| main.rs:153:9:153:9 | p | main.rs:153:9:153:9 | [SSA] p |
| main.rs:153:13:156:5 | Point {...} | main.rs:153:9:153:9 | p |
| main.rs:157:20:157:20 | [SSA] a | main.rs:158:10:158:10 | a |
| main.rs:157:20:157:20 | a | main.rs:157:20:157:20 | [SSA] a |
| main.rs:157:26:157:26 | [SSA] b | main.rs:159:10:159:10 | b |
| main.rs:157:26:157:26 | b | main.rs:157:26:157:26 | [SSA] b |
| main.rs:157:32:157:32 | p | main.rs:157:9:157:28 | Point {...} |
| main.rs:168:9:168:9 | [SSA] p | main.rs:175:10:175:10 | p |
| main.rs:168:9:168:9 | p | main.rs:168:9:168:9 | [SSA] p |
| main.rs:168:13:174:5 | Point3D {...} | main.rs:168:9:168:9 | p |
| main.rs:175:10:175:10 | [post] p | main.rs:176:10:176:10 | p |
| main.rs:175:10:175:10 | p | main.rs:176:10:176:10 | p |
| main.rs:176:10:176:10 | [post] p | main.rs:177:10:177:10 | p |
| main.rs:176:10:176:10 | p | main.rs:177:10:177:10 | p |
| main.rs:181:9:181:9 | [SSA] p | main.rs:188:11:188:11 | p |
| main.rs:181:9:181:9 | p | main.rs:181:9:181:9 | [SSA] p |
| main.rs:181:13:187:5 | Point3D {...} | main.rs:181:9:181:9 | p |
| main.rs:188:5:194:5 | match p { ... } | main.rs:180:26:195:1 | { ... } |
| main.rs:188:11:188:11 | p | main.rs:189:9:189:45 | Point3D {...} |
| main.rs:189:34:189:34 | [SSA] x | main.rs:190:18:190:18 | x |
| main.rs:189:34:189:34 | x | main.rs:189:34:189:34 | [SSA] x |
| main.rs:189:37:189:37 | [SSA] y | main.rs:191:18:191:18 | y |
| main.rs:189:37:189:37 | y | main.rs:189:37:189:37 | [SSA] y |
| main.rs:189:42:189:42 | [SSA] z | main.rs:192:18:192:18 | z |
| main.rs:189:42:189:42 | z | main.rs:189:42:189:42 | [SSA] z |
| main.rs:189:50:193:9 | { ... } | main.rs:188:5:194:5 | match p { ... } |
| main.rs:201:9:201:10 | [SSA] s1 | main.rs:203:11:203:12 | s1 |
| main.rs:201:9:201:10 | s1 | main.rs:201:9:201:10 | [SSA] s1 |
| main.rs:201:14:201:37 | ...::Some(...) | main.rs:201:9:201:10 | s1 |
| main.rs:202:9:202:10 | [SSA] s2 | main.rs:207:11:207:12 | s2 |
| main.rs:202:9:202:10 | s2 | main.rs:202:9:202:10 | [SSA] s2 |
| main.rs:202:14:202:28 | ...::Some(...) | main.rs:202:9:202:10 | s2 |
| main.rs:203:11:203:12 | s1 | main.rs:204:9:204:23 | ...::Some(...) |
| main.rs:203:11:203:12 | s1 | main.rs:205:9:205:20 | ...::None |
| main.rs:204:22:204:22 | [SSA] n | main.rs:204:33:204:33 | n |
| main.rs:204:22:204:22 | n | main.rs:204:22:204:22 | [SSA] n |
| main.rs:204:28:204:34 | sink(...) | main.rs:203:5:206:5 | match s1 { ... } |
| main.rs:205:25:205:31 | sink(...) | main.rs:203:5:206:5 | match s1 { ... } |
| main.rs:207:5:210:5 | match s2 { ... } | main.rs:200:37:211:1 | { ... } |
| main.rs:207:11:207:12 | s2 | main.rs:208:9:208:23 | ...::Some(...) |
| main.rs:207:11:207:12 | s2 | main.rs:209:9:209:20 | ...::None |
| main.rs:208:22:208:22 | [SSA] n | main.rs:208:33:208:33 | n |
| main.rs:208:22:208:22 | n | main.rs:208:22:208:22 | [SSA] n |
| main.rs:208:28:208:34 | sink(...) | main.rs:207:5:210:5 | match s2 { ... } |
| main.rs:209:25:209:31 | sink(...) | main.rs:207:5:210:5 | match s2 { ... } |
| main.rs:214:9:214:10 | [SSA] s1 | main.rs:216:11:216:12 | s1 |
| main.rs:214:9:214:10 | s1 | main.rs:214:9:214:10 | [SSA] s1 |
| main.rs:214:14:214:29 | Some(...) | main.rs:214:9:214:10 | s1 |
| main.rs:215:9:215:10 | [SSA] s2 | main.rs:220:11:220:12 | s2 |
| main.rs:215:9:215:10 | s2 | main.rs:215:9:215:10 | [SSA] s2 |
| main.rs:215:14:215:20 | Some(...) | main.rs:215:9:215:10 | s2 |
| main.rs:216:11:216:12 | s1 | main.rs:217:9:217:15 | Some(...) |
| main.rs:216:11:216:12 | s1 | main.rs:218:9:218:12 | None |
| main.rs:217:14:217:14 | [SSA] n | main.rs:217:25:217:25 | n |
| main.rs:217:14:217:14 | n | main.rs:217:14:217:14 | [SSA] n |
| main.rs:217:20:217:26 | sink(...) | main.rs:216:5:219:5 | match s1 { ... } |
| main.rs:218:17:218:23 | sink(...) | main.rs:216:5:219:5 | match s1 { ... } |
| main.rs:220:5:223:5 | match s2 { ... } | main.rs:213:39:224:1 | { ... } |
| main.rs:220:11:220:12 | s2 | main.rs:221:9:221:15 | Some(...) |
| main.rs:220:11:220:12 | s2 | main.rs:222:9:222:12 | None |
| main.rs:221:14:221:14 | [SSA] n | main.rs:221:25:221:25 | n |
| main.rs:221:14:221:14 | n | main.rs:221:14:221:14 | [SSA] n |
| main.rs:221:20:221:26 | sink(...) | main.rs:220:5:223:5 | match s2 { ... } |
| main.rs:222:17:222:23 | sink(...) | main.rs:220:5:223:5 | match s2 { ... } |
| main.rs:227:9:227:10 | [SSA] s1 | main.rs:228:10:228:11 | s1 |
| main.rs:227:9:227:10 | s1 | main.rs:227:9:227:10 | [SSA] s1 |
| main.rs:227:14:227:29 | Some(...) | main.rs:227:9:227:10 | s1 |
| main.rs:237:9:237:10 | [SSA] s1 | main.rs:239:11:239:12 | s1 |
| main.rs:237:9:237:10 | s1 | main.rs:237:9:237:10 | [SSA] s1 |
| main.rs:237:14:237:39 | ...::A(...) | main.rs:237:9:237:10 | s1 |
| main.rs:238:9:238:10 | [SSA] s2 | main.rs:246:11:246:12 | s2 |
| main.rs:238:9:238:10 | s2 | main.rs:238:9:238:10 | [SSA] s2 |
| main.rs:238:14:238:30 | ...::B(...) | main.rs:238:9:238:10 | s2 |
| main.rs:239:11:239:12 | s1 | main.rs:240:9:240:25 | ...::A(...) |
| main.rs:239:11:239:12 | s1 | main.rs:241:9:241:25 | ...::B(...) |
| main.rs:239:11:239:12 | s1 | main.rs:243:11:243:12 | s1 |
| main.rs:240:24:240:24 | [SSA] n | main.rs:240:35:240:35 | n |
| main.rs:240:24:240:24 | n | main.rs:240:24:240:24 | [SSA] n |
| main.rs:240:30:240:36 | sink(...) | main.rs:239:5:242:5 | match s1 { ... } |
| main.rs:241:24:241:24 | [SSA] n | main.rs:241:35:241:35 | n |
| main.rs:241:24:241:24 | n | main.rs:241:24:241:24 | [SSA] n |
| main.rs:241:30:241:36 | sink(...) | main.rs:239:5:242:5 | match s1 { ... } |
| main.rs:243:11:243:12 | s1 | main.rs:244:9:244:45 | ... \| ... |
| main.rs:244:9:244:45 | ... \| ... | main.rs:244:9:244:25 | ...::A(...) |
| main.rs:244:9:244:45 | ... \| ... | main.rs:244:29:244:45 | ...::B(...) |
| main.rs:244:9:244:45 | [SSA] [match(true)] phi | main.rs:244:55:244:55 | n |
| main.rs:244:24:244:24 | [SSA] [input] [match(true)] phi | main.rs:244:9:244:45 | [SSA] [match(true)] phi |
| main.rs:244:24:244:24 | [SSA] n | main.rs:244:24:244:24 | [SSA] [input] [match(true)] phi |
| main.rs:244:24:244:24 | n | main.rs:244:24:244:24 | [SSA] n |
| main.rs:244:44:244:44 | [SSA] [input] [match(true)] phi | main.rs:244:9:244:45 | [SSA] [match(true)] phi |
| main.rs:244:44:244:44 | [SSA] n | main.rs:244:44:244:44 | [SSA] [input] [match(true)] phi |
| main.rs:244:44:244:44 | n | main.rs:244:44:244:44 | [SSA] n |
| main.rs:244:50:244:56 | sink(...) | main.rs:243:5:245:5 | match s1 { ... } |
| main.rs:246:5:249:5 | match s2 { ... } | main.rs:236:48:250:1 | { ... } |
| main.rs:246:11:246:12 | s2 | main.rs:247:9:247:25 | ...::A(...) |
| main.rs:246:11:246:12 | s2 | main.rs:248:9:248:25 | ...::B(...) |
| main.rs:247:24:247:24 | [SSA] n | main.rs:247:35:247:35 | n |
| main.rs:247:24:247:24 | n | main.rs:247:24:247:24 | [SSA] n |
| main.rs:247:30:247:36 | sink(...) | main.rs:246:5:249:5 | match s2 { ... } |
| main.rs:248:24:248:24 | [SSA] n | main.rs:248:35:248:35 | n |
| main.rs:248:24:248:24 | n | main.rs:248:24:248:24 | [SSA] n |
| main.rs:248:30:248:36 | sink(...) | main.rs:246:5:249:5 | match s2 { ... } |
| main.rs:255:9:255:10 | [SSA] s1 | main.rs:257:11:257:12 | s1 |
| main.rs:255:9:255:10 | s1 | main.rs:255:9:255:10 | [SSA] s1 |
| main.rs:255:14:255:26 | A(...) | main.rs:255:9:255:10 | s1 |
| main.rs:256:9:256:10 | [SSA] s2 | main.rs:264:11:264:12 | s2 |
| main.rs:256:9:256:10 | s2 | main.rs:256:9:256:10 | [SSA] s2 |
| main.rs:256:14:256:17 | B(...) | main.rs:256:9:256:10 | s2 |
| main.rs:257:11:257:12 | s1 | main.rs:258:9:258:12 | A(...) |
| main.rs:257:11:257:12 | s1 | main.rs:259:9:259:12 | B(...) |
| main.rs:257:11:257:12 | s1 | main.rs:261:11:261:12 | s1 |
| main.rs:258:11:258:11 | [SSA] n | main.rs:258:22:258:22 | n |
| main.rs:258:11:258:11 | n | main.rs:258:11:258:11 | [SSA] n |
| main.rs:258:17:258:23 | sink(...) | main.rs:257:5:260:5 | match s1 { ... } |
| main.rs:259:11:259:11 | [SSA] n | main.rs:259:22:259:22 | n |
| main.rs:259:11:259:11 | n | main.rs:259:11:259:11 | [SSA] n |
| main.rs:259:17:259:23 | sink(...) | main.rs:257:5:260:5 | match s1 { ... } |
| main.rs:261:11:261:12 | s1 | main.rs:262:9:262:19 | ... \| ... |
| main.rs:262:9:262:19 | ... \| ... | main.rs:262:9:262:12 | A(...) |
| main.rs:262:9:262:19 | ... \| ... | main.rs:262:16:262:19 | B(...) |
| main.rs:262:9:262:19 | [SSA] [match(true)] phi | main.rs:262:29:262:29 | n |
| main.rs:262:11:262:11 | [SSA] [input] [match(true)] phi | main.rs:262:9:262:19 | [SSA] [match(true)] phi |
| main.rs:262:11:262:11 | [SSA] n | main.rs:262:11:262:11 | [SSA] [input] [match(true)] phi |
| main.rs:262:11:262:11 | n | main.rs:262:11:262:11 | [SSA] n |
| main.rs:262:18:262:18 | [SSA] [input] [match(true)] phi | main.rs:262:9:262:19 | [SSA] [match(true)] phi |
| main.rs:262:18:262:18 | [SSA] n | main.rs:262:18:262:18 | [SSA] [input] [match(true)] phi |
| main.rs:262:18:262:18 | n | main.rs:262:18:262:18 | [SSA] n |
| main.rs:262:24:262:30 | sink(...) | main.rs:261:5:263:5 | match s1 { ... } |
| main.rs:264:5:267:5 | match s2 { ... } | main.rs:254:50:268:1 | { ... } |
| main.rs:264:11:264:12 | s2 | main.rs:265:9:265:12 | A(...) |
| main.rs:264:11:264:12 | s2 | main.rs:266:9:266:12 | B(...) |
| main.rs:265:11:265:11 | [SSA] n | main.rs:265:22:265:22 | n |
| main.rs:265:11:265:11 | n | main.rs:265:11:265:11 | [SSA] n |
| main.rs:265:17:265:23 | sink(...) | main.rs:264:5:267:5 | match s2 { ... } |
| main.rs:266:11:266:11 | [SSA] n | main.rs:266:22:266:22 | n |
| main.rs:266:11:266:11 | n | main.rs:266:11:266:11 | [SSA] n |
| main.rs:266:17:266:23 | sink(...) | main.rs:264:5:267:5 | match s2 { ... } |
| main.rs:276:9:276:10 | [SSA] s1 | main.rs:280:11:280:12 | s1 |
| main.rs:276:9:276:10 | s1 | main.rs:276:9:276:10 | [SSA] s1 |
| main.rs:276:14:278:5 | ...::C {...} | main.rs:276:9:276:10 | s1 |
| main.rs:279:9:279:10 | [SSA] s2 | main.rs:287:11:287:12 | s2 |
| main.rs:279:9:279:10 | s2 | main.rs:279:9:279:10 | [SSA] s2 |
| main.rs:279:14:279:43 | ...::D {...} | main.rs:279:9:279:10 | s2 |
| main.rs:280:11:280:12 | s1 | main.rs:281:9:281:38 | ...::C {...} |
| main.rs:280:11:280:12 | s1 | main.rs:282:9:282:38 | ...::D {...} |
| main.rs:280:11:280:12 | s1 | main.rs:284:11:284:12 | s1 |
| main.rs:281:36:281:36 | [SSA] n | main.rs:281:48:281:48 | n |
| main.rs:281:36:281:36 | n | main.rs:281:36:281:36 | [SSA] n |
| main.rs:281:43:281:49 | sink(...) | main.rs:280:5:283:5 | match s1 { ... } |
| main.rs:282:36:282:36 | [SSA] n | main.rs:282:48:282:48 | n |
| main.rs:282:36:282:36 | n | main.rs:282:36:282:36 | [SSA] n |
| main.rs:282:43:282:49 | sink(...) | main.rs:280:5:283:5 | match s1 { ... } |
| main.rs:284:11:284:12 | s1 | main.rs:285:9:285:71 | ... \| ... |
| main.rs:285:9:285:71 | ... \| ... | main.rs:285:9:285:38 | ...::C {...} |
| main.rs:285:9:285:71 | ... \| ... | main.rs:285:42:285:71 | ...::D {...} |
| main.rs:285:9:285:71 | [SSA] [match(true)] phi | main.rs:285:81:285:81 | n |
| main.rs:285:36:285:36 | [SSA] [input] [match(true)] phi | main.rs:285:9:285:71 | [SSA] [match(true)] phi |
| main.rs:285:36:285:36 | [SSA] n | main.rs:285:36:285:36 | [SSA] [input] [match(true)] phi |
| main.rs:285:36:285:36 | n | main.rs:285:36:285:36 | [SSA] n |
| main.rs:285:69:285:69 | [SSA] [input] [match(true)] phi | main.rs:285:9:285:71 | [SSA] [match(true)] phi |
| main.rs:285:69:285:69 | [SSA] n | main.rs:285:69:285:69 | [SSA] [input] [match(true)] phi |
| main.rs:285:69:285:69 | n | main.rs:285:69:285:69 | [SSA] n |
| main.rs:285:76:285:82 | sink(...) | main.rs:284:5:286:5 | match s1 { ... } |
| main.rs:287:5:290:5 | match s2 { ... } | main.rs:275:49:291:1 | { ... } |
| main.rs:287:11:287:12 | s2 | main.rs:288:9:288:38 | ...::C {...} |
| main.rs:287:11:287:12 | s2 | main.rs:289:9:289:38 | ...::D {...} |
| main.rs:288:36:288:36 | [SSA] n | main.rs:288:48:288:48 | n |
| main.rs:288:36:288:36 | n | main.rs:288:36:288:36 | [SSA] n |
| main.rs:288:43:288:49 | sink(...) | main.rs:287:5:290:5 | match s2 { ... } |
| main.rs:289:36:289:36 | [SSA] n | main.rs:289:48:289:48 | n |
| main.rs:289:36:289:36 | n | main.rs:289:36:289:36 | [SSA] n |
| main.rs:289:43:289:49 | sink(...) | main.rs:287:5:290:5 | match s2 { ... } |
| main.rs:296:9:296:10 | [SSA] s1 | main.rs:300:11:300:12 | s1 |
| main.rs:296:9:296:10 | s1 | main.rs:296:9:296:10 | [SSA] s1 |
| main.rs:296:14:298:5 | C {...} | main.rs:296:9:296:10 | s1 |
| main.rs:299:9:299:10 | [SSA] s2 | main.rs:307:11:307:12 | s2 |
| main.rs:299:9:299:10 | s2 | main.rs:299:9:299:10 | [SSA] s2 |
| main.rs:299:14:299:29 | D {...} | main.rs:299:9:299:10 | s2 |
| main.rs:300:11:300:12 | s1 | main.rs:301:9:301:24 | C {...} |
| main.rs:300:11:300:12 | s1 | main.rs:302:9:302:24 | D {...} |
| main.rs:300:11:300:12 | s1 | main.rs:304:11:304:12 | s1 |
| main.rs:301:22:301:22 | [SSA] n | main.rs:301:34:301:34 | n |
| main.rs:301:22:301:22 | n | main.rs:301:22:301:22 | [SSA] n |
| main.rs:301:29:301:35 | sink(...) | main.rs:300:5:303:5 | match s1 { ... } |
| main.rs:302:22:302:22 | [SSA] n | main.rs:302:34:302:34 | n |
| main.rs:302:22:302:22 | n | main.rs:302:22:302:22 | [SSA] n |
| main.rs:302:29:302:35 | sink(...) | main.rs:300:5:303:5 | match s1 { ... } |
| main.rs:304:11:304:12 | s1 | main.rs:305:9:305:43 | ... \| ... |
| main.rs:305:9:305:43 | ... \| ... | main.rs:305:9:305:24 | C {...} |
| main.rs:305:9:305:43 | ... \| ... | main.rs:305:28:305:43 | D {...} |
| main.rs:305:9:305:43 | [SSA] [match(true)] phi | main.rs:305:53:305:53 | n |
| main.rs:305:22:305:22 | [SSA] [input] [match(true)] phi | main.rs:305:9:305:43 | [SSA] [match(true)] phi |
| main.rs:305:22:305:22 | [SSA] n | main.rs:305:22:305:22 | [SSA] [input] [match(true)] phi |
| main.rs:305:22:305:22 | n | main.rs:305:22:305:22 | [SSA] n |
| main.rs:305:41:305:41 | [SSA] [input] [match(true)] phi | main.rs:305:9:305:43 | [SSA] [match(true)] phi |
| main.rs:305:41:305:41 | [SSA] n | main.rs:305:41:305:41 | [SSA] [input] [match(true)] phi |
| main.rs:305:41:305:41 | n | main.rs:305:41:305:41 | [SSA] n |
| main.rs:305:48:305:54 | sink(...) | main.rs:304:5:306:5 | match s1 { ... } |
| main.rs:307:5:310:5 | match s2 { ... } | main.rs:295:51:311:1 | { ... } |
| main.rs:307:11:307:12 | s2 | main.rs:308:9:308:24 | C {...} |
| main.rs:307:11:307:12 | s2 | main.rs:309:9:309:24 | D {...} |
| main.rs:308:22:308:22 | [SSA] n | main.rs:308:34:308:34 | n |
| main.rs:308:22:308:22 | n | main.rs:308:22:308:22 | [SSA] n |
| main.rs:308:29:308:35 | sink(...) | main.rs:307:5:310:5 | match s2 { ... } |
| main.rs:309:22:309:22 | [SSA] n | main.rs:309:34:309:34 | n |
| main.rs:309:22:309:22 | n | main.rs:309:22:309:22 | [SSA] n |
| main.rs:309:29:309:35 | sink(...) | main.rs:307:5:310:5 | match s2 { ... } |
storeStep
| main.rs:117:19:117:28 | source(...) | Some | main.rs:117:14:117:29 | Some(...) |
| main.rs:118:19:118:19 | 2 | Some | main.rs:118:14:118:20 | Some(...) |
| main.rs:135:29:135:38 | source(...) | A | main.rs:135:14:135:39 | ...::A(...) |
| main.rs:136:29:136:29 | 2 | B | main.rs:136:14:136:30 | ...::B(...) |
| main.rs:153:16:153:25 | source(...) | A | main.rs:153:14:153:26 | A(...) |
| main.rs:154:16:154:16 | 2 | B | main.rs:154:14:154:17 | B(...) |
| main.rs:175:18:175:27 | source(...) | C | main.rs:174:14:176:5 | ...::C {...} |
| main.rs:177:41:177:41 | 2 | D | main.rs:177:14:177:43 | ...::D {...} |
| main.rs:195:18:195:27 | source(...) | C | main.rs:194:14:196:5 | C {...} |
| main.rs:197:27:197:27 | 2 | D | main.rs:197:14:197:29 | D {...} |
| main.rs:240:27:240:27 | 0 | Some | main.rs:240:22:240:28 | Some(...) |
| main.rs:94:14:94:22 | source(...) | tuple.0 | main.rs:94:13:94:26 | TupleExpr |
| main.rs:94:25:94:25 | 2 | tuple.1 | main.rs:94:13:94:26 | TupleExpr |
| main.rs:100:14:100:14 | 2 | tuple.0 | main.rs:100:13:100:30 | TupleExpr |
| main.rs:100:17:100:26 | source(...) | tuple.1 | main.rs:100:13:100:30 | TupleExpr |
| main.rs:100:29:100:29 | 2 | tuple.2 | main.rs:100:13:100:30 | TupleExpr |
| main.rs:108:18:108:18 | 2 | tuple.0 | main.rs:108:17:108:31 | TupleExpr |
| main.rs:108:21:108:30 | source(...) | tuple.1 | main.rs:108:17:108:31 | TupleExpr |
| main.rs:111:11:111:20 | source(...) | tuple.0 | main.rs:111:5:111:5 | [post] a |
| main.rs:112:11:112:11 | 2 | tuple.1 | main.rs:112:5:112:5 | [post] a |
| main.rs:118:14:118:14 | 3 | tuple.0 | main.rs:118:13:118:27 | TupleExpr |
| main.rs:118:17:118:26 | source(...) | tuple.1 | main.rs:118:13:118:27 | TupleExpr |
| main.rs:119:14:119:14 | a | tuple.0 | main.rs:119:13:119:18 | TupleExpr |
| main.rs:119:17:119:17 | 3 | tuple.1 | main.rs:119:13:119:18 | TupleExpr |
| main.rs:135:12:135:20 | source(...) | Point.x | main.rs:134:13:137:5 | Point {...} |
| main.rs:136:12:136:12 | 2 | Point.y | main.rs:134:13:137:5 | Point {...} |
| main.rs:144:12:144:20 | source(...) | Point.x | main.rs:143:17:146:5 | Point {...} |
| main.rs:145:12:145:12 | 2 | Point.y | main.rs:143:17:146:5 | Point {...} |
| main.rs:154:12:154:21 | source(...) | Point.x | main.rs:153:13:156:5 | Point {...} |
| main.rs:155:12:155:12 | 2 | Point.y | main.rs:153:13:156:5 | Point {...} |
| main.rs:169:16:172:9 | Point {...} | Point3D.plane | main.rs:168:13:174:5 | Point3D {...} |
| main.rs:170:16:170:16 | 2 | Point.x | main.rs:169:16:172:9 | Point {...} |
| main.rs:171:16:171:25 | source(...) | Point.y | main.rs:169:16:172:9 | Point {...} |
| main.rs:173:12:173:12 | 4 | Point3D.z | main.rs:168:13:174:5 | Point3D {...} |
| main.rs:182:16:185:9 | Point {...} | Point3D.plane | main.rs:181:13:187:5 | Point3D {...} |
| main.rs:183:16:183:16 | 2 | Point.x | main.rs:182:16:185:9 | Point {...} |
| main.rs:184:16:184:25 | source(...) | Point.y | main.rs:182:16:185:9 | Point {...} |
| main.rs:186:12:186:12 | 4 | Point3D.z | main.rs:181:13:187:5 | Point3D {...} |
| main.rs:214:19:214:28 | source(...) | Some | main.rs:214:14:214:29 | Some(...) |
| main.rs:215:19:215:19 | 2 | Some | main.rs:215:14:215:20 | Some(...) |
| main.rs:227:19:227:28 | source(...) | Some | main.rs:227:14:227:29 | Some(...) |
| main.rs:237:29:237:38 | source(...) | A | main.rs:237:14:237:39 | ...::A(...) |
| main.rs:238:29:238:29 | 2 | B | main.rs:238:14:238:30 | ...::B(...) |
| main.rs:255:16:255:25 | source(...) | A | main.rs:255:14:255:26 | A(...) |
| main.rs:256:16:256:16 | 2 | B | main.rs:256:14:256:17 | B(...) |
| main.rs:277:18:277:27 | source(...) | C | main.rs:276:14:278:5 | ...::C {...} |
| main.rs:279:41:279:41 | 2 | D | main.rs:279:14:279:43 | ...::D {...} |
| main.rs:297:18:297:27 | source(...) | C | main.rs:296:14:298:5 | C {...} |
| main.rs:299:27:299:27 | 2 | D | main.rs:299:14:299:29 | D {...} |
| main.rs:317:27:317:27 | 0 | Some | main.rs:317:22:317:28 | Some(...) |
readStep
| file://:0:0:0:0 | [summary param] self in lang:core::_::<crate::option::Option>::unwrap | Some | file://:0:0:0:0 | [summary] read: Argument[self].Variant[crate::std::option::Option::Some(0)] in lang:core::_::<crate::option::Option>::unwrap |
| main.rs:33:9:33:15 | Some(...) | Some | main.rs:33:14:33:14 | _ |
| main.rs:120:9:120:15 | Some(...) | Some | main.rs:120:14:120:14 | n |
| main.rs:124:9:124:15 | Some(...) | Some | main.rs:124:14:124:14 | n |
| main.rs:138:9:138:25 | ...::A(...) | A | main.rs:138:24:138:24 | n |
| main.rs:139:9:139:25 | ...::B(...) | B | main.rs:139:24:139:24 | n |
| main.rs:142:10:142:26 | ...::A(...) | A | main.rs:142:25:142:25 | n |
| main.rs:142:30:142:46 | ...::B(...) | B | main.rs:142:45:142:45 | n |
| main.rs:145:9:145:25 | ...::A(...) | A | main.rs:145:24:145:24 | n |
| main.rs:146:9:146:25 | ...::B(...) | B | main.rs:146:24:146:24 | n |
| main.rs:156:9:156:12 | A(...) | A | main.rs:156:11:156:11 | n |
| main.rs:157:9:157:12 | B(...) | B | main.rs:157:11:157:11 | n |
| main.rs:160:10:160:13 | A(...) | A | main.rs:160:12:160:12 | n |
| main.rs:160:17:160:20 | B(...) | B | main.rs:160:19:160:19 | n |
| main.rs:163:9:163:12 | A(...) | A | main.rs:163:11:163:11 | n |
| main.rs:164:9:164:12 | B(...) | B | main.rs:164:11:164:11 | n |
| main.rs:179:9:179:38 | ...::C {...} | C | main.rs:179:36:179:36 | n |
| main.rs:180:9:180:38 | ...::D {...} | D | main.rs:180:36:180:36 | n |
| main.rs:183:10:183:39 | ...::C {...} | C | main.rs:183:37:183:37 | n |
| main.rs:183:43:183:72 | ...::D {...} | D | main.rs:183:70:183:70 | n |
| main.rs:186:9:186:38 | ...::C {...} | C | main.rs:186:36:186:36 | n |
| main.rs:187:9:187:38 | ...::D {...} | D | main.rs:187:36:187:36 | n |
| main.rs:199:9:199:24 | C {...} | C | main.rs:199:22:199:22 | n |
| main.rs:200:9:200:24 | D {...} | D | main.rs:200:22:200:22 | n |
| main.rs:203:10:203:25 | C {...} | C | main.rs:203:23:203:23 | n |
| main.rs:203:29:203:44 | D {...} | D | main.rs:203:42:203:42 | n |
| main.rs:206:9:206:24 | C {...} | C | main.rs:206:22:206:22 | n |
| main.rs:207:9:207:24 | D {...} | D | main.rs:207:22:207:22 | n |
| main.rs:95:10:95:10 | a | tuple.0 | main.rs:95:10:95:12 | a.0 |
| main.rs:96:10:96:10 | a | tuple.1 | main.rs:96:10:96:12 | a.1 |
| main.rs:109:10:109:10 | a | tuple.0 | main.rs:109:10:109:12 | a.0 |
| main.rs:110:10:110:10 | a | tuple.1 | main.rs:110:10:110:12 | a.1 |
| main.rs:111:5:111:5 | a | tuple.0 | main.rs:111:5:111:7 | a.0 |
| main.rs:112:5:112:5 | a | tuple.1 | main.rs:112:5:112:7 | a.1 |
| main.rs:113:10:113:10 | a | tuple.0 | main.rs:113:10:113:12 | a.0 |
| main.rs:114:10:114:10 | a | tuple.1 | main.rs:114:10:114:12 | a.1 |
| main.rs:120:10:120:10 | b | tuple.0 | main.rs:120:10:120:12 | b.0 |
| main.rs:120:10:120:12 | b.0 | tuple.0 | main.rs:120:10:120:14 | ... .0 |
| main.rs:121:10:121:10 | b | tuple.0 | main.rs:121:10:121:12 | b.0 |
| main.rs:121:10:121:12 | b.0 | tuple.1 | main.rs:121:10:121:14 | ... .1 |
| main.rs:122:10:122:10 | b | tuple.1 | main.rs:122:10:122:12 | b.1 |
| main.rs:157:9:157:28 | Point {...} | Point.x | main.rs:157:20:157:20 | a |
| main.rs:157:9:157:28 | Point {...} | Point.y | main.rs:157:26:157:26 | b |
| main.rs:189:9:189:45 | Point3D {...} | Point3D.plane | main.rs:189:26:189:39 | Point {...} |
| main.rs:217:9:217:15 | Some(...) | Some | main.rs:217:14:217:14 | n |
| main.rs:221:9:221:15 | Some(...) | Some | main.rs:221:14:221:14 | n |
| main.rs:240:9:240:25 | ...::A(...) | A | main.rs:240:24:240:24 | n |
| main.rs:241:9:241:25 | ...::B(...) | B | main.rs:241:24:241:24 | n |
| main.rs:244:9:244:25 | ...::A(...) | A | main.rs:244:24:244:24 | n |
| main.rs:244:29:244:45 | ...::B(...) | B | main.rs:244:44:244:44 | n |
| main.rs:247:9:247:25 | ...::A(...) | A | main.rs:247:24:247:24 | n |
| main.rs:248:9:248:25 | ...::B(...) | B | main.rs:248:24:248:24 | n |
| main.rs:258:9:258:12 | A(...) | A | main.rs:258:11:258:11 | n |
| main.rs:259:9:259:12 | B(...) | B | main.rs:259:11:259:11 | n |
| main.rs:262:9:262:12 | A(...) | A | main.rs:262:11:262:11 | n |
| main.rs:262:16:262:19 | B(...) | B | main.rs:262:18:262:18 | n |
| main.rs:265:9:265:12 | A(...) | A | main.rs:265:11:265:11 | n |
| main.rs:266:9:266:12 | B(...) | B | main.rs:266:11:266:11 | n |
| main.rs:281:9:281:38 | ...::C {...} | C | main.rs:281:36:281:36 | n |
| main.rs:282:9:282:38 | ...::D {...} | D | main.rs:282:36:282:36 | n |
| main.rs:285:9:285:38 | ...::C {...} | C | main.rs:285:36:285:36 | n |
| main.rs:285:42:285:71 | ...::D {...} | D | main.rs:285:69:285:69 | n |
| main.rs:288:9:288:38 | ...::C {...} | C | main.rs:288:36:288:36 | n |
| main.rs:289:9:289:38 | ...::D {...} | D | main.rs:289:36:289:36 | n |
| main.rs:301:9:301:24 | C {...} | C | main.rs:301:22:301:22 | n |
| main.rs:302:9:302:24 | D {...} | D | main.rs:302:22:302:22 | n |
| main.rs:305:9:305:24 | C {...} | C | main.rs:305:22:305:22 | n |
| main.rs:305:28:305:43 | D {...} | D | main.rs:305:41:305:41 | n |
| main.rs:308:9:308:24 | C {...} | C | main.rs:308:22:308:22 | n |
| main.rs:309:9:309:24 | D {...} | D | main.rs:309:22:309:22 | n |

View File

@@ -5,38 +5,61 @@ edges
| main.rs:31:13:31:21 | source(...) | main.rs:36:10:36:10 | b | provenance | |
| main.rs:45:15:45:23 | source(...) | main.rs:47:10:47:10 | b | provenance | |
| main.rs:53:9:53:17 | source(...) | main.rs:54:10:54:10 | i | provenance | |
| main.rs:117:14:117:29 | Some(...) [Some] | main.rs:120:9:120:15 | Some(...) [Some] | provenance | |
| main.rs:117:19:117:28 | source(...) | main.rs:117:14:117:29 | Some(...) [Some] | provenance | |
| main.rs:120:9:120:15 | Some(...) [Some] | main.rs:120:14:120:14 | n | provenance | |
| main.rs:120:14:120:14 | n | main.rs:120:25:120:25 | n | provenance | |
| main.rs:135:14:135:39 | ...::A(...) [A] | main.rs:138:9:138:25 | ...::A(...) [A] | provenance | |
| main.rs:135:14:135:39 | ...::A(...) [A] | main.rs:142:10:142:26 | ...::A(...) [A] | provenance | |
| main.rs:135:29:135:38 | source(...) | main.rs:135:14:135:39 | ...::A(...) [A] | provenance | |
| main.rs:138:9:138:25 | ...::A(...) [A] | main.rs:138:24:138:24 | n | provenance | |
| main.rs:138:24:138:24 | n | main.rs:138:35:138:35 | n | provenance | |
| main.rs:142:10:142:26 | ...::A(...) [A] | main.rs:142:25:142:25 | n | provenance | |
| main.rs:142:25:142:25 | n | main.rs:142:57:142:57 | n | provenance | |
| main.rs:153:14:153:26 | A(...) [A] | main.rs:156:9:156:12 | A(...) [A] | provenance | |
| main.rs:153:14:153:26 | A(...) [A] | main.rs:160:10:160:13 | A(...) [A] | provenance | |
| main.rs:153:16:153:25 | source(...) | main.rs:153:14:153:26 | A(...) [A] | provenance | |
| main.rs:156:9:156:12 | A(...) [A] | main.rs:156:11:156:11 | n | provenance | |
| main.rs:156:11:156:11 | n | main.rs:156:22:156:22 | n | provenance | |
| main.rs:160:10:160:13 | A(...) [A] | main.rs:160:12:160:12 | n | provenance | |
| main.rs:160:12:160:12 | n | main.rs:160:31:160:31 | n | provenance | |
| main.rs:174:14:176:5 | ...::C {...} [C] | main.rs:179:9:179:38 | ...::C {...} [C] | provenance | |
| main.rs:174:14:176:5 | ...::C {...} [C] | main.rs:183:10:183:39 | ...::C {...} [C] | provenance | |
| main.rs:175:18:175:27 | source(...) | main.rs:174:14:176:5 | ...::C {...} [C] | provenance | |
| main.rs:179:9:179:38 | ...::C {...} [C] | main.rs:179:36:179:36 | n | provenance | |
| main.rs:179:36:179:36 | n | main.rs:179:48:179:48 | n | provenance | |
| main.rs:183:10:183:39 | ...::C {...} [C] | main.rs:183:37:183:37 | n | provenance | |
| main.rs:183:37:183:37 | n | main.rs:183:83:183:83 | n | provenance | |
| main.rs:194:14:196:5 | C {...} [C] | main.rs:199:9:199:24 | C {...} [C] | provenance | |
| main.rs:194:14:196:5 | C {...} [C] | main.rs:203:10:203:25 | C {...} [C] | provenance | |
| main.rs:195:18:195:27 | source(...) | main.rs:194:14:196:5 | C {...} [C] | provenance | |
| main.rs:199:9:199:24 | C {...} [C] | main.rs:199:22:199:22 | n | provenance | |
| main.rs:199:22:199:22 | n | main.rs:199:34:199:34 | n | provenance | |
| main.rs:203:10:203:25 | C {...} [C] | main.rs:203:23:203:23 | n | provenance | |
| main.rs:203:23:203:23 | n | main.rs:203:55:203:55 | n | provenance | |
| main.rs:94:13:94:26 | TupleExpr [tuple.0] | main.rs:95:10:95:10 | a [tuple.0] | provenance | |
| main.rs:94:14:94:22 | source(...) | main.rs:94:13:94:26 | TupleExpr [tuple.0] | provenance | |
| main.rs:95:10:95:10 | a [tuple.0] | main.rs:95:10:95:12 | a.0 | provenance | |
| main.rs:108:17:108:31 | TupleExpr [tuple.1] | main.rs:110:10:110:10 | a [tuple.1] | provenance | |
| main.rs:108:21:108:30 | source(...) | main.rs:108:17:108:31 | TupleExpr [tuple.1] | provenance | |
| main.rs:110:10:110:10 | a [tuple.1] | main.rs:110:10:110:12 | a.1 | provenance | |
| main.rs:111:5:111:5 | [post] a [tuple.0] | main.rs:112:5:112:5 | a [tuple.0] | provenance | |
| main.rs:111:11:111:20 | source(...) | main.rs:111:5:111:5 | [post] a [tuple.0] | provenance | |
| main.rs:112:5:112:5 | a [tuple.0] | main.rs:113:10:113:10 | a [tuple.0] | provenance | |
| main.rs:113:10:113:10 | a [tuple.0] | main.rs:113:10:113:12 | a.0 | provenance | |
| main.rs:118:13:118:27 | TupleExpr [tuple.1] | main.rs:119:14:119:14 | a [tuple.1] | provenance | |
| main.rs:118:17:118:26 | source(...) | main.rs:118:13:118:27 | TupleExpr [tuple.1] | provenance | |
| main.rs:119:13:119:18 | TupleExpr [tuple.0, tuple.1] | main.rs:121:10:121:10 | b [tuple.0, tuple.1] | provenance | |
| main.rs:119:14:119:14 | a [tuple.1] | main.rs:119:13:119:18 | TupleExpr [tuple.0, tuple.1] | provenance | |
| main.rs:121:10:121:10 | b [tuple.0, tuple.1] | main.rs:121:10:121:12 | b.0 [tuple.1] | provenance | |
| main.rs:121:10:121:12 | b.0 [tuple.1] | main.rs:121:10:121:14 | ... .1 | provenance | |
| main.rs:153:13:156:5 | Point {...} [Point.x] | main.rs:157:9:157:28 | Point {...} [Point.x] | provenance | |
| main.rs:154:12:154:21 | source(...) | main.rs:153:13:156:5 | Point {...} [Point.x] | provenance | |
| main.rs:157:9:157:28 | Point {...} [Point.x] | main.rs:157:20:157:20 | a | provenance | |
| main.rs:157:20:157:20 | a | main.rs:158:10:158:10 | a | provenance | |
| main.rs:214:14:214:29 | Some(...) [Some] | main.rs:217:9:217:15 | Some(...) [Some] | provenance | |
| main.rs:214:19:214:28 | source(...) | main.rs:214:14:214:29 | Some(...) [Some] | provenance | |
| main.rs:217:9:217:15 | Some(...) [Some] | main.rs:217:14:217:14 | n | provenance | |
| main.rs:217:14:217:14 | n | main.rs:217:25:217:25 | n | provenance | |
| main.rs:227:14:227:29 | Some(...) [Some] | main.rs:228:10:228:11 | s1 [Some] | provenance | |
| main.rs:227:19:227:28 | source(...) | main.rs:227:14:227:29 | Some(...) [Some] | provenance | |
| main.rs:228:10:228:11 | s1 [Some] | main.rs:228:10:228:20 | ... .unwrap(...) | provenance | |
| main.rs:237:14:237:39 | ...::A(...) [A] | main.rs:240:9:240:25 | ...::A(...) [A] | provenance | |
| main.rs:237:14:237:39 | ...::A(...) [A] | main.rs:244:9:244:25 | ...::A(...) [A] | provenance | |
| main.rs:237:29:237:38 | source(...) | main.rs:237:14:237:39 | ...::A(...) [A] | provenance | |
| main.rs:240:9:240:25 | ...::A(...) [A] | main.rs:240:24:240:24 | n | provenance | |
| main.rs:240:24:240:24 | n | main.rs:240:35:240:35 | n | provenance | |
| main.rs:244:9:244:25 | ...::A(...) [A] | main.rs:244:24:244:24 | n | provenance | |
| main.rs:244:24:244:24 | n | main.rs:244:55:244:55 | n | provenance | |
| main.rs:255:14:255:26 | A(...) [A] | main.rs:258:9:258:12 | A(...) [A] | provenance | |
| main.rs:255:14:255:26 | A(...) [A] | main.rs:262:9:262:12 | A(...) [A] | provenance | |
| main.rs:255:16:255:25 | source(...) | main.rs:255:14:255:26 | A(...) [A] | provenance | |
| main.rs:258:9:258:12 | A(...) [A] | main.rs:258:11:258:11 | n | provenance | |
| main.rs:258:11:258:11 | n | main.rs:258:22:258:22 | n | provenance | |
| main.rs:262:9:262:12 | A(...) [A] | main.rs:262:11:262:11 | n | provenance | |
| main.rs:262:11:262:11 | n | main.rs:262:29:262:29 | n | provenance | |
| main.rs:276:14:278:5 | ...::C {...} [C] | main.rs:281:9:281:38 | ...::C {...} [C] | provenance | |
| main.rs:276:14:278:5 | ...::C {...} [C] | main.rs:285:9:285:38 | ...::C {...} [C] | provenance | |
| main.rs:277:18:277:27 | source(...) | main.rs:276:14:278:5 | ...::C {...} [C] | provenance | |
| main.rs:281:9:281:38 | ...::C {...} [C] | main.rs:281:36:281:36 | n | provenance | |
| main.rs:281:36:281:36 | n | main.rs:281:48:281:48 | n | provenance | |
| main.rs:285:9:285:38 | ...::C {...} [C] | main.rs:285:36:285:36 | n | provenance | |
| main.rs:285:36:285:36 | n | main.rs:285:81:285:81 | n | provenance | |
| main.rs:296:14:298:5 | C {...} [C] | main.rs:301:9:301:24 | C {...} [C] | provenance | |
| main.rs:296:14:298:5 | C {...} [C] | main.rs:305:9:305:24 | C {...} [C] | provenance | |
| main.rs:297:18:297:27 | source(...) | main.rs:296:14:298:5 | C {...} [C] | provenance | |
| main.rs:301:9:301:24 | C {...} [C] | main.rs:301:22:301:22 | n | provenance | |
| main.rs:301:22:301:22 | n | main.rs:301:34:301:34 | n | provenance | |
| main.rs:305:9:305:24 | C {...} [C] | main.rs:305:22:305:22 | n | provenance | |
| main.rs:305:22:305:22 | n | main.rs:305:53:305:53 | n | provenance | |
nodes
| main.rs:15:10:15:18 | source(...) | semmle.label | source(...) |
| main.rs:19:13:19:21 | source(...) | semmle.label | source(...) |
@@ -49,49 +72,78 @@ nodes
| main.rs:47:10:47:10 | b | semmle.label | b |
| main.rs:53:9:53:17 | source(...) | semmle.label | source(...) |
| main.rs:54:10:54:10 | i | semmle.label | i |
| main.rs:117:14:117:29 | Some(...) [Some] | semmle.label | Some(...) [Some] |
| main.rs:117:19:117:28 | source(...) | semmle.label | source(...) |
| main.rs:120:9:120:15 | Some(...) [Some] | semmle.label | Some(...) [Some] |
| main.rs:120:14:120:14 | n | semmle.label | n |
| main.rs:120:25:120:25 | n | semmle.label | n |
| main.rs:135:14:135:39 | ...::A(...) [A] | semmle.label | ...::A(...) [A] |
| main.rs:135:29:135:38 | source(...) | semmle.label | source(...) |
| main.rs:138:9:138:25 | ...::A(...) [A] | semmle.label | ...::A(...) [A] |
| main.rs:138:24:138:24 | n | semmle.label | n |
| main.rs:138:35:138:35 | n | semmle.label | n |
| main.rs:142:10:142:26 | ...::A(...) [A] | semmle.label | ...::A(...) [A] |
| main.rs:142:25:142:25 | n | semmle.label | n |
| main.rs:142:57:142:57 | n | semmle.label | n |
| main.rs:153:14:153:26 | A(...) [A] | semmle.label | A(...) [A] |
| main.rs:153:16:153:25 | source(...) | semmle.label | source(...) |
| main.rs:156:9:156:12 | A(...) [A] | semmle.label | A(...) [A] |
| main.rs:156:11:156:11 | n | semmle.label | n |
| main.rs:156:22:156:22 | n | semmle.label | n |
| main.rs:160:10:160:13 | A(...) [A] | semmle.label | A(...) [A] |
| main.rs:160:12:160:12 | n | semmle.label | n |
| main.rs:160:31:160:31 | n | semmle.label | n |
| main.rs:174:14:176:5 | ...::C {...} [C] | semmle.label | ...::C {...} [C] |
| main.rs:175:18:175:27 | source(...) | semmle.label | source(...) |
| main.rs:179:9:179:38 | ...::C {...} [C] | semmle.label | ...::C {...} [C] |
| main.rs:179:36:179:36 | n | semmle.label | n |
| main.rs:179:48:179:48 | n | semmle.label | n |
| main.rs:183:10:183:39 | ...::C {...} [C] | semmle.label | ...::C {...} [C] |
| main.rs:183:37:183:37 | n | semmle.label | n |
| main.rs:183:83:183:83 | n | semmle.label | n |
| main.rs:194:14:196:5 | C {...} [C] | semmle.label | C {...} [C] |
| main.rs:195:18:195:27 | source(...) | semmle.label | source(...) |
| main.rs:199:9:199:24 | C {...} [C] | semmle.label | C {...} [C] |
| main.rs:199:22:199:22 | n | semmle.label | n |
| main.rs:199:34:199:34 | n | semmle.label | n |
| main.rs:203:10:203:25 | C {...} [C] | semmle.label | C {...} [C] |
| main.rs:203:23:203:23 | n | semmle.label | n |
| main.rs:203:55:203:55 | n | semmle.label | n |
| main.rs:94:13:94:26 | TupleExpr [tuple.0] | semmle.label | TupleExpr [tuple.0] |
| main.rs:94:14:94:22 | source(...) | semmle.label | source(...) |
| main.rs:95:10:95:10 | a [tuple.0] | semmle.label | a [tuple.0] |
| main.rs:95:10:95:12 | a.0 | semmle.label | a.0 |
| main.rs:108:17:108:31 | TupleExpr [tuple.1] | semmle.label | TupleExpr [tuple.1] |
| main.rs:108:21:108:30 | source(...) | semmle.label | source(...) |
| main.rs:110:10:110:10 | a [tuple.1] | semmle.label | a [tuple.1] |
| main.rs:110:10:110:12 | a.1 | semmle.label | a.1 |
| main.rs:111:5:111:5 | [post] a [tuple.0] | semmle.label | [post] a [tuple.0] |
| main.rs:111:11:111:20 | source(...) | semmle.label | source(...) |
| main.rs:112:5:112:5 | a [tuple.0] | semmle.label | a [tuple.0] |
| main.rs:113:10:113:10 | a [tuple.0] | semmle.label | a [tuple.0] |
| main.rs:113:10:113:12 | a.0 | semmle.label | a.0 |
| main.rs:118:13:118:27 | TupleExpr [tuple.1] | semmle.label | TupleExpr [tuple.1] |
| main.rs:118:17:118:26 | source(...) | semmle.label | source(...) |
| main.rs:119:13:119:18 | TupleExpr [tuple.0, tuple.1] | semmle.label | TupleExpr [tuple.0, tuple.1] |
| main.rs:119:14:119:14 | a [tuple.1] | semmle.label | a [tuple.1] |
| main.rs:121:10:121:10 | b [tuple.0, tuple.1] | semmle.label | b [tuple.0, tuple.1] |
| main.rs:121:10:121:12 | b.0 [tuple.1] | semmle.label | b.0 [tuple.1] |
| main.rs:121:10:121:14 | ... .1 | semmle.label | ... .1 |
| main.rs:153:13:156:5 | Point {...} [Point.x] | semmle.label | Point {...} [Point.x] |
| main.rs:154:12:154:21 | source(...) | semmle.label | source(...) |
| main.rs:157:9:157:28 | Point {...} [Point.x] | semmle.label | Point {...} [Point.x] |
| main.rs:157:20:157:20 | a | semmle.label | a |
| main.rs:158:10:158:10 | a | semmle.label | a |
| main.rs:214:14:214:29 | Some(...) [Some] | semmle.label | Some(...) [Some] |
| main.rs:214:19:214:28 | source(...) | semmle.label | source(...) |
| main.rs:217:9:217:15 | Some(...) [Some] | semmle.label | Some(...) [Some] |
| main.rs:217:14:217:14 | n | semmle.label | n |
| main.rs:217:25:217:25 | n | semmle.label | n |
| main.rs:227:14:227:29 | Some(...) [Some] | semmle.label | Some(...) [Some] |
| main.rs:227:19:227:28 | source(...) | semmle.label | source(...) |
| main.rs:228:10:228:11 | s1 [Some] | semmle.label | s1 [Some] |
| main.rs:228:10:228:20 | ... .unwrap(...) | semmle.label | ... .unwrap(...) |
| main.rs:237:14:237:39 | ...::A(...) [A] | semmle.label | ...::A(...) [A] |
| main.rs:237:29:237:38 | source(...) | semmle.label | source(...) |
| main.rs:240:9:240:25 | ...::A(...) [A] | semmle.label | ...::A(...) [A] |
| main.rs:240:24:240:24 | n | semmle.label | n |
| main.rs:240:35:240:35 | n | semmle.label | n |
| main.rs:244:9:244:25 | ...::A(...) [A] | semmle.label | ...::A(...) [A] |
| main.rs:244:24:244:24 | n | semmle.label | n |
| main.rs:244:55:244:55 | n | semmle.label | n |
| main.rs:255:14:255:26 | A(...) [A] | semmle.label | A(...) [A] |
| main.rs:255:16:255:25 | source(...) | semmle.label | source(...) |
| main.rs:258:9:258:12 | A(...) [A] | semmle.label | A(...) [A] |
| main.rs:258:11:258:11 | n | semmle.label | n |
| main.rs:258:22:258:22 | n | semmle.label | n |
| main.rs:262:9:262:12 | A(...) [A] | semmle.label | A(...) [A] |
| main.rs:262:11:262:11 | n | semmle.label | n |
| main.rs:262:29:262:29 | n | semmle.label | n |
| main.rs:276:14:278:5 | ...::C {...} [C] | semmle.label | ...::C {...} [C] |
| main.rs:277:18:277:27 | source(...) | semmle.label | source(...) |
| main.rs:281:9:281:38 | ...::C {...} [C] | semmle.label | ...::C {...} [C] |
| main.rs:281:36:281:36 | n | semmle.label | n |
| main.rs:281:48:281:48 | n | semmle.label | n |
| main.rs:285:9:285:38 | ...::C {...} [C] | semmle.label | ...::C {...} [C] |
| main.rs:285:36:285:36 | n | semmle.label | n |
| main.rs:285:81:285:81 | n | semmle.label | n |
| main.rs:296:14:298:5 | C {...} [C] | semmle.label | C {...} [C] |
| main.rs:297:18:297:27 | source(...) | semmle.label | source(...) |
| main.rs:301:9:301:24 | C {...} [C] | semmle.label | C {...} [C] |
| main.rs:301:22:301:22 | n | semmle.label | n |
| main.rs:301:34:301:34 | n | semmle.label | n |
| main.rs:305:9:305:24 | C {...} [C] | semmle.label | C {...} [C] |
| main.rs:305:22:305:22 | n | semmle.label | n |
| main.rs:305:53:305:53 | n | semmle.label | n |
subpaths
testFailures
| main.rs:156:22:156:22 | n | Fixed missing result: hasValueFlow=16 |
| main.rs:160:31:160:31 | n | Fixed missing result: hasValueFlow=16 |
| main.rs:199:34:199:34 | n | Fixed missing result: hasValueFlow=18 |
| main.rs:203:55:203:55 | n | Fixed missing result: hasValueFlow=18 |
| main.rs:258:22:258:22 | n | Fixed missing result: hasValueFlow=16 |
| main.rs:262:29:262:29 | n | Fixed missing result: hasValueFlow=16 |
| main.rs:301:34:301:34 | n | Fixed missing result: hasValueFlow=18 |
| main.rs:305:53:305:53 | n | Fixed missing result: hasValueFlow=18 |
#select
| main.rs:15:10:15:18 | source(...) | main.rs:15:10:15:18 | source(...) | main.rs:15:10:15:18 | source(...) | $@ | main.rs:15:10:15:18 | source(...) | source(...) |
| main.rs:20:10:20:10 | s | main.rs:19:13:19:21 | source(...) | main.rs:20:10:20:10 | s | $@ | main.rs:19:13:19:21 | source(...) | source(...) |
@@ -99,12 +151,18 @@ testFailures
| main.rs:36:10:36:10 | b | main.rs:31:13:31:21 | source(...) | main.rs:36:10:36:10 | b | $@ | main.rs:31:13:31:21 | source(...) | source(...) |
| main.rs:47:10:47:10 | b | main.rs:45:15:45:23 | source(...) | main.rs:47:10:47:10 | b | $@ | main.rs:45:15:45:23 | source(...) | source(...) |
| main.rs:54:10:54:10 | i | main.rs:53:9:53:17 | source(...) | main.rs:54:10:54:10 | i | $@ | main.rs:53:9:53:17 | source(...) | source(...) |
| main.rs:120:25:120:25 | n | main.rs:117:19:117:28 | source(...) | main.rs:120:25:120:25 | n | $@ | main.rs:117:19:117:28 | source(...) | source(...) |
| main.rs:138:35:138:35 | n | main.rs:135:29:135:38 | source(...) | main.rs:138:35:138:35 | n | $@ | main.rs:135:29:135:38 | source(...) | source(...) |
| main.rs:142:57:142:57 | n | main.rs:135:29:135:38 | source(...) | main.rs:142:57:142:57 | n | $@ | main.rs:135:29:135:38 | source(...) | source(...) |
| main.rs:156:22:156:22 | n | main.rs:153:16:153:25 | source(...) | main.rs:156:22:156:22 | n | $@ | main.rs:153:16:153:25 | source(...) | source(...) |
| main.rs:160:31:160:31 | n | main.rs:153:16:153:25 | source(...) | main.rs:160:31:160:31 | n | $@ | main.rs:153:16:153:25 | source(...) | source(...) |
| main.rs:179:48:179:48 | n | main.rs:175:18:175:27 | source(...) | main.rs:179:48:179:48 | n | $@ | main.rs:175:18:175:27 | source(...) | source(...) |
| main.rs:183:83:183:83 | n | main.rs:175:18:175:27 | source(...) | main.rs:183:83:183:83 | n | $@ | main.rs:175:18:175:27 | source(...) | source(...) |
| main.rs:199:34:199:34 | n | main.rs:195:18:195:27 | source(...) | main.rs:199:34:199:34 | n | $@ | main.rs:195:18:195:27 | source(...) | source(...) |
| main.rs:203:55:203:55 | n | main.rs:195:18:195:27 | source(...) | main.rs:203:55:203:55 | n | $@ | main.rs:195:18:195:27 | source(...) | source(...) |
| main.rs:95:10:95:12 | a.0 | main.rs:94:14:94:22 | source(...) | main.rs:95:10:95:12 | a.0 | $@ | main.rs:94:14:94:22 | source(...) | source(...) |
| main.rs:110:10:110:12 | a.1 | main.rs:108:21:108:30 | source(...) | main.rs:110:10:110:12 | a.1 | $@ | main.rs:108:21:108:30 | source(...) | source(...) |
| main.rs:113:10:113:12 | a.0 | main.rs:111:11:111:20 | source(...) | main.rs:113:10:113:12 | a.0 | $@ | main.rs:111:11:111:20 | source(...) | source(...) |
| main.rs:121:10:121:14 | ... .1 | main.rs:118:17:118:26 | source(...) | main.rs:121:10:121:14 | ... .1 | $@ | main.rs:118:17:118:26 | source(...) | source(...) |
| main.rs:158:10:158:10 | a | main.rs:154:12:154:21 | source(...) | main.rs:158:10:158:10 | a | $@ | main.rs:154:12:154:21 | source(...) | source(...) |
| main.rs:217:25:217:25 | n | main.rs:214:19:214:28 | source(...) | main.rs:217:25:217:25 | n | $@ | main.rs:214:19:214:28 | source(...) | source(...) |
| main.rs:228:10:228:20 | ... .unwrap(...) | main.rs:227:19:227:28 | source(...) | main.rs:228:10:228:20 | ... .unwrap(...) | $@ | main.rs:227:19:227:28 | source(...) | source(...) |
| main.rs:240:35:240:35 | n | main.rs:237:29:237:38 | source(...) | main.rs:240:35:240:35 | n | $@ | main.rs:237:29:237:38 | source(...) | source(...) |
| main.rs:244:55:244:55 | n | main.rs:237:29:237:38 | source(...) | main.rs:244:55:244:55 | n | $@ | main.rs:237:29:237:38 | source(...) | source(...) |
| main.rs:258:22:258:22 | n | main.rs:255:16:255:25 | source(...) | main.rs:258:22:258:22 | n | $@ | main.rs:255:16:255:25 | source(...) | source(...) |
| main.rs:262:29:262:29 | n | main.rs:255:16:255:25 | source(...) | main.rs:262:29:262:29 | n | $@ | main.rs:255:16:255:25 | source(...) | source(...) |
| main.rs:281:48:281:48 | n | main.rs:277:18:277:27 | source(...) | main.rs:281:48:281:48 | n | $@ | main.rs:277:18:277:27 | source(...) | source(...) |
| main.rs:285:81:285:81 | n | main.rs:277:18:277:27 | source(...) | main.rs:285:81:285:81 | n | $@ | main.rs:277:18:277:27 | source(...) | source(...) |
| main.rs:301:34:301:34 | n | main.rs:297:18:297:27 | source(...) | main.rs:301:34:301:34 | n | $@ | main.rs:297:18:297:27 | source(...) | source(...) |
| main.rs:305:53:305:53 | n | main.rs:297:18:297:27 | source(...) | main.rs:305:53:305:53 | n | $@ | main.rs:297:18:297:27 | source(...) | source(...) |

View File

@@ -54,52 +54,149 @@ fn assignment() {
sink(i); // $ hasValueFlow=6
}
fn block_expression1() -> i64 {
let a = { 0 };
a
}
fn block_expression2(b: bool) -> i64 {
let a = 'block: {
if b {
break 'block 1;
};
2
};
a
}
fn block_expression3(b: bool) -> i64 {
let a = 'block: {
if b {
break 'block 1;
}
break 'block 2;
};
a
}
// -----------------------------------------------------------------------------
// Data flow through data structures by writing and reading
// Data flow through `Box`
fn box_deref() {
let i = Box::new(source(7));
sink(*i); // $ MISSING: hasValueFlow=7
}
// -----------------------------------------------------------------------------
// Data flow through tuples
fn tuple() {
let a = (source(8), 2);
sink(a.0); // $ MISSING: hasValueFlow=8
sink(a.0); // $ hasValueFlow=8
sink(a.1);
}
fn tuple_match() {
let a = (2, source(38), 2);
let (a0, a1, a2) = a;
sink(a0);
sink(a1); // $ MISSING: hasValueFlow=38
sink(a2);
}
fn tuple_mutation() {
let mut a = (2, source(38));
sink(a.0);
sink(a.1); // $ hasValueFlow=38
a.0 = source(70);
a.1 = 2;
sink(a.0); // $ hasValueFlow=70
sink(a.1);
}
fn tuple_nested() {
let a = (3, source(59));
let b = (a, 3);
sink(b.0.0);
sink(b.0.1); // $ hasValueFlow=59
sink(b.1);
}
// -----------------------------------------------------------------------------
// Data flow through structs
struct Point {
x: i64,
y: i64,
z: i64,
}
fn struct_field() {
let p = Point {
x: source(9),
y: 2,
z: source(10),
};
sink(p.x); // $ MISSING: hasValueFlow=9
sink(p.y);
sink(p.z); // $ MISSING: hasValueFlow=10
}
// -----------------------------------------------------------------------------
// Data flow through data structures by pattern matching
fn struct_mutation() {
let mut p = Point {
x: source(9),
y: 2,
};
sink(p.y);
p.y = source(54);
sink(p.y); // $ MISSING: hasValueFlow=54
}
fn struct_pattern_match() {
let p = Point {
x: source(11),
y: 2,
z: source(12),
};
let Point { x: a, y: b, z: c } = p;
sink(a); // $ MISSING: hasValueFlow=11
let Point { x: a, y: b } = p;
sink(a); // $ hasValueFlow=11
sink(b);
sink(c); // $ MISSING: hasValueFlow=12
}
struct Point3D {
plane: Point,
z: i64
}
fn struct_nested_field() {
let p = Point3D {
plane: Point {
x: 2,
y: source(77),
},
z: 4
};
sink(p.plane.x);
sink(p.plane.y); // $ MISSING: hasValueFlow=77
sink(p.z);
}
fn struct_nested_match() {
let p = Point3D {
plane: Point {
x: 2,
y: source(93),
},
z: 4
};
match p {
Point3D { plane: Point { x, y }, z, } => {
sink(x);
sink(y); // MISSING: hasValueFlow=93
sink(z);
}
}
}
// -----------------------------------------------------------------------------
// Data flow through enums
fn option_pattern_match_qualified() {
let s1 = Option::Some(source(13));
let s2 = Option::Some(2);
@@ -126,6 +223,11 @@ fn option_pattern_match_unqualified() {
}
}
fn option_unwrap() {
let s1 = Some(source(19));
sink(s1.unwrap()); // $ hasValueFlow=19
}
enum MyTupleEnum {
A(i64),
B(i64),
@@ -139,7 +241,7 @@ fn custom_tuple_enum_pattern_match_qualified() {
MyTupleEnum::B(n) => sink(n),
}
match s1 {
(MyTupleEnum::A(n) | MyTupleEnum::B(n)) => sink(n), // $ hasValueFlow=15
MyTupleEnum::A(n) | MyTupleEnum::B(n) => sink(n), // $ hasValueFlow=15
}
match s2 {
MyTupleEnum::A(n) => sink(n),
@@ -157,7 +259,7 @@ fn custom_tuple_enum_pattern_match_unqualified() {
B(n) => sink(n),
}
match s1 {
(A(n) | B(n)) => sink(n), // $ MISSING: hasValueFlow=16
A(n) | B(n) => sink(n), // $ MISSING: hasValueFlow=16
}
match s2 {
A(n) => sink(n),
@@ -180,7 +282,7 @@ fn custom_record_enum_pattern_match_qualified() {
MyRecordEnum::D { field_d: n } => sink(n),
}
match s1 {
(MyRecordEnum::C { field_c: n } | MyRecordEnum::D { field_d: n }) => sink(n), // $ hasValueFlow=17
MyRecordEnum::C { field_c: n } | MyRecordEnum::D { field_d: n } => sink(n), // $ hasValueFlow=17
}
match s2 {
MyRecordEnum::C { field_c: n } => sink(n),
@@ -200,7 +302,7 @@ fn custom_record_enum_pattern_match_unqualified() {
D { field_d: n } => sink(n),
}
match s1 {
(C { field_c: n } | D { field_d: n }) => sink(n), // $ MISSING: hasValueFlow=18
C { field_c: n } | D { field_d: n } => sink(n), // $ MISSING: hasValueFlow=18
}
match s2 {
C { field_c: n } => sink(n),
@@ -208,31 +310,6 @@ fn custom_record_enum_pattern_match_unqualified() {
}
}
fn block_expression1() -> i64 {
let a = { 0 };
a
}
fn block_expression2(b: bool) -> i64 {
let a = 'block: {
if b {
break 'block 1;
};
2
};
a
}
fn block_expression3(b: bool) -> i64 {
let a = 'block: {
if b {
break 'block 1;
}
break 'block 2;
};
a
}
fn main() {
direct();
variable_usage();
@@ -242,10 +319,17 @@ fn main() {
assignment();
box_deref();
tuple();
tuple_match();
tuple_mutation();
tuple_nested();
struct_field();
struct_mutation();
struct_pattern_match();
struct_nested_field();
struct_nested_match();
option_pattern_match_qualified();
option_pattern_match_unqualified();
option_unwrap();
custom_tuple_enum_pattern_match_qualified();
custom_tuple_enum_pattern_match_unqualified();
custom_record_enum_pattern_match_qualified();

View File

@@ -0,0 +1,89 @@
fn source(i: i64) -> i64 {
1000 + i
}
fn sink(s: i64) {
println!("{}", s);
}
// has a flow model
fn identity(i: i64) -> i64 {
0
}
fn test_identify() {
let s = source(1);
sink(identity(s)); // $ hasValueFlow=1
}
enum MyPosEnum {
A(i64),
B(i64),
}
// has a flow model
fn get_var_pos(e: MyPosEnum) -> i64 {
0
}
fn test_get_var_pos() {
let s = source(2);
let e1 = MyPosEnum::A(s);
sink(get_var_pos(e1)); // $ hasValueFlow=2
let e2 = MyPosEnum::B(s);
sink(get_var_pos(e2));
}
// has a flow model
fn set_var_pos(i: i64) -> MyPosEnum {
MyPosEnum::A(0)
}
fn test_set_var_pos() {
let s = source(3);
let e1 = set_var_pos(s);
match e1 {
MyPosEnum::A(i) => sink(i),
MyPosEnum::B(i) => sink(i), // $ hasValueFlow=3
}
}
enum MyFieldEnum {
C { field_c: i64 },
D { field_d: i64 },
}
// has a flow model
fn get_var_field(e: MyFieldEnum) -> i64 {
0
}
fn test_get_var_field() {
let s = source(4);
let e1 = MyFieldEnum::C { field_c: s };
sink(get_var_field(e1)); // $ hasValueFlow=4
let e2 = MyFieldEnum::D { field_d: s };
sink(get_var_field(e2));
}
// has a flow model
fn set_var_field(i: i64) -> MyFieldEnum {
MyFieldEnum::C { field_c: 0 }
}
fn test_set_var_field() {
let s = source(5);
let e1 = set_var_field(s);
match e1 {
MyFieldEnum::C { field_c: i } => sink(i),
MyFieldEnum::D { field_d: i } => sink(i), // $ hasValueFlow=5
}
}
fn main() {
test_identify();
test_get_var_pos();
test_set_var_pos();
test_get_var_field();
test_set_var_field();
}

View File

@@ -0,0 +1,57 @@
models
edges
| main.rs:15:13:15:21 | source(...) | main.rs:16:19:16:19 | s | provenance | |
| main.rs:16:19:16:19 | s | main.rs:16:10:16:20 | identity(...) | provenance | |
| main.rs:30:13:30:21 | source(...) | main.rs:31:27:31:27 | s | provenance | |
| main.rs:31:14:31:28 | ...::A(...) [A] | main.rs:32:22:32:23 | e1 [A] | provenance | |
| main.rs:31:27:31:27 | s | main.rs:31:14:31:28 | ...::A(...) [A] | provenance | |
| main.rs:32:22:32:23 | e1 [A] | main.rs:32:10:32:24 | get_var_pos(...) | provenance | |
| main.rs:43:13:43:21 | source(...) | main.rs:44:26:44:26 | s | provenance | |
| main.rs:44:14:44:27 | set_var_pos(...) [B] | main.rs:47:9:47:23 | TupleStructPat [B] | provenance | |
| main.rs:44:26:44:26 | s | main.rs:44:14:44:27 | set_var_pos(...) [B] | provenance | |
| main.rs:47:9:47:23 | TupleStructPat [B] | main.rs:47:22:47:22 | i | provenance | |
| main.rs:47:22:47:22 | i | main.rs:47:33:47:33 | i | provenance | |
| main.rs:62:13:62:21 | source(...) | main.rs:63:40:63:40 | s | provenance | |
| main.rs:63:14:63:42 | ...::C {...} [C] | main.rs:64:24:64:25 | e1 [C] | provenance | |
| main.rs:63:40:63:40 | s | main.rs:63:14:63:42 | ...::C {...} [C] | provenance | |
| main.rs:64:24:64:25 | e1 [C] | main.rs:64:10:64:26 | get_var_field(...) | provenance | |
| main.rs:75:13:75:21 | source(...) | main.rs:76:28:76:28 | s | provenance | |
| main.rs:76:14:76:29 | set_var_field(...) [D] | main.rs:79:9:79:37 | ...::D {...} [D] | provenance | |
| main.rs:76:28:76:28 | s | main.rs:76:14:76:29 | set_var_field(...) [D] | provenance | |
| main.rs:79:9:79:37 | ...::D {...} [D] | main.rs:79:35:79:35 | i | provenance | |
| main.rs:79:35:79:35 | i | main.rs:79:47:79:47 | i | provenance | |
nodes
| main.rs:15:13:15:21 | source(...) | semmle.label | source(...) |
| main.rs:16:10:16:20 | identity(...) | semmle.label | identity(...) |
| main.rs:16:19:16:19 | s | semmle.label | s |
| main.rs:30:13:30:21 | source(...) | semmle.label | source(...) |
| main.rs:31:14:31:28 | ...::A(...) [A] | semmle.label | ...::A(...) [A] |
| main.rs:31:27:31:27 | s | semmle.label | s |
| main.rs:32:10:32:24 | get_var_pos(...) | semmle.label | get_var_pos(...) |
| main.rs:32:22:32:23 | e1 [A] | semmle.label | e1 [A] |
| main.rs:43:13:43:21 | source(...) | semmle.label | source(...) |
| main.rs:44:14:44:27 | set_var_pos(...) [B] | semmle.label | set_var_pos(...) [B] |
| main.rs:44:26:44:26 | s | semmle.label | s |
| main.rs:47:9:47:23 | TupleStructPat [B] | semmle.label | TupleStructPat [B] |
| main.rs:47:22:47:22 | i | semmle.label | i |
| main.rs:47:33:47:33 | i | semmle.label | i |
| main.rs:62:13:62:21 | source(...) | semmle.label | source(...) |
| main.rs:63:14:63:42 | ...::C {...} [C] | semmle.label | ...::C {...} [C] |
| main.rs:63:40:63:40 | s | semmle.label | s |
| main.rs:64:10:64:26 | get_var_field(...) | semmle.label | get_var_field(...) |
| main.rs:64:24:64:25 | e1 [C] | semmle.label | e1 [C] |
| main.rs:75:13:75:21 | source(...) | semmle.label | source(...) |
| main.rs:76:14:76:29 | set_var_field(...) [D] | semmle.label | set_var_field(...) [D] |
| main.rs:76:28:76:28 | s | semmle.label | s |
| main.rs:79:9:79:37 | ...::D {...} [D] | semmle.label | ...::D {...} [D] |
| main.rs:79:35:79:35 | i | semmle.label | i |
| main.rs:79:47:79:47 | i | semmle.label | i |
subpaths
testFailures
invalidSpecComponent
#select
| main.rs:16:10:16:20 | identity(...) | main.rs:15:13:15:21 | source(...) | main.rs:16:10:16:20 | identity(...) | $@ | main.rs:15:13:15:21 | source(...) | source(...) |
| main.rs:32:10:32:24 | get_var_pos(...) | main.rs:30:13:30:21 | source(...) | main.rs:32:10:32:24 | get_var_pos(...) | $@ | main.rs:30:13:30:21 | source(...) | source(...) |
| main.rs:47:33:47:33 | i | main.rs:43:13:43:21 | source(...) | main.rs:47:33:47:33 | i | $@ | main.rs:43:13:43:21 | source(...) | source(...) |
| main.rs:64:10:64:26 | get_var_field(...) | main.rs:62:13:62:21 | source(...) | main.rs:64:10:64:26 | get_var_field(...) | $@ | main.rs:62:13:62:21 | source(...) | source(...) |
| main.rs:79:47:79:47 | i | main.rs:75:13:75:21 | source(...) | main.rs:79:47:79:47 | i | $@ | main.rs:75:13:75:21 | source(...) | source(...) |

View File

@@ -0,0 +1,78 @@
/**
* @kind path-problem
*/
import rust
import utils.InlineFlowTest
import codeql.rust.dataflow.DataFlow
import codeql.rust.dataflow.FlowSummary
import codeql.rust.dataflow.TaintTracking
import codeql.rust.dataflow.internal.FlowSummaryImpl
import PathGraph
query predicate invalidSpecComponent(SummarizedCallable sc, string s, string c) {
(sc.propagatesFlow(s, _, _) or sc.propagatesFlow(_, s, _)) and
Private::External::invalidSpecComponent(s, c)
}
private class SummarizedCallableIdentity extends SummarizedCallable::Range {
SummarizedCallableIdentity() { this = "repo::test::_::crate::identity" }
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
input = "Argument[0]" and
output = "ReturnValue" and
preservesValue = true
}
}
private class SummarizedCallableGetVarPos extends SummarizedCallable::Range {
SummarizedCallableGetVarPos() { this = "repo::test::_::crate::get_var_pos" }
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
input = "Argument[0].Variant[crate::MyPosEnum::A(0)]" and
output = "ReturnValue" and
preservesValue = true
}
}
private class SummarizedCallableSetVarPos extends SummarizedCallable::Range {
SummarizedCallableSetVarPos() { this = "repo::test::_::crate::set_var_pos" }
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
input = "Argument[0]" and
output = "ReturnValue.Variant[crate::MyPosEnum::B(0)]" and
preservesValue = true
}
}
private class SummarizedCallableGetVarField extends SummarizedCallable::Range {
SummarizedCallableGetVarField() { this = "repo::test::_::crate::get_var_field" }
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
input = "Argument[0].Variant[crate::MyFieldEnum::C::field_c]" and
output = "ReturnValue" and
preservesValue = true
}
}
private class SummarizedCallableSetVarField extends SummarizedCallable::Range {
SummarizedCallableSetVarField() { this = "repo::test::_::crate::set_var_field" }
override predicate propagatesFlow(string input, string output, boolean preservesValue) {
input = "Argument[0]" and
output = "ReturnValue.Variant[crate::MyFieldEnum::D::field_d]" and
preservesValue = true
}
}
module CustomConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { DefaultFlowConfig::isSource(source) }
predicate isSink(DataFlow::Node sink) { DefaultFlowConfig::isSink(sink) }
}
import ValueFlowTest<CustomConfig>
from PathNode source, PathNode sink
where flowPath(source, sink)
select sink, source, sink, "$@", source, source.toString()

View File

@@ -2,3 +2,4 @@
| Multiple parents | 0 |
| Multiple primary QL classes | 0 |
| Multiple toStrings | 0 |
| No location | 0 |

View File

@@ -343,7 +343,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
bindingset[n, cc]
pragma[inline_late]
private predicate isUnreachableInCall1(NodeEx n, LocalCallContextSpecificCall cc) {
cc.unreachable(n.asNode())
cc.unreachable(n)
}
/**
@@ -423,7 +423,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
pragma[nomagic]
private predicate readSetEx(NodeEx node1, ContentSet c, NodeEx node2) {
readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode())) and
readEx(node1, c, node2) and
stepFilter(node1, node2)
or
exists(Node n |
@@ -450,20 +450,19 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
bindingset[c]
private predicate expectsContentEx(NodeEx n, Content c) {
exists(ContentSet cs |
expectsContentCached(n.asNode(), cs) and
expectsContentSet(n, cs) and
pragma[only_bind_out](c) = pragma[only_bind_into](cs).getAReadContent()
)
}
pragma[nomagic]
private predicate notExpectsContent(NodeEx n) { not expectsContentCached(n.asNode(), _) }
private predicate notExpectsContent(NodeEx n) { not expectsContentSet(n, _) }
pragma[nomagic]
private predicate storeExUnrestricted(
private predicate storeUnrestricted(
NodeEx node1, Content c, NodeEx node2, DataFlowType contentType, DataFlowType containerType
) {
store(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode()),
contentType, containerType) and
storeEx(node1, c, node2, contentType, containerType) and
stepFilter(node1, node2)
}
@@ -471,23 +470,13 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
private predicate hasReadStep(Content c) { read(_, c, _) }
pragma[nomagic]
private predicate storeEx(
private predicate store(
NodeEx node1, Content c, NodeEx node2, DataFlowType contentType, DataFlowType containerType
) {
storeExUnrestricted(node1, c, node2, contentType, containerType) and
storeUnrestricted(node1, c, node2, contentType, containerType) and
hasReadStep(c)
}
pragma[nomagic]
private predicate viableReturnPosOutEx(DataFlowCall call, ReturnPosition pos, NodeEx out) {
viableReturnPosOut(call, pos, out.asNode())
}
pragma[nomagic]
private predicate viableParamArgEx(DataFlowCall call, ParamNodeEx p, ArgNodeEx arg) {
viableParamArg(call, p.asNode(), arg.asNode())
}
/**
* Holds if field flow should be used for the given configuration.
*/
@@ -520,7 +509,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
exists(ParameterPosition pos | p.isParameterOf(_, pos) |
not kind.(ParamUpdateReturnKind).getPosition() = pos
or
allowParameterReturnInSelfCached(p.asNode())
allowParameterReturnInSelfEx(p)
)
}
@@ -558,7 +547,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
exists(NodeEx mid |
useFieldFlow() and
fwdFlow(mid, cc) and
storeEx(mid, _, node, _, _)
store(mid, _, node, _, _)
)
or
// read
@@ -653,7 +642,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
not fullBarrier(node) and
useFieldFlow() and
fwdFlow(mid, _) and
storeEx(mid, c, node, _, _)
store(mid, c, node, _, _)
)
}
@@ -796,7 +785,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
exists(NodeEx mid |
revFlow(mid, toReturn) and
fwdFlowConsCand(c) and
storeEx(node, c, mid, _, _)
store(node, c, mid, _, _)
)
}
@@ -893,7 +882,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
) {
revFlowIsReadAndStored(c) and
revFlow(node2) and
storeEx(node1, c, node2, contentType, containerType) and
store(node1, c, node2, contentType, containerType) and
exists(ap1)
}
@@ -1152,7 +1141,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
flowOutOfCallNodeCand1(call, ret, _, out) and
c = ret.getEnclosingCallable()
|
scope = getSecondLevelScopeCached(ret.asNode())
scope = getSecondLevelScopeEx(ret)
or
ret = TParamReturnNode(_, scope)
)
@@ -1496,7 +1485,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
PrevStage::revFlow(node, state, apa) and
filter(node, state, t0, ap, t) and
(
if castingNodeEx(node)
if node instanceof CastingNodeEx
then
ap instanceof ApNil or
compatibleContainer(getHeadContent(ap), node.getDataFlowType()) or
@@ -2627,10 +2616,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
FlowCheckNode() {
revFlow(this, _, _) and
(
castNode(this.asNode()) or
clearsContentCached(this.asNode(), _) or
expectsContentCached(this.asNode(), _) or
neverSkipInPathGraph(this.asNode()) or
flowCheckNode(this) or
Config::neverSkip(this.asNode())
)
}
@@ -2665,7 +2651,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
or
node instanceof ParamNodeEx
or
node.asNode() instanceof OutNodeExt
node instanceof OutNodeEx
or
storeStepCand(_, _, _, node, _, _)
or
@@ -2899,15 +2885,9 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
predicate isHidden() {
not Config::includeHiddenNodes() and
(
hiddenNode(this.getNodeEx().asNode()) and
not this.isSource() and
not this instanceof PathNodeSink
or
this.getNodeEx() instanceof TNodeImplicitRead
or
hiddenNode(this.getNodeEx().asParamReturnNode())
)
hiddenNode(this.getNodeEx()) and
not this.isSource() and
not this instanceof PathNodeSink
}
/** Gets a textual representation of this element. */
@@ -3770,11 +3750,6 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
private module Stage2 = MkStage<Stage1>::Stage<Stage2Param>;
pragma[nomagic]
private predicate castingNodeEx(NodeEx node) {
node.asNode() instanceof CastingNode or exists(node.asParamReturnNode())
}
private module Stage3Param implements MkStage<Stage2>::StageParam {
private module PrevStage = Stage2;
@@ -3888,7 +3863,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
bindingset[node, t0]
private predicate strengthenType(NodeEx node, DataFlowType t0, DataFlowType t) {
if castingNodeEx(node)
if node instanceof CastingNodeEx
then
exists(DataFlowType nt | nt = node.getDataFlowType() |
if typeStrongerThanFilter(nt, t0)
@@ -3945,7 +3920,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
pragma[nomagic]
private predicate clearSet(NodeEx node, ContentSet c) {
PrevStage::revFlow(node) and
clearsContentCached(node.asNode(), c)
clearsContentSet(node, c)
}
pragma[nomagic]
@@ -5024,7 +4999,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
bindingset[c]
private predicate clearsContentEx(NodeEx n, Content c) {
exists(ContentSet cs |
clearsContentCached(n.asNode(), cs) and
clearsContentSet(n, cs) and
pragma[only_bind_out](c) = pragma[only_bind_into](cs).getAReadContent()
)
}
@@ -5377,7 +5352,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
midNode = mid.getNodeEx() and
t1 = mid.getType() and
ap1 = mid.getAp() and
storeExUnrestricted(midNode, c, node, contentType, t2) and
storeUnrestricted(midNode, c, node, contentType, t2) and
ap2.getHead() = c and
ap2.len() = unbindInt(ap1.len() + 1) and
compatibleTypesFilter(t1, contentType)
@@ -5442,9 +5417,8 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
PartialAccessPath ap
) {
exists(ReturnKindExt kind, DataFlowCall call |
partialPathOutOfCallable1(mid, call, kind, state, cc, t, ap)
|
out.asNode() = kind.getAnOutNode(call)
partialPathOutOfCallable1(mid, call, kind, state, cc, t, ap) and
out = kind.getAnOutNodeEx(call)
)
}
@@ -5529,7 +5503,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
) {
exists(DataFlowCall call, ReturnKindExt kind |
partialPathThroughCallable0(call, mid, kind, state, cc, t, ap) and
out.asNode() = kind.getAnOutNode(call)
out = kind.getAnOutNodeEx(call)
)
}
@@ -5549,7 +5523,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
not outBarrier(node, state) and
// if a node is not the target of a store, we can check `clearsContent` immediately
(
storeExUnrestricted(_, _, node, _, _)
storeUnrestricted(_, _, node, _, _)
or
not clearsContentEx(node, ap.getHead())
)
@@ -5690,7 +5664,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
exists(NodeEx midNode |
midNode = mid.getNodeEx() and
ap = mid.getAp() and
storeExUnrestricted(node, c, midNode, _, _) and
storeUnrestricted(node, c, midNode, _, _) and
ap.getHead() = c
)
}
@@ -5745,7 +5719,7 @@ module MakeImpl<LocationSig Location, InputSig<Location> Lang> {
) {
exists(DataFlowCall call, ArgumentPosition pos |
revPartialPathThroughCallable0(call, mid, pos, state, ap) and
node.asNode().(ArgNode).argumentOf(call, pos)
node.argumentOf(call, pos)
)
}

View File

@@ -286,7 +286,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
) {
revLambdaFlow0(lambdaCall, kind, node, t, toReturn, toJump, lastCall) and
not expectsContent(node, _) and
if castNode(node) or node instanceof ArgNode or node instanceof ReturnNode
if node instanceof CastNode or node instanceof ArgNode or node instanceof ReturnNode
then compatibleTypesFilter(t, getNodeDataFlowType(node))
else any()
}
@@ -372,7 +372,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
) {
revLambdaFlow(lambdaCall, kind, out, t, _, toJump, lastCall) and
exists(ReturnKindExt rk |
out = rk.getAnOutNode(call) and
out = getAnOutNodeExt(call, rk) and
lambdaCall(call, _, _)
)
}
@@ -901,20 +901,36 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
Location getLocation() { result = this.projectToNode().getLocation() }
}
final class ArgNodeEx extends NodeEx {
ArgNodeEx() { this.asNode() instanceof ArgNode }
/**
* A `Node` at which a cast can occur such that the type should be checked.
*/
final class CastingNodeEx extends NodeEx {
CastingNodeEx() { castingNodeEx(this) }
}
DataFlowCall getCall() { this.asNode().(ArgNode).argumentOf(result, _) }
final class ArgNodeEx extends NodeEx {
private DataFlowCall call_;
private ArgumentPosition pos_;
ArgNodeEx() { this.asNode().(ArgNode).argumentOf(call_, pos_) }
predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
call = call_ and
pos = pos_
}
DataFlowCall getCall() { result = call_ }
}
final class ParamNodeEx extends NodeEx {
ParamNodeEx() { this.asNode() instanceof ParamNode }
private DataFlowCallable c_;
private ParameterPosition pos_;
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
this.asNode().(ParamNode).isParameterOf(c, pos)
}
ParamNodeEx() { this.asNode().(ParamNode).isParameterOf(c_, pos_) }
ParameterPosition getPosition() { this.isParameterOf(_, result) }
predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) { c = c_ and pos = pos_ }
ParameterPosition getPosition() { result = pos_ }
}
/**
@@ -931,6 +947,18 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
ReturnKindExt getKind() { result = pos.getKind() }
}
final class OutNodeEx extends NodeEx {
OutNodeEx() { this.asNode() instanceof OutNodeExt }
}
pragma[nomagic]
private SndLevelScopeOption getSecondLevelScope0(Node n) {
result = SndLevelScopeOption::some(getSecondLevelScope(n))
or
result instanceof SndLevelScopeOption::None and
not exists(getSecondLevelScope(n))
}
cached
private module Cached {
/**
@@ -942,11 +970,8 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
predicate forceCachingInSameStage() { any() }
cached
SndLevelScopeOption getSecondLevelScopeCached(Node n) {
result = SndLevelScopeOption::some(getSecondLevelScope(n))
or
result instanceof SndLevelScopeOption::None and
not exists(getSecondLevelScope(n))
SndLevelScopeOption getSecondLevelScopeEx(NodeEx n) {
result = getSecondLevelScope0(n.asNode())
}
cached
@@ -978,11 +1003,14 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
predicate jumpStepCached(Node node1, Node node2) { jumpStep(node1, node2) }
cached
predicate clearsContentCached(Node n, ContentSet c) { clearsContent(n, c) }
predicate clearsContentSet(NodeEx n, ContentSet c) { clearsContent(n.asNode(), c) }
cached
predicate expectsContentCached(Node n, ContentSet c) { expectsContent(n, c) }
cached
predicate expectsContentSet(NodeEx n, ContentSet c) { expectsContent(n.asNode(), c) }
cached
predicate isUnreachableInCallCached(NodeRegion nr, DataFlowCall call) {
isUnreachableInCall(nr, call)
@@ -996,16 +1024,15 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
}
cached
predicate hiddenNode(Node n) { nodeIsHidden(n) }
predicate hiddenNode(NodeEx n) {
nodeIsHidden([n.asNode(), n.asParamReturnNode()])
or
n instanceof TNodeImplicitRead
}
cached
OutNodeExt getAnOutNodeExt(DataFlowCall call, ReturnKindExt k) {
result = getAnOutNode(call, k.(ValueReturnKind).getKind())
or
exists(ArgNode arg |
result.(PostUpdateNode).getPreUpdateNode() = arg and
arg.argumentOf(call, k.(ParamUpdateReturnKind).getAMatchingArgumentPosition())
)
OutNodeEx getAnOutNodeEx(DataFlowCall call, ReturnKindExt k) {
result.asNode() = getAnOutNodeExt(call, k)
}
pragma[nomagic]
@@ -1016,22 +1043,22 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
parameterValueFlowsToPreUpdate(p, n) and
p.isParameterOf(_, pos) and
k = TParamUpdate(pos) and
scope = getSecondLevelScopeCached(n)
scope = getSecondLevelScope0(n)
)
}
cached
predicate castNode(Node n) { n instanceof CastNode }
predicate flowCheckNode(NodeEx n) {
n.asNode() instanceof CastNode or
clearsContentSet(n, _) or
expectsContentSet(n, _) or
neverSkipInPathGraph(n.asNode())
}
cached
predicate castingNode(Node n) {
castNode(n) or
n instanceof ParamNode or
n instanceof OutNodeExt or
// For reads, `x.f`, we want to check that the tracked type after the read (which
// is obtained by popping the head of the access path stack) is compatible with
// the type of `x.f`.
readSet(_, _, n)
predicate castingNodeEx(NodeEx n) {
n.asNode() instanceof CastingNode or
exists(n.asParamReturnNode())
}
cached
@@ -1208,6 +1235,15 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
)
}
/**
* Holds if `arg` is a possible argument to `p` in `call`, taking virtual
* dispatch into account.
*/
cached
predicate viableParamArgEx(DataFlowCall call, ParamNodeEx p, ArgNodeEx arg) {
viableParamArg(call, p.asNode(), arg.asNode())
}
pragma[nomagic]
private ReturnPosition viableReturnPos(DataFlowCall call, ReturnKindExt kind) {
viableCallableExt(call) = result.getCallable() and
@@ -1219,13 +1255,22 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
* taking virtual dispatch into account.
*/
cached
predicate viableReturnPosOut(DataFlowCall call, ReturnPosition pos, Node out) {
predicate viableReturnPosOut(DataFlowCall call, ReturnPosition pos, OutNodeExt out) {
exists(ReturnKindExt kind |
pos = viableReturnPos(call, kind) and
out = kind.getAnOutNode(call)
out = getAnOutNodeExt(call, kind)
)
}
/**
* Holds if a value at return position `pos` can be returned to `out` via `call`,
* taking virtual dispatch into account.
*/
cached
predicate viableReturnPosOutEx(DataFlowCall call, ReturnPosition pos, OutNodeEx out) {
viableReturnPosOut(call, pos, out.asNode())
}
/** Provides predicates for calculating flow-through summaries. */
private module FlowThrough {
/**
@@ -1559,6 +1604,11 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
cached
predicate readSet(Node node1, ContentSet c, Node node2) { readStep(node1, c, node2) }
cached
predicate readEx(NodeEx node1, ContentSet c, NodeEx node2) {
readSet(pragma[only_bind_into](node1.asNode()), c, pragma[only_bind_into](node2.asNode()))
}
cached
predicate storeSet(
Node node1, ContentSet c, Node node2, DataFlowType contentType, DataFlowType containerType
@@ -1587,11 +1637,13 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
* been stored into, in order to handle cases like `x.f1.f2 = y`.
*/
cached
predicate store(
Node node1, Content c, Node node2, DataFlowType contentType, DataFlowType containerType
predicate storeEx(
NodeEx node1, Content c, NodeEx node2, DataFlowType contentType, DataFlowType containerType
) {
exists(ContentSet cs |
c = cs.getAStoreContent() and storeSet(node1, cs, node2, contentType, containerType)
c = cs.getAStoreContent() and
storeSet(pragma[only_bind_into](node1.asNode()), cs, pragma[only_bind_into](node2.asNode()),
contentType, containerType)
)
}
@@ -1627,7 +1679,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
}
cached
predicate allowParameterReturnInSelfCached(ParamNode p) { allowParameterReturnInSelf(p) }
predicate allowParameterReturnInSelfEx(ParamNodeEx p) { allowParameterReturnInSelf(p.asNode()) }
cached
predicate paramMustFlow(ParamNode p, ArgNode arg) { localMustFlowStep+(p, arg) }
@@ -1657,7 +1709,9 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
string toString() { result = "Unreachable" }
cached
predicate contains(Node n) { exists(NodeRegion nr | super.contains(nr) and nr.contains(n)) }
predicate contains(NodeEx n) {
exists(NodeRegion nr | super.contains(nr) and nr.contains(n.asNode()))
}
cached
DataFlowCallable getEnclosingCallable() {
@@ -2209,7 +2263,15 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
* A `Node` at which a cast can occur such that the type should be checked.
*/
class CastingNode extends NodeFinal {
CastingNode() { castingNode(this) }
CastingNode() {
this instanceof CastNode or
this instanceof ParamNode or
this instanceof OutNodeExt or
// For reads, `x.f`, we want to check that the tracked type after the read (which
// is obtained by popping the head of the access path stack) is compatible with
// the type of `x.f`.
readSet(_, _, this)
}
}
private predicate readStepWithTypes(
@@ -2266,7 +2328,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
}
/** Holds if this call context makes `n` unreachable. */
predicate unreachable(Node n) { ns.contains(n) }
predicate unreachable(NodeEx n) { ns.contains(n) }
}
private DataFlowCallable getNodeRegionEnclosingCallable(NodeRegion nr) {
@@ -2307,6 +2369,16 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
OutNodeExt() { outNodeExt(this) }
}
pragma[nomagic]
OutNodeExt getAnOutNodeExt(DataFlowCall call, ReturnKindExt k) {
result = getAnOutNode(call, k.(ValueReturnKind).getKind())
or
exists(ArgNode arg |
result.(PostUpdateNode).getPreUpdateNode() = arg and
arg.argumentOf(call, k.(ParamUpdateReturnKind).getAMatchingArgumentPosition())
)
}
/**
* An extended return kind. A return kind describes how data can be returned
* from a callable. This can either be through a returned value or an updated
@@ -2317,7 +2389,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
abstract string toString();
/** Gets a node corresponding to data flow out of `call`. */
final OutNodeExt getAnOutNode(DataFlowCall call) { result = getAnOutNodeExt(call, this) }
final OutNodeEx getAnOutNodeEx(DataFlowCall call) { result = getAnOutNodeEx(call, this) }
}
class ValueReturnKind extends ReturnKindExt, TValueReturn {

View File

@@ -1207,6 +1207,11 @@ module Make<
)
}
/** Holds if the value of `succ` is uniquely determined by the value of `pred`. */
predicate summaryLocalMustFlowStep(SummaryNode pred, SummaryNode succ) {
pred = unique(SummaryNode n1 | summaryLocalStep(n1, succ, true, _))
}
/**
* Holds if there is a read step of content `c` from `pred` to `succ`, which
* is synthesized from a flow summary.
@@ -1355,7 +1360,7 @@ module Make<
exists(DataFlowCall call, ReturnKindExt rk |
result = summaryArgParam(call, arg, sc) and
summaryReturnNodeExt(ret, pragma[only_bind_into](rk)) and
out = pragma[only_bind_into](rk).getAnOutNode(call)
out = getAnOutNodeExt(call, pragma[only_bind_into](rk))
)
}

View File

@@ -464,8 +464,10 @@ module MakeModelGenerator<
predicate isAdditionalFlowStep(
DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2
) {
exists(DataFlow::ContentSet c |
DataFlow::store(node1, c.getAStoreContent(), node2, _, _) and
exists(DataFlow::NodeEx n1, DataFlow::NodeEx n2, DataFlow::ContentSet c |
node1 = n1.asNode() and
node2 = n2.asNode() and
DataFlow::storeEx(n1, c.getAStoreContent(), n2, _, _) and
isRelevantContent0(c) and
(
state1 instanceof TaintRead and state2.(TaintStore).getStep() = 1