mirror of
https://github.com/github/codeql.git
synced 2026-04-22 15:25:18 +02:00
Merge branch 'main' into redsun82/rust-less-canonical-paths
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"image": "mcr.microsoft.com/devcontainers/base:ubuntu-24.04",
|
||||
"extensions": [
|
||||
"rust-lang.rust-analyzer",
|
||||
"bungcip.better-toml",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
|
||||
16
csharp/.vscode/launch.json
vendored
16
csharp/.vscode/launch.json
vendored
@@ -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
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@@ -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,,,,,,,,,,,,,,,
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* .NET 9 is now required to build the C# extractor.
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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)) }
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
failures
|
||||
testFailures
|
||||
failures
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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() |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
failures
|
||||
testFailures
|
||||
failures
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -8,7 +8,6 @@ type Qux struct {
|
||||
*Baz
|
||||
}
|
||||
|
||||
// EmbedsBaz should have a field A but does not
|
||||
type EmbedsBaz struct {
|
||||
Qux
|
||||
Baz string
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -12,3 +12,9 @@ type MixedExportedAndNot interface {
|
||||
Exported()
|
||||
notExported()
|
||||
}
|
||||
|
||||
type NameClash struct {
|
||||
NCField string
|
||||
}
|
||||
|
||||
func (t NameClash) NCMethod() {}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
@@ -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`.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -76,7 +76,7 @@ module RegExpInjection {
|
||||
*/
|
||||
class MetacharEscapeSanitizer extends Sanitizer, StringReplaceCall {
|
||||
MetacharEscapeSanitizer() {
|
||||
this.isGlobal() and
|
||||
this.maybeGlobal() and
|
||||
(
|
||||
RegExp::alwaysMatchesMetaCharacter(this.getRegExp().getRoot(), ["{", "[", "+"])
|
||||
or
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -245,7 +245,7 @@ module UnsafeShellCommandConstruction {
|
||||
class ReplaceQuotesSanitizer extends Sanitizer, StringReplaceCall {
|
||||
ReplaceQuotesSanitizer() {
|
||||
this.getAReplacedString() = "'" and
|
||||
this.isGlobal() and
|
||||
this.maybeGlobal() and
|
||||
this.getRawReplacement().mayHaveStringValue(["'\\''", ""])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ module Shared {
|
||||
*/
|
||||
class MetacharEscapeSanitizer extends Sanitizer, StringReplaceCall {
|
||||
MetacharEscapeSanitizer() {
|
||||
this.isGlobal() and
|
||||
this.maybeGlobal() and
|
||||
(
|
||||
RegExp::alwaysMatchesMetaCharacter(this.getRegExp().getRoot(), ["<", "'", "\""])
|
||||
or
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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.
|
||||
}
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 ... &") | 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 ... &") | 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 ... &") | This replacement may double-escape '&' characters from $@. | tst.js:99:10:100:51 | s.repla ... apos;") | here |
|
||||
|
||||
@@ -94,3 +94,21 @@ function testWithCapturedVar(x) {
|
||||
function encodeDecodeEncode(s) {
|
||||
return goodEncode(goodDecode(goodEncode(s)));
|
||||
}
|
||||
|
||||
function badEncode(s) {
|
||||
return s.replace(new RegExp("\"", "g"), """)
|
||||
.replace(new RegExp("\'", "g"), "'")
|
||||
.replace(new RegExp("&", "g"), "&"); // NOT OK
|
||||
}
|
||||
|
||||
function goodEncode(s) {
|
||||
return s.replace(new RegExp("\"", ""), """)
|
||||
.replace(new RegExp("\'", ""), "'")
|
||||
.replace(new RegExp("&", ""), "&"); // OK
|
||||
}
|
||||
|
||||
function goodEncode(s) {
|
||||
return s.replace(new RegExp("\"", unknownFlags()), """)
|
||||
.replace(new RegExp("\'", unknownFlags()), "'")
|
||||
.replace(new RegExp("&", unknownFlags()), "&"); // OK
|
||||
}
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 | \\. | ../ |
|
||||
|
||||
@@ -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/. |
|
||||
|
||||
@@ -327,4 +327,41 @@ function incompleteComplexSanitizers() {
|
||||
if (str === "\"")
|
||||
return """;
|
||||
}) + '"';
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
});
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
})();
|
||||
|
||||
@@ -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*) |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
});
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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.
|
||||
});
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
});
|
||||
|
||||
37
ql/ql/src/queries/style/ValidatePredicateGetReturns.ql
Normal file
37
ql/ql/src/queries/style/ValidatePredicateGetReturns.ql
Normal 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."
|
||||
@@ -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. |
|
||||
@@ -0,0 +1 @@
|
||||
queries/style/ValidatePredicateGetReturns.ql
|
||||
@@ -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;
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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| {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
69
rust/ql/lib/codeql/rust/dataflow/FlowSummary.qll
Normal file
69
rust/ql/lib/codeql/rust/dataflow/FlowSummary.qll
Normal 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;
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
103
rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll
Normal file
103
rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll
Normal 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)
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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 | { ... } |
|
||||
@@ -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 |
|
||||
@@ -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 |
|
||||
|
||||
@@ -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(...) |
|
||||
|
||||
@@ -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();
|
||||
|
||||
89
rust/ql/test/library-tests/dataflow/models/main.rs
Normal file
89
rust/ql/test/library-tests/dataflow/models/main.rs
Normal 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();
|
||||
}
|
||||
57
rust/ql/test/library-tests/dataflow/models/models.expected
Normal file
57
rust/ql/test/library-tests/dataflow/models/models.expected
Normal 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(...) |
|
||||
78
rust/ql/test/library-tests/dataflow/models/models.ql
Normal file
78
rust/ql/test/library-tests/dataflow/models/models.ql
Normal 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()
|
||||
@@ -2,3 +2,4 @@
|
||||
| Multiple parents | 0 |
|
||||
| Multiple primary QL classes | 0 |
|
||||
| Multiple toStrings | 0 |
|
||||
| No location | 0 |
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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))
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user