mirror of
https://github.com/github/codeql.git
synced 2026-04-22 07:15:15 +02:00
Merge branch 'main' into redsun82/rust-canonical-enum
This commit is contained in:
87
.vscode/tasks.json
vendored
87
.vscode/tasks.json
vendored
@@ -38,6 +38,93 @@
|
||||
"command": "${config:python.pythonPath}",
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Create query change note",
|
||||
"type": "process",
|
||||
"command": "python3",
|
||||
"args": [
|
||||
"misc/scripts/create-change-note.py",
|
||||
"${input:language}",
|
||||
"src",
|
||||
"${input:name}",
|
||||
"${input:categoryQuery}"
|
||||
],
|
||||
"presentation": {
|
||||
"reveal": "never",
|
||||
"close": true
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Create library change note",
|
||||
"type": "process",
|
||||
"command": "python3",
|
||||
"args": [
|
||||
"misc/scripts/create-change-note.py",
|
||||
"${input:language}",
|
||||
"lib",
|
||||
"${input:name}",
|
||||
"${input:categoryLibrary}"
|
||||
],
|
||||
"presentation": {
|
||||
"reveal": "never",
|
||||
"close": true
|
||||
},
|
||||
"problemMatcher": []
|
||||
}
|
||||
],
|
||||
"inputs": [
|
||||
{
|
||||
"type": "pickString",
|
||||
"id": "language",
|
||||
"description": "Language",
|
||||
"options":
|
||||
[
|
||||
"go",
|
||||
"java",
|
||||
"javascript",
|
||||
"cpp",
|
||||
"csharp",
|
||||
"python",
|
||||
"ruby",
|
||||
"rust",
|
||||
"swift",
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "promptString",
|
||||
"id": "name",
|
||||
"description": "Short name (kebab-case)"
|
||||
},
|
||||
{
|
||||
"type": "pickString",
|
||||
"id": "categoryQuery",
|
||||
"description": "Category (query change)",
|
||||
"options":
|
||||
[
|
||||
"breaking",
|
||||
"deprecated",
|
||||
"newQuery",
|
||||
"queryMetadata",
|
||||
"majorAnalysis",
|
||||
"minorAnalysis",
|
||||
"fix",
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "pickString",
|
||||
"id": "categoryLibrary",
|
||||
"description": "Category (library change)",
|
||||
"options":
|
||||
[
|
||||
"breaking",
|
||||
"deprecated",
|
||||
"feature",
|
||||
"majorAnalysis",
|
||||
"minorAnalysis",
|
||||
"fix",
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -793,28 +793,27 @@ private Element interpretElement0(
|
||||
) {
|
||||
(
|
||||
// Non-member functions
|
||||
elementSpec(namespace, type, subtypes, name, signature, _) and
|
||||
funcHasQualifiedName(result, namespace, name) and
|
||||
subtypes = false and
|
||||
type = "" and
|
||||
(
|
||||
elementSpecMatchesSignature(result, namespace, type, subtypes, name, signature)
|
||||
or
|
||||
signature = "" and
|
||||
elementSpec(namespace, type, subtypes, name, "", _) and
|
||||
funcHasQualifiedName(result, namespace, name)
|
||||
elementSpec(namespace, type, subtypes, name, signature, _)
|
||||
)
|
||||
or
|
||||
// Member functions
|
||||
exists(Class namedClass, Class classWithMethod |
|
||||
hasClassAndName(classWithMethod, result, name) and
|
||||
classHasQualifiedName(namedClass, namespace, type)
|
||||
|
|
||||
(
|
||||
elementSpecMatchesSignature(result, namespace, type, subtypes, name, signature) and
|
||||
hasClassAndName(classWithMethod, result, name)
|
||||
elementSpecMatchesSignature(result, namespace, type, subtypes, name, signature)
|
||||
or
|
||||
signature = "" and
|
||||
elementSpec(namespace, type, subtypes, name, "", _) and
|
||||
hasClassAndName(classWithMethod, result, name)
|
||||
elementSpec(namespace, type, subtypes, name, "", _)
|
||||
) and
|
||||
classHasQualifiedName(namedClass, namespace, type) and
|
||||
(
|
||||
// member declared in the named type or a subtype of it
|
||||
subtypes = true and
|
||||
|
||||
@@ -164,4 +164,10 @@ void test_format() {
|
||||
|
||||
auto s2 = std::format(string::source());
|
||||
sink(s2); // $ ir MISSING: ast
|
||||
}
|
||||
|
||||
void test(std::format_string s) {
|
||||
int x = source();
|
||||
int y = std::same_signature_as_format_but_different_name(s, x);
|
||||
sink(y); // clean
|
||||
}
|
||||
@@ -451,6 +451,9 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future
|
||||
| format.cpp:162:24:162:27 | {} | format.cpp:162:24:162:27 | call to basic_format_string | TAINT |
|
||||
| format.cpp:165:13:165:23 | call to format | format.cpp:166:8:166:9 | s2 | |
|
||||
| format.cpp:165:25:165:38 | call to source | format.cpp:165:25:165:40 | call to basic_format_string | TAINT |
|
||||
| format.cpp:169:30:169:30 | s | format.cpp:171:60:171:60 | s | |
|
||||
| format.cpp:170:11:170:16 | call to source | format.cpp:171:63:171:63 | x | |
|
||||
| format.cpp:171:11:171:58 | call to same_signature_as_format_but_different_name | format.cpp:172:8:172:8 | y | |
|
||||
| map.cpp:21:28:21:28 | call to pair | map.cpp:23:2:23:2 | a | |
|
||||
| map.cpp:21:28:21:28 | call to pair | map.cpp:24:7:24:7 | a | |
|
||||
| map.cpp:21:28:21:28 | call to pair | map.cpp:25:7:25:7 | a | |
|
||||
|
||||
@@ -676,4 +676,9 @@ namespace std {
|
||||
using format_string = basic_format_string<char>; // simplified from `char, std::type_identity_t<Args>...`
|
||||
|
||||
template<class... Args> string format( format_string fmt, Args&&... args );
|
||||
|
||||
// This function has the same signature as `format`, but a different name. It should NOT be able to use
|
||||
// the model for `format`.
|
||||
template <typename... Args>
|
||||
int same_signature_as_format_but_different_name(format_string, Args &&...args);
|
||||
}
|
||||
@@ -265,6 +265,8 @@ signatureMatches
|
||||
| stl.h:678:33:678:38 | format | (format_string,Args &&) | | format<Args> | 0 |
|
||||
| stl.h:678:33:678:38 | format | (format_string,Args &&) | | format<Args> | 1 |
|
||||
| stl.h:678:33:678:38 | format | (format_string,Args &&) | | format<Args> | 1 |
|
||||
| stl.h:683:6:683:48 | same_signature_as_format_but_different_name | (format_string,Args &&) | | format<Args> | 0 |
|
||||
| stl.h:683:6:683:48 | same_signature_as_format_but_different_name | (format_string,Args &&) | | format<Args> | 1 |
|
||||
getSignatureParameterName
|
||||
| (InputIt,InputIt) | deque | assign<InputIt> | 0 | func:0 |
|
||||
| (InputIt,InputIt) | deque | assign<InputIt> | 1 | func:0 |
|
||||
@@ -729,6 +731,8 @@ getParameterTypeName
|
||||
| stl.h:678:33:678:38 | format | 0 | format_string |
|
||||
| stl.h:678:33:678:38 | format | 1 | func:0 && |
|
||||
| stl.h:678:33:678:38 | format | 1 | func:0 && |
|
||||
| stl.h:683:6:683:48 | same_signature_as_format_but_different_name | 0 | format_string |
|
||||
| stl.h:683:6:683:48 | same_signature_as_format_but_different_name | 1 | func:0 && |
|
||||
| stringstream.cpp:18:6:18:9 | sink | 0 | const basic_ostream> & |
|
||||
| stringstream.cpp:21:6:21:9 | sink | 0 | const basic_istream> & |
|
||||
| stringstream.cpp:24:6:24:9 | sink | 0 | const basic_iostream> & |
|
||||
|
||||
@@ -130,6 +130,7 @@ os,29,11,6,3,,,,,26,,,,,,,,,,,7,3,,1,6,
|
||||
path,,,18,,,,,,,,,,,,,,,,,,,,,18,
|
||||
reflect,,,37,,,,,,,,,,,,,,,,,,,,,37,
|
||||
regexp,10,,20,,,,,,,3,3,4,,,,,,,,,,,,20,
|
||||
slices,,,17,,,,,,,,,,,,,,,,,,,,,,17
|
||||
sort,,,1,,,,,,,,,,,,,,,,,,,,,1,
|
||||
strconv,,,9,,,,,,,,,,,,,,,,,,,,,9,
|
||||
strings,,,34,,,,,,,,,,,,,,,,,,,,,34,
|
||||
|
||||
|
@@ -26,7 +26,7 @@ Go framework & library support
|
||||
`Macaron <https://gopkg.in/macaron.v1>`_,``gopkg.in/macaron*``,12,1,1
|
||||
`Revel <http://revel.github.io/>`_,"``github.com/revel/revel*``, ``github.com/robfig/revel*``",46,20,4
|
||||
`SendGrid <https://github.com/sendgrid/sendgrid-go>`_,``github.com/sendgrid/sendgrid-go*``,,1,
|
||||
`Standard library <https://pkg.go.dev/std>`_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``",33,587,104
|
||||
`Standard library <https://pkg.go.dev/std>`_,"````, ``archive/*``, ``bufio``, ``bytes``, ``cmp``, ``compress/*``, ``container/*``, ``context``, ``crypto``, ``crypto/*``, ``database/*``, ``debug/*``, ``embed``, ``encoding``, ``encoding/*``, ``errors``, ``expvar``, ``flag``, ``fmt``, ``go/*``, ``hash``, ``hash/*``, ``html``, ``html/*``, ``image``, ``image/*``, ``index/*``, ``io``, ``io/*``, ``log``, ``log/*``, ``maps``, ``math``, ``math/*``, ``mime``, ``mime/*``, ``net``, ``net/*``, ``os``, ``os/*``, ``path``, ``path/*``, ``plugin``, ``reflect``, ``reflect/*``, ``regexp``, ``regexp/*``, ``slices``, ``sort``, ``strconv``, ``strings``, ``sync``, ``sync/*``, ``syscall``, ``syscall/*``, ``testing``, ``testing/*``, ``text/*``, ``time``, ``time/*``, ``unicode``, ``unicode/*``, ``unsafe``",33,604,104
|
||||
`XPath <https://github.com/antchfx/xpath>`_,``github.com/antchfx/xpath*``,,,4
|
||||
`appleboy/gin-jwt <https://github.com/appleboy/gin-jwt>`_,``github.com/appleboy/gin-jwt*``,,,1
|
||||
`beego <https://beego.me/>`_,"``github.com/astaxie/beego*``, ``github.com/beego/beego*``",63,63,213
|
||||
@@ -61,5 +61,5 @@ Go framework & library support
|
||||
`yaml <https://gopkg.in/yaml.v3>`_,``gopkg.in/yaml*``,,9,
|
||||
`zap <https://go.uber.org/zap>`_,``go.uber.org/zap*``,,11,33
|
||||
Others,"``github.com/Masterminds/squirrel``, ``github.com/caarlos0/env``, ``github.com/go-gorm/gorm``, ``github.com/go-xorm/xorm``, ``github.com/gobuffalo/envy``, ``github.com/gogf/gf/database/gdb``, ``github.com/hashicorp/go-envparse``, ``github.com/jinzhu/gorm``, ``github.com/jmoiron/sqlx``, ``github.com/joho/godotenv``, ``github.com/kelseyhightower/envconfig``, ``github.com/lann/squirrel``, ``github.com/raindog308/gorqlite``, ``github.com/rqlite/gorqlite``, ``github.com/uptrace/bun``, ``go.mongodb.org/mongo-driver/mongo``, ``gopkg.in/Masterminds/squirrel``, ``gorm.io/gorm``, ``xorm.io/xorm``",23,2,391
|
||||
Totals,,307,911,1532
|
||||
Totals,,307,928,1532
|
||||
|
||||
|
||||
31
go/ql/lib/ext/slices.model.yml
Normal file
31
go/ql/lib/ext/slices.model.yml
Normal file
@@ -0,0 +1,31 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/go-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
# All should be modeled when we have a way to model iterators
|
||||
# AppendSec should be modeled when we have a way to model iterators
|
||||
# Backward should be modeled when we have a way to model iterators
|
||||
# Chunk should be modeled when we have a way to model iterators
|
||||
- ["slices", "", False, "Clip", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"]
|
||||
- ["slices", "", False, "Clone", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"]
|
||||
# Collect should be modeled when we have a way to model iterators
|
||||
- ["slices", "", False, "Compact", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"]
|
||||
- ["slices", "", False, "CompactFunc", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"]
|
||||
- ["slices", "", False, "Concat", "", "", "Argument[0].ArrayElement.ArrayElement", "ReturnValue.ArrayElement", "value", "manual"]
|
||||
- ["slices", "", False, "Delete", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"]
|
||||
- ["slices", "", False, "DeleteFunc", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"]
|
||||
- ["slices", "", False, "Grow", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"]
|
||||
- ["slices", "", False, "Insert", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"]
|
||||
- ["slices", "", False, "Insert", "", "", "Argument[2].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"]
|
||||
- ["slices", "", False, "Max", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"]
|
||||
- ["slices", "", False, "MaxFunc", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"]
|
||||
- ["slices", "", False, "Min", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"]
|
||||
- ["slices", "", False, "MinFunc", "", "", "Argument[0].ArrayElement", "ReturnValue", "value", "manual"]
|
||||
- ["slices", "", False, "Repeat", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"]
|
||||
- ["slices", "", False, "Replace", "", "", "Argument[0].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"]
|
||||
- ["slices", "", False, "Replace", "", "", "Argument[3].ArrayElement", "ReturnValue.ArrayElement", "value", "manual"]
|
||||
# Sorted should be modeled when we have a way to model iterators
|
||||
# SortedFunc should be modeled when we have a way to model iterators
|
||||
# SortedStableFunc should be modeled when we have a way to model iterators
|
||||
# Values should be modeled when we have a way to model iterators
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added value flow models for functions in the `slices` package which do not involve the `iter` package.
|
||||
@@ -0,0 +1,193 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func TaintStepTest_SlicesClip(fromStringSlice []string) []string {
|
||||
toStringSlice := slices.Clip(fromStringSlice)
|
||||
return toStringSlice
|
||||
}
|
||||
|
||||
func TaintStepTest_SlicesClone(fromStringSlice []string) []string {
|
||||
toStringSlice := slices.Clone(fromStringSlice)
|
||||
return toStringSlice
|
||||
}
|
||||
|
||||
func TaintStepTest_SlicesCompact(fromStringSlice []string) []string {
|
||||
toStringSlice := slices.Compact(fromStringSlice)
|
||||
return toStringSlice
|
||||
}
|
||||
|
||||
func TaintStepTest_SlicesCompactFunc(fromStringSlice []string) []string {
|
||||
toStringSlice := slices.CompactFunc(fromStringSlice, strings.EqualFold)
|
||||
return toStringSlice
|
||||
}
|
||||
|
||||
func TaintStepTest_SlicesConcat0(fromStringSlice []string) []string {
|
||||
toStringSlice := slices.Concat(fromStringSlice, []string{"a", "b", "c"})
|
||||
return toStringSlice
|
||||
}
|
||||
|
||||
func TaintStepTest_SlicesConcat1(fromStringSlice []string) []string {
|
||||
toStringSlice := slices.Concat([]string{"a", "b", "c"}, fromStringSlice)
|
||||
return toStringSlice
|
||||
}
|
||||
|
||||
func TaintStepTest_SlicesDelete(fromStringSlice []string) []string {
|
||||
toStringSlice := slices.Delete(fromStringSlice, 0, 1)
|
||||
return toStringSlice
|
||||
}
|
||||
|
||||
func TaintStepTest_SlicesDeleteFunc(fromStringSlice []string) []string {
|
||||
deleteEmptyString := func(str string) bool {
|
||||
return str == ""
|
||||
}
|
||||
toStringSlice := slices.DeleteFunc(fromStringSlice, deleteEmptyString)
|
||||
return toStringSlice
|
||||
}
|
||||
|
||||
func TaintStepTest_SlicesGrow(fromStringSlice []string) []string {
|
||||
toStringSlice := slices.Grow(fromStringSlice, 1)
|
||||
return toStringSlice
|
||||
}
|
||||
|
||||
func TaintStepTest_SlicesInsert0(fromStringSlice []string) []string {
|
||||
toStringSlice := slices.Insert(fromStringSlice, 1, "a", "b")
|
||||
return toStringSlice
|
||||
}
|
||||
|
||||
func TaintStepTest_SlicesInsert2(fromString string) []string {
|
||||
toStringSlice := slices.Insert([]string{}, 0, fromString, "b")
|
||||
return toStringSlice
|
||||
}
|
||||
|
||||
func TaintStepTest_SlicesMax(fromStringSlice []string) string {
|
||||
toString := slices.Max(fromStringSlice)
|
||||
return toString
|
||||
}
|
||||
|
||||
func TaintStepTest_SlicesMaxFunc(fromStringSlice []string) string {
|
||||
toString := slices.MaxFunc(fromStringSlice, cmp.Compare)
|
||||
return toString
|
||||
}
|
||||
|
||||
func TaintStepTest_SlicesMin(fromStringSlice []string) string {
|
||||
toString := slices.Min(fromStringSlice)
|
||||
return toString
|
||||
}
|
||||
|
||||
func TaintStepTest_SlicesMinFunc(fromStringSlice []string) string {
|
||||
toString := slices.MinFunc(fromStringSlice, cmp.Compare)
|
||||
return toString
|
||||
}
|
||||
|
||||
func TaintStepTest_SlicesRepeat(fromStringSlice []string) []string {
|
||||
toStringSlice := slices.Repeat(fromStringSlice, 2)
|
||||
return toStringSlice
|
||||
}
|
||||
|
||||
func TaintStepTest_SlicesReplace0(fromStringSlice []string) []string {
|
||||
toStringSlice := slices.Replace(fromStringSlice, 1, 2, "a")
|
||||
return toStringSlice
|
||||
}
|
||||
|
||||
func TaintStepTest_SlicesReplace3(fromString string) []string {
|
||||
toStringSlice := slices.Replace([]string{}, 1, 3, fromString, "b")
|
||||
return toStringSlice
|
||||
}
|
||||
|
||||
func RunAllTaints_Slices() {
|
||||
{
|
||||
source := []string{newSource(0).(string)}
|
||||
out := TaintStepTest_SlicesClip(source)
|
||||
sink(0, out[0])
|
||||
}
|
||||
{
|
||||
source := []string{newSource(1).(string)}
|
||||
out := TaintStepTest_SlicesClone(source)
|
||||
sink(1, out[0])
|
||||
}
|
||||
{
|
||||
source := []string{newSource(2).(string)}
|
||||
out := TaintStepTest_SlicesCompact(source)
|
||||
sink(2, out[0])
|
||||
}
|
||||
{
|
||||
source := []string{newSource(3).(string)}
|
||||
out := TaintStepTest_SlicesCompactFunc(source)
|
||||
sink(3, out[0])
|
||||
}
|
||||
{
|
||||
source := []string{newSource(4).(string)}
|
||||
out := TaintStepTest_SlicesConcat0(source)
|
||||
sink(4, out[0])
|
||||
}
|
||||
{
|
||||
source := []string{newSource(5).(string)}
|
||||
out := TaintStepTest_SlicesConcat1(source)
|
||||
sink(5, out[0])
|
||||
}
|
||||
{
|
||||
source := []string{newSource(6).(string)}
|
||||
out := TaintStepTest_SlicesDelete(source)
|
||||
sink(6, out[0])
|
||||
}
|
||||
{
|
||||
source := []string{newSource(7).(string)}
|
||||
out := TaintStepTest_SlicesDeleteFunc(source)
|
||||
sink(7, out[0])
|
||||
}
|
||||
{
|
||||
source := []string{newSource(8).(string)}
|
||||
out := TaintStepTest_SlicesGrow(source)
|
||||
sink(8, out[0])
|
||||
}
|
||||
{
|
||||
source := []string{newSource(9).(string)}
|
||||
out := TaintStepTest_SlicesInsert0(source)
|
||||
sink(9, out[0])
|
||||
}
|
||||
{
|
||||
source := newSource(10).(string)
|
||||
out := TaintStepTest_SlicesInsert2(source)
|
||||
sink(10, out[0])
|
||||
}
|
||||
{
|
||||
source := []string{newSource(11).(string)}
|
||||
out := TaintStepTest_SlicesMax(source)
|
||||
sink(11, out)
|
||||
}
|
||||
{
|
||||
source := []string{newSource(12).(string)}
|
||||
out := TaintStepTest_SlicesMaxFunc(source)
|
||||
sink(12, out)
|
||||
}
|
||||
{
|
||||
source := []string{newSource(13).(string)}
|
||||
out := TaintStepTest_SlicesMin(source)
|
||||
sink(13, out)
|
||||
}
|
||||
{
|
||||
source := []string{newSource(14).(string)}
|
||||
out := TaintStepTest_SlicesMinFunc(source)
|
||||
sink(14, out)
|
||||
}
|
||||
{
|
||||
source := []string{newSource(15).(string)}
|
||||
out := TaintStepTest_SlicesRepeat(source)
|
||||
sink(15, out[0])
|
||||
}
|
||||
{
|
||||
source := []string{newSource(16).(string)}
|
||||
out := TaintStepTest_SlicesReplace0(source)
|
||||
sink(16, out[0])
|
||||
}
|
||||
{
|
||||
source := newSource(17).(string)
|
||||
out := TaintStepTest_SlicesReplace3(source)
|
||||
sink(17, out[0])
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
module example.com/m
|
||||
|
||||
go 1.20
|
||||
go 1.23
|
||||
|
||||
require (
|
||||
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# golang.org/x/net v0.0.0-20201010224723-4f7140c49acb
|
||||
## explicit
|
||||
golang.org/x/net
|
||||
## explicit; go 1.11
|
||||
golang.org/x/net/context
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Calling `coll.contains(x)` is now a taint sanitizer (for any query) for the value `x`, where `coll` is a collection of constants.
|
||||
@@ -28,6 +28,7 @@ private module Frameworks {
|
||||
private import semmle.code.java.frameworks.ThreadLocal
|
||||
private import semmle.code.java.frameworks.ratpack.RatpackExec
|
||||
private import semmle.code.java.frameworks.stapler.Stapler
|
||||
private import semmle.code.java.security.ListOfConstantsSanitizer
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -189,3 +190,8 @@ private class NumberTaintPreservingCallable extends TaintPreservingCallable {
|
||||
* map-key and map-value content, so that e.g. a tainted `Map` is assumed to have tainted keys and values.
|
||||
*/
|
||||
abstract class TaintInheritingContent extends DataFlow::Content { }
|
||||
|
||||
/**
|
||||
* A sanitizer in all global taint flow configurations but not in local taint.
|
||||
*/
|
||||
abstract class DefaultTaintSanitizer extends DataFlow::Node { }
|
||||
|
||||
@@ -13,24 +13,27 @@ private import semmle.code.java.dispatch.VirtualDispatch
|
||||
private import semmle.code.java.dataflow.internal.BaseSSA
|
||||
private import semmle.code.java.controlflow.Guards
|
||||
private import codeql.typeflow.TypeFlow
|
||||
private import codeql.typeflow.UniversalFlow as UniversalFlow
|
||||
|
||||
private module Input implements TypeFlowInput<Location> {
|
||||
private newtype TTypeFlowNode =
|
||||
/** Gets `t` if it is a `RefType` or the boxed type if `t` is a primitive type. */
|
||||
private RefType boxIfNeeded(J::Type t) {
|
||||
t.(PrimitiveType).getBoxedType() = result or
|
||||
result = t
|
||||
}
|
||||
|
||||
/** Provides the input types and predicates for instantiation of `UniversalFlow`. */
|
||||
module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
|
||||
private newtype TFlowNode =
|
||||
TField(Field f) { not f.getType() instanceof PrimitiveType } or
|
||||
TSsa(BaseSsaVariable ssa) { not ssa.getSourceVariable().getType() instanceof PrimitiveType } or
|
||||
TExpr(Expr e) or
|
||||
TMethod(Method m) { not m.getReturnType() instanceof PrimitiveType }
|
||||
|
||||
/** Gets `t` if it is a `RefType` or the boxed type if `t` is a primitive type. */
|
||||
private RefType boxIfNeeded(J::Type t) {
|
||||
t.(PrimitiveType).getBoxedType() = result or
|
||||
result = t
|
||||
}
|
||||
|
||||
/**
|
||||
* A `Field`, `BaseSsaVariable`, `Expr`, or `Method`.
|
||||
*/
|
||||
class TypeFlowNode extends TTypeFlowNode {
|
||||
class FlowNode extends TFlowNode {
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() {
|
||||
result = this.asField().toString() or
|
||||
result = this.asSsa().toString() or
|
||||
@@ -38,6 +41,7 @@ private module Input implements TypeFlowInput<Location> {
|
||||
result = this.asMethod().toString()
|
||||
}
|
||||
|
||||
/** Gets the source location for this element. */
|
||||
Location getLocation() {
|
||||
result = this.asField().getLocation() or
|
||||
result = this.asSsa().getLocation() or
|
||||
@@ -45,14 +49,19 @@ private module Input implements TypeFlowInput<Location> {
|
||||
result = this.asMethod().getLocation()
|
||||
}
|
||||
|
||||
/** Gets the field corresponding to this node, if any. */
|
||||
Field asField() { this = TField(result) }
|
||||
|
||||
/** Gets the SSA variable corresponding to this node, if any. */
|
||||
BaseSsaVariable asSsa() { this = TSsa(result) }
|
||||
|
||||
/** Gets the expression corresponding to this node, if any. */
|
||||
Expr asExpr() { this = TExpr(result) }
|
||||
|
||||
/** Gets the method corresponding to this node, if any. */
|
||||
Method asMethod() { this = TMethod(result) }
|
||||
|
||||
/** Gets the type of this node. */
|
||||
RefType getType() {
|
||||
result = this.asField().getType() or
|
||||
result = this.asSsa().getSourceVariable().getType() or
|
||||
@@ -61,8 +70,6 @@ private module Input implements TypeFlowInput<Location> {
|
||||
}
|
||||
}
|
||||
|
||||
class Type = RefType;
|
||||
|
||||
private SrcCallable viableCallable_v1(Call c) {
|
||||
result = viableImpl_v1(c)
|
||||
or
|
||||
@@ -88,7 +95,7 @@ private module Input implements TypeFlowInput<Location> {
|
||||
*
|
||||
* For a given `n2`, this predicate must include all possible `n1` that can flow to `n2`.
|
||||
*/
|
||||
predicate step(TypeFlowNode n1, TypeFlowNode n2) {
|
||||
predicate step(FlowNode n1, FlowNode n2) {
|
||||
n2.asExpr().(ChooseExpr).getAResultExpr() = n1.asExpr()
|
||||
or
|
||||
exists(Field f, Expr e |
|
||||
@@ -134,7 +141,7 @@ private module Input implements TypeFlowInput<Location> {
|
||||
/**
|
||||
* Holds if `null` is the only value that flows to `n`.
|
||||
*/
|
||||
predicate isNullValue(TypeFlowNode n) {
|
||||
predicate isNullValue(FlowNode n) {
|
||||
n.asExpr() instanceof NullLiteral
|
||||
or
|
||||
exists(LocalVariableDeclExpr decl |
|
||||
@@ -144,11 +151,21 @@ private module Input implements TypeFlowInput<Location> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate isExcludedFromNullAnalysis(TypeFlowNode n) {
|
||||
predicate isExcludedFromNullAnalysis(FlowNode n) {
|
||||
// Fields that are never assigned a non-null value are probably set by
|
||||
// reflection and are thus not always null.
|
||||
exists(n.asField())
|
||||
}
|
||||
}
|
||||
|
||||
private module Input implements TypeFlowInput<Location> {
|
||||
import FlowStepsInput
|
||||
|
||||
class TypeFlowNode = FlowNode;
|
||||
|
||||
predicate isExcludedFromNullAnalysis = FlowStepsInput::isExcludedFromNullAnalysis/1;
|
||||
|
||||
class Type = RefType;
|
||||
|
||||
predicate exactTypeBase(TypeFlowNode n, RefType t) {
|
||||
exists(ClassInstanceExpr e |
|
||||
|
||||
@@ -38,6 +38,7 @@ class BaseSsaSourceVariable extends TBaseSsaSourceVariable {
|
||||
/** Gets the `Callable` in which this `BaseSsaSourceVariable` is defined. */
|
||||
Callable getEnclosingCallable() { this = TLocalVar(result, _) }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() {
|
||||
exists(LocalScopeVariable v, Callable c | this = TLocalVar(c, v) |
|
||||
if c = v.getCallable()
|
||||
@@ -46,6 +47,7 @@ class BaseSsaSourceVariable extends TBaseSsaSourceVariable {
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the source location for this element. */
|
||||
Location getLocation() {
|
||||
exists(LocalScopeVariable v | this = TLocalVar(_, v) and result = v.getLocation())
|
||||
}
|
||||
@@ -482,8 +484,10 @@ class BaseSsaVariable extends TBaseSsaVariable {
|
||||
this = TSsaEntryDef(_, result)
|
||||
}
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { none() }
|
||||
|
||||
/** Gets the source location for this element. */
|
||||
Location getLocation() { result = this.getCfgNode().getLocation() }
|
||||
|
||||
/** Gets the `BasicBlock` in which this SSA variable is defined. */
|
||||
|
||||
@@ -161,6 +161,7 @@ private module Cached {
|
||||
*/
|
||||
cached
|
||||
predicate defaultTaintSanitizer(DataFlow::Node node) {
|
||||
node instanceof DefaultTaintSanitizer or
|
||||
// Ignore paths through test code.
|
||||
node.getEnclosingCallable().getDeclaringType() instanceof NonSecurityTestClass or
|
||||
node.asExpr() instanceof ValidatedVariableAccess
|
||||
|
||||
@@ -246,7 +246,7 @@ string getInsecureAlgorithmRegex() {
|
||||
string getASecureAlgorithmName() {
|
||||
result =
|
||||
[
|
||||
"RSA", "SHA-?256", "SHA-?512", "CCM", "GCM", "AES(?)",
|
||||
"RSA", "SHA-?(256|384|512)", "CCM", "GCM", "AES(?)",
|
||||
"Blowfish", "ECIES", "SHA3-(256|384|512)"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,263 @@
|
||||
/**
|
||||
* Provides a default taint sanitizer identifying comparisons against lists of
|
||||
* compile-time constants.
|
||||
*/
|
||||
|
||||
import java
|
||||
private import codeql.typeflow.UniversalFlow as UniversalFlow
|
||||
private import semmle.code.java.Collections
|
||||
private import semmle.code.java.controlflow.Guards
|
||||
private import semmle.code.java.dataflow.internal.BaseSSA
|
||||
private import semmle.code.java.dataflow.TaintTracking
|
||||
private import semmle.code.java.dataflow.TypeFlow
|
||||
private import semmle.code.java.dispatch.VirtualDispatch
|
||||
|
||||
private class FlowNode = FlowStepsInput::FlowNode;
|
||||
|
||||
/**
|
||||
* Holds if `n2` is an unmodifiable collection constructed from input `n1`,
|
||||
* which is either another collection or a number of elements.
|
||||
*/
|
||||
private predicate unmodifiableCollectionStep(FlowNode n1, FlowNode n2) {
|
||||
exists(Call c, Callable tgt |
|
||||
n2.asExpr() = c and
|
||||
n1.asExpr() = c.getAnArgument() and
|
||||
c.getCallee().getSourceDeclaration() = tgt
|
||||
|
|
||||
tgt.hasQualifiedName("java.util", "Collections",
|
||||
["unmodifiableCollection", "unmodifiableList", "unmodifiableSet"])
|
||||
or
|
||||
tgt.hasQualifiedName("java.util", ["List", "Set"], ["copyOf", "of"])
|
||||
or
|
||||
tgt.hasQualifiedName("com.google.common.collect", ["ImmutableList", "ImmutableSet"],
|
||||
["copyOf", "of"])
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `n2` is a collection or array constructed from input `n1`, which is
|
||||
* either a collection, an array, or a number of elements.
|
||||
*/
|
||||
private predicate collectionStep(FlowNode n1, FlowNode n2) {
|
||||
n2.asExpr().(ArrayInit).getAnInit() = n1.asExpr()
|
||||
or
|
||||
n2.asExpr().(ArrayCreationExpr).getInit() = n1.asExpr()
|
||||
or
|
||||
unmodifiableCollectionStep(n1, n2)
|
||||
or
|
||||
exists(Call c, Callable tgt |
|
||||
n2.asExpr() = c and
|
||||
n1.asExpr() = c.getAnArgument() and
|
||||
c.getCallee().getSourceDeclaration() = tgt
|
||||
|
|
||||
tgt.hasQualifiedName("java.util", "Arrays", "asList")
|
||||
or
|
||||
tgt.isStatic() and
|
||||
tgt.hasName(["copyOf", "of"]) and
|
||||
tgt.getDeclaringType().getASourceSupertype+().hasQualifiedName("java.util", "Collection")
|
||||
or
|
||||
tgt instanceof Constructor and
|
||||
tgt.getNumberOfParameters() = 1 and
|
||||
tgt.getParameterType(0) instanceof CollectionType and
|
||||
tgt.getDeclaringType() instanceof CollectionType
|
||||
)
|
||||
}
|
||||
|
||||
private module BaseUniversalFlow = UniversalFlow::Make<Location, FlowStepsInput>;
|
||||
|
||||
private module UnmodifiableProp implements BaseUniversalFlow::NullaryPropertySig {
|
||||
predicate hasPropertyBase(FlowNode n) { unmodifiableCollectionStep(_, n) }
|
||||
}
|
||||
|
||||
/** Holds if the given node is an unmodifiable collection. */
|
||||
private predicate unmodifiableCollection =
|
||||
BaseUniversalFlow::FlowNullary<UnmodifiableProp>::hasProperty/1;
|
||||
|
||||
/**
|
||||
* Holds if `v` is a collection or array with an access, `coll`, at which the
|
||||
* element `e` gets added.
|
||||
*/
|
||||
private predicate collectionAddition(Variable v, VarAccess coll, Expr e) {
|
||||
exists(MethodCall mc, Method m, int arg |
|
||||
mc.getMethod().getSourceDeclaration().overridesOrInstantiates*(m) and
|
||||
mc.getQualifier() = coll and
|
||||
v.getAnAccess() = coll and
|
||||
mc.getArgument(arg) = e
|
||||
|
|
||||
m.hasQualifiedName("java.util", "Collection", ["add", "addAll"]) and
|
||||
m.getNumberOfParameters() = 1 and
|
||||
arg = 0
|
||||
or
|
||||
m.hasQualifiedName("java.util", "List", ["add", "addAll"]) and
|
||||
m.getNumberOfParameters() = 2 and
|
||||
arg = 1
|
||||
or
|
||||
m.hasQualifiedName("java.util", "SequencedCollection", ["addFirst", "addLast"]) and
|
||||
m.getNumberOfParameters() = 1 and
|
||||
arg = 0
|
||||
)
|
||||
or
|
||||
v.getAnAccess() = coll and
|
||||
exists(Assignment assign | assign.getSource() = e |
|
||||
coll = assign.getDest().(ArrayAccess).getArray()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `n` represents a definition of `v` and `v` is a collection or
|
||||
* array that has additions occurring as side-effects after its definition.
|
||||
*/
|
||||
private predicate nodeWithAddition(FlowNode n, Variable v) {
|
||||
collectionAddition(v, _, _) and
|
||||
(
|
||||
n.asField() = v
|
||||
or
|
||||
n.asSsa().getSourceVariable().getVariable() = v and
|
||||
(n.asSsa() instanceof BaseSsaUpdate or n.asSsa().(BaseSsaImplicitInit).isParameterDefinition(_))
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `c` does not add elements to the given collection. */
|
||||
private predicate safeCallable(Callable c) {
|
||||
c instanceof CollectionQueryMethod
|
||||
or
|
||||
c instanceof CollectionMethod and
|
||||
c.hasName(["clear", "remove", "removeAll", "stream", "iterator", "toArray"])
|
||||
or
|
||||
c.hasQualifiedName("org.apache.commons.lang3", "StringUtils", "join")
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `n` might be mutated in ways that adds elements that are not
|
||||
* tracked by the `collectionAddition` predicate.
|
||||
*/
|
||||
private predicate collectionWithPossibleMutation(FlowNode n) {
|
||||
not unmodifiableCollection(n) and
|
||||
(
|
||||
exists(Expr e |
|
||||
n.asExpr() = e and
|
||||
(e.getType() instanceof CollectionType or e.getType() instanceof Array) and
|
||||
not collectionAddition(_, e, _) and
|
||||
not collectionStep(n, _)
|
||||
|
|
||||
exists(ArrayAccess aa | e = aa.getArray())
|
||||
or
|
||||
exists(Call c, Callable tgt | c.getAnArgument() = e or c.getQualifier() = e |
|
||||
tgt = c.getCallee().getSourceDeclaration() and
|
||||
not safeCallable(tgt)
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(FlowNode mid |
|
||||
FlowStepsInput::step(n, mid) and
|
||||
collectionWithPossibleMutation(mid)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A collection constructor that constructs an empty mutable collection.
|
||||
*/
|
||||
private class EmptyCollectionConstructor extends Constructor {
|
||||
EmptyCollectionConstructor() {
|
||||
this.getDeclaringType() instanceof CollectionType and
|
||||
forall(Type t | t = this.getAParamType() | t instanceof PrimitiveType)
|
||||
}
|
||||
}
|
||||
|
||||
private module CollectionFlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
|
||||
import FlowStepsInput
|
||||
|
||||
/**
|
||||
* Holds if `n2` is a collection/array/constant whose value(s) are
|
||||
* determined completely from the range of `n1` nodes.
|
||||
*/
|
||||
predicate step(FlowNode n1, FlowNode n2) {
|
||||
// Exclude the regular input constraints for those nodes that are covered
|
||||
// completely by `collectionStep`.
|
||||
FlowStepsInput::step(n1, n2) and
|
||||
not collectionStep(_, n2)
|
||||
or
|
||||
// For collections with side-effects in the form of additions, we add the
|
||||
// sources of those additions as additional input that need to originate
|
||||
// from constants.
|
||||
exists(Variable v |
|
||||
nodeWithAddition(n2, v) and
|
||||
collectionAddition(v, _, n1.asExpr())
|
||||
)
|
||||
or
|
||||
// Include various forms of collection transformation.
|
||||
collectionStep(n1, n2)
|
||||
}
|
||||
|
||||
predicate isExcludedFromNullAnalysis = FlowStepsInput::isExcludedFromNullAnalysis/1;
|
||||
}
|
||||
|
||||
private module CollectionUniversalFlow = UniversalFlow::Make<Location, CollectionFlowStepsInput>;
|
||||
|
||||
private module ConstantCollectionProp implements CollectionUniversalFlow::NullaryPropertySig {
|
||||
/**
|
||||
* Holds if `n` forms the base case for finding collections of constants.
|
||||
* These are individual constants and empty collections.
|
||||
*/
|
||||
predicate hasPropertyBase(FlowNode n) {
|
||||
n.asExpr().isCompileTimeConstant() or
|
||||
n.asExpr().(ConstructorCall).getConstructor() instanceof EmptyCollectionConstructor
|
||||
}
|
||||
|
||||
predicate barrier = collectionWithPossibleMutation/1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the given node is either a constant or a collection/array of
|
||||
* constants.
|
||||
*/
|
||||
private predicate constantCollection =
|
||||
CollectionUniversalFlow::FlowNullary<ConstantCollectionProp>::hasProperty/1;
|
||||
|
||||
/** Gets the result of a case normalization call of `arg`. */
|
||||
private MethodCall normalizeCaseCall(Expr arg) {
|
||||
exists(Method changecase | result.getMethod() = changecase |
|
||||
changecase.hasName(["toUpperCase", "toLowerCase"]) and
|
||||
changecase.getDeclaringType() instanceof TypeString and
|
||||
arg = result.getQualifier()
|
||||
or
|
||||
changecase
|
||||
.hasQualifiedName(["org.apache.commons.lang", "org.apache.commons.lang3"], "StringUtils",
|
||||
["lowerCase", "upperCase"]) and
|
||||
arg = result.getArgument(0)
|
||||
or
|
||||
changecase
|
||||
.hasQualifiedName("org.apache.hadoop.util", "StringUtils", ["toLowerCase", "toUpperCase"]) and
|
||||
arg = result.getArgument(0)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the guard `g` ensures that the expression `e` is one of a set of
|
||||
* known constants upon evaluating to `branch`.
|
||||
*/
|
||||
private predicate constantCollectionContainsCheck(Guard g, Expr e, boolean branch) {
|
||||
exists(MethodCall mc, Method m, FlowNode n, Expr checked |
|
||||
g = mc and
|
||||
mc.getMethod().getSourceDeclaration().overridesOrInstantiates*(m) and
|
||||
m.hasQualifiedName("java.util", "Collection", "contains") and
|
||||
n.asExpr() = mc.getQualifier() and
|
||||
constantCollection(n) and
|
||||
checked = mc.getAnArgument() and
|
||||
branch = true
|
||||
|
|
||||
checked = e or
|
||||
checked = normalizeCaseCall(e)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A comparison against a list of compile-time constants, sanitizing taint by
|
||||
* restricting to a set of known values.
|
||||
*/
|
||||
private class ListOfConstantsComparisonSanitizerGuard extends TaintTracking::DefaultTaintSanitizer {
|
||||
ListOfConstantsComparisonSanitizerGuard() {
|
||||
this = DataFlow::BarrierGuard<constantCollectionContainsCheck/3>::getABarrierNode()
|
||||
}
|
||||
}
|
||||
4
java/ql/src/change-notes/2024-11-24-sha2.md
Normal file
4
java/ql/src/change-notes/2024-11-24-sha2.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added SHA-384 to the list of secure hashing algorithms. As a result the `java/potentially-weak-cryptographic-algorithm` query should no longer flag up uses of SHA-384.
|
||||
158
java/ql/test/library-tests/dataflow/range-analysis-inline/B.java
Normal file
158
java/ql/test/library-tests/dataflow/range-analysis-inline/B.java
Normal file
@@ -0,0 +1,158 @@
|
||||
public class B {
|
||||
|
||||
// Use this method to mark non-integer bounds
|
||||
// that should also be annotated.
|
||||
static void bound(int b) { }
|
||||
|
||||
public int forLoop() {
|
||||
int result = 0;
|
||||
for (int i = 0;
|
||||
i < 10; // $ bound="i in [0..10]"
|
||||
i++) { // $ bound="i in [0..9]"
|
||||
result = i; // $ bound="i in [0..9]"
|
||||
}
|
||||
return result; // $ bound="result in [0..9]"
|
||||
}
|
||||
|
||||
public int forLoopExit() {
|
||||
int result = 0;
|
||||
for (; result < 10;) { // $ bound="result in [0..10]"
|
||||
result += 1; // $ bound="result in [0..9]"
|
||||
}
|
||||
return result; // $ bound="result = 10"
|
||||
}
|
||||
|
||||
public int forLoopExitStep() {
|
||||
int result = 0;
|
||||
for (; result < 10;) { // $ bound="result in [0..12]"
|
||||
result += 3; // $ bound="result in [0..9]"
|
||||
}
|
||||
return result; // $ bound="result = 12"
|
||||
}
|
||||
|
||||
public int forLoopExitUpd() {
|
||||
int result = 0;
|
||||
for (; result < 10; // $ bound="result in [0..10]"
|
||||
result++) { // $ bound="result in [0..9]"
|
||||
}
|
||||
return result; // $ bound="result = 10"
|
||||
}
|
||||
|
||||
public int forLoopExitNested() {
|
||||
int result = 0;
|
||||
for (; result < 10;) {
|
||||
int i = 0;
|
||||
for (; i < 3;) { // $ bound="i in [0..3]"
|
||||
i += 1; // $ bound="i in [0..2]"
|
||||
}
|
||||
result += i; // $ bound="result in [0..9]" bound="i = 3"
|
||||
}
|
||||
return result; // $ MISSING:bound="result = 12"
|
||||
}
|
||||
|
||||
public int emptyForLoop() {
|
||||
int result = 0;
|
||||
for (int i = 0; i < 0; // $ bound="i = 0"
|
||||
i++) { // $ bound="i in [0..-1]"
|
||||
result = i; // $ bound="i in [0..-1]"
|
||||
}
|
||||
return result; // $ bound="result = 0"
|
||||
}
|
||||
|
||||
public int noLoop() {
|
||||
int result = 0;
|
||||
result += 1; // $ bound="result = 0"
|
||||
return result; // $ bound="result = 1"
|
||||
}
|
||||
|
||||
public int foreachLoop() {
|
||||
int result = 0;
|
||||
for (int i : new int[] {1, 2, 3, 4, 5}) {
|
||||
result = i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public int emptyForeachLoop() {
|
||||
int result = 0;
|
||||
for (int i : new int[] {}) {
|
||||
result = i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public int whileLoop() {
|
||||
int result = 100;
|
||||
while (result > 5) { // $ bound="result in [4..100]"
|
||||
result = result - 2; // $ bound="result in [6..100]"
|
||||
}
|
||||
return result; // $ bound="result = 4"
|
||||
}
|
||||
|
||||
public int oddWhileLoop() {
|
||||
int result = 101;
|
||||
while (result > 5) { // $ bound="result in [5..101]"
|
||||
result = result - 2; // $ bound="result in [7..101]"
|
||||
}
|
||||
return result; // $ bound="result = 5"
|
||||
}
|
||||
|
||||
static void arrayLength(int[] arr) {
|
||||
bound(arr.length);
|
||||
for (int i = 0;
|
||||
i < arr.length;
|
||||
i++) { // $ bound="i <= arr.length - 1"
|
||||
arr[i]++; // $ bound="i <= arr.length - 1"
|
||||
}
|
||||
}
|
||||
|
||||
static int varBound(int b) {
|
||||
bound(b);
|
||||
int result = 0;
|
||||
for (int i = 0;
|
||||
i < b;
|
||||
i++) { // $ bound="i <= b - 1"
|
||||
result = i; // $ bound="i <= b - 1"
|
||||
}
|
||||
return result; // We cannot conclude anything here, since we do not know that b > 0
|
||||
}
|
||||
|
||||
static int varBoundPositiveGuard(int b) {
|
||||
bound(b);
|
||||
if (b > 0) {
|
||||
int result = 0;
|
||||
for (int i = 0;
|
||||
i < b;
|
||||
i++) { // $ bound="i <= b - 1"
|
||||
result = i; // $ bound="i <= b - 1"
|
||||
}
|
||||
return result; // $ MISSING: bound="result <= b - 1"
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int varBoundPositiveGuardEarlyReturn(int b) {
|
||||
bound(b);
|
||||
if (b <= 0) return 0;
|
||||
int result = 0;
|
||||
for (int i = 0;
|
||||
i < b;
|
||||
i++) { // $ bound="i <= b - 1"
|
||||
result = i; // $ bound="i <= b - 1"
|
||||
}
|
||||
return result; // $ MISSING: bound="result <= b - 1"
|
||||
}
|
||||
|
||||
static int varBoundPositiveAssert(int b) {
|
||||
bound(b);
|
||||
assert b > 0;
|
||||
int result = 0;
|
||||
for (int i = 0;
|
||||
i < b;
|
||||
i++) { // $ bound="i <= b - 1"
|
||||
result = i; // $ bound="i <= b - 1"
|
||||
}
|
||||
return result; // $ MISSING: bound="result <= b - 1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Inline range analysis tests for Java.
|
||||
* See `shared/util/codeql/dataflow/test/InlineFlowTest.qll`
|
||||
*/
|
||||
|
||||
import java
|
||||
import semmle.code.java.dataflow.RangeAnalysis
|
||||
private import TestUtilities.InlineExpectationsTest as IET
|
||||
|
||||
module RangeTest implements IET::TestSig {
|
||||
string getARelevantTag() { result = "bound" }
|
||||
|
||||
predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "bound" and
|
||||
(
|
||||
// simple integer bounds (`ZeroBound`s)
|
||||
exists(Expr e, int lower, int upper |
|
||||
constrained(e, lower, upper) and
|
||||
e instanceof VarRead and
|
||||
e.getCompilationUnit().fromSource()
|
||||
|
|
||||
location = e.getLocation() and
|
||||
element = e.toString() and
|
||||
if lower = upper
|
||||
then value = "\"" + e.toString() + " = " + lower.toString() + "\""
|
||||
else
|
||||
value = "\"" + e.toString() + " in [" + lower.toString() + ".." + upper.toString() + "]\""
|
||||
)
|
||||
or
|
||||
// advanced bounds
|
||||
exists(Expr e, int delta, string deltaStr, boolean upper, string cmp, Expr boundExpr |
|
||||
annotatedBound(e, _, boundExpr, delta, upper) and
|
||||
e instanceof VarRead and
|
||||
e.getCompilationUnit().fromSource() and
|
||||
(
|
||||
if delta = 0
|
||||
then deltaStr = ""
|
||||
else
|
||||
if delta > 0
|
||||
then deltaStr = " + " + delta.toString()
|
||||
else deltaStr = " - " + delta.abs().toString()
|
||||
) and
|
||||
if upper = true then cmp = "<=" else cmp = ">="
|
||||
|
|
||||
location = e.getLocation() and
|
||||
element = e.toString() and
|
||||
value = "\"" + e.toString() + " " + cmp + " " + boundExpr.toString() + deltaStr + "\""
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate constrained(Expr e, int lower, int upper) {
|
||||
bounded(e, any(ZeroBound z), lower, false, _) and
|
||||
bounded(e, any(ZeroBound z), upper, true, _)
|
||||
}
|
||||
|
||||
private predicate annotatedBound(Expr e, Bound b, Expr boundExpr, int delta, boolean upper) {
|
||||
bounded(e, b, delta, upper, _) and
|
||||
// the expression for the bound is explicitly requested as being annotated
|
||||
// via a call such as
|
||||
// ```java
|
||||
// bound(expr);
|
||||
// ```
|
||||
boundExpr = b.getExpr() and
|
||||
exists(Call c | c.getCallee().getName() = "bound" and c.getArgument(0) = boundExpr) and
|
||||
// non-trivial bound
|
||||
not e = b.getExpr()
|
||||
}
|
||||
}
|
||||
|
||||
import IET::MakeTest<RangeTest>
|
||||
35
java/ql/test/library-tests/listofconstants/A.java
Normal file
35
java/ql/test/library-tests/listofconstants/A.java
Normal file
@@ -0,0 +1,35 @@
|
||||
import java.util.*;
|
||||
|
||||
public class A {
|
||||
private static final Set<String> SEPARATORS =
|
||||
Collections.unmodifiableSet(
|
||||
new HashSet<>(Arrays.asList("\t", "\n", ";")));
|
||||
|
||||
public static void sink(String s) { }
|
||||
|
||||
private void checkSeparator(String separator) {
|
||||
if (SEPARATORS.contains(separator)) {
|
||||
sink(separator);
|
||||
}
|
||||
}
|
||||
|
||||
public static final String URI1 = "yarn.io/gpu";
|
||||
public static final String URI2 = "yarn.io/fpga";
|
||||
|
||||
public static final Set<String> SCHEMAS = Set.of(URI1, URI2, "s3a", "wasb");
|
||||
|
||||
private void checkSchema(String schema) {
|
||||
if (SCHEMAS.contains(schema)) {
|
||||
sink(schema);
|
||||
}
|
||||
}
|
||||
|
||||
private void testAdd(String inp) {
|
||||
Set<String> s = new HashSet<>();
|
||||
s.add("AA");
|
||||
s.add("BB");
|
||||
if (s.contains(inp.toUpperCase())) {
|
||||
sink(inp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
| Type A uses out-of-scope type variable E. Note the Java extractor is known to sometimes do this; the Kotlin extractor should not. |
|
||||
3
java/ql/test/library-tests/listofconstants/test.expected
Normal file
3
java/ql/test/library-tests/listofconstants/test.expected
Normal file
@@ -0,0 +1,3 @@
|
||||
| A.java:12:12:12:20 | separator |
|
||||
| A.java:23:12:23:17 | schema |
|
||||
| A.java:32:12:32:14 | inp |
|
||||
5
java/ql/test/library-tests/listofconstants/test.ql
Normal file
5
java/ql/test/library-tests/listofconstants/test.ql
Normal file
@@ -0,0 +1,5 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.FlowSteps
|
||||
|
||||
from DefaultTaintSanitizer e
|
||||
select e
|
||||
@@ -0,0 +1,306 @@
|
||||
// Test cases for CWE-089 (SQL injection and Java Persistence query injection)
|
||||
// http://cwe.mitre.org/data/definitions/89.html
|
||||
package test.cwe089.semmle.tests;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
class AllowListSanitizerWithJavaUtilList {
|
||||
public static Connection connection;
|
||||
public static final List<String> goodAllowList1 = List.of("allowed1", "allowed2", "allowed3");
|
||||
public static final List<String> goodAllowList2 = Collections.unmodifiableList(Arrays.asList("allowed1"));
|
||||
public static final List<String> goodAllowList3;
|
||||
public static final List<String> goodAllowList4;
|
||||
public static final List<String> goodAllowList5;
|
||||
public static final List<String> badAllowList1 = List.of("allowed1", "allowed2", getNonConstantString());
|
||||
public static final List<String> badAllowList2 = Collections.unmodifiableList(Arrays.asList("allowed1", getNonConstantString()));
|
||||
public static final List<String> badAllowList3;
|
||||
public static final List<String> badAllowList4;
|
||||
public static List<String> badAllowList6 = List.of("allowed1", "allowed2", "allowed3");
|
||||
public final List<String> goodAllowList7 = List.of("allowed1", "allowed2", "allowed3");
|
||||
|
||||
static {
|
||||
goodAllowList3 = List.of("allowed1", "allowed2", "allowed3");
|
||||
goodAllowList4 = Collections.unmodifiableList(Arrays.asList("allowed1", "allowed2"));
|
||||
badAllowList3 = List.of(getNonConstantString(), "allowed2", "allowed3");
|
||||
badAllowList4 = Collections.unmodifiableList(Arrays.asList("allowed1", getNonConstantString()));
|
||||
goodAllowList5 = new ArrayList<String>();
|
||||
goodAllowList5.add("allowed1");
|
||||
goodAllowList5.add("allowed2");
|
||||
goodAllowList5.add("allowed3");
|
||||
}
|
||||
|
||||
public static String getNonConstantString() {
|
||||
return String.valueOf(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException, SQLException {
|
||||
badAllowList6 = List.of("allowed1", getNonConstantString(), "allowed3");
|
||||
testStaticFields(args);
|
||||
testLocal(args);
|
||||
var x = new AllowListSanitizerWithJavaUtilList();
|
||||
x.testNonStaticFields(args);
|
||||
testMultipleSources(args);
|
||||
testEscape(args);
|
||||
}
|
||||
|
||||
private static void testStaticFields(String[] args) throws IOException, SQLException {
|
||||
String tainted = args[1];
|
||||
// GOOD: an allowlist is used with constant strings
|
||||
if(goodAllowList1.contains(tainted.toLowerCase())){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
// GOOD: an allowlist is used with constant strings
|
||||
if(goodAllowList2.contains(tainted.toUpperCase())){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
// GOOD: an allowlist is used with constant strings
|
||||
if(goodAllowList3.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
// GOOD: an allowlist is used with constant strings
|
||||
if(goodAllowList4.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
// BAD: an allowlist is used with constant strings
|
||||
if(badAllowList1.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
// BAD: an allowlist is used with constant strings
|
||||
if(badAllowList2.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
// BAD: an allowlist is used with constant strings
|
||||
if(badAllowList3.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
// BAD: an allowlist is used with constant strings
|
||||
if(badAllowList4.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
// GOOD: an allowlist is used with constant strings
|
||||
if(goodAllowList5.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
// BAD: the allowlist is in a non-final field
|
||||
if(badAllowList6.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
|
||||
private void testNonStaticFields(String[] args) throws IOException, SQLException {
|
||||
String tainted = args[0];
|
||||
// GOOD: the allowlist is in a non-static field
|
||||
if(goodAllowList7.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testLocal(String[] args) throws IOException, SQLException {
|
||||
String tainted = args[1];
|
||||
// GOOD: an allowlist is used with constant strings
|
||||
{
|
||||
List<String> allowlist = List.of("allowed1", "allowed2", "allowed3");
|
||||
if(allowlist.contains(tainted.toLowerCase())){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
// BAD: an allowlist is used but one of the entries is not a compile-time constant
|
||||
{
|
||||
List<String> allowlist = List.of("allowed1", "allowed2", args[2]);
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
// GOOD: an allowlist is used with constant strings
|
||||
{
|
||||
String[] allowedArray = {"allowed1", "allowed2", "allowed3"};
|
||||
List<String> allowlist = List.of(allowedArray);
|
||||
if(allowlist.contains(tainted.toUpperCase())){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
// BAD: an allowlist is used but one of the entries is not a compile-time constant
|
||||
{
|
||||
String[] allowedArray = {"allowed1", "allowed2", args[2]};
|
||||
List<String> allowlist = List.of(allowedArray);
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
// GOOD: an allowlist is used with constant strings
|
||||
{
|
||||
List<String> allowlist = Collections.unmodifiableList(Arrays.asList("allowed1"));
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
// BAD: an allowlist is used but one of the entries is not a compile-time constant
|
||||
{
|
||||
List<String> allowlist = Collections.unmodifiableList(Arrays.asList("allowed1", "allowed2", args[2]));
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
// GOOD: an allowlist is used with constant strings
|
||||
{
|
||||
String[] allowedArray = {"allowed1", "allowed2", "allowed3"};
|
||||
List<String> allowlist = Collections.unmodifiableList(Arrays.asList(allowedArray));
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
// BAD: an allowlist is used but one of the entries is not a compile-time constant
|
||||
{
|
||||
String[] allowedArray = {"allowed1", "allowed2", args[2]};
|
||||
List<String> allowlist = Collections.unmodifiableList(Arrays.asList(allowedArray));
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
// GOOD: an allowlist is used with constant string
|
||||
{
|
||||
List<String> allowlist = new ArrayList<String>();
|
||||
allowlist.add("allowed1");
|
||||
allowlist.add("allowed2");
|
||||
allowlist.add("allowed3");
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
// BAD: an allowlist is used but one of the entries is not a compile-time constant
|
||||
{
|
||||
List<String> allowlist = new ArrayList<String>();
|
||||
allowlist.add("allowed1");
|
||||
allowlist.add(getNonConstantString());
|
||||
allowlist.add("allowed3");
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
// BAD: an allowlist is used but it contains a non-compile-time constant element
|
||||
{
|
||||
List<String> allowlist = new ArrayList<String>();
|
||||
allowlist.add("allowed1");
|
||||
addNonConstantStringDirectly(allowlist);
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void testMultipleSources(String[] args) throws IOException, SQLException {
|
||||
String tainted = args[1];
|
||||
boolean b = args[2] == "True";
|
||||
{
|
||||
// BAD: an allowlist is used which might contain constant strings
|
||||
List<String> allowlist = new ArrayList<String>();
|
||||
allowlist.add("allowed1");
|
||||
if (b) {
|
||||
allowlist.add(getNonConstantString());
|
||||
}
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
{
|
||||
// BAD: an allowlist is used which might contain constant strings
|
||||
List<String> allowlist = b ? goodAllowList1 : badAllowList1;
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
{
|
||||
// BAD: an allowlist is used which might contain constant strings
|
||||
List<String> allowlist = b ? goodAllowList1 : List.of("allowed1", "allowed2", args[2]);;
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void testEscape(String[] args) throws IOException, SQLException {
|
||||
String tainted = args[1];
|
||||
boolean b = args[2] == "True";
|
||||
{
|
||||
// BAD: an allowlist is used which contains constant strings
|
||||
List<String> allowlist = new ArrayList<String>();
|
||||
addNonConstantStringViaLambda(e -> allowlist.add(e));
|
||||
if(allowlist.contains(tainted)){ // missing result
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void addNonConstantStringDirectly(List<String> list) {
|
||||
list.add(getNonConstantString());
|
||||
}
|
||||
|
||||
private static void addNonConstantStringViaLambda(Consumer<String> adder) {
|
||||
adder.accept(getNonConstantString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
// Test cases for CWE-089 (SQL injection and Java Persistence query injection)
|
||||
// http://cwe.mitre.org/data/definitions/89.html
|
||||
package test.cwe089.semmle.tests;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
class AllowListSanitizerWithJavaUtilSet {
|
||||
public static Connection connection;
|
||||
public static final Set<String> goodAllowList1 = Set.of("allowed1", "allowed2", "allowed3");
|
||||
public static final Set<String> goodAllowList2 = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList("allowed1","allowed2")));
|
||||
public static final Set<String> goodAllowList3;
|
||||
public static final Set<String> goodAllowList4;
|
||||
public static final Set<String> goodAllowList5;
|
||||
public static final Set<String> badAllowList1 = Set.of("allowed1", "allowed2", getNonConstantString());
|
||||
public static final Set<String> badAllowList2 = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList("allowed1", getNonConstantString())));
|
||||
public static final Set<String> badAllowList3;
|
||||
public static final Set<String> badAllowList4;
|
||||
public static Set<String> badAllowList6 = Set.of("allowed1", "allowed2", "allowed3");
|
||||
public final Set<String> goodAllowList7 = Set.of("allowed1", "allowed2", "allowed3");
|
||||
|
||||
static {
|
||||
goodAllowList3 = Set.of("allowed1", "allowed2", "allowed3");
|
||||
goodAllowList4 = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList("allowed1", "allowed2")));
|
||||
badAllowList3 = Set.of(getNonConstantString(), "allowed2", "allowed3");
|
||||
badAllowList4 = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList("allowed1", getNonConstantString())));
|
||||
goodAllowList5 = new HashSet<String>();
|
||||
goodAllowList5.add("allowed1");
|
||||
goodAllowList5.add("allowed2");
|
||||
goodAllowList5.add("allowed3");
|
||||
}
|
||||
|
||||
public static String getNonConstantString() {
|
||||
return String.valueOf(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException, SQLException {
|
||||
badAllowList6 = Set.of("allowed1", getNonConstantString(), "allowed3");
|
||||
testStaticFields(args);
|
||||
testLocal(args);
|
||||
var x = new AllowListSanitizerWithJavaUtilSet();
|
||||
x.testNonStaticFields(args);
|
||||
testMultipleSources(args);
|
||||
testEscape(args);
|
||||
}
|
||||
|
||||
private static void testStaticFields(String[] args) throws IOException, SQLException {
|
||||
String tainted = args[1];
|
||||
// GOOD: an allowlist is used with constant strings
|
||||
if(goodAllowList1.contains(tainted.toLowerCase())){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
// GOOD: an allowlist is used with constant strings
|
||||
if(goodAllowList2.contains(tainted.toUpperCase())){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
// GOOD: an allowlist is used with constant strings
|
||||
if(goodAllowList3.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
// GOOD: an allowlist is used with constant strings
|
||||
if(goodAllowList4.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
// BAD: an allowlist is used with constant strings
|
||||
if(badAllowList1.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
// BAD: an allowlist is used with constant strings
|
||||
if(badAllowList2.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
// BAD: an allowlist is used with constant strings
|
||||
if(badAllowList3.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
// BAD: an allowlist is used with constant strings
|
||||
if(badAllowList4.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
// GOOD: an allowlist is used with constant strings
|
||||
if(goodAllowList5.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
// BAD: the allowlist is in a non-final field
|
||||
if(badAllowList6.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
|
||||
private void testNonStaticFields(String[] args) throws IOException, SQLException {
|
||||
String tainted = args[1];
|
||||
// GOOD: the allowlist is in a non-static field
|
||||
if(goodAllowList7.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
|
||||
private static void testLocal(String[] args) throws IOException, SQLException {
|
||||
String tainted = args[1];
|
||||
// GOOD: an allowlist is used with constant strings
|
||||
{
|
||||
Set<String> allowlist = Set.of("allowed1", "allowed2", "allowed3");
|
||||
if(allowlist.contains(tainted.toLowerCase())){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
// BAD: an allowlist is used but one of the entries is not a compile-time constant
|
||||
{
|
||||
Set<String> allowlist = Set.of("allowed1", "allowed2", args[2]);
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
// GOOD: an allowlist is used with constant strings
|
||||
{
|
||||
String[] allowedArray = {"allowed1", "allowed2", "allowed3"};
|
||||
Set<String> allowlist = Set.of(allowedArray);
|
||||
if(allowlist.contains(tainted.toUpperCase())){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
// BAD: an allowlist is used but one of the entries is not a compile-time constant
|
||||
{
|
||||
String[] allowedArray = {"allowed1", "allowed2", args[2]};
|
||||
Set<String> allowlist = Set.of(allowedArray);
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
// GOOD: an allowlist is used with constant strings
|
||||
{
|
||||
Set<String> allowlist = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("allowed1")));
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
// BAD: an allowlist is used but one of the entries is not a compile-time constant
|
||||
{
|
||||
Set<String> allowlist = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("allowed1", "allowed2", args[2])));
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
// GOOD: an allowlist is used with constant strings
|
||||
{
|
||||
String[] allowedArray = {"allowed1", "allowed2", "allowed3"};
|
||||
Set<String> allowlist = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(allowedArray)));
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
// BAD: an allowlist is used but one of the entries is not a compile-time constant
|
||||
{
|
||||
String[] allowedArray = {"allowed1", "allowed2", args[2]};
|
||||
Set<String> allowlist = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(allowedArray)));
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
// GOOD: an allowlist is used with constant string
|
||||
{
|
||||
Set<String> allowlist = new HashSet<String>();
|
||||
allowlist.add("allowed1");
|
||||
allowlist.add("allowed2");
|
||||
allowlist.add("allowed3");
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
// BAD: an allowlist is used but one of the entries is not a compile-time constant
|
||||
{
|
||||
Set<String> allowlist = new HashSet<String>();
|
||||
allowlist.add("allowed1");
|
||||
allowlist.add(getNonConstantString());
|
||||
allowlist.add("allowed3");
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
// BAD: an allowlist is used but it contains a non-compile-time constant element
|
||||
{
|
||||
Set<String> allowlist = new HashSet<String>();
|
||||
allowlist.add("allowed1");
|
||||
addNonConstantStringDirectly(allowlist);
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void testMultipleSources(String[] args) throws IOException, SQLException {
|
||||
String tainted = args[1];
|
||||
boolean b = args[2] == "True";
|
||||
{
|
||||
// BAD: an allowlist is used which might contain constant strings
|
||||
Set<String> allowlist = new HashSet<String>();
|
||||
allowlist.add("allowed1");
|
||||
if (b) {
|
||||
allowlist.add(getNonConstantString());
|
||||
}
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
{
|
||||
// BAD: an allowlist is used which might contain constant strings
|
||||
Set<String> allowlist = b ? goodAllowList1 : badAllowList1;
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
{
|
||||
// BAD: an allowlist is used which might contain constant strings
|
||||
Set<String> allowlist = b ? goodAllowList1 : Set.of("allowed1", "allowed2", args[2]);;
|
||||
if(allowlist.contains(tainted)){
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void testEscape(String[] args) throws IOException, SQLException {
|
||||
String tainted = args[1];
|
||||
boolean b = args[2] == "True";
|
||||
{
|
||||
// BAD: an allowlist is used which contains constant strings
|
||||
Set<String> allowlist = new HashSet<String>();
|
||||
addNonConstantStringViaLambda(e -> allowlist.add(e));
|
||||
if(allowlist.contains(tainted)){ // missing result
|
||||
String query = "SELECT ITEM,PRICE FROM PRODUCT WHERE ITEM_CATEGORY='"
|
||||
+ tainted + "' ORDER BY PRICE";
|
||||
ResultSet results = connection.createStatement().executeQuery(query);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void addNonConstantStringDirectly(Set<String> set) {
|
||||
set.add(getNonConstantString());
|
||||
}
|
||||
|
||||
private static void addNonConstantStringViaLambda(Consumer<String> adder) {
|
||||
adder.accept(getNonConstantString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
| Type AllowListSanitizerWithJavaUtilSet uses out-of-scope type variable E. Note the Java extractor is known to sometimes do this; the Kotlin extractor should not. |
|
||||
@@ -1,3 +1,55 @@
|
||||
| AllowListSanitizerWithJavaUtilList.java:64:66:64:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:63:8:63:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:70:66:70:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:69:8:69:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:76:66:76:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:75:8:75:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:82:66:82:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:81:8:81:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:88:66:88:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:87:8:87:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:93:8:93:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:99:8:99:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:105:8:105:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:112:66:112:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:111:8:111:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:117:8:117:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:128:66:128:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:127:8:127:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:140:67:140:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:139:9:139:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:148:9:148:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:159:67:159:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:158:9:158:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:168:9:168:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:178:67:178:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:177:9:177:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:187:67:187:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:186:9:186:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:197:67:197:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:196:9:196:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:207:67:207:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:206:9:206:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:219:67:219:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:218:9:218:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:231:67:231:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:230:9:230:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:242:67:242:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:241:9:241:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:260:67:260:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:259:9:259:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:269:67:269:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:268:9:268:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:278:67:278:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:277:9:277:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilList.java:293:67:293:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilList.java:292:9:292:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:63:66:63:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:62:8:62:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:69:66:69:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:68:8:68:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:75:66:75:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:74:8:74:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:81:66:81:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:80:8:80:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:87:66:87:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:86:8:86:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:92:8:92:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:98:8:98:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:104:8:104:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:111:66:111:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:110:8:110:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:116:8:116:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:127:66:127:70 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:126:8:126:14 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:139:67:139:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:138:9:138:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:147:9:147:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:158:67:158:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:157:9:157:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:167:9:167:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:177:67:177:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:176:9:176:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:186:67:186:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:185:9:185:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:196:67:196:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:195:9:195:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:206:67:206:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:205:9:205:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:218:67:218:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:217:9:217:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:230:67:230:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:229:9:229:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:241:67:241:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:240:9:240:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:259:67:259:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:258:9:258:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:268:67:268:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:267:9:267:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:277:67:277:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:276:9:276:15 | tainted | this expression |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:292:67:292:71 | query | Query built by concatenation with $@, which may be untrusted. | AllowListSanitizerWithJavaUtilSet.java:291:9:291:15 | tainted | this expression |
|
||||
| Test.java:36:47:36:52 | query1 | Query built by concatenation with $@, which may be untrusted. | Test.java:35:8:35:15 | category | this expression |
|
||||
| Test.java:42:57:42:62 | query2 | Query built by concatenation with $@, which may be untrusted. | Test.java:41:51:41:52 | id | this expression |
|
||||
| Test.java:50:62:50:67 | query3 | Query built by concatenation with $@, which may be untrusted. | Test.java:49:8:49:15 | category | this expression |
|
||||
|
||||
@@ -1,4 +1,34 @@
|
||||
#select
|
||||
| AllowListSanitizerWithJavaUtilList.java:88:66:88:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:88:66:88:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilList.java:187:67:187:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:187:67:187:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilList.java:207:67:207:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:207:67:207:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilList.java:231:67:231:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:231:67:231:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilList.java:242:67:242:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:242:67:242:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilList.java:260:67:260:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:260:67:260:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilList.java:269:67:269:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:269:67:269:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilList.java:278:67:278:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:278:67:278:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilList.java:293:67:293:71 | query | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:293:67:293:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:87:66:87:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:87:66:87:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:186:67:186:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:186:67:186:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:206:67:206:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:206:67:206:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:230:67:230:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:230:67:230:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:241:67:241:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:241:67:241:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:259:67:259:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:259:67:259:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:268:67:268:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:268:67:268:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:277:67:277:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:277:67:277:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:292:67:292:71 | query | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:292:67:292:71 | query | This query depends on a $@. | AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args | user-provided value |
|
||||
| Mongo.java:17:45:17:67 | parse(...) | Mongo.java:10:29:10:41 | args : String[] | Mongo.java:17:45:17:67 | parse(...) | This query depends on a $@. | Mongo.java:10:29:10:41 | args | user-provided value |
|
||||
| Mongo.java:21:49:21:52 | json | Mongo.java:10:29:10:41 | args : String[] | Mongo.java:21:49:21:52 | json | This query depends on a $@. | Mongo.java:10:29:10:41 | args | user-provided value |
|
||||
| Test.java:36:47:36:52 | query1 | Test.java:227:26:227:38 | args : String[] | Test.java:36:47:36:52 | query1 | This query depends on a $@. | Test.java:227:26:227:38 | args | user-provided value |
|
||||
@@ -10,6 +40,52 @@
|
||||
| Test.java:209:47:209:68 | queryWithUserTableName | Test.java:227:26:227:38 | args : String[] | Test.java:209:47:209:68 | queryWithUserTableName | This query depends on a $@. | Test.java:227:26:227:38 | args | user-provided value |
|
||||
| Test.java:221:81:221:111 | ... + ... | Test.java:227:26:227:38 | args : String[] | Test.java:221:81:221:111 | ... + ... | This query depends on a $@. | Test.java:227:26:227:38 | args | user-provided value |
|
||||
edges
|
||||
| AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:50:20:50:23 | args : String[] | provenance | |
|
||||
| AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:51:13:51:16 | args : String[] | provenance | |
|
||||
| AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:54:23:54:26 | args : String[] | provenance | |
|
||||
| AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | AllowListSanitizerWithJavaUtilList.java:55:14:55:17 | args : String[] | provenance | |
|
||||
| AllowListSanitizerWithJavaUtilList.java:50:20:50:23 | args : String[] | AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | provenance | |
|
||||
| AllowListSanitizerWithJavaUtilList.java:51:13:51:16 | args : String[] | AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | provenance | |
|
||||
| AllowListSanitizerWithJavaUtilList.java:54:23:54:26 | args : String[] | AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | provenance | |
|
||||
| AllowListSanitizerWithJavaUtilList.java:55:14:55:17 | args : String[] | AllowListSanitizerWithJavaUtilList.java:283:33:283:45 | args : String[] | provenance | |
|
||||
| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:88:66:88:70 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:187:67:187:71 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:207:67:207:71 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:231:67:231:71 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | AllowListSanitizerWithJavaUtilList.java:242:67:242:71 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | AllowListSanitizerWithJavaUtilList.java:260:67:260:71 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | AllowListSanitizerWithJavaUtilList.java:269:67:269:71 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | AllowListSanitizerWithJavaUtilList.java:278:67:278:71 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilList.java:283:33:283:45 | args : String[] | AllowListSanitizerWithJavaUtilList.java:293:67:293:71 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:49:20:49:23 | args : String[] | provenance | |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:50:13:50:16 | args : String[] | provenance | |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:53:23:53:26 | args : String[] | provenance | |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:54:14:54:17 | args : String[] | provenance | |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:49:20:49:23 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | provenance | |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:50:13:50:16 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | provenance | |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:53:23:53:26 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | provenance | |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:54:14:54:17 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:282:33:282:45 | args : String[] | provenance | |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:87:66:87:70 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:186:67:186:71 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:206:67:206:71 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:230:67:230:71 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:241:67:241:71 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:259:67:259:71 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:268:67:268:71 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:277:67:277:71 | query | provenance | Sink:MaD:4 |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:282:33:282:45 | args : String[] | AllowListSanitizerWithJavaUtilSet.java:292:67:292:71 | query | provenance | Sink:MaD:4 |
|
||||
| Mongo.java:10:29:10:41 | args : String[] | Mongo.java:17:56:17:66 | stringQuery : String | provenance | |
|
||||
| Mongo.java:10:29:10:41 | args : String[] | Mongo.java:21:49:21:52 | json | provenance | |
|
||||
| Mongo.java:17:56:17:66 | stringQuery : String | Mongo.java:17:45:17:67 | parse(...) | provenance | Config |
|
||||
@@ -40,6 +116,54 @@ models
|
||||
| 6 | Summary: java.lang; AbstractStringBuilder; true; append; ; ; Argument[0]; Argument[this]; taint; manual |
|
||||
| 7 | Summary: java.lang; CharSequence; true; toString; ; ; Argument[this]; ReturnValue; taint; manual |
|
||||
nodes
|
||||
| AllowListSanitizerWithJavaUtilList.java:48:26:48:38 | args : String[] | semmle.label | args : String[] |
|
||||
| AllowListSanitizerWithJavaUtilList.java:50:20:50:23 | args : String[] | semmle.label | args : String[] |
|
||||
| AllowListSanitizerWithJavaUtilList.java:51:13:51:16 | args : String[] | semmle.label | args : String[] |
|
||||
| AllowListSanitizerWithJavaUtilList.java:54:23:54:26 | args : String[] | semmle.label | args : String[] |
|
||||
| AllowListSanitizerWithJavaUtilList.java:55:14:55:17 | args : String[] | semmle.label | args : String[] |
|
||||
| AllowListSanitizerWithJavaUtilList.java:58:39:58:51 | args : String[] | semmle.label | args : String[] |
|
||||
| AllowListSanitizerWithJavaUtilList.java:88:66:88:70 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilList.java:94:66:94:70 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilList.java:100:66:100:70 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilList.java:106:66:106:70 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilList.java:118:66:118:70 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilList.java:132:32:132:44 | args : String[] | semmle.label | args : String[] |
|
||||
| AllowListSanitizerWithJavaUtilList.java:149:67:149:71 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilList.java:169:67:169:71 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilList.java:187:67:187:71 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilList.java:207:67:207:71 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilList.java:231:67:231:71 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilList.java:242:67:242:71 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilList.java:247:42:247:54 | args : String[] | semmle.label | args : String[] |
|
||||
| AllowListSanitizerWithJavaUtilList.java:260:67:260:71 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilList.java:269:67:269:71 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilList.java:278:67:278:71 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilList.java:283:33:283:45 | args : String[] | semmle.label | args : String[] |
|
||||
| AllowListSanitizerWithJavaUtilList.java:293:67:293:71 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:47:26:47:38 | args : String[] | semmle.label | args : String[] |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:49:20:49:23 | args : String[] | semmle.label | args : String[] |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:50:13:50:16 | args : String[] | semmle.label | args : String[] |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:53:23:53:26 | args : String[] | semmle.label | args : String[] |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:54:14:54:17 | args : String[] | semmle.label | args : String[] |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:57:39:57:51 | args : String[] | semmle.label | args : String[] |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:87:66:87:70 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:93:66:93:70 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:99:66:99:70 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:105:66:105:70 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:117:66:117:70 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:131:32:131:44 | args : String[] | semmle.label | args : String[] |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:148:67:148:71 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:168:67:168:71 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:186:67:186:71 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:206:67:206:71 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:230:67:230:71 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:241:67:241:71 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:246:42:246:54 | args : String[] | semmle.label | args : String[] |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:259:67:259:71 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:268:67:268:71 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:277:67:277:71 | query | semmle.label | query |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:282:33:282:45 | args : String[] | semmle.label | args : String[] |
|
||||
| AllowListSanitizerWithJavaUtilSet.java:292:67:292:71 | query | semmle.label | query |
|
||||
| Mongo.java:10:29:10:41 | args : String[] | semmle.label | args : String[] |
|
||||
| Mongo.java:17:45:17:67 | parse(...) | semmle.label | parse(...) |
|
||||
| Mongo.java:17:56:17:66 | stringQuery : String | semmle.label | stringQuery : String |
|
||||
|
||||
@@ -19,7 +19,7 @@ public class WeakHashing {
|
||||
|
||||
// BAD: Using a strong hashing algorithm but with a weak default
|
||||
MessageDigest bad3 = MessageDigest.getInstance(props.getProperty("hashAlg2", "MD5"));
|
||||
|
||||
|
||||
// GOOD: Using a strong hashing algorithm
|
||||
MessageDigest ok = MessageDigest.getInstance(props.getProperty("hashAlg2"));
|
||||
|
||||
@@ -28,5 +28,8 @@ public class WeakHashing {
|
||||
|
||||
// GOOD: Using a strong hashing algorithm
|
||||
MessageDigest ok3 = MessageDigest.getInstance("SHA3-512");
|
||||
|
||||
// GOOD: Using a strong hashing algorithm
|
||||
MessageDigest ok4 = MessageDigest.getInstance("SHA384");
|
||||
}
|
||||
}
|
||||
|
||||
55
misc/scripts/create-change-note.py
Normal file
55
misc/scripts/create-change-note.py
Normal file
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Creates a change note and opens it in VSCode for editing.
|
||||
|
||||
# Expects to receive the following arguments:
|
||||
# - What language the change note is for
|
||||
# - Whether it's a query or library change (the string `src` or `lib`)
|
||||
# - The name of the change note (in kebab-case)
|
||||
# - The category of the change.
|
||||
|
||||
# The change note will be created in the `{language}/ql/{subdir}/change-notes` directory, where `subdir` is either `src` or `lib`.
|
||||
|
||||
# The format of the change note filename is `{current_date}-{change_note_name}.md` with the date in
|
||||
# the format `YYYY-MM-DD`.
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Read the given arguments
|
||||
language = sys.argv[1]
|
||||
subdir = sys.argv[2]
|
||||
change_note_name = sys.argv[3]
|
||||
change_category = sys.argv[4]
|
||||
|
||||
# Find the root of the repository. The current script should be located in `misc/scripts`.
|
||||
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
# Go to the repo root
|
||||
os.chdir(root)
|
||||
|
||||
output_dir = f"{language}/ql/{subdir}/change-notes"
|
||||
|
||||
# Abort if the output directory doesn't exist
|
||||
if not os.path.exists(output_dir):
|
||||
print(f"Output directory {output_dir} does not exist")
|
||||
sys.exit(1)
|
||||
|
||||
# Get the current date
|
||||
import datetime
|
||||
current_date = datetime.datetime.now().strftime("%Y-%m-%d")
|
||||
|
||||
# Create the change note file
|
||||
change_note_file = f"{output_dir}/{current_date}-{change_note_name}.md"
|
||||
|
||||
change_note = f"""
|
||||
---
|
||||
category: {change_category}
|
||||
---
|
||||
* """.lstrip()
|
||||
|
||||
with open(change_note_file, "w") as f:
|
||||
f.write(change_note)
|
||||
|
||||
# Open the change note file in VSCode, reusing the existing window if possible
|
||||
os.system(f"code -r {change_note_file}")
|
||||
@@ -14,24 +14,29 @@ fn project_root() -> PathBuf {
|
||||
PathBuf::from(dir).parent().unwrap().to_owned()
|
||||
}
|
||||
|
||||
fn class_name(type_name: &String) -> String {
|
||||
match type_name.as_str() {
|
||||
"BinExpr" => "BinaryExpr".to_owned(),
|
||||
"ElseBranch" => "Expr".to_owned(),
|
||||
"Fn" => "Function".to_owned(),
|
||||
"Literal" => "LiteralExpr".to_owned(),
|
||||
"Type" => "TypeRef".to_owned(),
|
||||
_ => type_name.to_owned(),
|
||||
}
|
||||
fn class_name(type_name: &str) -> String {
|
||||
let name = match type_name {
|
||||
"BinExpr" => "BinaryExpr",
|
||||
"ElseBranch" => "Expr",
|
||||
"Fn" => "Function",
|
||||
"Literal" => "LiteralExpr",
|
||||
"Type" => "TypeRef",
|
||||
_ => type_name,
|
||||
};
|
||||
name.to_owned()
|
||||
}
|
||||
|
||||
fn property_name(type_name: &String, field_name: &String) -> String {
|
||||
match (type_name.as_str(), field_name.as_str()) {
|
||||
("Path", "segment") => "part".to_owned(),
|
||||
(_, "then_branch") => "then".to_owned(),
|
||||
(_, "else_branch") => "else_".to_owned(),
|
||||
_ => field_name.to_owned(),
|
||||
}
|
||||
fn property_name(type_name: &str, field_name: &str) -> String {
|
||||
let name = match (type_name, field_name) {
|
||||
("CallExpr", "expr") => "function",
|
||||
("LetExpr", "expr") => "scrutinee",
|
||||
("MatchExpr", "expr") => "scrutinee",
|
||||
("Path", "segment") => "part",
|
||||
(_, "then_branch") => "then",
|
||||
(_, "else_branch") => "else_",
|
||||
_ => field_name,
|
||||
};
|
||||
name.to_owned()
|
||||
}
|
||||
|
||||
fn to_lower_snake_case(s: &str) -> String {
|
||||
@@ -61,7 +66,7 @@ fn write_schema(
|
||||
|
||||
for node in &grammar.enums {
|
||||
let super_classses = if let Some(cls) = super_types.get(&node.name) {
|
||||
let super_classes: Vec<String> = cls.iter().map(class_name).collect();
|
||||
let super_classes: Vec<String> = cls.iter().map(|s| class_name(s)).collect();
|
||||
super_classes.join(",")
|
||||
} else {
|
||||
"AstNode".to_owned()
|
||||
@@ -76,7 +81,7 @@ fn write_schema(
|
||||
}
|
||||
for node in &grammar.nodes {
|
||||
let super_classses = if let Some(cls) = super_types.get(&node.name) {
|
||||
let super_classes: Vec<String> = cls.iter().map(class_name).collect();
|
||||
let super_classes: Vec<String> = cls.iter().map(|s| class_name(s)).collect();
|
||||
super_classes.join(",")
|
||||
} else {
|
||||
"AstNode".to_owned()
|
||||
|
||||
2
rust/extractor/src/generated/.generated.list
generated
2
rust/extractor/src/generated/.generated.list
generated
@@ -1,2 +1,2 @@
|
||||
mod.rs 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7
|
||||
top.rs bc12e91ac724df9ca0c5d438067762d7e540bc20bde01c053af048b2a8391e2e bc12e91ac724df9ca0c5d438067762d7e540bc20bde01c053af048b2a8391e2e
|
||||
top.rs 272ecf2f56f35211d2449dbf55b1907d8414a8e4cceded03fd12f6f599852c73 272ecf2f56f35211d2449dbf55b1907d8414a8e4cceded03fd12f6f599852c73
|
||||
|
||||
18
rust/extractor/src/generated/top.rs
generated
18
rust/extractor/src/generated/top.rs
generated
@@ -4942,7 +4942,7 @@ impl From<trap::Label<LabelableExpr>> for trap::Label<Locatable> {
|
||||
pub struct LetExpr {
|
||||
pub id: trap::TrapId<LetExpr>,
|
||||
pub attrs: Vec<trap::Label<Attr>>,
|
||||
pub expr: Option<trap::Label<Expr>>,
|
||||
pub scrutinee: Option<trap::Label<Expr>>,
|
||||
pub pat: Option<trap::Label<Pat>>,
|
||||
}
|
||||
|
||||
@@ -4956,8 +4956,8 @@ impl trap::TrapEntry for LetExpr {
|
||||
for (i, v) in self.attrs.into_iter().enumerate() {
|
||||
out.add_tuple("let_expr_attrs", vec![id.into(), i.into(), v.into()]);
|
||||
}
|
||||
if let Some(v) = self.expr {
|
||||
out.add_tuple("let_expr_exprs", vec![id.into(), v.into()]);
|
||||
if let Some(v) = self.scrutinee {
|
||||
out.add_tuple("let_expr_scrutinees", vec![id.into(), v.into()]);
|
||||
}
|
||||
if let Some(v) = self.pat {
|
||||
out.add_tuple("let_expr_pats", vec![id.into(), v.into()]);
|
||||
@@ -5509,7 +5509,7 @@ impl From<trap::Label<MacroType>> for trap::Label<TypeRef> {
|
||||
pub struct MatchExpr {
|
||||
pub id: trap::TrapId<MatchExpr>,
|
||||
pub attrs: Vec<trap::Label<Attr>>,
|
||||
pub expr: Option<trap::Label<Expr>>,
|
||||
pub scrutinee: Option<trap::Label<Expr>>,
|
||||
pub match_arm_list: Option<trap::Label<MatchArmList>>,
|
||||
}
|
||||
|
||||
@@ -5523,8 +5523,8 @@ impl trap::TrapEntry for MatchExpr {
|
||||
for (i, v) in self.attrs.into_iter().enumerate() {
|
||||
out.add_tuple("match_expr_attrs", vec![id.into(), i.into(), v.into()]);
|
||||
}
|
||||
if let Some(v) = self.expr {
|
||||
out.add_tuple("match_expr_exprs", vec![id.into(), v.into()]);
|
||||
if let Some(v) = self.scrutinee {
|
||||
out.add_tuple("match_expr_scrutinees", vec![id.into(), v.into()]);
|
||||
}
|
||||
if let Some(v) = self.match_arm_list {
|
||||
out.add_tuple("match_expr_match_arm_lists", vec![id.into(), v.into()]);
|
||||
@@ -8120,7 +8120,7 @@ pub struct CallExpr {
|
||||
pub id: trap::TrapId<CallExpr>,
|
||||
pub arg_list: Option<trap::Label<ArgList>>,
|
||||
pub attrs: Vec<trap::Label<Attr>>,
|
||||
pub expr: Option<trap::Label<Expr>>,
|
||||
pub function: Option<trap::Label<Expr>>,
|
||||
}
|
||||
|
||||
impl trap::TrapEntry for CallExpr {
|
||||
@@ -8136,8 +8136,8 @@ impl trap::TrapEntry for CallExpr {
|
||||
for (i, v) in self.attrs.into_iter().enumerate() {
|
||||
out.add_tuple("call_expr_base_attrs", vec![id.into(), i.into(), v.into()]);
|
||||
}
|
||||
if let Some(v) = self.expr {
|
||||
out.add_tuple("call_expr_exprs", vec![id.into(), v.into()]);
|
||||
if let Some(v) = self.function {
|
||||
out.add_tuple("call_expr_functions", vec![id.into(), v.into()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
12
rust/extractor/src/translate/generated.rs
generated
12
rust/extractor/src/translate/generated.rs
generated
@@ -397,12 +397,12 @@ impl Translator<'_> {
|
||||
pub(crate) fn emit_call_expr(&mut self, node: ast::CallExpr) -> Label<generated::CallExpr> {
|
||||
let arg_list = node.arg_list().map(|x| self.emit_arg_list(x));
|
||||
let attrs = node.attrs().map(|x| self.emit_attr(x)).collect();
|
||||
let expr = node.expr().map(|x| self.emit_expr(x));
|
||||
let function = node.expr().map(|x| self.emit_expr(x));
|
||||
let label = self.trap.emit(generated::CallExpr {
|
||||
id: TrapId::Star,
|
||||
arg_list,
|
||||
attrs,
|
||||
expr,
|
||||
function,
|
||||
});
|
||||
self.emit_location(label, &node);
|
||||
emit_detached!(CallExpr, self, node, label);
|
||||
@@ -958,12 +958,12 @@ impl Translator<'_> {
|
||||
|
||||
pub(crate) fn emit_let_expr(&mut self, node: ast::LetExpr) -> Label<generated::LetExpr> {
|
||||
let attrs = node.attrs().map(|x| self.emit_attr(x)).collect();
|
||||
let expr = node.expr().map(|x| self.emit_expr(x));
|
||||
let scrutinee = node.expr().map(|x| self.emit_expr(x));
|
||||
let pat = node.pat().map(|x| self.emit_pat(x));
|
||||
let label = self.trap.emit(generated::LetExpr {
|
||||
id: TrapId::Star,
|
||||
attrs,
|
||||
expr,
|
||||
scrutinee,
|
||||
pat,
|
||||
});
|
||||
self.emit_location(label, &node);
|
||||
@@ -1224,12 +1224,12 @@ impl Translator<'_> {
|
||||
|
||||
pub(crate) fn emit_match_expr(&mut self, node: ast::MatchExpr) -> Label<generated::MatchExpr> {
|
||||
let attrs = node.attrs().map(|x| self.emit_attr(x)).collect();
|
||||
let expr = node.expr().map(|x| self.emit_expr(x));
|
||||
let scrutinee = node.expr().map(|x| self.emit_expr(x));
|
||||
let match_arm_list = node.match_arm_list().map(|x| self.emit_match_arm_list(x));
|
||||
let label = self.trap.emit(generated::MatchExpr {
|
||||
id: TrapId::Star,
|
||||
attrs,
|
||||
expr,
|
||||
scrutinee,
|
||||
match_arm_list,
|
||||
});
|
||||
self.emit_location(label, &node);
|
||||
|
||||
19
rust/ql/.generated.list
generated
19
rust/ql/.generated.list
generated
@@ -1,4 +1,4 @@
|
||||
lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll 5e6ce2581b312d74ac8ffde44941b77f643025a7ff2c47799b3834596a513fa4 24dc5d28eb4754f968cf850294ac32057a2a97cf5156a3e90e0924c28e50e810
|
||||
lib/codeql/rust/controlflow/internal/generated/CfgNodes.qll a8e083c7d8c4dea6459c5e128e2123f5cf8fd14c076f2256ebda508c13d553cd 16fcc0d34097b0b37a0041281515ca028d2702eec6d9c1d03c39a1158883bdef
|
||||
lib/codeql/rust/elements/Abi.qll 4c973d28b6d628f5959d1f1cc793704572fd0acaae9a97dfce82ff9d73f73476 250f68350180af080f904cd34cb2af481c5c688dc93edf7365fd0ae99855e893
|
||||
lib/codeql/rust/elements/Addressable.qll 13011bfd2e1556694c3d440cc34af8527da4df49ad92b62f2939d3699ff2cea5 ddb25935f7553a1a384b1abe2e4b4fa90ab50b952dadec32fd867afcb054f4be
|
||||
lib/codeql/rust/elements/ArgList.qll 661f5100f5d3ef8351452d9058b663a2a5c720eea8cf11bedd628969741486a2 28e424aac01a90fb58cd6f9f83c7e4cf379eea39e636bc0ba07efc818be71c71
|
||||
@@ -298,7 +298,6 @@ lib/codeql/rust/elements/internal/OrPatConstructor.qll 4ef583e07298487c0c4c6d7c7
|
||||
lib/codeql/rust/elements/internal/ParamBaseImpl.qll fe11999c728c443c46c992e9bed7a2b3e23afa16ae99592e70054bc57ae371b8 df86fdb23266bdfb9ed8a8f02558a760b67f173943b9d075b081229eb5844f66
|
||||
lib/codeql/rust/elements/internal/ParamConstructor.qll b98a2d8969f289fdcc8c0fb11cbd19a3b0c71be038c4a74f5988295a2bae52f0 77d81b31064167945b79b19d9697b57ca24462c3a7cc19e462c4693ce87db532
|
||||
lib/codeql/rust/elements/internal/ParamListConstructor.qll 3123142ab3cab46fb53d7f3eff6ba2d3ff7a45b78839a53dc1979a9c6a54920e 165f3d777ea257cfcf142cc4ba9a0ebcd1902eb99842b8a6657c87087f3df6fe
|
||||
lib/codeql/rust/elements/internal/ParamListImpl.qll 0ed6e9affe1dc0144641502292c2ddd51958fe3d503419caf15198176e3a4174 92d053cc5fdf40a2d98acb665083b5da15403d7da205779a97a4ee66fac0add4
|
||||
lib/codeql/rust/elements/internal/ParenExprConstructor.qll 104b67dc3fd53ab52e2a42ffde37f3a3a50647aa7bf35df9ba9528e9670da210 d1f5937756e87a477710c61698d141cdad0ccce8b07ecb51bab00330a1ca9835
|
||||
lib/codeql/rust/elements/internal/ParenPatConstructor.qll 9aea3c3b677755177d85c63e20234c234f530a16db20ab699de05ca3f1b59787 29f24aed0d880629a53b30550467ade09a0a778dbf88891769c1e11b0b239f98
|
||||
lib/codeql/rust/elements/internal/ParenTypeConstructor.qll d62e656a4a3c8ffd4eb87d49585a7a3bfb5dbe3826fbcbd11cb87b46f34c19ae febf6535965afa0f6eac4d2b08730f5a07bbb36a7434abe0a7663d7264961a3f
|
||||
@@ -431,7 +430,7 @@ lib/codeql/rust/elements/internal/generated/BinaryExpr.qll 64e9bd9c571edd6e5f3e7
|
||||
lib/codeql/rust/elements/internal/generated/BlockExpr.qll 5a5ddbe34bc478a7bd9b0d07d3b6f017c2d1f20581d859251a963314e6514d1f 9804c30b8b279038b864c52557535f854bd012bacdfe8e5840f1f777c74e52df
|
||||
lib/codeql/rust/elements/internal/generated/BoxPat.qll ec946a3e671ab7417e04b0207967adad004df512c570c4f0780ca5816d12d75f b0e64860855c4e85914042b1a51034899ff7cd1b2c6857188de89310a2726ea3
|
||||
lib/codeql/rust/elements/internal/generated/BreakExpr.qll 0f428a8b2f4209b134c2ffc3e1c93c30bc6b0e9c9172f140cefa88c1f77d8690 957b39f38ff6befe9061f55bc0b403c2f1c366dd0cf63b874bae6f8216576d76
|
||||
lib/codeql/rust/elements/internal/generated/CallExpr.qll 23ee64e3bf643cd5e6ff705181d2bb31e1aeaffecb5bdce73836172dbf15f12f 34b280139b1f8f70d78e1432392f03c971be392e8cb68d014eb325d0c101bddd
|
||||
lib/codeql/rust/elements/internal/generated/CallExpr.qll f1b8dae487077cc9d1dccf8c3cd61fd17afe860585f17ce8b860be4859be7ca4 6034fc03778e38802cdf3a6e460364b74e92912622581b31e6179951022bbbd6
|
||||
lib/codeql/rust/elements/internal/generated/CallExprBase.qll cce796e36847249f416629bacf3ea146313084de3374587412e66c10d2917b83 c219aa2174321c161a4a742ca0605521687ca9a5ca32db453a5c62db6f7784cc
|
||||
lib/codeql/rust/elements/internal/generated/Callable.qll b0502b5263b7bcd18e740f284f992c0e600e37d68556e3e0ba54a2ac42b94934 bda3e1eea11cacf5a9b932cd72efc2de6105103e8c575880fcd0cd89daadf068
|
||||
lib/codeql/rust/elements/internal/generated/CastExpr.qll d6fbf02e9e202254666082a9116634d0eb933177866ac4c0a57b5e9c4bb4b383 477f67773492e3b82695461d56327c9db05a7d1a67e8d192406265f2ce369670
|
||||
@@ -478,7 +477,7 @@ lib/codeql/rust/elements/internal/generated/ItemList.qll 73c8398a96d4caa47a2dc11
|
||||
lib/codeql/rust/elements/internal/generated/Label.qll 6630fe16e9d2de6c759ff2684f5b9950bc8566a1525c835c131ebb26f3eea63e 671143775e811fd88ec90961837a6c0ee4db96e54f42efd80c5ae2571661f108
|
||||
lib/codeql/rust/elements/internal/generated/LabelableExpr.qll 896fd165b438b60d7169e8f30fa2a94946490c4d284e1bbadfec4253b909ee6c 5c6b029ea0b22cf096df2b15fe6f9384ad3e65b50b253cae7f19a2e5ffb04a58
|
||||
lib/codeql/rust/elements/internal/generated/LetElse.qll 7ca556118b5446bfc85abba8f0edd4970e029b30d414ea824a1b5f568310a76c a403540881336f9d0269cbcdb4b87107a17ab234a985247dc52a380f150a1641
|
||||
lib/codeql/rust/elements/internal/generated/LetExpr.qll 9af0f89b294c8a0a751317e7074fe370339563d36c1df4911d1ea082a4df77fd 68272593d1feb88990bfbd0b8c222776f085e49694894384fc6d96e9464ba734
|
||||
lib/codeql/rust/elements/internal/generated/LetExpr.qll 6f831be1d0f76258d5f74c847636e070a819dee5aa090be0c52a971f261eaff3 e85a48e7492862f738e184f5f1512c2d18d33a0cfb516e269334acf7448b508a
|
||||
lib/codeql/rust/elements/internal/generated/LetStmt.qll aa1852db86ec29f857a90677f0c6b4a07f0fd965fc193d4141be95ce15862fca 40f32a37c0cc161b099fe0b4c7d713da928781d3e2c3de90db991df1d9062647
|
||||
lib/codeql/rust/elements/internal/generated/Lifetime.qll 90d01c76188ce0c053122c62b41e47f27c4c7717ca5a4999a76797360043da0d 7b9feb202da5a06cd17f7770bb66742fd9e7cff0d410fefc7ffaafe710ac16d6
|
||||
lib/codeql/rust/elements/internal/generated/LifetimeArg.qll 7c1a44e3d480e75142b171eb51382c9492d393043833c0ab4a4036eba19043b8 7d8273b62794268dab6938ba1e3a3560a80a2c49cd9a9717345785dacd311059
|
||||
@@ -515,7 +514,7 @@ lib/codeql/rust/elements/internal/generated/ParamList.qll c808c9d84dd7800573832b
|
||||
lib/codeql/rust/elements/internal/generated/ParenExpr.qll bc0731505bfe88516205ec360582a4222d2681d11342c93e15258590ddee82f2 d4bd6e0c80cf1d63746c88d4bcb3a01d4c75732e5da09e3ebd9437ced227fb60
|
||||
lib/codeql/rust/elements/internal/generated/ParenPat.qll ce24b8f8ecbf0f204af200317405724063887257460c80cf250c39b2fdf37185 e7c87d37e1a0ca7ea03840017e1aa9ddb7f927f1f3b6396c0305b46aeee33db6
|
||||
lib/codeql/rust/elements/internal/generated/ParenType.qll 9cc954d73f8330dcac7b475f97748b63af5c8766dee9d2f2872c0a7e4c903537 c07534c8a9c683c4a9b11d490095647e420de0a0bfc23273eaf6f31b00244273
|
||||
lib/codeql/rust/elements/internal/generated/ParentChild.qll 0ef5a17cc0d38e942e8a3dbe26b34befdea3ba23bc18cc2450e0ce0bd55e145d 0aa61484a16cf47dc3802a77f46b055394d38bf3736f0197115e3ff004115635
|
||||
lib/codeql/rust/elements/internal/generated/ParentChild.qll db7a782f11a14305acc666c865118475e2d324d2bf5d4110b157e1d488b62b75 3b5d31528d0baa0ceee139097e93461d18503797a1507288dc43428f378500e2
|
||||
lib/codeql/rust/elements/internal/generated/Pat.qll 3605ac062be2f294ee73336e9669027b8b655f4ad55660e1eab35266275154ee 7f9400db2884d336dd1d21df2a8093759c2a110be9bf6482ce8e80ae0fd74ed4
|
||||
lib/codeql/rust/elements/internal/generated/Path.qll 4c1c8e840ed57880e574142b081b11d7a7428a009f10e3aa8f4645e211f6b2e0 989668cf0f1bdee7557e2f97c01e41d2a56848227fed41477833f5fc1e1d35f6
|
||||
lib/codeql/rust/elements/internal/generated/PathExpr.qll 2096e3c1db22ee488a761690adabfc9cfdea501c99f7c5d96c0019cb113fc506 54245ce0449c4e263173213df01e079d5168a758503a5dbd61b25ad35a311140
|
||||
@@ -528,7 +527,7 @@ lib/codeql/rust/elements/internal/generated/PtrType.qll 40099c5a4041314b66932dfd
|
||||
lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590 ea294a3ba33fd1bc632046c4fedbcb84dcb961a8e4599969d65893b19d90e590
|
||||
lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9
|
||||
lib/codeql/rust/elements/internal/generated/RangePat.qll efd93730de217cf50dcba5875595263a5eadf9f7e4e1272401342a094d158614 229b251b3d118932e31e78ac4dfb75f48b766f240f20d436062785606d44467b
|
||||
lib/codeql/rust/elements/internal/generated/Raw.qll 631450d9014ad3eb191007e2b0054162ca86aaccf9d5275be831ba762ee966a5 bc302f73decc7ceafbe285c32d74b5911830d2b3c95c7033507512de857feabb
|
||||
lib/codeql/rust/elements/internal/generated/Raw.qll 7de290d66bd594f4c5b5a296502792e803e9f1084bb2616d9774196e33b16c87 28150fdd3cff3bb49b407f0c2119602be13e78cbb1f8fd749edd31f5d9772f7a
|
||||
lib/codeql/rust/elements/internal/generated/RecordExpr.qll eb6cb662e463f9260efae1a6ce874fa781172063b916ef1963f861e9942d308d 1a21cbccc8f3799ff13281e822818ebfb21d81591720a427cac3625512cb9d40
|
||||
lib/codeql/rust/elements/internal/generated/RecordExprField.qll 7e9f8663d3b74ebbc9603b10c9912f082febba6bd73d344b100bbd3edf837802 fbe6b578e7fd5d5a6f21bbb8c388957ab7210a6a249ec71510a50fb35b319ea1
|
||||
lib/codeql/rust/elements/internal/generated/RecordExprFieldList.qll 179a97211fe7aa6265085d4d54115cdbc0e1cd7c9b2135591e8f36d6432f13d3 dd44bbbc1e83a1ed3a587afb729d7debf7aeb7b63245de181726af13090e50c0
|
||||
@@ -635,10 +634,10 @@ test/extractor-tests/generated/BreakExpr/BreakExpr.ql cdde2855d98f658187c60b9edc
|
||||
test/extractor-tests/generated/BreakExpr/BreakExpr_getAttr.ql c7690a9aab1923bf3c2fb06f0a1d441d480b3c91ee1df3a868bbbd96c4042053 c592dd077fb6e22b2d6ddcaec37da2c5a26ba92d84f5d1ae4c78a615b9013765
|
||||
test/extractor-tests/generated/BreakExpr/BreakExpr_getExpr.ql 0358f4fe6a66da56177703cf0e991042729c5e34ae8b6dccbb827f95fe936c72 1cb2dd778c50e19fe04c5fdf3a08a502635ea8303e71ff38d03aa7dc53213986
|
||||
test/extractor-tests/generated/BreakExpr/BreakExpr_getLifetime.ql ad83cc0db3c0f959fef6bb7ce0938d241a877e8cf84d15fb63879be2fe47238c 240b2fe2156b763d3a82fc64159615872db65b65ffb9ba2f3fd5d1ebd6c60f34
|
||||
test/extractor-tests/generated/CallExpr/CallExpr.ql 69d88b3c799f6e81fe53fe04724ed6c1cbfbfcc21023dd62aed3a3f852c6a2aa 0caa94802919d30bf2749d8a1c58545163e2b1cad5490f19158b5e5063806443
|
||||
test/extractor-tests/generated/CallExpr/CallExpr.ql ffb0cf1cb359a6dcbdf792a570c281e2d300779dca2dbc0f324990652adb972f 978a9e6c82758f9e8b334a682a02d6b893a6bf1db3cd85e9535839a9696b09b4
|
||||
test/extractor-tests/generated/CallExpr/CallExpr_getArgList.ql b022e7b6b6db9932e787e37b7760c6a09c91140a0368940374a2c919688e0488 c20849c96b53c96f6f717efff5e8b4c0e900c0ef5d715cfbaf7101c7056ad8f4
|
||||
test/extractor-tests/generated/CallExpr/CallExpr_getAttr.ql 1ace458070875b9ff2c671c2ee18392ea7bf6e51b68ee98d412c8606e8eb8d33 4c35da8255d2975cef4adee15623662441bb8f2e1d73582e4c193d1bc11cc1b5
|
||||
test/extractor-tests/generated/CallExpr/CallExpr_getExpr.ql f680f04423ece282c459d5908e5aa0bc43ca072ff0e605587dfa94210da1d06d f8a709015b8317b8e2dcf3b3ee9370e2c3a655ef7e3c6034b1b90f4d75ebdda2
|
||||
test/extractor-tests/generated/CallExpr/CallExpr_getFunction.ql 060a6c8b5b85c839b14fe96f9e50291a7a0e5662a945f4f337070f782ec76715 e9a1e44433936146d87be939aa160848b9a7d7333c36da601fb7d1a66d71eb59
|
||||
test/extractor-tests/generated/CastExpr/CastExpr.ql 2ffb22ebc6e47953a49162488b3605d36b9d89330b1e71187066e7bbc40a22ad 7621a39d49f573b9862b9a4e1021d53205670ee59b49e4d81128637926f76485
|
||||
test/extractor-tests/generated/CastExpr/CastExpr_getAttr.ql 5d5d98172e495cdb8b5cea9d6588c4c245107b441464e3ffd6c27668af11ab4e 5820bf083aaa4c3275004a2cd9eeecc4b45ab96916cbc0655a1b42611c540715
|
||||
test/extractor-tests/generated/CastExpr/CastExpr_getExpr.ql c37186b8f3e3dab8ae28c0da7263ff7272c40501beb16736ec0fb8990d285e22 59d50d7349234afcf84986b7570db9dcd342e16812f7c46199d4736cdfa5462d
|
||||
@@ -780,10 +779,10 @@ test/extractor-tests/generated/Label/Label.ql 6a92a27d615dd9c380cb9d889eecf827fc
|
||||
test/extractor-tests/generated/Label/Label_getLifetime.ql 3d6ddc3b44182e6432e938d5c1c95e0281575e320d517e431f6bad7748efb93e 56d07e485cb5e4263443eb5a0d62d7d4456bb0c2748331b371e519bfe14d3b81
|
||||
test/extractor-tests/generated/LetElse/LetElse.ql bdf2b17d5efe6b9cb5bb4fcfe854a5fcd72443d39ae1e7981d2a0459c481e394 a14a611d0783ae38d631600c2bde7409f4e739ba2f284314b90ec9a21c23ab3a
|
||||
test/extractor-tests/generated/LetElse/LetElse_getBlockExpr.ql 32c21ad843884944738a735f01e272032a347d1860fa6d27d17652c549f941b0 2bfd8a5e3d42eb1c73eb679ada847dd29f2f0657a0ad8ef15da126e54fff5ef5
|
||||
test/extractor-tests/generated/LetExpr/LetExpr.ql a25072a00cfe1242dc846b38199c000ed7217d33fdd50d2763237fdfda7b9449 8c9367af79d9fbc98ed2fe62450929fa876512f1c999615b5c1ecff082fdc7bc
|
||||
test/extractor-tests/generated/LetExpr/LetExpr.ql c76a0c4aaa73f4064207dacc8d2c649d3a5f8046c0f6e1aae985d2402a342e73 c5abe3845d4975d05c98ee6496732da384cdaca60ed49235776338e6dbe80b3d
|
||||
test/extractor-tests/generated/LetExpr/LetExpr_getAttr.ql 911b143afebaa0a487b13d533f089c5b0eaf336a44a4cab42147c284338484ba 625c91fb6d8c2e3a9f13e5679cc0cd29329c6c2b213d2e1191e23db2b65841dd
|
||||
test/extractor-tests/generated/LetExpr/LetExpr_getExpr.ql ccabfaa15cfc8685e86cb950cb62b7f2fec278f28906ab34deb97b308f160cc4 e0574537d47a77f1be85090970f3e1263858174479002fd4de3f85b777ee4336
|
||||
test/extractor-tests/generated/LetExpr/LetExpr_getPat.ql bc0363f77bc2ba583619ab7d309293ace0ed6a851bfb9b886f75729f96eb40a8 bc0cd9233b7904d8cc7f9021377120f5f4bcc5c7aa28b1b55f17bc738c434d78
|
||||
test/extractor-tests/generated/LetExpr/LetExpr_getScrutinee.ql ee33d3bbaf0ee7cdf9bd7b800e9684b5ac7ce8cf1939378cd460cb0c5ea11742 5d69e727b3e9d1ab4ce9eef702a7b1911515469625056bce87fac1d27ba863e6
|
||||
test/extractor-tests/generated/LetStmt/LetStmt.ql 02db64303bfe87a11a85663e4c79bdabd9ca13693f146c7923b47c4c92850fcc 9ec1326b8bc58b270b178a4c02621b1650d107de7c02a9408d97c59f0d8a6178
|
||||
test/extractor-tests/generated/LetStmt/LetStmt_getAttr.ql 68f69c4c054514140c0f0833a170e9f3facf950bd7af663ac9019f6c88ba0ea7 ca54d25cc052289458c7e34e40f0304bca2c412cecfb407f31279262bd74c15a
|
||||
test/extractor-tests/generated/LetStmt/LetStmt_getInitializer.ql 6a5f0eed3ce3e8cbc57be6ec2b4eed732f00e084108d21a61d9ab28b65e494ca a48b426b97a6c347ad04fe2e592cd25b5c66b2a6a299cbf8c0da03e14304fd70
|
||||
|
||||
5
rust/ql/.gitattributes
generated
vendored
5
rust/ql/.gitattributes
generated
vendored
@@ -300,7 +300,6 @@
|
||||
/lib/codeql/rust/elements/internal/ParamBaseImpl.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/ParamConstructor.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/ParamListConstructor.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/ParamListImpl.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/ParenExprConstructor.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/ParenPatConstructor.qll linguist-generated
|
||||
/lib/codeql/rust/elements/internal/ParenTypeConstructor.qll linguist-generated
|
||||
@@ -640,7 +639,7 @@
|
||||
/test/extractor-tests/generated/CallExpr/CallExpr.ql linguist-generated
|
||||
/test/extractor-tests/generated/CallExpr/CallExpr_getArgList.ql linguist-generated
|
||||
/test/extractor-tests/generated/CallExpr/CallExpr_getAttr.ql linguist-generated
|
||||
/test/extractor-tests/generated/CallExpr/CallExpr_getExpr.ql linguist-generated
|
||||
/test/extractor-tests/generated/CallExpr/CallExpr_getFunction.ql linguist-generated
|
||||
/test/extractor-tests/generated/CastExpr/CastExpr.ql linguist-generated
|
||||
/test/extractor-tests/generated/CastExpr/CastExpr_getAttr.ql linguist-generated
|
||||
/test/extractor-tests/generated/CastExpr/CastExpr_getExpr.ql linguist-generated
|
||||
@@ -784,8 +783,8 @@
|
||||
/test/extractor-tests/generated/LetElse/LetElse_getBlockExpr.ql linguist-generated
|
||||
/test/extractor-tests/generated/LetExpr/LetExpr.ql linguist-generated
|
||||
/test/extractor-tests/generated/LetExpr/LetExpr_getAttr.ql linguist-generated
|
||||
/test/extractor-tests/generated/LetExpr/LetExpr_getExpr.ql linguist-generated
|
||||
/test/extractor-tests/generated/LetExpr/LetExpr_getPat.ql linguist-generated
|
||||
/test/extractor-tests/generated/LetExpr/LetExpr_getScrutinee.ql linguist-generated
|
||||
/test/extractor-tests/generated/LetStmt/LetStmt.ql linguist-generated
|
||||
/test/extractor-tests/generated/LetStmt/LetStmt_getAttr.ql linguist-generated
|
||||
/test/extractor-tests/generated/LetStmt/LetStmt_getInitializer.ql linguist-generated
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
private import codeql.rust.dataflow.DataFlow
|
||||
private import codeql.threatmodels.ThreatModels
|
||||
private import codeql.rust.Frameworks
|
||||
|
||||
/**
|
||||
* A data flow source for a specific threat-model.
|
||||
@@ -46,6 +47,63 @@ class ActiveThreatModelSource extends ThreatModelSource {
|
||||
ActiveThreatModelSource() { currentThreatModel(this.getThreatModel()) }
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow source corresponding to the program's command line arguments or path.
|
||||
*/
|
||||
final class CommandLineArgsSource = CommandLineArgsSource::Range;
|
||||
|
||||
/**
|
||||
* Provides a class for modeling new sources for the program's command line arguments or path.
|
||||
*/
|
||||
module CommandLineArgsSource {
|
||||
/**
|
||||
* A data flow source corresponding to the program's command line arguments or path.
|
||||
*/
|
||||
abstract class Range extends ThreatModelSource::Range {
|
||||
override string getThreatModel() { result = "commandargs" }
|
||||
|
||||
override string getSourceType() { result = "CommandLineArgs" }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow source corresponding to the program's environment.
|
||||
*/
|
||||
final class EnvironmentSource = EnvironmentSource::Range;
|
||||
|
||||
/**
|
||||
* Provides a class for modeling new sources for the program's environment.
|
||||
*/
|
||||
module EnvironmentSource {
|
||||
/**
|
||||
* A data flow source corresponding to the program's environment.
|
||||
*/
|
||||
abstract class Range extends ThreatModelSource::Range {
|
||||
override string getThreatModel() { result = "environment" }
|
||||
|
||||
override string getSourceType() { result = "EnvironmentSource" }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data flow source for remote (network) data.
|
||||
*/
|
||||
final class RemoteSource = RemoteSource::Range;
|
||||
|
||||
/**
|
||||
* Provides a class for modeling new sources of remote (network) data.
|
||||
*/
|
||||
module RemoteSource {
|
||||
/**
|
||||
* A data flow source for remote (network) data.
|
||||
*/
|
||||
abstract class Range extends ThreatModelSource::Range {
|
||||
override string getThreatModel() { result = "remote" }
|
||||
|
||||
override string getSourceType() { result = "RemoteSource" }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data-flow node that constructs a SQL statement.
|
||||
*
|
||||
|
||||
6
rust/ql/lib/codeql/rust/Frameworks.qll
Normal file
6
rust/ql/lib/codeql/rust/Frameworks.qll
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* This file imports all models of frameworks and libraries.
|
||||
*/
|
||||
|
||||
private import codeql.rust.frameworks.Reqwest
|
||||
private import codeql.rust.frameworks.stdlib.Env
|
||||
@@ -187,9 +187,37 @@ final class RecordExprCfgNode extends Nodes::RecordExprCfgNode {
|
||||
|
||||
RecordExprCfgNode() { node = this.getRecordExpr() }
|
||||
|
||||
/** Gets the `i`th record expression. */
|
||||
ExprCfgNode getExpr(int i) {
|
||||
any(ChildMapping mapping)
|
||||
.hasCfgChild(node, node.getRecordExprFieldList().getField(i).getExpr(), this, result)
|
||||
/** Gets the record expression for the field `field`. */
|
||||
pragma[nomagic]
|
||||
ExprCfgNode getFieldExpr(string field) {
|
||||
exists(RecordExprField ref |
|
||||
ref = node.getRecordExprFieldList().getAField() and
|
||||
any(ChildMapping mapping).hasCfgChild(node, ref.getExpr(), this, result) and
|
||||
field = ref.getNameRef().getText()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A record pattern. For example:
|
||||
* ```rust
|
||||
* match x {
|
||||
* Foo { a: 1, b: 2 } => "ok",
|
||||
* Foo { .. } => "fail",
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
final class RecordPatCfgNode extends Nodes::RecordPatCfgNode {
|
||||
private RecordPatChildMapping node;
|
||||
|
||||
RecordPatCfgNode() { node = this.getRecordPat() }
|
||||
|
||||
/** Gets the record pattern for the field `field`. */
|
||||
PatCfgNode getFieldPat(string field) {
|
||||
exists(RecordPatField rpf |
|
||||
rpf = node.getRecordPatFieldList().getAField() and
|
||||
any(ChildMapping mapping).hasCfgChild(node, rpf.getPat(), this, result) and
|
||||
field = rpf.getNameRef().getText()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,12 @@ class RecordExprChildMapping extends ParentAstNode, RecordExpr {
|
||||
}
|
||||
}
|
||||
|
||||
class RecordPatChildMapping extends ParentAstNode, RecordPat {
|
||||
override predicate relevantChild(AstNode child) {
|
||||
child = this.getRecordPatFieldList().getAField().getPat()
|
||||
}
|
||||
}
|
||||
|
||||
class FormatArgsExprChildMapping extends ParentAstNode, CfgImpl::ExprTrees::FormatArgsExprTree {
|
||||
override predicate relevantChild(AstNode child) { child = this.getChildNode(_) }
|
||||
}
|
||||
|
||||
@@ -313,7 +313,7 @@ module ExprTrees {
|
||||
|
||||
class CallExprTree extends StandardPostOrderTree instanceof CallExpr {
|
||||
override AstNode getChildNode(int i) {
|
||||
i = 0 and result = super.getExpr()
|
||||
i = 0 and result = super.getFunction()
|
||||
or
|
||||
result = super.getArgList().getArg(i - 1)
|
||||
}
|
||||
@@ -410,7 +410,7 @@ module ExprTrees {
|
||||
class LetExprTree extends StandardPreOrderTree, LetExpr {
|
||||
override AstNode getChildNode(int i) {
|
||||
i = 0 and
|
||||
result = this.getExpr()
|
||||
result = this.getScrutinee()
|
||||
or
|
||||
i = 1 and
|
||||
result = this.getPat()
|
||||
|
||||
@@ -570,7 +570,7 @@ module MakeCfgNodes<LocationSig Loc, InputSig<Loc> Input> {
|
||||
override predicate relevantChild(AstNode child) {
|
||||
none()
|
||||
or
|
||||
child = this.getExpr()
|
||||
child = this.getFunction()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -592,16 +592,16 @@ module MakeCfgNodes<LocationSig Loc, InputSig<Loc> Input> {
|
||||
CallExpr getCallExpr() { result = node }
|
||||
|
||||
/**
|
||||
* Gets the expression of this call expression, if it exists.
|
||||
* Gets the function of this call expression, if it exists.
|
||||
*/
|
||||
ExprCfgNode getExpr() {
|
||||
any(ChildMapping mapping).hasCfgChild(node, node.getExpr(), this, result)
|
||||
ExprCfgNode getFunction() {
|
||||
any(ChildMapping mapping).hasCfgChild(node, node.getFunction(), this, result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `getExpr()` exists.
|
||||
* Holds if `getFunction()` exists.
|
||||
*/
|
||||
predicate hasExpr() { exists(this.getExpr()) }
|
||||
predicate hasFunction() { exists(this.getFunction()) }
|
||||
}
|
||||
|
||||
final private class ParentCallExprBase extends ParentAstNode, CallExprBase {
|
||||
@@ -1245,7 +1245,7 @@ module MakeCfgNodes<LocationSig Loc, InputSig<Loc> Input> {
|
||||
override predicate relevantChild(AstNode child) {
|
||||
none()
|
||||
or
|
||||
child = this.getExpr()
|
||||
child = this.getScrutinee()
|
||||
or
|
||||
child = this.getPat()
|
||||
}
|
||||
@@ -1283,16 +1283,16 @@ module MakeCfgNodes<LocationSig Loc, InputSig<Loc> Input> {
|
||||
int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) }
|
||||
|
||||
/**
|
||||
* Gets the expression of this let expression, if it exists.
|
||||
* Gets the scrutinee of this let expression, if it exists.
|
||||
*/
|
||||
ExprCfgNode getExpr() {
|
||||
any(ChildMapping mapping).hasCfgChild(node, node.getExpr(), this, result)
|
||||
ExprCfgNode getScrutinee() {
|
||||
any(ChildMapping mapping).hasCfgChild(node, node.getScrutinee(), this, result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `getExpr()` exists.
|
||||
* Holds if `getScrutinee()` exists.
|
||||
*/
|
||||
predicate hasExpr() { exists(this.getExpr()) }
|
||||
predicate hasScrutinee() { exists(this.getScrutinee()) }
|
||||
|
||||
/**
|
||||
* Gets the pat of this let expression, if it exists.
|
||||
@@ -3211,14 +3211,14 @@ module MakeCfgNodes<LocationSig Loc, InputSig<Loc> Input> {
|
||||
cfgNode
|
||||
)
|
||||
or
|
||||
pred = "getExpr" and
|
||||
pred = "getFunction" and
|
||||
parent =
|
||||
any(Nodes::CallExprCfgNode cfgNode, CallExpr astNode |
|
||||
astNode = cfgNode.getCallExpr() and
|
||||
child = getDesugared(astNode.getExpr()) and
|
||||
child = getDesugared(astNode.getFunction()) and
|
||||
i = -1 and
|
||||
hasCfgNode(child) and
|
||||
not child = cfgNode.getExpr().getAstNode()
|
||||
not child = cfgNode.getFunction().getAstNode()
|
||||
|
|
||||
cfgNode
|
||||
)
|
||||
@@ -3355,14 +3355,14 @@ module MakeCfgNodes<LocationSig Loc, InputSig<Loc> Input> {
|
||||
cfgNode
|
||||
)
|
||||
or
|
||||
pred = "getExpr" and
|
||||
pred = "getScrutinee" and
|
||||
parent =
|
||||
any(Nodes::LetExprCfgNode cfgNode, LetExpr astNode |
|
||||
astNode = cfgNode.getLetExpr() and
|
||||
child = getDesugared(astNode.getExpr()) and
|
||||
child = getDesugared(astNode.getScrutinee()) and
|
||||
i = -1 and
|
||||
hasCfgNode(child) and
|
||||
not child = cfgNode.getExpr().getAstNode()
|
||||
not child = cfgNode.getScrutinee().getAstNode()
|
||||
|
|
||||
cfgNode
|
||||
)
|
||||
|
||||
@@ -19,6 +19,12 @@ module DataFlow {
|
||||
|
||||
final class PostUpdateNode = Node::PostUpdateNode;
|
||||
|
||||
final class Content = DataFlowImpl::Content;
|
||||
|
||||
final class VariantContent = DataFlowImpl::VariantContent;
|
||||
|
||||
final class ContentSet = DataFlowImpl::ContentSet;
|
||||
|
||||
/**
|
||||
* Holds if data flows from `nodeFrom` to `nodeTo` in exactly one local
|
||||
* (intra-procedural) step.
|
||||
|
||||
@@ -115,6 +115,11 @@ module Node {
|
||||
*/
|
||||
ExprCfgNode asExpr() { none() }
|
||||
|
||||
/**
|
||||
* Gets the pattern that corresponds to this node, if any.
|
||||
*/
|
||||
PatCfgNode asPat() { none() }
|
||||
|
||||
/** Gets the enclosing callable. */
|
||||
DataFlowCallable getEnclosingCallable() { result = TCfgScope(this.getCfgScope()) }
|
||||
|
||||
@@ -177,8 +182,7 @@ module Node {
|
||||
|
||||
PatNode() { this = TPatNode(n) }
|
||||
|
||||
/** Gets the `PatCfgNode` in the CFG that this node corresponds to. */
|
||||
PatCfgNode getPat() { result = n }
|
||||
override PatCfgNode asPat() { result = n }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -322,8 +326,7 @@ module LocalFlow {
|
||||
nodeFrom.(Node::AstCfgFlowNode).getCfgNode() =
|
||||
nodeTo.(Node::SsaNode).getDefinitionExt().(Ssa::WriteDefinition).getControlFlowNode()
|
||||
or
|
||||
nodeFrom.(Node::ParameterNode).getParameter().(ParamCfgNode).getPat() =
|
||||
nodeTo.(Node::PatNode).getPat()
|
||||
nodeFrom.(Node::ParameterNode).getParameter().(ParamCfgNode).getPat() = nodeTo.asPat()
|
||||
or
|
||||
SsaFlow::localFlowStep(_, nodeFrom, nodeTo, _)
|
||||
or
|
||||
@@ -331,18 +334,165 @@ module LocalFlow {
|
||||
a.getRhs() = nodeFrom.getCfgNode() and
|
||||
a.getLhs() = nodeTo.getCfgNode()
|
||||
)
|
||||
or
|
||||
exists(MatchExprCfgNode match |
|
||||
nodeFrom.asExpr() = match.getScrutinee() and
|
||||
nodeTo.asPat() = match.getArmPat(_)
|
||||
)
|
||||
or
|
||||
nodeFrom.asPat().(OrPatCfgNode).getAPat() = nodeTo.asPat()
|
||||
}
|
||||
}
|
||||
|
||||
private class DataFlowCallableAlias = DataFlowCallable;
|
||||
private import codeql.util.Option
|
||||
|
||||
private class ReturnKindAlias = ReturnKind;
|
||||
private class CrateOrigin extends string {
|
||||
CrateOrigin() {
|
||||
this = [any(Item i).getCrateOrigin(), any(Resolvable r).getResolvedCrateOrigin()]
|
||||
}
|
||||
}
|
||||
|
||||
private class DataFlowCallAlias = DataFlowCall;
|
||||
private class CrateOriginOption = Option<CrateOrigin>::Option;
|
||||
|
||||
private class ParameterPositionAlias = ParameterPosition;
|
||||
pragma[nomagic]
|
||||
private predicate hasExtendedCanonicalPath(Item i, CrateOriginOption crate, string path) {
|
||||
path = i.getExtendedCanonicalPath() and
|
||||
(
|
||||
crate.asSome() = i.getCrateOrigin()
|
||||
or
|
||||
crate.isNone() and
|
||||
not i.hasCrateOrigin()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate variantHasExtendedCanonicalPath(
|
||||
Enum e, Variant v, CrateOriginOption crate, string path, string name
|
||||
) {
|
||||
hasExtendedCanonicalPath(e, crate, path) and
|
||||
v = e.getVariantList().getAVariant() and
|
||||
name = v.getName().getText()
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate resolveExtendedCanonicalPath(Resolvable r, CrateOriginOption crate, string path) {
|
||||
path = r.getResolvedPath() and
|
||||
(
|
||||
crate.asSome() = r.getResolvedCrateOrigin()
|
||||
or
|
||||
crate.isNone() and
|
||||
not r.hasResolvedCrateOrigin()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A path to a value contained in an object. For example a field name of a struct.
|
||||
*/
|
||||
abstract class Content extends TContent {
|
||||
/** Gets a textual representation of this content. */
|
||||
abstract string toString();
|
||||
}
|
||||
|
||||
/** A canonical path pointing to an enum variant. */
|
||||
private class VariantCanonicalPath extends MkVariantCanonicalPath {
|
||||
CrateOriginOption crate;
|
||||
string path;
|
||||
string name;
|
||||
|
||||
VariantCanonicalPath() { this = MkVariantCanonicalPath(crate, path, name) }
|
||||
|
||||
/** Gets the underlying variant. */
|
||||
Variant getVariant() { variantHasExtendedCanonicalPath(_, result, crate, path, name) }
|
||||
|
||||
string toString() { result = name }
|
||||
|
||||
Location getLocation() { result = this.getVariant().getLocation() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A variant of an `enum`. In addition to the variant itself, this also includes the
|
||||
* position (for tuple variants) or the field name (for record variants).
|
||||
*/
|
||||
abstract class VariantContent extends Content { }
|
||||
|
||||
/** A tuple variant. */
|
||||
private class VariantPositionContent extends VariantContent, TVariantPositionContent {
|
||||
private VariantCanonicalPath v;
|
||||
private int pos_;
|
||||
|
||||
VariantPositionContent() { this = TVariantPositionContent(v, pos_) }
|
||||
|
||||
VariantCanonicalPath getVariantCanonicalPath(int pos) { result = v and pos = pos_ }
|
||||
|
||||
final override string toString() {
|
||||
// only print indices when the arity is > 1
|
||||
if exists(TVariantPositionContent(v, 1))
|
||||
then result = v.toString() + "(" + pos_ + ")"
|
||||
else result = v.toString()
|
||||
}
|
||||
}
|
||||
|
||||
/** A record variant. */
|
||||
private class VariantFieldContent extends VariantContent, TVariantFieldContent {
|
||||
private VariantCanonicalPath v;
|
||||
private string field_;
|
||||
|
||||
VariantFieldContent() { this = TVariantFieldContent(v, field_) }
|
||||
|
||||
VariantCanonicalPath getVariantCanonicalPath(string field) { result = v and field = field_ }
|
||||
|
||||
final override string toString() {
|
||||
// only print field when the arity is > 1
|
||||
if strictcount(string f | exists(TVariantFieldContent(v, f))) > 1
|
||||
then result = v.toString() + "{" + field_ + "}"
|
||||
else result = v.toString()
|
||||
}
|
||||
}
|
||||
|
||||
/** A value that represents a set of `Content`s. */
|
||||
abstract class ContentSet extends TContentSet {
|
||||
/** Gets a textual representation of this element. */
|
||||
abstract string toString();
|
||||
|
||||
/** Gets a content that may be stored into when storing into this set. */
|
||||
abstract Content getAStoreContent();
|
||||
|
||||
/** Gets a content that may be read from when reading from this set. */
|
||||
abstract Content getAReadContent();
|
||||
}
|
||||
|
||||
final private class SingletonContentSet extends ContentSet, TSingletonContentSet {
|
||||
private Content c;
|
||||
|
||||
SingletonContentSet() { this = TSingletonContentSet(c) }
|
||||
|
||||
Content getContent() { result = c }
|
||||
|
||||
override string toString() { result = c.toString() }
|
||||
|
||||
override Content getAStoreContent() { result = c }
|
||||
|
||||
override Content getAReadContent() { result = c }
|
||||
}
|
||||
|
||||
// Defines a set of aliases needed for the `RustDataFlow` module
|
||||
private module Aliases {
|
||||
class DataFlowCallableAlias = DataFlowCallable;
|
||||
|
||||
class ReturnKindAlias = ReturnKind;
|
||||
|
||||
class DataFlowCallAlias = DataFlowCall;
|
||||
|
||||
class ParameterPositionAlias = ParameterPosition;
|
||||
|
||||
class ContentAlias = Content;
|
||||
|
||||
class ContentSetAlias = ContentSet;
|
||||
}
|
||||
|
||||
module RustDataFlow implements InputSig<Location> {
|
||||
private import Aliases
|
||||
|
||||
/**
|
||||
* An element, viewed as a node in a data flow graph. Either an expression
|
||||
* (`ExprNode`) or a parameter (`ParameterNode`).
|
||||
@@ -388,55 +538,19 @@ module RustDataFlow implements InputSig<Location> {
|
||||
|
||||
final class ReturnKind = ReturnKindAlias;
|
||||
|
||||
private import codeql.util.Option
|
||||
|
||||
private class CrateOrigin extends string {
|
||||
CrateOrigin() {
|
||||
this = [any(Item i).getCrateOrigin(), any(Resolvable r).getResolvedCrateOrigin()]
|
||||
}
|
||||
}
|
||||
|
||||
private class CrateOriginOption = Option<CrateOrigin>::Option;
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate hasExtendedCanonicalPath(
|
||||
DataFlowCallable c, CrateOriginOption crate, string path
|
||||
) {
|
||||
exists(Item i |
|
||||
i = c.asCfgScope() and
|
||||
path = i.getExtendedCanonicalPath()
|
||||
|
|
||||
crate.asSome() = i.getCrateOrigin()
|
||||
or
|
||||
crate.isNone() and
|
||||
not i.hasCrateOrigin()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate resolvesExtendedCanonicalPath(
|
||||
DataFlowCall c, CrateOriginOption crate, string path
|
||||
) {
|
||||
exists(Resolvable r |
|
||||
path = r.getResolvedPath() and
|
||||
(
|
||||
r = c.asMethodCallExprCfgNode().getExpr()
|
||||
or
|
||||
r = c.asCallExprCfgNode().getExpr().(PathExprCfgNode).getPath()
|
||||
)
|
||||
|
|
||||
crate.asSome() = r.getResolvedCrateOrigin()
|
||||
or
|
||||
crate.isNone() and
|
||||
not r.hasResolvedCrateOrigin()
|
||||
)
|
||||
private Resolvable getCallResolvable(CallExprBase call) {
|
||||
result = call.(MethodCallExpr)
|
||||
or
|
||||
result = call.(CallExpr).getFunction().(PathExpr).getPath()
|
||||
}
|
||||
|
||||
/** Gets a viable implementation of the target of the given `Call`. */
|
||||
DataFlowCallable viableCallable(DataFlowCall call) {
|
||||
exists(string path, CrateOriginOption crate |
|
||||
hasExtendedCanonicalPath(result, crate, path) and
|
||||
resolvesExtendedCanonicalPath(call, crate, path)
|
||||
exists(Resolvable r, string path, CrateOriginOption crate |
|
||||
hasExtendedCanonicalPath(result.asCfgScope(), crate, path) and
|
||||
r = getCallResolvable(call.asCallBaseExprCfgNode().getExpr()) and
|
||||
resolveExtendedCanonicalPath(r, crate, path)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -450,30 +564,23 @@ module RustDataFlow implements InputSig<Location> {
|
||||
|
||||
// NOTE: For now we use the type `Unit` and do not benefit from type
|
||||
// information in the data flow analysis.
|
||||
final class DataFlowType = Unit;
|
||||
final class DataFlowType extends Unit {
|
||||
string toString() { result = "" }
|
||||
}
|
||||
|
||||
predicate compatibleTypes(DataFlowType t1, DataFlowType t2) { any() }
|
||||
|
||||
predicate typeStrongerThan(DataFlowType t1, DataFlowType t2) { none() }
|
||||
|
||||
final class Content = Void;
|
||||
class Content = ContentAlias;
|
||||
|
||||
class ContentSet = ContentSetAlias;
|
||||
|
||||
predicate forceHighPrecision(Content c) { none() }
|
||||
|
||||
class ContentSet extends TContentSet {
|
||||
/** Gets a textual representation of this element. */
|
||||
string toString() { result = "ContentSet" }
|
||||
final class ContentApprox = Content; // TODO: Implement if needed
|
||||
|
||||
/** Gets a content that may be stored into when storing into this set. */
|
||||
Content getAStoreContent() { none() }
|
||||
|
||||
/** Gets a content that may be read from when reading from this set. */
|
||||
Content getAReadContent() { none() }
|
||||
}
|
||||
|
||||
final class ContentApprox = Void;
|
||||
|
||||
ContentApprox getContentApprox(Content c) { any() }
|
||||
ContentApprox getContentApprox(Content c) { result = c }
|
||||
|
||||
class ParameterPosition = ParameterPositionAlias;
|
||||
|
||||
@@ -501,19 +608,95 @@ module RustDataFlow implements InputSig<Location> {
|
||||
*/
|
||||
predicate jumpStep(Node node1, Node node2) { none() }
|
||||
|
||||
/** Holds if path `p` resolves to variant `v`. */
|
||||
private predicate pathResolveToVariantCanonicalPath(Path p, VariantCanonicalPath v) {
|
||||
exists(CrateOriginOption crate, string path |
|
||||
resolveExtendedCanonicalPath(p.getQualifier(), crate, path) and
|
||||
v = MkVariantCanonicalPath(crate, path, p.getPart().getNameRef().getText())
|
||||
)
|
||||
or
|
||||
// TODO: Remove once library types are extracted
|
||||
not p.hasQualifier() and
|
||||
v = MkVariantCanonicalPath(_, "crate::std::option::Option", p.getPart().getNameRef().getText())
|
||||
or
|
||||
// TODO: Remove once library types are extracted
|
||||
not p.hasQualifier() and
|
||||
v = MkVariantCanonicalPath(_, "crate::std::result::Result", p.getPart().getNameRef().getText())
|
||||
}
|
||||
|
||||
/** Holds if `p` destructs an enum variant `v`. */
|
||||
pragma[nomagic]
|
||||
private predicate tupleVariantDestruction(TupleStructPat p, VariantCanonicalPath v) {
|
||||
pathResolveToVariantCanonicalPath(p.getPath(), v)
|
||||
}
|
||||
|
||||
/** Holds if `p` destructs an enum variant `v`. */
|
||||
pragma[nomagic]
|
||||
private predicate recordVariantDestruction(RecordPat p, VariantCanonicalPath v) {
|
||||
pathResolveToVariantCanonicalPath(p.getPath(), v)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* value ends up in `node2`.
|
||||
*/
|
||||
predicate readStep(Node node1, ContentSet c, Node node2) { none() }
|
||||
predicate readStep(Node node1, ContentSet cs, Node node2) {
|
||||
exists(Content c | c = cs.(SingletonContentSet).getContent() |
|
||||
exists(TupleStructPatCfgNode pat, int pos |
|
||||
pat = node1.asPat() and
|
||||
tupleVariantDestruction(pat.getPat(),
|
||||
c.(VariantPositionContent).getVariantCanonicalPath(pos)) and
|
||||
node2.asPat() = pat.getField(pos)
|
||||
)
|
||||
or
|
||||
exists(RecordPatCfgNode pat, string field |
|
||||
pat = node1.asPat() and
|
||||
recordVariantDestruction(pat.getPat(),
|
||||
c.(VariantFieldContent).getVariantCanonicalPath(field)) and
|
||||
node2.asPat() = pat.getFieldPat(field)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `ce` constructs an enum value of type `v`. */
|
||||
pragma[nomagic]
|
||||
private predicate tupleVariantConstruction(CallExpr ce, VariantCanonicalPath v) {
|
||||
pathResolveToVariantCanonicalPath(ce.getFunction().(PathExpr).getPath(), v)
|
||||
}
|
||||
|
||||
/** Holds if `re` constructs an enum value of type `v`. */
|
||||
pragma[nomagic]
|
||||
private predicate recordVariantConstruction(RecordExpr re, VariantCanonicalPath v) {
|
||||
pathResolveToVariantCanonicalPath(re.getPath(), v)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* contains the value of `node1`.
|
||||
*/
|
||||
predicate storeStep(Node node1, ContentSet c, Node node2) { none() }
|
||||
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
|
||||
)
|
||||
or
|
||||
node2.asExpr() =
|
||||
any(RecordExprCfgNode re, string field |
|
||||
recordVariantConstruction(re.getRecordExpr(),
|
||||
c.(VariantFieldContent).getVariantCanonicalPath(field)) and
|
||||
node1.asExpr() = re.getFieldExpr(field)
|
||||
|
|
||||
re
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if values stored inside content `c` are cleared at node `n`. For example,
|
||||
@@ -580,8 +763,6 @@ module RustDataFlow implements InputSig<Location> {
|
||||
class DataFlowSecondLevelScope = Void;
|
||||
}
|
||||
|
||||
final class ContentSet = RustDataFlow::ContentSet;
|
||||
|
||||
import MakeImpl<Location, RustDataFlow>
|
||||
|
||||
/** A collection of cached types and predicates to be evaluated in the same stage. */
|
||||
@@ -598,14 +779,6 @@ private module Cached {
|
||||
cached
|
||||
newtype TDataFlowCall = TCall(CallExprBaseCfgNode c)
|
||||
|
||||
cached
|
||||
newtype TOptionalContentSet =
|
||||
TAnyElementContent() or
|
||||
TAnyContent()
|
||||
|
||||
cached
|
||||
class TContentSet = TAnyElementContent or TAnyContent;
|
||||
|
||||
cached
|
||||
newtype TDataFlowCallable = TCfgScope(CfgScope scope)
|
||||
|
||||
@@ -621,6 +794,42 @@ private module Cached {
|
||||
i in [0 .. max([any(ParamList l).getNumberOfParams(), any(ArgList l).getNumberOfArgs()]) - 1]
|
||||
} or
|
||||
TSelfParameterPosition()
|
||||
|
||||
cached
|
||||
newtype TVariantCanonicalPath =
|
||||
MkVariantCanonicalPath(CrateOriginOption crate, string path, string name) {
|
||||
variantHasExtendedCanonicalPath(_, _, crate, path, name)
|
||||
or
|
||||
// TODO: Remove once library types are extracted
|
||||
crate.isNone() and
|
||||
path = "crate::std::option::Option" and
|
||||
name = "Some"
|
||||
or
|
||||
// TODO: Remove once library types are extracted
|
||||
crate.isNone() and
|
||||
path = "crate::std::result::Result" and
|
||||
name = ["Ok", "Err"]
|
||||
}
|
||||
|
||||
cached
|
||||
newtype TContent =
|
||||
TVariantPositionContent(VariantCanonicalPath v, int pos) {
|
||||
pos in [0 .. v.getVariant().getFieldList().(TupleFieldList).getNumberOfFields() - 1]
|
||||
or
|
||||
// TODO: Remove once library types are extracted
|
||||
v = MkVariantCanonicalPath(_, "crate::std::option::Option", "Some") and
|
||||
pos = 0
|
||||
or
|
||||
// TODO: Remove once library types are extracted
|
||||
v = MkVariantCanonicalPath(_, "crate::std::result::Result", ["Ok", "Err"]) and
|
||||
pos = 0
|
||||
} or
|
||||
TVariantFieldContent(VariantCanonicalPath v, string field) {
|
||||
field = v.getVariant().getFieldList().(RecordFieldList).getAField().getName().getText()
|
||||
}
|
||||
|
||||
cached
|
||||
newtype TContentSet = TSingletonContentSet(Content c)
|
||||
}
|
||||
|
||||
import Cached
|
||||
|
||||
@@ -24,6 +24,8 @@ predicate variableWrite(AstNode write, Variable v) {
|
||||
not isUnitializedLet(pat, v)
|
||||
)
|
||||
or
|
||||
exists(SelfParam self | self = write and self = v.getSelfParam())
|
||||
or
|
||||
exists(VariableAccess access |
|
||||
access = write and
|
||||
access.getVariable() = v
|
||||
@@ -477,7 +479,7 @@ private module DataFlowIntegrationInput implements Impl::DataFlowIntegrationInpu
|
||||
none() // handled in `DataFlowImpl.qll` instead
|
||||
}
|
||||
|
||||
class Parameter = CfgNodes::ParamCfgNode;
|
||||
class Parameter = CfgNodes::ParamBaseCfgNode;
|
||||
|
||||
/** Holds if SSA definition `def` initializes parameter `p` at function entry. */
|
||||
predicate ssaDefInitializesParam(WriteDefinition def, Parameter p) {
|
||||
|
||||
@@ -23,6 +23,6 @@ module Impl {
|
||||
* ```
|
||||
*/
|
||||
class CallExpr extends Generated::CallExpr {
|
||||
override string toString() { result = this.getExpr().toAbbreviatedString() + "(...)" }
|
||||
override string toString() { result = this.getFunction().toAbbreviatedString() + "(...)" }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ module Impl {
|
||||
or
|
||||
index = 1 and result = this.getPat().toAbbreviatedString()
|
||||
or
|
||||
index = 2 and result = "= " + this.getExpr().toAbbreviatedString()
|
||||
index = 2 and result = "= " + this.getScrutinee().toAbbreviatedString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// generated by codegen, remove this comment if you wish to edit this file
|
||||
/**
|
||||
* This module provides a hand-modifiable wrapper around the generated class `ParamList`.
|
||||
*
|
||||
@@ -12,11 +11,17 @@ private import codeql.rust.elements.internal.generated.ParamList
|
||||
* be referenced directly.
|
||||
*/
|
||||
module Impl {
|
||||
// the following QLdoc is generated: if you need to edit it, do it in the schema file
|
||||
/**
|
||||
* A ParamList. For example:
|
||||
* ```rust
|
||||
* todo!()
|
||||
* ```
|
||||
*/
|
||||
class ParamList extends Generated::ParamList { }
|
||||
class ParamList extends Generated::ParamList {
|
||||
/**
|
||||
* Gets any of the parameters of this parameter list.
|
||||
*/
|
||||
final ParamBase getAParamBase() { result = this.getParam(_) or result = this.getSelfParam() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,24 +73,35 @@ module Impl {
|
||||
* where `definingNode` is the entire `Either::Left(x) | Either::Right(x)`
|
||||
* pattern.
|
||||
*/
|
||||
private predicate variableDecl(AstNode definingNode, IdentPat p, string name) {
|
||||
(
|
||||
definingNode = getOutermostEnclosingOrPat(p)
|
||||
or
|
||||
not exists(getOutermostEnclosingOrPat(p)) and
|
||||
definingNode = p.getName()
|
||||
) and
|
||||
name = p.getName().getText() and
|
||||
// exclude for now anything starting with an uppercase character, which may be a reference to
|
||||
// an enum constant (e.g. `None`). This excludes static and constant variables (UPPERCASE),
|
||||
// which we don't appear to recognize yet anyway. This also assumes programmers follow the
|
||||
// naming guidelines, which they generally do, but they're not enforced.
|
||||
not name.charAt(0).isUppercase() and
|
||||
// exclude parameters from functions without a body as these are trait method declarations
|
||||
// without implementations
|
||||
not exists(Function f | not f.hasBody() and f.getParamList().getAParam().getPat() = p) and
|
||||
// exclude parameters from function pointer types (e.g. `x` in `fn(x: i32) -> i32`)
|
||||
not exists(FnPtrType fp | fp.getParamList().getParam(_).getPat() = p)
|
||||
private predicate variableDecl(AstNode definingNode, AstNode p, string name) {
|
||||
p =
|
||||
any(SelfParam sp |
|
||||
definingNode = sp.getName() and
|
||||
name = sp.getName().getText() and
|
||||
// exclude self parameters from functions without a body as these are
|
||||
// trait method declarations without implementations
|
||||
not exists(Function f | not f.hasBody() and f.getParamList().getSelfParam() = sp)
|
||||
)
|
||||
or
|
||||
p =
|
||||
any(IdentPat pat |
|
||||
(
|
||||
definingNode = getOutermostEnclosingOrPat(pat)
|
||||
or
|
||||
not exists(getOutermostEnclosingOrPat(pat)) and definingNode = pat.getName()
|
||||
) and
|
||||
name = pat.getName().getText() and
|
||||
// exclude for now anything starting with an uppercase character, which may be a reference to
|
||||
// an enum constant (e.g. `None`). This excludes static and constant variables (UPPERCASE),
|
||||
// which we don't appear to recognize yet anyway. This also assumes programmers follow the
|
||||
// naming guidelines, which they generally do, but they're not enforced.
|
||||
not name.charAt(0).isUppercase() and
|
||||
// exclude parameters from functions without a body as these are trait method declarations
|
||||
// without implementations
|
||||
not exists(Function f | not f.hasBody() and f.getParamList().getAParam().getPat() = pat) and
|
||||
// exclude parameters from function pointer types (e.g. `x` in `fn(x: i32) -> i32`)
|
||||
not exists(FnPtrType fp | fp.getParamList().getParam(_).getPat() = pat)
|
||||
)
|
||||
}
|
||||
|
||||
/** A variable. */
|
||||
@@ -112,8 +123,11 @@ module Impl {
|
||||
/** Gets an access to this variable. */
|
||||
VariableAccess getAnAccess() { result.getVariable() = this }
|
||||
|
||||
/** Gets the `self` parameter that declares this variable, if one exists. */
|
||||
SelfParam getSelfParam() { variableDecl(definingNode, result, name) }
|
||||
|
||||
/**
|
||||
* Gets the pattern that declares this variable.
|
||||
* Gets the pattern that declares this variable, if any.
|
||||
*
|
||||
* Normally, the pattern is unique, except when introduced in an or pattern:
|
||||
*
|
||||
@@ -135,7 +149,9 @@ module Impl {
|
||||
predicate isCaptured() { this.getAnAccess().isCapture() }
|
||||
|
||||
/** Gets the parameter that introduces this variable, if any. */
|
||||
Param getParameter() { parameterDeclInScope(result, this, _) }
|
||||
ParamBase getParameter() {
|
||||
result = this.getSelfParam() or result.(Param).getPat() = getAVariablePatAncestor(this)
|
||||
}
|
||||
|
||||
/** Hold is this variable is mutable. */
|
||||
predicate isMutable() { this.getPat().isMut() }
|
||||
@@ -144,7 +160,11 @@ module Impl {
|
||||
predicate isImmutable() { not this.isMutable() }
|
||||
}
|
||||
|
||||
/** A path expression that may access a local variable. */
|
||||
/**
|
||||
* A path expression that may access a local variable. These are paths that
|
||||
* only consists of a simple name (i.e., without generic arguments,
|
||||
* qualifiers, etc.).
|
||||
*/
|
||||
private class VariableAccessCand extends PathExprBase {
|
||||
string name_;
|
||||
|
||||
@@ -190,10 +210,7 @@ module Impl {
|
||||
private VariableScope getEnclosingScope(AstNode n) { result = getAnAncestorInVariableScope(n) }
|
||||
|
||||
private Pat getAVariablePatAncestor(Variable v) {
|
||||
exists(AstNode definingNode, string name |
|
||||
v = MkVariable(definingNode, name) and
|
||||
variableDecl(definingNode, result, name)
|
||||
)
|
||||
result = v.getPat()
|
||||
or
|
||||
exists(Pat mid |
|
||||
mid = getAVariablePatAncestor(v) and
|
||||
@@ -202,23 +219,12 @@ module Impl {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if parameter `p` introduces the variable `v` inside variable scope
|
||||
* `scope`.
|
||||
* Holds if a parameter declares the variable `v` inside variable scope `scope`.
|
||||
*/
|
||||
private predicate parameterDeclInScope(Param p, Variable v, VariableScope scope) {
|
||||
exists(Pat pat |
|
||||
pat = getAVariablePatAncestor(v) and
|
||||
p.getPat() = pat
|
||||
|
|
||||
exists(Function f |
|
||||
f.getParamList().getAParam() = p and
|
||||
scope = f.getBody()
|
||||
)
|
||||
or
|
||||
exists(ClosureExpr ce |
|
||||
ce.getParamList().getAParam() = p and
|
||||
scope = ce.getBody()
|
||||
)
|
||||
private predicate parameterDeclInScope(Variable v, VariableScope scope) {
|
||||
exists(Callable f |
|
||||
v.getParameter() = f.getParamList().getAParamBase() and
|
||||
scope = [f.(Function).getBody(), f.(ClosureExpr).getBody()]
|
||||
)
|
||||
}
|
||||
|
||||
@@ -231,7 +237,7 @@ module Impl {
|
||||
) {
|
||||
name = v.getName() and
|
||||
(
|
||||
parameterDeclInScope(_, v, scope) and
|
||||
parameterDeclInScope(v, scope) and
|
||||
scope.getLocation().hasLocationFileInfo(_, line, column, _, _)
|
||||
or
|
||||
exists(Pat pat | pat = getAVariablePatAncestor(v) |
|
||||
|
||||
@@ -29,16 +29,16 @@ module Generated {
|
||||
override string getAPrimaryQlClass() { result = "CallExpr" }
|
||||
|
||||
/**
|
||||
* Gets the expression of this call expression, if it exists.
|
||||
* Gets the function of this call expression, if it exists.
|
||||
*/
|
||||
Expr getExpr() {
|
||||
Expr getFunction() {
|
||||
result =
|
||||
Synth::convertExprFromRaw(Synth::convertCallExprToRaw(this).(Raw::CallExpr).getExpr())
|
||||
Synth::convertExprFromRaw(Synth::convertCallExprToRaw(this).(Raw::CallExpr).getFunction())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `getExpr()` exists.
|
||||
* Holds if `getFunction()` exists.
|
||||
*/
|
||||
final predicate hasExpr() { exists(this.getExpr()) }
|
||||
final predicate hasFunction() { exists(this.getFunction()) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,16 +48,17 @@ module Generated {
|
||||
final int getNumberOfAttrs() { result = count(int i | exists(this.getAttr(i))) }
|
||||
|
||||
/**
|
||||
* Gets the expression of this let expression, if it exists.
|
||||
* Gets the scrutinee of this let expression, if it exists.
|
||||
*/
|
||||
Expr getExpr() {
|
||||
result = Synth::convertExprFromRaw(Synth::convertLetExprToRaw(this).(Raw::LetExpr).getExpr())
|
||||
Expr getScrutinee() {
|
||||
result =
|
||||
Synth::convertExprFromRaw(Synth::convertLetExprToRaw(this).(Raw::LetExpr).getScrutinee())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `getExpr()` exists.
|
||||
* Holds if `getScrutinee()` exists.
|
||||
*/
|
||||
final predicate hasExpr() { exists(this.getExpr()) }
|
||||
final predicate hasScrutinee() { exists(this.getScrutinee()) }
|
||||
|
||||
/**
|
||||
* Gets the pat of this let expression, if it exists.
|
||||
|
||||
@@ -1836,13 +1836,13 @@ private module Impl {
|
||||
}
|
||||
|
||||
private Element getImmediateChildOfLetExpr(LetExpr e, int index, string partialPredicateCall) {
|
||||
exists(int b, int bExpr, int n, int nAttr, int nExpr, int nPat |
|
||||
exists(int b, int bExpr, int n, int nAttr, int nScrutinee, int nPat |
|
||||
b = 0 and
|
||||
bExpr = b + 1 + max(int i | i = -1 or exists(getImmediateChildOfExpr(e, i, _)) | i) and
|
||||
n = bExpr and
|
||||
nAttr = n + 1 + max(int i | i = -1 or exists(e.getAttr(i)) | i) and
|
||||
nExpr = nAttr + 1 and
|
||||
nPat = nExpr + 1 and
|
||||
nScrutinee = nAttr + 1 and
|
||||
nPat = nScrutinee + 1 and
|
||||
(
|
||||
none()
|
||||
or
|
||||
@@ -1851,9 +1851,9 @@ private module Impl {
|
||||
result = e.getAttr(index - n) and
|
||||
partialPredicateCall = "Attr(" + (index - n).toString() + ")"
|
||||
or
|
||||
index = nAttr and result = e.getExpr() and partialPredicateCall = "Expr()"
|
||||
index = nAttr and result = e.getScrutinee() and partialPredicateCall = "Scrutinee()"
|
||||
or
|
||||
index = nExpr and result = e.getPat() and partialPredicateCall = "Pat()"
|
||||
index = nScrutinee and result = e.getPat() and partialPredicateCall = "Pat()"
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -2807,18 +2807,18 @@ private module Impl {
|
||||
}
|
||||
|
||||
private Element getImmediateChildOfCallExpr(CallExpr e, int index, string partialPredicateCall) {
|
||||
exists(int b, int bCallExprBase, int n, int nExpr |
|
||||
exists(int b, int bCallExprBase, int n, int nFunction |
|
||||
b = 0 and
|
||||
bCallExprBase =
|
||||
b + 1 + max(int i | i = -1 or exists(getImmediateChildOfCallExprBase(e, i, _)) | i) and
|
||||
n = bCallExprBase and
|
||||
nExpr = n + 1 and
|
||||
nFunction = n + 1 and
|
||||
(
|
||||
none()
|
||||
or
|
||||
result = getImmediateChildOfCallExprBase(e, index - b, partialPredicateCall)
|
||||
or
|
||||
index = n and result = e.getExpr() and partialPredicateCall = "Expr()"
|
||||
index = n and result = e.getFunction() and partialPredicateCall = "Function()"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1927,9 +1927,9 @@ module Raw {
|
||||
Attr getAttr(int index) { let_expr_attrs(this, index, result) }
|
||||
|
||||
/**
|
||||
* Gets the expression of this let expression, if it exists.
|
||||
* Gets the scrutinee of this let expression, if it exists.
|
||||
*/
|
||||
Expr getExpr() { let_expr_exprs(this, result) }
|
||||
Expr getScrutinee() { let_expr_scrutinees(this, result) }
|
||||
|
||||
/**
|
||||
* Gets the pat of this let expression, if it exists.
|
||||
@@ -2144,7 +2144,7 @@ module Raw {
|
||||
/**
|
||||
* Gets the scrutinee (the expression being matched) of this match expression, if it exists.
|
||||
*/
|
||||
Expr getScrutinee() { match_expr_exprs(this, result) }
|
||||
Expr getScrutinee() { match_expr_scrutinees(this, result) }
|
||||
|
||||
/**
|
||||
* Gets the match arm list of this match expression, if it exists.
|
||||
@@ -3072,9 +3072,9 @@ module Raw {
|
||||
override string toString() { result = "CallExpr" }
|
||||
|
||||
/**
|
||||
* Gets the expression of this call expression, if it exists.
|
||||
* Gets the function of this call expression, if it exists.
|
||||
*/
|
||||
Expr getExpr() { call_expr_exprs(this, result) }
|
||||
Expr getFunction() { call_expr_functions(this, result) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
20
rust/ql/lib/codeql/rust/frameworks/Reqwest.qll
Normal file
20
rust/ql/lib/codeql/rust/frameworks/Reqwest.qll
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Provides modeling for the `reqwest` library.
|
||||
*/
|
||||
|
||||
private import rust
|
||||
private import codeql.rust.Concepts
|
||||
|
||||
/**
|
||||
* A call to `reqwest::get` or `reqwest::blocking::get`.
|
||||
*/
|
||||
private class ReqwestGet extends RemoteSource::Range {
|
||||
ReqwestGet() {
|
||||
exists(CallExpr ce |
|
||||
this.asExpr().getExpr() = ce and
|
||||
ce.getFunction().(PathExpr).getPath().getResolvedCrateOrigin().matches("%reqwest") and
|
||||
ce.getFunction().(PathExpr).getPath().getResolvedPath() =
|
||||
["crate::get", "crate::blocking::get"]
|
||||
)
|
||||
}
|
||||
}
|
||||
36
rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll
Normal file
36
rust/ql/lib/codeql/rust/frameworks/stdlib/Env.qll
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Provides modeling for the `std::env` library.
|
||||
*/
|
||||
|
||||
private import rust
|
||||
private import codeql.rust.Concepts
|
||||
|
||||
/**
|
||||
* A call to `std::env::args` or `std::env::args_os`.
|
||||
*/
|
||||
private class StdEnvArgs extends CommandLineArgsSource::Range {
|
||||
StdEnvArgs() {
|
||||
this.asExpr().getExpr().(CallExpr).getFunction().(PathExpr).getPath().getResolvedPath() =
|
||||
["crate::env::args", "crate::env::args_os"]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `std::env::current_dir`, `std::env::current_exe` or `std::env::home_dir`.
|
||||
*/
|
||||
private class StdEnvDir extends CommandLineArgsSource::Range {
|
||||
StdEnvDir() {
|
||||
this.asExpr().getExpr().(CallExpr).getFunction().(PathExpr).getPath().getResolvedPath() =
|
||||
["crate::env::current_dir", "crate::env::current_exe", "crate::env::home_dir"]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to `std::env::var`, `std::env::var_os`, `std::env::vars` or `std::env::vars_os`.
|
||||
*/
|
||||
private class StdEnvVar extends EnvironmentSource::Range {
|
||||
StdEnvVar() {
|
||||
this.asExpr().getExpr().(CallExpr).getFunction().(PathExpr).getPath().getResolvedPath() =
|
||||
["crate::env::var", "crate::env::var_os", "crate::env::vars", "crate::env::vars_os"]
|
||||
}
|
||||
}
|
||||
@@ -95,7 +95,7 @@ module Stages {
|
||||
or
|
||||
exists(AstCfgNode n)
|
||||
or
|
||||
exists(CallExprCfgNode n | exists(n.getExpr()))
|
||||
exists(CallExprCfgNode n | exists(n.getFunction()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1718,9 +1718,9 @@ let_expr_attrs(
|
||||
);
|
||||
|
||||
#keyset[id]
|
||||
let_expr_exprs(
|
||||
let_expr_scrutinees(
|
||||
int id: @let_expr ref,
|
||||
int expr: @expr ref
|
||||
int scrutinee: @expr ref
|
||||
);
|
||||
|
||||
#keyset[id]
|
||||
@@ -1866,9 +1866,9 @@ match_expr_attrs(
|
||||
);
|
||||
|
||||
#keyset[id]
|
||||
match_expr_exprs(
|
||||
match_expr_scrutinees(
|
||||
int id: @match_expr ref,
|
||||
int expr: @expr ref
|
||||
int scrutinee: @expr ref
|
||||
);
|
||||
|
||||
#keyset[id]
|
||||
@@ -2538,9 +2538,9 @@ call_exprs(
|
||||
);
|
||||
|
||||
#keyset[id]
|
||||
call_expr_exprs(
|
||||
call_expr_functions(
|
||||
int id: @call_expr ref,
|
||||
int expr: @expr ref
|
||||
int function: @expr ref
|
||||
);
|
||||
|
||||
consts(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/**
|
||||
* @name Unextracted Elements
|
||||
* @description List all elements that weren't extracted due to unimplemented features or parse errors.
|
||||
* @kind diagnostic
|
||||
* @id rust/diagnostics/unextracted-elements
|
||||
*/
|
||||
|
||||
|
||||
12
rust/ql/src/queries/diagnostics/UnresolvedMacroCalls.ql
Normal file
12
rust/ql/src/queries/diagnostics/UnresolvedMacroCalls.ql
Normal file
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* @name Unresolved Macro Calls
|
||||
* @description List all macro calls that were not resolved to a target.
|
||||
* @kind diagnostic
|
||||
* @id rust/diagnostics/unresolved-macro-calls
|
||||
*/
|
||||
|
||||
import rust
|
||||
|
||||
from MacroCall mc
|
||||
where not mc.hasExpanded()
|
||||
select mc, "Macro call was not resolved to a target."
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
import rust
|
||||
import codeql.rust.Concepts
|
||||
import codeql.rust.Diagnostics
|
||||
import Stats
|
||||
|
||||
@@ -37,4 +38,14 @@ where
|
||||
key = "Inconsistencies - CFG" and value = getTotalCfgInconsistencies()
|
||||
or
|
||||
key = "Inconsistencies - data flow" and value = getTotalDataFlowInconsistencies()
|
||||
select key, value
|
||||
or
|
||||
key = "Macro calls - total" and value = count(MacroCall mc)
|
||||
or
|
||||
key = "Macro calls - resolved" and value = count(MacroCall mc | mc.hasExpanded())
|
||||
or
|
||||
key = "Macro calls - unresolved" and value = count(MacroCall mc | not mc.hasExpanded())
|
||||
or
|
||||
key = "Taint sources - total" and value = count(ThreatModelSource s)
|
||||
or
|
||||
key = "Taint sources - active" and value = count(ActiveThreatModelSource s)
|
||||
select key, value order by key
|
||||
|
||||
18
rust/ql/src/queries/summary/TaintSources.ql
Normal file
18
rust/ql/src/queries/summary/TaintSources.ql
Normal file
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @name Taint Sources
|
||||
* @description List all sources of untrusted input that have been idenfitied
|
||||
* in the database.
|
||||
* @kind problem
|
||||
* @problem.severity info
|
||||
* @id rust/summary/taint-sources
|
||||
* @tags summary
|
||||
*/
|
||||
|
||||
import rust
|
||||
import codeql.rust.Concepts
|
||||
|
||||
from ThreatModelSource s, string defaultString
|
||||
where
|
||||
if s instanceof ActiveThreatModelSource then defaultString = " (DEFAULT)" else defaultString = ""
|
||||
select s,
|
||||
"Flow source '" + s.getSourceType() + "' of type " + s.getThreatModel() + defaultString + "."
|
||||
@@ -1,4 +1,4 @@
|
||||
| gen_call_expr.rs:5:5:5:11 | foo(...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes |
|
||||
| gen_call_expr.rs:6:5:6:23 | foo::<...>(...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes |
|
||||
| gen_call_expr.rs:7:5:7:14 | ...(...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes |
|
||||
| gen_call_expr.rs:8:5:8:10 | foo(...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasExpr: | yes |
|
||||
| gen_call_expr.rs:5:5:5:11 | foo(...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasFunction: | yes |
|
||||
| gen_call_expr.rs:6:5:6:23 | foo::<...>(...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasFunction: | yes |
|
||||
| gen_call_expr.rs:7:5:7:14 | ...(...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasFunction: | yes |
|
||||
| gen_call_expr.rs:8:5:8:10 | foo(...) | hasArgList: | yes | getNumberOfAttrs: | 0 | hasFunction: | yes |
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
import codeql.rust.elements
|
||||
import TestUtils
|
||||
|
||||
from CallExpr x, string hasArgList, int getNumberOfAttrs, string hasExpr
|
||||
from CallExpr x, string hasArgList, int getNumberOfAttrs, string hasFunction
|
||||
where
|
||||
toBeTested(x) and
|
||||
not x.isUnknown() and
|
||||
(if x.hasArgList() then hasArgList = "yes" else hasArgList = "no") and
|
||||
getNumberOfAttrs = x.getNumberOfAttrs() and
|
||||
if x.hasExpr() then hasExpr = "yes" else hasExpr = "no"
|
||||
select x, "hasArgList:", hasArgList, "getNumberOfAttrs:", getNumberOfAttrs, "hasExpr:", hasExpr
|
||||
if x.hasFunction() then hasFunction = "yes" else hasFunction = "no"
|
||||
select x, "hasArgList:", hasArgList, "getNumberOfAttrs:", getNumberOfAttrs, "hasFunction:",
|
||||
hasFunction
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
| gen_call_expr.rs:5:5:5:11 | foo(...) | gen_call_expr.rs:5:5:5:7 | foo |
|
||||
| gen_call_expr.rs:6:5:6:23 | foo::<...>(...) | gen_call_expr.rs:6:5:6:19 | foo::<...> |
|
||||
| gen_call_expr.rs:7:5:7:14 | ...(...) | gen_call_expr.rs:7:5:7:10 | foo[0] |
|
||||
| gen_call_expr.rs:8:5:8:10 | foo(...) | gen_call_expr.rs:8:5:8:7 | foo |
|
||||
@@ -4,4 +4,4 @@ import TestUtils
|
||||
|
||||
from CallExpr x
|
||||
where toBeTested(x) and not x.isUnknown()
|
||||
select x, x.getExpr()
|
||||
select x, x.getFunction()
|
||||
@@ -1 +1 @@
|
||||
| gen_let_expr.rs:5:8:5:31 | let ... = maybe_some | getNumberOfAttrs: | 0 | hasExpr: | yes | hasPat: | yes |
|
||||
| gen_let_expr.rs:5:8:5:31 | let ... = maybe_some | getNumberOfAttrs: | 0 | hasScrutinee: | yes | hasPat: | yes |
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
import codeql.rust.elements
|
||||
import TestUtils
|
||||
|
||||
from LetExpr x, int getNumberOfAttrs, string hasExpr, string hasPat
|
||||
from LetExpr x, int getNumberOfAttrs, string hasScrutinee, string hasPat
|
||||
where
|
||||
toBeTested(x) and
|
||||
not x.isUnknown() and
|
||||
getNumberOfAttrs = x.getNumberOfAttrs() and
|
||||
(if x.hasExpr() then hasExpr = "yes" else hasExpr = "no") and
|
||||
(if x.hasScrutinee() then hasScrutinee = "yes" else hasScrutinee = "no") and
|
||||
if x.hasPat() then hasPat = "yes" else hasPat = "no"
|
||||
select x, "getNumberOfAttrs:", getNumberOfAttrs, "hasExpr:", hasExpr, "hasPat:", hasPat
|
||||
select x, "getNumberOfAttrs:", getNumberOfAttrs, "hasScrutinee:", hasScrutinee, "hasPat:", hasPat
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
| gen_let_expr.rs:5:8:5:31 | let ... = maybe_some | gen_let_expr.rs:5:22:5:31 | maybe_some |
|
||||
@@ -4,4 +4,4 @@ import TestUtils
|
||||
|
||||
from LetExpr x
|
||||
where toBeTested(x) and not x.isUnknown()
|
||||
select x, x.getExpr()
|
||||
select x, x.getScrutinee()
|
||||
@@ -1,29 +1,29 @@
|
||||
models
|
||||
edges
|
||||
| main.rs:9:13:9:19 | ...: ... : unit | main.rs:9:30:14:1 | { ... } : unit | provenance | |
|
||||
| main.rs:21:13:21:21 | source(...) : unit | main.rs:22:10:22:10 | s | provenance | |
|
||||
| main.rs:26:13:26:21 | source(...) : unit | main.rs:27:22:27:22 | s : unit | provenance | |
|
||||
| main.rs:27:13:27:23 | sanitize(...) : unit | main.rs:28:10:28:10 | s | provenance | |
|
||||
| main.rs:27:22:27:22 | s : unit | main.rs:9:13:9:19 | ...: ... : unit | provenance | |
|
||||
| main.rs:27:22:27:22 | s : unit | main.rs:27:13:27:23 | sanitize(...) : unit | provenance | |
|
||||
| main.rs:32:13:32:21 | source(...) : unit | main.rs:33:10:33:10 | s | provenance | |
|
||||
| main.rs:9:13:9:19 | ...: ... | main.rs:9:30:14:1 | { ... } | provenance | |
|
||||
| main.rs:21:13:21:21 | source(...) | main.rs:22:10:22:10 | s | provenance | |
|
||||
| main.rs:26:13:26:21 | source(...) | main.rs:27:22:27:22 | s | provenance | |
|
||||
| main.rs:27:13:27:23 | sanitize(...) | main.rs:28:10:28:10 | s | provenance | |
|
||||
| main.rs:27:22:27:22 | s | main.rs:9:13:9:19 | ...: ... | provenance | |
|
||||
| main.rs:27:22:27:22 | s | main.rs:27:13:27:23 | sanitize(...) | provenance | |
|
||||
| main.rs:32:13:32:21 | source(...) | main.rs:33:10:33:10 | s | provenance | |
|
||||
nodes
|
||||
| main.rs:9:13:9:19 | ...: ... : unit | semmle.label | ...: ... : unit |
|
||||
| main.rs:9:30:14:1 | { ... } : unit | semmle.label | { ... } : unit |
|
||||
| main.rs:9:13:9:19 | ...: ... | semmle.label | ...: ... |
|
||||
| main.rs:9:30:14:1 | { ... } | semmle.label | { ... } |
|
||||
| main.rs:17:10:17:18 | source(...) | semmle.label | source(...) |
|
||||
| main.rs:21:13:21:21 | source(...) : unit | semmle.label | source(...) : unit |
|
||||
| main.rs:21:13:21:21 | source(...) | semmle.label | source(...) |
|
||||
| main.rs:22:10:22:10 | s | semmle.label | s |
|
||||
| main.rs:26:13:26:21 | source(...) : unit | semmle.label | source(...) : unit |
|
||||
| main.rs:27:13:27:23 | sanitize(...) : unit | semmle.label | sanitize(...) : unit |
|
||||
| main.rs:27:22:27:22 | s : unit | semmle.label | s : unit |
|
||||
| main.rs:26:13:26:21 | source(...) | semmle.label | source(...) |
|
||||
| main.rs:27:13:27:23 | sanitize(...) | semmle.label | sanitize(...) |
|
||||
| main.rs:27:22:27:22 | s | semmle.label | s |
|
||||
| main.rs:28:10:28:10 | s | semmle.label | s |
|
||||
| main.rs:32:13:32:21 | source(...) : unit | semmle.label | source(...) : unit |
|
||||
| main.rs:32:13:32:21 | source(...) | semmle.label | source(...) |
|
||||
| main.rs:33:10:33:10 | s | semmle.label | s |
|
||||
subpaths
|
||||
| main.rs:27:22:27:22 | s : unit | main.rs:9:13:9:19 | ...: ... : unit | main.rs:9:30:14:1 | { ... } : unit | main.rs:27:13:27:23 | sanitize(...) : unit |
|
||||
| main.rs:27:22:27:22 | s | main.rs:9:13:9:19 | ...: ... | main.rs:9:30:14:1 | { ... } | main.rs:27:13:27:23 | sanitize(...) |
|
||||
testFailures
|
||||
#select
|
||||
| main.rs:17:10:17:18 | source(...) | main.rs:17:10:17:18 | source(...) | main.rs:17:10:17:18 | source(...) | $@ | main.rs:17:10:17:18 | source(...) | source(...) |
|
||||
| main.rs:22:10:22:10 | s | main.rs:21:13:21:21 | source(...) : unit | main.rs:22:10:22:10 | s | $@ | main.rs:21:13:21:21 | source(...) : unit | source(...) : unit |
|
||||
| main.rs:28:10:28:10 | s | main.rs:26:13:26:21 | source(...) : unit | main.rs:28:10:28:10 | s | $@ | main.rs:26:13:26:21 | source(...) : unit | source(...) : unit |
|
||||
| main.rs:33:10:33:10 | s | main.rs:32:13:32:21 | source(...) : unit | main.rs:33:10:33:10 | s | $@ | main.rs:32:13:32:21 | source(...) : unit | source(...) : unit |
|
||||
| main.rs:22:10:22:10 | s | main.rs:21:13:21:21 | source(...) | main.rs:22:10:22:10 | s | $@ | main.rs:21:13:21:21 | source(...) | source(...) |
|
||||
| main.rs:28:10:28:10 | s | main.rs:26:13:26:21 | source(...) | main.rs:28:10:28:10 | s | $@ | main.rs:26:13:26:21 | source(...) | source(...) |
|
||||
| main.rs:33:10:33:10 | s | main.rs:32:13:32:21 | source(...) | main.rs:33:10:33:10 | s | $@ | main.rs:32:13:32:21 | source(...) | source(...) |
|
||||
|
||||
@@ -1,74 +1,74 @@
|
||||
models
|
||||
edges
|
||||
| main.rs:12:28:14:1 | { ... } : unit | main.rs:17:13:17:23 | get_data(...) : unit | provenance | |
|
||||
| main.rs:13:5:13:13 | source(...) : unit | main.rs:12:28:14:1 | { ... } : unit | provenance | |
|
||||
| main.rs:17:13:17:23 | get_data(...) : unit | main.rs:18:10:18:10 | a | provenance | |
|
||||
| main.rs:21:12:21:17 | ...: i64 : unit | main.rs:22:10:22:10 | n | provenance | |
|
||||
| main.rs:26:13:26:21 | source(...) : unit | main.rs:27:13:27:13 | a : unit | provenance | |
|
||||
| main.rs:27:13:27:13 | a : unit | main.rs:21:12:21:17 | ...: i64 : unit | provenance | |
|
||||
| main.rs:30:17:30:22 | ...: i64 : unit | main.rs:30:32:32:1 | { ... } : unit | provenance | |
|
||||
| main.rs:35:13:35:21 | source(...) : unit | main.rs:36:26:36:26 | a : unit | provenance | |
|
||||
| main.rs:36:13:36:27 | pass_through(...) : unit | main.rs:37:10:37:10 | b | provenance | |
|
||||
| main.rs:36:26:36:26 | a : unit | main.rs:30:17:30:22 | ...: i64 : unit | provenance | |
|
||||
| main.rs:36:26:36:26 | a : unit | main.rs:36:13:36:27 | pass_through(...) : unit | provenance | |
|
||||
| main.rs:41:13:44:6 | pass_through(...) : unit | main.rs:45:10:45:10 | a | provenance | |
|
||||
| main.rs:41:26:44:5 | { ... } : unit | main.rs:30:17:30:22 | ...: i64 : unit | provenance | |
|
||||
| main.rs:41:26:44:5 | { ... } : unit | main.rs:41:13:44:6 | pass_through(...) : unit | provenance | |
|
||||
| main.rs:43:9:43:18 | source(...) : unit | main.rs:41:26:44:5 | { ... } : unit | provenance | |
|
||||
| main.rs:56:23:56:28 | ...: i64 : unit | main.rs:57:14:57:14 | n | provenance | |
|
||||
| main.rs:59:31:65:5 | { ... } : unit | main.rs:77:13:77:25 | ... .get_data(...) : unit | provenance | |
|
||||
| main.rs:63:13:63:21 | source(...) : unit | main.rs:59:31:65:5 | { ... } : unit | provenance | |
|
||||
| main.rs:66:28:66:33 | ...: i64 : unit | main.rs:66:43:72:5 | { ... } : unit | provenance | |
|
||||
| main.rs:77:13:77:25 | ... .get_data(...) : unit | main.rs:78:10:78:10 | a | provenance | |
|
||||
| main.rs:83:13:83:21 | source(...) : unit | main.rs:84:16:84:16 | a : unit | provenance | |
|
||||
| main.rs:84:16:84:16 | a : unit | main.rs:56:23:56:28 | ...: i64 : unit | provenance | |
|
||||
| main.rs:89:13:89:21 | source(...) : unit | main.rs:90:29:90:29 | a : unit | provenance | |
|
||||
| main.rs:90:13:90:30 | ... .data_through(...) : unit | main.rs:91:10:91:10 | b | provenance | |
|
||||
| main.rs:90:29:90:29 | a : unit | main.rs:66:28:66:33 | ...: i64 : unit | provenance | |
|
||||
| main.rs:90:29:90:29 | a : unit | main.rs:90:13:90:30 | ... .data_through(...) : unit | provenance | |
|
||||
| main.rs:12:28:14:1 | { ... } | main.rs:17:13:17:23 | get_data(...) | provenance | |
|
||||
| main.rs:13:5:13:13 | source(...) | main.rs:12:28:14:1 | { ... } | provenance | |
|
||||
| main.rs:17:13:17:23 | get_data(...) | main.rs:18:10:18:10 | a | provenance | |
|
||||
| main.rs:21:12:21:17 | ...: i64 | main.rs:22:10:22:10 | n | provenance | |
|
||||
| main.rs:26:13:26:21 | source(...) | main.rs:27:13:27:13 | a | provenance | |
|
||||
| main.rs:27:13:27:13 | a | main.rs:21:12:21:17 | ...: i64 | provenance | |
|
||||
| main.rs:30:17:30:22 | ...: i64 | main.rs:30:32:32:1 | { ... } | provenance | |
|
||||
| main.rs:35:13:35:21 | source(...) | main.rs:36:26:36:26 | a | provenance | |
|
||||
| main.rs:36:13:36:27 | pass_through(...) | main.rs:37:10:37:10 | b | provenance | |
|
||||
| main.rs:36:26:36:26 | a | main.rs:30:17:30:22 | ...: i64 | provenance | |
|
||||
| main.rs:36:26:36:26 | a | main.rs:36:13:36:27 | pass_through(...) | provenance | |
|
||||
| main.rs:41:13:44:6 | pass_through(...) | main.rs:45:10:45:10 | a | provenance | |
|
||||
| main.rs:41:26:44:5 | { ... } | main.rs:30:17:30:22 | ...: i64 | provenance | |
|
||||
| main.rs:41:26:44:5 | { ... } | main.rs:41:13:44:6 | pass_through(...) | provenance | |
|
||||
| main.rs:43:9:43:18 | source(...) | main.rs:41:26:44:5 | { ... } | provenance | |
|
||||
| main.rs:56:23:56:28 | ...: i64 | main.rs:57:14:57:14 | n | provenance | |
|
||||
| main.rs:59:31:65:5 | { ... } | main.rs:77:13:77:25 | ... .get_data(...) | provenance | |
|
||||
| main.rs:63:13:63:21 | source(...) | main.rs:59:31:65:5 | { ... } | provenance | |
|
||||
| main.rs:66:28:66:33 | ...: i64 | main.rs:66:43:72:5 | { ... } | provenance | |
|
||||
| main.rs:77:13:77:25 | ... .get_data(...) | main.rs:78:10:78:10 | a | provenance | |
|
||||
| main.rs:83:13:83:21 | source(...) | main.rs:84:16:84:16 | a | provenance | |
|
||||
| main.rs:84:16:84:16 | a | main.rs:56:23:56:28 | ...: i64 | provenance | |
|
||||
| main.rs:89:13:89:21 | source(...) | main.rs:90:29:90:29 | a | provenance | |
|
||||
| main.rs:90:13:90:30 | ... .data_through(...) | main.rs:91:10:91:10 | b | provenance | |
|
||||
| main.rs:90:29:90:29 | a | main.rs:66:28:66:33 | ...: i64 | provenance | |
|
||||
| main.rs:90:29:90:29 | a | main.rs:90:13:90:30 | ... .data_through(...) | provenance | |
|
||||
nodes
|
||||
| main.rs:12:28:14:1 | { ... } : unit | semmle.label | { ... } : unit |
|
||||
| main.rs:13:5:13:13 | source(...) : unit | semmle.label | source(...) : unit |
|
||||
| main.rs:17:13:17:23 | get_data(...) : unit | semmle.label | get_data(...) : unit |
|
||||
| main.rs:12:28:14:1 | { ... } | semmle.label | { ... } |
|
||||
| main.rs:13:5:13:13 | source(...) | semmle.label | source(...) |
|
||||
| main.rs:17:13:17:23 | get_data(...) | semmle.label | get_data(...) |
|
||||
| main.rs:18:10:18:10 | a | semmle.label | a |
|
||||
| main.rs:21:12:21:17 | ...: i64 : unit | semmle.label | ...: i64 : unit |
|
||||
| main.rs:21:12:21:17 | ...: i64 | semmle.label | ...: i64 |
|
||||
| main.rs:22:10:22:10 | n | semmle.label | n |
|
||||
| main.rs:26:13:26:21 | source(...) : unit | semmle.label | source(...) : unit |
|
||||
| main.rs:27:13:27:13 | a : unit | semmle.label | a : unit |
|
||||
| main.rs:30:17:30:22 | ...: i64 : unit | semmle.label | ...: i64 : unit |
|
||||
| main.rs:30:32:32:1 | { ... } : unit | semmle.label | { ... } : unit |
|
||||
| main.rs:35:13:35:21 | source(...) : unit | semmle.label | source(...) : unit |
|
||||
| main.rs:36:13:36:27 | pass_through(...) : unit | semmle.label | pass_through(...) : unit |
|
||||
| main.rs:36:26:36:26 | a : unit | semmle.label | a : unit |
|
||||
| main.rs:26:13:26:21 | source(...) | semmle.label | source(...) |
|
||||
| main.rs:27:13:27:13 | a | semmle.label | a |
|
||||
| main.rs:30:17:30:22 | ...: i64 | semmle.label | ...: i64 |
|
||||
| main.rs:30:32:32:1 | { ... } | semmle.label | { ... } |
|
||||
| main.rs:35:13:35:21 | source(...) | semmle.label | source(...) |
|
||||
| main.rs:36:13:36:27 | pass_through(...) | semmle.label | pass_through(...) |
|
||||
| main.rs:36:26:36:26 | a | semmle.label | a |
|
||||
| main.rs:37:10:37:10 | b | semmle.label | b |
|
||||
| main.rs:41:13:44:6 | pass_through(...) : unit | semmle.label | pass_through(...) : unit |
|
||||
| main.rs:41:26:44:5 | { ... } : unit | semmle.label | { ... } : unit |
|
||||
| main.rs:43:9:43:18 | source(...) : unit | semmle.label | source(...) : unit |
|
||||
| main.rs:41:13:44:6 | pass_through(...) | semmle.label | pass_through(...) |
|
||||
| main.rs:41:26:44:5 | { ... } | semmle.label | { ... } |
|
||||
| main.rs:43:9:43:18 | source(...) | semmle.label | source(...) |
|
||||
| main.rs:45:10:45:10 | a | semmle.label | a |
|
||||
| main.rs:56:23:56:28 | ...: i64 : unit | semmle.label | ...: i64 : unit |
|
||||
| main.rs:56:23:56:28 | ...: i64 | semmle.label | ...: i64 |
|
||||
| main.rs:57:14:57:14 | n | semmle.label | n |
|
||||
| main.rs:59:31:65:5 | { ... } : unit | semmle.label | { ... } : unit |
|
||||
| main.rs:63:13:63:21 | source(...) : unit | semmle.label | source(...) : unit |
|
||||
| main.rs:66:28:66:33 | ...: i64 : unit | semmle.label | ...: i64 : unit |
|
||||
| main.rs:66:43:72:5 | { ... } : unit | semmle.label | { ... } : unit |
|
||||
| main.rs:77:13:77:25 | ... .get_data(...) : unit | semmle.label | ... .get_data(...) : unit |
|
||||
| main.rs:59:31:65:5 | { ... } | semmle.label | { ... } |
|
||||
| main.rs:63:13:63:21 | source(...) | semmle.label | source(...) |
|
||||
| main.rs:66:28:66:33 | ...: i64 | semmle.label | ...: i64 |
|
||||
| main.rs:66:43:72:5 | { ... } | semmle.label | { ... } |
|
||||
| main.rs:77:13:77:25 | ... .get_data(...) | semmle.label | ... .get_data(...) |
|
||||
| main.rs:78:10:78:10 | a | semmle.label | a |
|
||||
| main.rs:83:13:83:21 | source(...) : unit | semmle.label | source(...) : unit |
|
||||
| main.rs:84:16:84:16 | a : unit | semmle.label | a : unit |
|
||||
| main.rs:89:13:89:21 | source(...) : unit | semmle.label | source(...) : unit |
|
||||
| main.rs:90:13:90:30 | ... .data_through(...) : unit | semmle.label | ... .data_through(...) : unit |
|
||||
| main.rs:90:29:90:29 | a : unit | semmle.label | a : unit |
|
||||
| main.rs:83:13:83:21 | source(...) | semmle.label | source(...) |
|
||||
| main.rs:84:16:84:16 | a | semmle.label | a |
|
||||
| main.rs:89:13:89:21 | source(...) | semmle.label | source(...) |
|
||||
| main.rs:90:13:90:30 | ... .data_through(...) | semmle.label | ... .data_through(...) |
|
||||
| main.rs:90:29:90:29 | a | semmle.label | a |
|
||||
| main.rs:91:10:91:10 | b | semmle.label | b |
|
||||
subpaths
|
||||
| main.rs:36:26:36:26 | a : unit | main.rs:30:17:30:22 | ...: i64 : unit | main.rs:30:32:32:1 | { ... } : unit | main.rs:36:13:36:27 | pass_through(...) : unit |
|
||||
| main.rs:41:26:44:5 | { ... } : unit | main.rs:30:17:30:22 | ...: i64 : unit | main.rs:30:32:32:1 | { ... } : unit | main.rs:41:13:44:6 | pass_through(...) : unit |
|
||||
| main.rs:90:29:90:29 | a : unit | main.rs:66:28:66:33 | ...: i64 : unit | main.rs:66:43:72:5 | { ... } : unit | main.rs:90:13:90:30 | ... .data_through(...) : unit |
|
||||
| main.rs:36:26:36:26 | a | main.rs:30:17:30:22 | ...: i64 | main.rs:30:32:32:1 | { ... } | main.rs:36:13:36:27 | pass_through(...) |
|
||||
| main.rs:41:26:44:5 | { ... } | main.rs:30:17:30:22 | ...: i64 | main.rs:30:32:32:1 | { ... } | main.rs:41:13:44:6 | pass_through(...) |
|
||||
| main.rs:90:29:90:29 | a | main.rs:66:28:66:33 | ...: i64 | main.rs:66:43:72:5 | { ... } | main.rs:90:13:90:30 | ... .data_through(...) |
|
||||
testFailures
|
||||
#select
|
||||
| main.rs:18:10:18:10 | a | main.rs:13:5:13:13 | source(...) : unit | main.rs:18:10:18:10 | a | $@ | main.rs:13:5:13:13 | source(...) : unit | source(...) : unit |
|
||||
| main.rs:22:10:22:10 | n | main.rs:26:13:26:21 | source(...) : unit | main.rs:22:10:22:10 | n | $@ | main.rs:26:13:26:21 | source(...) : unit | source(...) : unit |
|
||||
| main.rs:37:10:37:10 | b | main.rs:35:13:35:21 | source(...) : unit | main.rs:37:10:37:10 | b | $@ | main.rs:35:13:35:21 | source(...) : unit | source(...) : unit |
|
||||
| main.rs:45:10:45:10 | a | main.rs:43:9:43:18 | source(...) : unit | main.rs:45:10:45:10 | a | $@ | main.rs:43:9:43:18 | source(...) : unit | source(...) : unit |
|
||||
| main.rs:57:14:57:14 | n | main.rs:83:13:83:21 | source(...) : unit | main.rs:57:14:57:14 | n | $@ | main.rs:83:13:83:21 | source(...) : unit | source(...) : unit |
|
||||
| main.rs:78:10:78:10 | a | main.rs:63:13:63:21 | source(...) : unit | main.rs:78:10:78:10 | a | $@ | main.rs:63:13:63:21 | source(...) : unit | source(...) : unit |
|
||||
| main.rs:91:10:91:10 | b | main.rs:89:13:89:21 | source(...) : unit | main.rs:91:10:91:10 | b | $@ | main.rs:89:13:89:21 | source(...) : unit | source(...) : unit |
|
||||
| main.rs:18:10:18:10 | a | main.rs:13:5:13:13 | source(...) | main.rs:18:10:18:10 | a | $@ | main.rs:13:5:13:13 | source(...) | source(...) |
|
||||
| main.rs:22:10:22:10 | n | main.rs:26:13:26:21 | source(...) | main.rs:22:10:22:10 | n | $@ | main.rs:26:13:26:21 | source(...) | source(...) |
|
||||
| main.rs:37:10:37:10 | b | main.rs:35:13:35:21 | source(...) | main.rs:37:10:37:10 | b | $@ | main.rs:35:13:35:21 | source(...) | source(...) |
|
||||
| main.rs:45:10:45:10 | a | main.rs:43:9:43:18 | source(...) | main.rs:45:10:45:10 | a | $@ | main.rs:43:9:43:18 | source(...) | source(...) |
|
||||
| main.rs:57:14:57:14 | n | main.rs:83:13:83:21 | source(...) | main.rs:57:14:57:14 | n | $@ | main.rs:83:13:83:21 | source(...) | source(...) |
|
||||
| main.rs:78:10:78:10 | a | main.rs:63:13:63:21 | source(...) | main.rs:78:10:78:10 | a | $@ | main.rs:63:13:63:21 | source(...) | source(...) |
|
||||
| main.rs:91:10:91:10 | b | main.rs:89:13:89:21 | source(...) | main.rs:91:10:91:10 | b | $@ | main.rs:89:13:89:21 | source(...) | source(...) |
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
localStep
|
||||
| main.rs:3:11:3:11 | [SSA] i | main.rs:4:12:4:12 | i |
|
||||
| main.rs:3:11:3:11 | i | main.rs:3:11:3:11 | [SSA] i |
|
||||
| main.rs:3:11:3:16 | ...: i64 | main.rs:3:11:3:11 | i |
|
||||
@@ -33,6 +34,8 @@
|
||||
| main.rs:32:9:32:9 | [SSA] b | main.rs:36:10:36:10 | b |
|
||||
| main.rs:32:9:32:9 | b | main.rs:32:9:32:9 | [SSA] b |
|
||||
| main.rs:32:13:35:5 | match m { ... } | main.rs:32:9:32:9 | b |
|
||||
| main.rs:32:19:32:19 | m | main.rs:33:9:33:15 | TupleStructPat |
|
||||
| main.rs:32:19:32:19 | m | main.rs:34:9:34:12 | None |
|
||||
| main.rs:33:20:33:20 | a | main.rs:32:13:35:5 | match m { ... } |
|
||||
| main.rs:34:17:34:17 | 0 | main.rs:32:13:35:5 | match m { ... } |
|
||||
| main.rs:40:9:40:9 | [SSA] a | main.rs:43:10:43:10 | a |
|
||||
@@ -75,42 +78,229 @@
|
||||
| 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:28 | Some(...) | main.rs:104:9:104:10 | 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:20 | Some(...) | main.rs:105:9:105:10 | s2 |
|
||||
| main.rs:107:14:107:14 | [SSA] n | main.rs:107:25:107:25 | n |
|
||||
| main.rs:107:14:107:14 | n | main.rs:107:14:107:14 | [SSA] n |
|
||||
| main.rs:107:20:107:26 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } |
|
||||
| main.rs:108:17:108:23 | sink(...) | main.rs:106:5:109:5 | match s1 { ... } |
|
||||
| main.rs:110:5:113:5 | match s2 { ... } | main.rs:103:27:114:1 | { ... } |
|
||||
| main.rs:111:14:111:14 | [SSA] n | main.rs:111:25:111:25 | n |
|
||||
| main.rs:111:14:111:14 | n | main.rs:111:14:111:14 | [SSA] n |
|
||||
| main.rs:111:20:111:26 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } |
|
||||
| main.rs:112:17:112:23 | sink(...) | main.rs:110:5:113:5 | match s2 { ... } |
|
||||
| main.rs:117:9:117:9 | [SSA] a | main.rs:118:5:118:5 | a |
|
||||
| main.rs:117:9:117:9 | a | main.rs:117:9:117:9 | [SSA] a |
|
||||
| main.rs:117:13:117:17 | { ... } | main.rs:117:9:117:9 | a |
|
||||
| main.rs:117:15:117:15 | 0 | main.rs:117:13:117:17 | { ... } |
|
||||
| main.rs:118:5:118:5 | a | main.rs:116:31:119:1 | { ... } |
|
||||
| main.rs:121:22:121:22 | [SSA] b | main.rs:123:12:123:12 | b |
|
||||
| main.rs:121:22:121:22 | b | main.rs:121:22:121:22 | [SSA] b |
|
||||
| main.rs:121:22:121:28 | ...: bool | main.rs:121:22:121:22 | b |
|
||||
| main.rs:122:9:122:9 | [SSA] a | main.rs:128:5:128:5 | a |
|
||||
| main.rs:122:9:122:9 | a | main.rs:122:9:122:9 | [SSA] a |
|
||||
| main.rs:122:13:127:5 | 'block: { ... } | main.rs:122:9:122:9 | a |
|
||||
| main.rs:124:13:124:26 | break ''block 1 | main.rs:122:13:127:5 | 'block: { ... } |
|
||||
| main.rs:124:26:124:26 | 1 | main.rs:124:13:124:26 | break ''block 1 |
|
||||
| main.rs:126:9:126:9 | 2 | main.rs:122:13:127:5 | 'block: { ... } |
|
||||
| main.rs:128:5:128:5 | a | main.rs:121:38:129:1 | { ... } |
|
||||
| main.rs:131:22:131:22 | [SSA] b | main.rs:133:12:133:12 | b |
|
||||
| main.rs:131:22:131:22 | b | main.rs:131:22:131:22 | [SSA] b |
|
||||
| main.rs:131:22:131:28 | ...: bool | main.rs:131:22:131:22 | b |
|
||||
| main.rs:132:9:132:9 | [SSA] a | main.rs:138:5:138:5 | a |
|
||||
| main.rs:132:9:132:9 | a | main.rs:132:9:132:9 | [SSA] a |
|
||||
| main.rs:132:13:137:5 | 'block: { ... } | main.rs:132:9:132:9 | a |
|
||||
| main.rs:134:13:134:26 | break ''block 1 | main.rs:132:13:137:5 | 'block: { ... } |
|
||||
| main.rs:134:26:134:26 | 1 | main.rs:134:13:134:26 | break ''block 1 |
|
||||
| main.rs:136:9:136:22 | break ''block 2 | main.rs:132:13:137:5 | 'block: { ... } |
|
||||
| main.rs:136:22:136:22 | 2 | main.rs:136:9:136:22 | break ''block 2 |
|
||||
| main.rs:138:5:138:5 | a | main.rs:131:38:139:1 | { ... } |
|
||||
| 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 | TupleStructPat |
|
||||
| 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 | TupleStructPat |
|
||||
| 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 | TupleStructPat |
|
||||
| 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 | TupleStructPat |
|
||||
| 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 | TupleStructPat |
|
||||
| main.rs:137:11:137:12 | s1 | main.rs:139:9:139:25 | TupleStructPat |
|
||||
| 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 | TupleStructPat |
|
||||
| main.rs:142:10:142:46 | ... \| ... | main.rs:142:30:142:46 | TupleStructPat |
|
||||
| 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 | TupleStructPat |
|
||||
| main.rs:144:11:144:12 | s2 | main.rs:146:9:146:25 | TupleStructPat |
|
||||
| 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 | TupleStructPat |
|
||||
| main.rs:155:11:155:12 | s1 | main.rs:157:9:157:12 | TupleStructPat |
|
||||
| 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 | TupleStructPat |
|
||||
| main.rs:160:10:160:20 | ... \| ... | main.rs:160:17:160:20 | TupleStructPat |
|
||||
| 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 | TupleStructPat |
|
||||
| main.rs:162:11:162:12 | s2 | main.rs:164:9:164:12 | TupleStructPat |
|
||||
| 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 | { ... } |
|
||||
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: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:240:27:240:27 | 0 | Some | main.rs:240:22:240:28 | Some(...) |
|
||||
readStep
|
||||
| main.rs:33:9:33:15 | TupleStructPat | Some | main.rs:33:14:33:14 | _ |
|
||||
| main.rs:120:9:120:15 | TupleStructPat | Some | main.rs:120:14:120:14 | n |
|
||||
| main.rs:124:9:124:15 | TupleStructPat | Some | main.rs:124:14:124:14 | n |
|
||||
| main.rs:138:9:138:25 | TupleStructPat | A | main.rs:138:24:138:24 | n |
|
||||
| main.rs:139:9:139:25 | TupleStructPat | B | main.rs:139:24:139:24 | n |
|
||||
| main.rs:142:10:142:26 | TupleStructPat | A | main.rs:142:25:142:25 | n |
|
||||
| main.rs:142:30:142:46 | TupleStructPat | B | main.rs:142:45:142:45 | n |
|
||||
| main.rs:145:9:145:25 | TupleStructPat | A | main.rs:145:24:145:24 | n |
|
||||
| main.rs:146:9:146:25 | TupleStructPat | B | main.rs:146:24:146:24 | 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 |
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import codeql.rust.dataflow.DataFlow
|
||||
import codeql.rust.dataflow.internal.DataFlowImpl
|
||||
|
||||
from DataFlow::Node pred, DataFlow::Node succ
|
||||
where DataFlow::localFlowStep(pred, succ)
|
||||
select pred, succ
|
||||
query predicate localStep = DataFlow::localFlowStep/2;
|
||||
|
||||
query predicate storeStep = RustDataFlow::storeStep/3;
|
||||
|
||||
query predicate readStep = RustDataFlow::readStep/3;
|
||||
|
||||
@@ -1,28 +1,72 @@
|
||||
models
|
||||
edges
|
||||
| main.rs:19:13:19:21 | source(...) : unit | main.rs:20:10:20:10 | s | provenance | |
|
||||
| main.rs:24:13:24:21 | source(...) : unit | main.rs:27:10:27:10 | c | provenance | |
|
||||
| main.rs:31:13:31:21 | source(...) : unit | main.rs:36:10:36:10 | b | provenance | |
|
||||
| main.rs:45:15:45:23 | source(...) : unit | main.rs:47:10:47:10 | b | provenance | |
|
||||
| main.rs:53:9:53:17 | source(...) : unit | main.rs:54:10:54:10 | i | provenance | |
|
||||
| main.rs:19:13:19:21 | source(...) | main.rs:20:10:20:10 | s | provenance | |
|
||||
| main.rs:24:13:24:21 | source(...) | main.rs:27:10:27:10 | c | provenance | |
|
||||
| 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 | TupleStructPat [Some] | provenance | |
|
||||
| main.rs:117:19:117:28 | source(...) | main.rs:117:14:117:29 | Some(...) [Some] | provenance | |
|
||||
| main.rs:120:9:120:15 | TupleStructPat [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 | TupleStructPat [A] | provenance | |
|
||||
| main.rs:135:14:135:39 | ...::A(...) [A] | main.rs:142:10:142:26 | TupleStructPat [A] | provenance | |
|
||||
| main.rs:135:29:135:38 | source(...) | main.rs:135:14:135:39 | ...::A(...) [A] | provenance | |
|
||||
| main.rs:138:9:138:25 | TupleStructPat [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 | TupleStructPat [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: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 | |
|
||||
nodes
|
||||
| main.rs:15:10:15:18 | source(...) | semmle.label | source(...) |
|
||||
| main.rs:19:13:19:21 | source(...) : unit | semmle.label | source(...) : unit |
|
||||
| main.rs:19:13:19:21 | source(...) | semmle.label | source(...) |
|
||||
| main.rs:20:10:20:10 | s | semmle.label | s |
|
||||
| main.rs:24:13:24:21 | source(...) : unit | semmle.label | source(...) : unit |
|
||||
| main.rs:24:13:24:21 | source(...) | semmle.label | source(...) |
|
||||
| main.rs:27:10:27:10 | c | semmle.label | c |
|
||||
| main.rs:31:13:31:21 | source(...) : unit | semmle.label | source(...) : unit |
|
||||
| main.rs:31:13:31:21 | source(...) | semmle.label | source(...) |
|
||||
| main.rs:36:10:36:10 | b | semmle.label | b |
|
||||
| main.rs:45:15:45:23 | source(...) : unit | semmle.label | source(...) : unit |
|
||||
| main.rs:45:15:45:23 | source(...) | semmle.label | source(...) |
|
||||
| main.rs:47:10:47:10 | b | semmle.label | b |
|
||||
| main.rs:53:9:53:17 | source(...) : unit | semmle.label | source(...) : unit |
|
||||
| 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 | TupleStructPat [Some] | semmle.label | TupleStructPat [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 | TupleStructPat [A] | semmle.label | TupleStructPat [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 | TupleStructPat [A] | semmle.label | TupleStructPat [A] |
|
||||
| main.rs:142:25:142:25 | n | semmle.label | n |
|
||||
| main.rs:142:57:142:57 | 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 |
|
||||
subpaths
|
||||
testFailures
|
||||
#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(...) : unit | main.rs:20:10:20:10 | s | $@ | main.rs:19:13:19:21 | source(...) : unit | source(...) : unit |
|
||||
| main.rs:27:10:27:10 | c | main.rs:24:13:24:21 | source(...) : unit | main.rs:27:10:27:10 | c | $@ | main.rs:24:13:24:21 | source(...) : unit | source(...) : unit |
|
||||
| main.rs:36:10:36:10 | b | main.rs:31:13:31:21 | source(...) : unit | main.rs:36:10:36:10 | b | $@ | main.rs:31:13:31:21 | source(...) : unit | source(...) : unit |
|
||||
| main.rs:47:10:47:10 | b | main.rs:45:15:45:23 | source(...) : unit | main.rs:47:10:47:10 | b | $@ | main.rs:45:15:45:23 | source(...) : unit | source(...) : unit |
|
||||
| main.rs:54:10:54:10 | i | main.rs:53:9:53:17 | source(...) : unit | main.rs:54:10:54:10 | i | $@ | main.rs:53:9:53:17 | source(...) : unit | source(...) : unit |
|
||||
| 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(...) |
|
||||
| main.rs:27:10:27:10 | c | main.rs:24:13:24:21 | source(...) | main.rs:27:10:27:10 | c | $@ | main.rs:24:13:24:21 | source(...) | source(...) |
|
||||
| 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: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(...) |
|
||||
|
||||
@@ -16,24 +16,24 @@ fn direct() {
|
||||
}
|
||||
|
||||
fn variable_usage() {
|
||||
let s = source(1);
|
||||
sink(s); // $ hasValueFlow=1
|
||||
let s = source(2);
|
||||
sink(s); // $ hasValueFlow=2
|
||||
}
|
||||
|
||||
fn if_expression(cond: bool) {
|
||||
let a = source(1);
|
||||
let a = source(3);
|
||||
let b = 2;
|
||||
let c = if cond { a } else { b };
|
||||
sink(c); // $ hasValueFlow=1
|
||||
sink(c); // $ hasValueFlow=3
|
||||
}
|
||||
|
||||
fn match_expression(m: Option<i64>) {
|
||||
let a = source(1);
|
||||
let a = source(4);
|
||||
let b = match m {
|
||||
Some(_) => a,
|
||||
None => 0,
|
||||
};
|
||||
sink(b); // $ hasValueFlow=1
|
||||
sink(b); // $ hasValueFlow=4
|
||||
}
|
||||
|
||||
fn loop_with_break() {
|
||||
@@ -42,29 +42,29 @@ fn loop_with_break() {
|
||||
};
|
||||
sink(a);
|
||||
let b = loop {
|
||||
break source(1);
|
||||
break source(5);
|
||||
};
|
||||
sink(b); // $ hasValueFlow=1
|
||||
sink(b); // $ hasValueFlow=5
|
||||
}
|
||||
|
||||
fn assignment() {
|
||||
let mut i = 1;
|
||||
sink(i);
|
||||
i = source(2);
|
||||
sink(i); // $ hasValueFlow=2
|
||||
i = source(6);
|
||||
sink(i); // $ hasValueFlow=6
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Data flow through data structures by writing and reading
|
||||
|
||||
fn box_deref() {
|
||||
let i = Box::new(source(1));
|
||||
sink(*i); // $ MISSING: hasValueFlow=1
|
||||
let i = Box::new(source(7));
|
||||
sink(*i); // $ MISSING: hasValueFlow=7
|
||||
}
|
||||
|
||||
fn tuple() {
|
||||
let a = (source(1), 2);
|
||||
sink(a.0); // $ MISSING: hasValueFlow=1
|
||||
let a = (source(8), 2);
|
||||
sink(a.0); // $ MISSING: hasValueFlow=8
|
||||
sink(a.1);
|
||||
}
|
||||
|
||||
@@ -76,13 +76,13 @@ struct Point {
|
||||
|
||||
fn struct_field() {
|
||||
let p = Point {
|
||||
x: source(1),
|
||||
x: source(9),
|
||||
y: 2,
|
||||
z: source(3),
|
||||
z: source(10),
|
||||
};
|
||||
sink(p.x); // MISSING: hasValueFlow=1
|
||||
sink(p.x); // $ MISSING: hasValueFlow=9
|
||||
sink(p.y);
|
||||
sink(p.z); // MISSING: hasValueFlow=3
|
||||
sink(p.z); // $ MISSING: hasValueFlow=10
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -90,21 +90,34 @@ fn struct_field() {
|
||||
|
||||
fn struct_pattern_match() {
|
||||
let p = Point {
|
||||
x: source(1),
|
||||
x: source(11),
|
||||
y: 2,
|
||||
z: source(3),
|
||||
z: source(12),
|
||||
};
|
||||
let Point { x: a, y: b, z: c } = p;
|
||||
sink(a); // MISSING: hasValueFlow=1
|
||||
sink(a); // $ MISSING: hasValueFlow=11
|
||||
sink(b);
|
||||
sink(c); // MISSING: hasValueFlow=3
|
||||
sink(c); // $ MISSING: hasValueFlow=12
|
||||
}
|
||||
|
||||
fn option_pattern_match() {
|
||||
let s1 = Some(source(1));
|
||||
fn option_pattern_match_qualified() {
|
||||
let s1 = Option::Some(source(13));
|
||||
let s2 = Option::Some(2);
|
||||
match s1 {
|
||||
Option::Some(n) => sink(n), // $ MISSING: hasValueFlow=13
|
||||
Option::None => sink(0),
|
||||
}
|
||||
match s2 {
|
||||
Option::Some(n) => sink(n),
|
||||
Option::None => sink(0),
|
||||
}
|
||||
}
|
||||
|
||||
fn option_pattern_match_unqualified() {
|
||||
let s1 = Some(source(14));
|
||||
let s2 = Some(2);
|
||||
match s1 {
|
||||
Some(n) => sink(n), // MISSING: hasValueFlow=3
|
||||
Some(n) => sink(n), // $ hasValueFlow=14
|
||||
None => sink(0),
|
||||
}
|
||||
match s2 {
|
||||
@@ -113,6 +126,88 @@ fn option_pattern_match() {
|
||||
}
|
||||
}
|
||||
|
||||
enum MyTupleEnum {
|
||||
A(i64),
|
||||
B(i64),
|
||||
}
|
||||
|
||||
fn custom_tuple_enum_pattern_match_qualified() {
|
||||
let s1 = MyTupleEnum::A(source(15));
|
||||
let s2 = MyTupleEnum::B(2);
|
||||
match s1 {
|
||||
MyTupleEnum::A(n) => sink(n), // $ hasValueFlow=15
|
||||
MyTupleEnum::B(n) => sink(n),
|
||||
}
|
||||
match s1 {
|
||||
(MyTupleEnum::A(n) | MyTupleEnum::B(n)) => sink(n), // $ hasValueFlow=15
|
||||
}
|
||||
match s2 {
|
||||
MyTupleEnum::A(n) => sink(n),
|
||||
MyTupleEnum::B(n) => sink(n),
|
||||
}
|
||||
}
|
||||
|
||||
use crate::MyTupleEnum::*;
|
||||
|
||||
fn custom_tuple_enum_pattern_match_unqualified() {
|
||||
let s1 = A(source(16));
|
||||
let s2 = B(2);
|
||||
match s1 {
|
||||
A(n) => sink(n), // $ MISSING: hasValueFlow=16
|
||||
B(n) => sink(n),
|
||||
}
|
||||
match s1 {
|
||||
(A(n) | B(n)) => sink(n), // $ MISSING: hasValueFlow=16
|
||||
}
|
||||
match s2 {
|
||||
A(n) => sink(n),
|
||||
B(n) => sink(n),
|
||||
}
|
||||
}
|
||||
|
||||
enum MyRecordEnum {
|
||||
C { field_c: i64 },
|
||||
D { field_d: i64 },
|
||||
}
|
||||
|
||||
fn custom_record_enum_pattern_match_qualified() {
|
||||
let s1 = MyRecordEnum::C {
|
||||
field_c: source(17),
|
||||
};
|
||||
let s2 = MyRecordEnum::D { field_d: 2 };
|
||||
match s1 {
|
||||
MyRecordEnum::C { field_c: n } => sink(n), // $ hasValueFlow=17
|
||||
MyRecordEnum::D { field_d: n } => sink(n),
|
||||
}
|
||||
match s1 {
|
||||
(MyRecordEnum::C { field_c: n } | MyRecordEnum::D { field_d: n }) => sink(n), // $ hasValueFlow=17
|
||||
}
|
||||
match s2 {
|
||||
MyRecordEnum::C { field_c: n } => sink(n),
|
||||
MyRecordEnum::D { field_d: n } => sink(n),
|
||||
}
|
||||
}
|
||||
|
||||
use crate::MyRecordEnum::*;
|
||||
|
||||
fn custom_record_enum_pattern_match_unqualified() {
|
||||
let s1 = C {
|
||||
field_c: source(18),
|
||||
};
|
||||
let s2 = D { field_d: 2 };
|
||||
match s1 {
|
||||
C { field_c: n } => sink(n), // $ MISSING: hasValueFlow=18
|
||||
D { field_d: n } => sink(n),
|
||||
}
|
||||
match s1 {
|
||||
(C { field_c: n } | D { field_d: n }) => sink(n), // $ MISSING: hasValueFlow=18
|
||||
}
|
||||
match s2 {
|
||||
C { field_c: n } => sink(n),
|
||||
D { field_d: n } => sink(n),
|
||||
}
|
||||
}
|
||||
|
||||
fn block_expression1() -> i64 {
|
||||
let a = { 0 };
|
||||
a
|
||||
@@ -149,7 +244,12 @@ fn main() {
|
||||
tuple();
|
||||
struct_field();
|
||||
struct_pattern_match();
|
||||
option_pattern_match();
|
||||
option_pattern_match_qualified();
|
||||
option_pattern_match_unqualified();
|
||||
custom_tuple_enum_pattern_match_qualified();
|
||||
custom_tuple_enum_pattern_match_unqualified();
|
||||
custom_record_enum_pattern_match_qualified();
|
||||
custom_record_enum_pattern_match_unqualified();
|
||||
block_expression1();
|
||||
block_expression2(true);
|
||||
block_expression3(true);
|
||||
|
||||
21
rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql
Normal file
21
rust/ql/test/library-tests/dataflow/sources/InlineFlow.ql
Normal file
@@ -0,0 +1,21 @@
|
||||
import rust
|
||||
import codeql.rust.dataflow.DataFlow
|
||||
import codeql.rust.Concepts
|
||||
import utils.InlineFlowTest
|
||||
|
||||
/**
|
||||
* Configuration for flow from any threat model source to an argument of the function `sink`.
|
||||
*/
|
||||
module MyFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof ThreatModelSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
any(CallExpr call |
|
||||
call.getFunction().(PathExpr).getPath().getResolvedPath() = "crate::test::sink"
|
||||
).getArgList().getAnArg() = sink.asExpr().getExpr()
|
||||
}
|
||||
}
|
||||
|
||||
module MyFlowTest = TaintFlowTest<MyFlowConfig>;
|
||||
|
||||
import MyFlowTest
|
||||
@@ -0,0 +1,17 @@
|
||||
| test.rs:8:10:8:30 | ...::var(...) | Flow source 'EnvironmentSource' of type environment. |
|
||||
| test.rs:9:10:9:33 | ...::var_os(...) | Flow source 'EnvironmentSource' of type environment. |
|
||||
| test.rs:11:16:11:36 | ...::var(...) | Flow source 'EnvironmentSource' of type environment. |
|
||||
| test.rs:12:16:12:39 | ...::var_os(...) | Flow source 'EnvironmentSource' of type environment. |
|
||||
| test.rs:17:25:17:40 | ...::vars(...) | Flow source 'EnvironmentSource' of type environment. |
|
||||
| test.rs:22:25:22:43 | ...::vars_os(...) | Flow source 'EnvironmentSource' of type environment. |
|
||||
| test.rs:29:29:29:44 | ...::args(...) | Flow source 'CommandLineArgs' of type commandargs. |
|
||||
| test.rs:32:16:32:31 | ...::args(...) | Flow source 'CommandLineArgs' of type commandargs. |
|
||||
| test.rs:33:16:33:34 | ...::args_os(...) | Flow source 'CommandLineArgs' of type commandargs. |
|
||||
| test.rs:40:16:40:31 | ...::args(...) | Flow source 'CommandLineArgs' of type commandargs. |
|
||||
| test.rs:44:16:44:34 | ...::args_os(...) | Flow source 'CommandLineArgs' of type commandargs. |
|
||||
| test.rs:50:15:50:37 | ...::current_dir(...) | Flow source 'CommandLineArgs' of type commandargs. |
|
||||
| test.rs:51:15:51:37 | ...::current_exe(...) | Flow source 'CommandLineArgs' of type commandargs. |
|
||||
| test.rs:52:16:52:35 | ...::home_dir(...) | Flow source 'CommandLineArgs' of type commandargs. |
|
||||
| test.rs:60:26:60:70 | ...::get(...) | Flow source 'RemoteSource' of type remote (DEFAULT). |
|
||||
| test.rs:63:26:63:70 | ...::get(...) | Flow source 'RemoteSource' of type remote (DEFAULT). |
|
||||
| test.rs:66:26:66:60 | ...::get(...) | Flow source 'RemoteSource' of type remote (DEFAULT). |
|
||||
@@ -0,0 +1,2 @@
|
||||
query: queries/summary/TaintSources.ql
|
||||
postprocess: utils/InlineExpectationsTestQuery.ql
|
||||
3
rust/ql/test/library-tests/dataflow/sources/options.yml
Normal file
3
rust/ql/test/library-tests/dataflow/sources/options.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
qltest_cargo_check: true
|
||||
qltest_dependencies:
|
||||
- reqwest = { version = "0.12.9", features = ["blocking"] }
|
||||
36
rust/ql/test/library-tests/dataflow/sources/reqwest.rs
Normal file
36
rust/ql/test/library-tests/dataflow/sources/reqwest.rs
Normal file
@@ -0,0 +1,36 @@
|
||||
|
||||
// --- stubs for the "reqwest" library ---
|
||||
|
||||
/*
|
||||
--- we don't seem to have a way to use this, hence we currently test against the real reqwest library
|
||||
#[derive(Debug)]
|
||||
pub struct Error { }
|
||||
|
||||
pub mod blocking {
|
||||
pub struct Response { }
|
||||
impl Response {
|
||||
pub fn text(self) -> Result<String, super::Error> {
|
||||
Ok("".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get<T>(url: T) -> Result<Response, super::Error> {
|
||||
let _url = url;
|
||||
|
||||
Ok(Response {})
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Response { }
|
||||
impl Response {
|
||||
pub async fn text(self) -> Result<String, Error> {
|
||||
Ok("".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get<T>(url: T) -> Result<Response, Error> {
|
||||
let _url = url;
|
||||
|
||||
Ok(Response {})
|
||||
}
|
||||
*/
|
||||
70
rust/ql/test/library-tests/dataflow/sources/test.rs
Normal file
70
rust/ql/test/library-tests/dataflow/sources/test.rs
Normal file
@@ -0,0 +1,70 @@
|
||||
#![allow(deprecated)]
|
||||
|
||||
fn sink<T>(_: T) { }
|
||||
|
||||
// --- tests ---
|
||||
|
||||
fn test_env_vars() {
|
||||
sink(std::env::var("HOME")); // $ Alert[rust/summary/taint-sources] hasTaintFlow
|
||||
sink(std::env::var_os("PATH")); // $ Alert[rust/summary/taint-sources] hasTaintFlow
|
||||
|
||||
let var1 = std::env::var("HOME").expect("HOME not set"); // $ Alert[rust/summary/taint-sources]
|
||||
let var2 = std::env::var_os("PATH").unwrap(); // $ Alert[rust/summary/taint-sources]
|
||||
|
||||
sink(var1); // $ MISSING: hasTaintFlow
|
||||
sink(var2); // $ MISSING: hasTaintFlow
|
||||
|
||||
for (key, value) in std::env::vars() { // $ Alert[rust/summary/taint-sources]
|
||||
sink(key); // $ MISSING: hasTaintFlow
|
||||
sink(value); // $ MISSING: hasTaintFlow
|
||||
}
|
||||
|
||||
for (key, value) in std::env::vars_os() { // $ Alert[rust/summary/taint-sources]
|
||||
sink(key); // $ MISSING: hasTaintFlow
|
||||
sink(value); // $ MISSING: hasTaintFlow
|
||||
}
|
||||
}
|
||||
|
||||
fn test_env_args() {
|
||||
let args: Vec<String> = std::env::args().collect(); // $ Alert[rust/summary/taint-sources]
|
||||
let my_path = &args[0];
|
||||
let arg1 = &args[1];
|
||||
let arg2 = std::env::args().nth(2).unwrap(); // $ Alert[rust/summary/taint-sources]
|
||||
let arg3 = std::env::args_os().nth(3).unwrap(); // $ Alert[rust/summary/taint-sources]
|
||||
|
||||
sink(my_path); // $ MISSING: hasTaintFlow
|
||||
sink(arg1); // $ MISSING: hasTaintFlow
|
||||
sink(arg2); // $ MISSING: hasTaintFlow
|
||||
sink(arg3); // $ MISSING: hasTaintFlow
|
||||
|
||||
for arg in std::env::args() { // $ Alert[rust/summary/taint-sources]
|
||||
sink(arg); // $ MISSING: hasTaintFlow
|
||||
}
|
||||
|
||||
for arg in std::env::args_os() { // $ Alert[rust/summary/taint-sources]
|
||||
sink(arg); // $ MISSING: hasTaintFlow
|
||||
}
|
||||
}
|
||||
|
||||
fn test_env_dirs() {
|
||||
let dir = std::env::current_dir().expect("FAILED"); // $ Alert[rust/summary/taint-sources]
|
||||
let exe = std::env::current_exe().expect("FAILED"); // $ Alert[rust/summary/taint-sources]
|
||||
let home = std::env::home_dir().expect("FAILED"); // $ Alert[rust/summary/taint-sources]
|
||||
|
||||
sink(dir); // $ MISSING: hasTaintFlow
|
||||
sink(exe); // $ MISSING: hasTaintFlow
|
||||
sink(home); // $ MISSING: hasTaintFlow
|
||||
}
|
||||
|
||||
async fn test_reqwest() -> Result<(), reqwest::Error> {
|
||||
let remote_string1 = reqwest::blocking::get("http://example.com/")?.text()?; // $ Alert[rust/summary/taint-sources]
|
||||
sink(remote_string1); // $ MISSING: hasTaintFlow
|
||||
|
||||
let remote_string2 = reqwest::blocking::get("http://example.com/").unwrap().text().unwrap(); // $ Alert[rust/summary/taint-sources]
|
||||
sink(remote_string2); // $ MISSING: hasTaintFlow
|
||||
|
||||
let remote_string3 = reqwest::get("http://example.com/").await?.text().await?; // $ Alert[rust/summary/taint-sources]
|
||||
sink(remote_string3); // $ MISSING: hasTaintFlow
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1078,195 +1078,201 @@ edges
|
||||
| variables.rs:483:9:483:24 | ExprStmt | variables.rs:483:16:483:19 | self | |
|
||||
| variables.rs:483:16:483:19 | self | variables.rs:483:16:483:23 | self.val | |
|
||||
| variables.rs:483:16:483:23 | self.val | variables.rs:483:9:483:23 | return ... | |
|
||||
| variables.rs:487:1:494:1 | enter fn structs | variables.rs:488:5:488:36 | let ... = ... | |
|
||||
| variables.rs:487:1:494:1 | exit fn structs (normal) | variables.rs:487:1:494:1 | exit fn structs | |
|
||||
| variables.rs:487:14:494:1 | { ... } | variables.rs:487:1:494:1 | exit fn structs (normal) | |
|
||||
| variables.rs:488:5:488:36 | let ... = ... | variables.rs:488:33:488:33 | 1 | |
|
||||
| variables.rs:488:9:488:13 | a | variables.rs:489:5:489:26 | ExprStmt | match |
|
||||
| variables.rs:488:17:488:35 | MyStruct {...} | variables.rs:488:9:488:13 | a | |
|
||||
| variables.rs:488:33:488:33 | 1 | variables.rs:488:17:488:35 | MyStruct {...} | |
|
||||
| variables.rs:489:5:489:13 | print_i64 | variables.rs:489:15:489:15 | a | |
|
||||
| variables.rs:489:5:489:25 | print_i64(...) | variables.rs:490:5:490:14 | ExprStmt | |
|
||||
| variables.rs:489:5:489:26 | ExprStmt | variables.rs:489:5:489:13 | print_i64 | |
|
||||
| variables.rs:489:15:489:15 | a | variables.rs:489:15:489:24 | ... .my_get(...) | |
|
||||
| variables.rs:489:15:489:24 | ... .my_get(...) | variables.rs:489:5:489:25 | print_i64(...) | |
|
||||
| variables.rs:490:5:490:5 | a | variables.rs:490:5:490:9 | a.val | |
|
||||
| variables.rs:490:5:490:9 | a.val | variables.rs:490:13:490:13 | 5 | |
|
||||
| variables.rs:490:5:490:13 | ... = ... | variables.rs:491:5:491:26 | ExprStmt | |
|
||||
| variables.rs:490:5:490:14 | ExprStmt | variables.rs:490:5:490:5 | a | |
|
||||
| variables.rs:490:13:490:13 | 5 | variables.rs:490:5:490:13 | ... = ... | |
|
||||
| variables.rs:491:5:491:13 | print_i64 | variables.rs:491:15:491:15 | a | |
|
||||
| variables.rs:491:5:491:25 | print_i64(...) | variables.rs:492:5:492:28 | ExprStmt | |
|
||||
| variables.rs:491:5:491:26 | ExprStmt | variables.rs:491:5:491:13 | print_i64 | |
|
||||
| variables.rs:491:15:491:15 | a | variables.rs:491:15:491:24 | ... .my_get(...) | |
|
||||
| variables.rs:491:15:491:24 | ... .my_get(...) | variables.rs:491:5:491:25 | print_i64(...) | |
|
||||
| variables.rs:492:5:492:5 | a | variables.rs:492:25:492:25 | 2 | |
|
||||
| variables.rs:492:5:492:27 | ... = ... | variables.rs:493:5:493:26 | ExprStmt | |
|
||||
| variables.rs:492:5:492:28 | ExprStmt | variables.rs:492:5:492:5 | a | |
|
||||
| variables.rs:492:9:492:27 | MyStruct {...} | variables.rs:492:5:492:27 | ... = ... | |
|
||||
| variables.rs:492:25:492:25 | 2 | variables.rs:492:9:492:27 | MyStruct {...} | |
|
||||
| variables.rs:486:5:488:5 | enter fn id | variables.rs:486:11:486:14 | self | |
|
||||
| variables.rs:486:5:488:5 | exit fn id (normal) | variables.rs:486:5:488:5 | exit fn id | |
|
||||
| variables.rs:486:11:486:14 | SelfParam | variables.rs:487:9:487:12 | self | |
|
||||
| variables.rs:486:11:486:14 | self | variables.rs:486:11:486:14 | SelfParam | |
|
||||
| variables.rs:486:25:488:5 | { ... } | variables.rs:486:5:488:5 | exit fn id (normal) | |
|
||||
| variables.rs:487:9:487:12 | self | variables.rs:486:25:488:5 | { ... } | |
|
||||
| variables.rs:491:1:498:1 | enter fn structs | variables.rs:492:5:492:36 | let ... = ... | |
|
||||
| variables.rs:491:1:498:1 | exit fn structs (normal) | variables.rs:491:1:498:1 | exit fn structs | |
|
||||
| variables.rs:491:14:498:1 | { ... } | variables.rs:491:1:498:1 | exit fn structs (normal) | |
|
||||
| variables.rs:492:5:492:36 | let ... = ... | variables.rs:492:33:492:33 | 1 | |
|
||||
| variables.rs:492:9:492:13 | a | variables.rs:493:5:493:26 | ExprStmt | match |
|
||||
| variables.rs:492:17:492:35 | MyStruct {...} | variables.rs:492:9:492:13 | a | |
|
||||
| variables.rs:492:33:492:33 | 1 | variables.rs:492:17:492:35 | MyStruct {...} | |
|
||||
| variables.rs:493:5:493:13 | print_i64 | variables.rs:493:15:493:15 | a | |
|
||||
| variables.rs:493:5:493:25 | print_i64(...) | variables.rs:487:14:494:1 | { ... } | |
|
||||
| variables.rs:493:5:493:25 | print_i64(...) | variables.rs:494:5:494:14 | ExprStmt | |
|
||||
| variables.rs:493:5:493:26 | ExprStmt | variables.rs:493:5:493:13 | print_i64 | |
|
||||
| variables.rs:493:15:493:15 | a | variables.rs:493:15:493:24 | ... .my_get(...) | |
|
||||
| variables.rs:493:15:493:24 | ... .my_get(...) | variables.rs:493:5:493:25 | print_i64(...) | |
|
||||
| variables.rs:496:1:503:1 | enter fn ref_arg | variables.rs:497:5:497:15 | let ... = 16 | |
|
||||
| variables.rs:496:1:503:1 | exit fn ref_arg (normal) | variables.rs:496:1:503:1 | exit fn ref_arg | |
|
||||
| variables.rs:496:14:503:1 | { ... } | variables.rs:496:1:503:1 | exit fn ref_arg (normal) | |
|
||||
| variables.rs:497:5:497:15 | let ... = 16 | variables.rs:497:13:497:14 | 16 | |
|
||||
| variables.rs:497:9:497:9 | x | variables.rs:498:5:498:22 | ExprStmt | match |
|
||||
| variables.rs:497:13:497:14 | 16 | variables.rs:497:9:497:9 | x | |
|
||||
| variables.rs:498:5:498:17 | print_i64_ref | variables.rs:498:20:498:20 | x | |
|
||||
| variables.rs:498:5:498:21 | print_i64_ref(...) | variables.rs:499:5:499:17 | ExprStmt | |
|
||||
| variables.rs:498:5:498:22 | ExprStmt | variables.rs:498:5:498:17 | print_i64_ref | |
|
||||
| variables.rs:498:19:498:20 | &x | variables.rs:498:5:498:21 | print_i64_ref(...) | |
|
||||
| variables.rs:498:20:498:20 | x | variables.rs:498:19:498:20 | &x | |
|
||||
| variables.rs:499:5:499:13 | print_i64 | variables.rs:499:15:499:15 | x | |
|
||||
| variables.rs:499:5:499:16 | print_i64(...) | variables.rs:501:5:501:15 | let ... = 17 | |
|
||||
| variables.rs:499:5:499:17 | ExprStmt | variables.rs:499:5:499:13 | print_i64 | |
|
||||
| variables.rs:499:15:499:15 | x | variables.rs:499:5:499:16 | print_i64(...) | |
|
||||
| variables.rs:501:5:501:15 | let ... = 17 | variables.rs:501:13:501:14 | 17 | |
|
||||
| variables.rs:501:9:501:9 | z | variables.rs:502:5:502:22 | ExprStmt | match |
|
||||
| variables.rs:501:13:501:14 | 17 | variables.rs:501:9:501:9 | z | |
|
||||
| variables.rs:502:5:502:17 | print_i64_ref | variables.rs:502:20:502:20 | z | |
|
||||
| variables.rs:502:5:502:21 | print_i64_ref(...) | variables.rs:496:14:503:1 | { ... } | |
|
||||
| variables.rs:494:5:494:5 | a | variables.rs:494:5:494:9 | a.val | |
|
||||
| variables.rs:494:5:494:9 | a.val | variables.rs:494:13:494:13 | 5 | |
|
||||
| variables.rs:494:5:494:13 | ... = ... | variables.rs:495:5:495:26 | ExprStmt | |
|
||||
| variables.rs:494:5:494:14 | ExprStmt | variables.rs:494:5:494:5 | a | |
|
||||
| variables.rs:494:13:494:13 | 5 | variables.rs:494:5:494:13 | ... = ... | |
|
||||
| variables.rs:495:5:495:13 | print_i64 | variables.rs:495:15:495:15 | a | |
|
||||
| variables.rs:495:5:495:25 | print_i64(...) | variables.rs:496:5:496:28 | ExprStmt | |
|
||||
| variables.rs:495:5:495:26 | ExprStmt | variables.rs:495:5:495:13 | print_i64 | |
|
||||
| variables.rs:495:15:495:15 | a | variables.rs:495:15:495:24 | ... .my_get(...) | |
|
||||
| variables.rs:495:15:495:24 | ... .my_get(...) | variables.rs:495:5:495:25 | print_i64(...) | |
|
||||
| variables.rs:496:5:496:5 | a | variables.rs:496:25:496:25 | 2 | |
|
||||
| variables.rs:496:5:496:27 | ... = ... | variables.rs:497:5:497:26 | ExprStmt | |
|
||||
| variables.rs:496:5:496:28 | ExprStmt | variables.rs:496:5:496:5 | a | |
|
||||
| variables.rs:496:9:496:27 | MyStruct {...} | variables.rs:496:5:496:27 | ... = ... | |
|
||||
| variables.rs:496:25:496:25 | 2 | variables.rs:496:9:496:27 | MyStruct {...} | |
|
||||
| variables.rs:497:5:497:13 | print_i64 | variables.rs:497:15:497:15 | a | |
|
||||
| variables.rs:497:5:497:25 | print_i64(...) | variables.rs:491:14:498:1 | { ... } | |
|
||||
| variables.rs:497:5:497:26 | ExprStmt | variables.rs:497:5:497:13 | print_i64 | |
|
||||
| variables.rs:497:15:497:15 | a | variables.rs:497:15:497:24 | ... .my_get(...) | |
|
||||
| variables.rs:497:15:497:24 | ... .my_get(...) | variables.rs:497:5:497:25 | print_i64(...) | |
|
||||
| variables.rs:500:1:507:1 | enter fn ref_arg | variables.rs:501:5:501:15 | let ... = 16 | |
|
||||
| variables.rs:500:1:507:1 | exit fn ref_arg (normal) | variables.rs:500:1:507:1 | exit fn ref_arg | |
|
||||
| variables.rs:500:14:507:1 | { ... } | variables.rs:500:1:507:1 | exit fn ref_arg (normal) | |
|
||||
| variables.rs:501:5:501:15 | let ... = 16 | variables.rs:501:13:501:14 | 16 | |
|
||||
| variables.rs:501:9:501:9 | x | variables.rs:502:5:502:22 | ExprStmt | match |
|
||||
| variables.rs:501:13:501:14 | 16 | variables.rs:501:9:501:9 | x | |
|
||||
| variables.rs:502:5:502:17 | print_i64_ref | variables.rs:502:20:502:20 | x | |
|
||||
| variables.rs:502:5:502:21 | print_i64_ref(...) | variables.rs:503:5:503:17 | ExprStmt | |
|
||||
| variables.rs:502:5:502:22 | ExprStmt | variables.rs:502:5:502:17 | print_i64_ref | |
|
||||
| variables.rs:502:19:502:20 | &z | variables.rs:502:5:502:21 | print_i64_ref(...) | |
|
||||
| variables.rs:502:20:502:20 | z | variables.rs:502:19:502:20 | &z | |
|
||||
| variables.rs:510:3:512:3 | enter fn bar | variables.rs:510:15:510:18 | self | |
|
||||
| variables.rs:510:3:512:3 | exit fn bar (normal) | variables.rs:510:3:512:3 | exit fn bar | |
|
||||
| variables.rs:510:10:510:18 | SelfParam | variables.rs:511:5:511:32 | ExprStmt | |
|
||||
| variables.rs:510:15:510:18 | self | variables.rs:510:10:510:18 | SelfParam | |
|
||||
| variables.rs:510:21:512:3 | { ... } | variables.rs:510:3:512:3 | exit fn bar (normal) | |
|
||||
| variables.rs:511:5:511:9 | * ... | variables.rs:511:29:511:29 | 3 | |
|
||||
| variables.rs:511:5:511:31 | ... = ... | variables.rs:510:21:512:3 | { ... } | |
|
||||
| variables.rs:511:5:511:32 | ExprStmt | variables.rs:511:6:511:9 | self | |
|
||||
| variables.rs:511:6:511:9 | self | variables.rs:511:5:511:9 | * ... | |
|
||||
| variables.rs:511:13:511:31 | MyStruct {...} | variables.rs:511:5:511:31 | ... = ... | |
|
||||
| variables.rs:511:29:511:29 | 3 | variables.rs:511:13:511:31 | MyStruct {...} | |
|
||||
| variables.rs:515:1:520:1 | enter fn ref_methodcall_receiver | variables.rs:516:3:516:34 | let ... = ... | |
|
||||
| variables.rs:515:1:520:1 | exit fn ref_methodcall_receiver (normal) | variables.rs:515:1:520:1 | exit fn ref_methodcall_receiver | |
|
||||
| variables.rs:515:30:520:1 | { ... } | variables.rs:515:1:520:1 | exit fn ref_methodcall_receiver (normal) | |
|
||||
| variables.rs:516:3:516:34 | let ... = ... | variables.rs:516:31:516:31 | 1 | |
|
||||
| variables.rs:516:7:516:11 | a | variables.rs:517:3:517:10 | ExprStmt | match |
|
||||
| variables.rs:516:15:516:33 | MyStruct {...} | variables.rs:516:7:516:11 | a | |
|
||||
| variables.rs:516:31:516:31 | 1 | variables.rs:516:15:516:33 | MyStruct {...} | |
|
||||
| variables.rs:517:3:517:3 | a | variables.rs:517:3:517:9 | ... .bar(...) | |
|
||||
| variables.rs:517:3:517:9 | ... .bar(...) | variables.rs:519:3:519:19 | ExprStmt | |
|
||||
| variables.rs:517:3:517:10 | ExprStmt | variables.rs:517:3:517:3 | a | |
|
||||
| variables.rs:519:3:519:11 | print_i64 | variables.rs:519:13:519:13 | a | |
|
||||
| variables.rs:519:3:519:18 | print_i64(...) | variables.rs:515:30:520:1 | { ... } | |
|
||||
| variables.rs:519:3:519:19 | ExprStmt | variables.rs:519:3:519:11 | print_i64 | |
|
||||
| variables.rs:519:13:519:13 | a | variables.rs:519:13:519:17 | a.val | |
|
||||
| variables.rs:519:13:519:17 | a.val | variables.rs:519:3:519:18 | print_i64(...) | |
|
||||
| variables.rs:522:1:556:1 | enter fn main | variables.rs:523:5:523:25 | ExprStmt | |
|
||||
| variables.rs:522:1:556:1 | exit fn main (normal) | variables.rs:522:1:556:1 | exit fn main | |
|
||||
| variables.rs:522:11:556:1 | { ... } | variables.rs:522:1:556:1 | exit fn main (normal) | |
|
||||
| variables.rs:523:5:523:22 | immutable_variable | variables.rs:523:5:523:24 | immutable_variable(...) | |
|
||||
| variables.rs:523:5:523:24 | immutable_variable(...) | variables.rs:524:5:524:23 | ExprStmt | |
|
||||
| variables.rs:523:5:523:25 | ExprStmt | variables.rs:523:5:523:22 | immutable_variable | |
|
||||
| variables.rs:524:5:524:20 | mutable_variable | variables.rs:524:5:524:22 | mutable_variable(...) | |
|
||||
| variables.rs:524:5:524:22 | mutable_variable(...) | variables.rs:525:5:525:40 | ExprStmt | |
|
||||
| variables.rs:524:5:524:23 | ExprStmt | variables.rs:524:5:524:20 | mutable_variable | |
|
||||
| variables.rs:525:5:525:37 | mutable_variable_immutable_borrow | variables.rs:525:5:525:39 | mutable_variable_immutable_borrow(...) | |
|
||||
| variables.rs:525:5:525:39 | mutable_variable_immutable_borrow(...) | variables.rs:526:5:526:23 | ExprStmt | |
|
||||
| variables.rs:525:5:525:40 | ExprStmt | variables.rs:525:5:525:37 | mutable_variable_immutable_borrow | |
|
||||
| variables.rs:526:5:526:20 | variable_shadow1 | variables.rs:526:5:526:22 | variable_shadow1(...) | |
|
||||
| variables.rs:526:5:526:22 | variable_shadow1(...) | variables.rs:527:5:527:23 | ExprStmt | |
|
||||
| variables.rs:526:5:526:23 | ExprStmt | variables.rs:526:5:526:20 | variable_shadow1 | |
|
||||
| variables.rs:527:5:527:20 | variable_shadow2 | variables.rs:527:5:527:22 | variable_shadow2(...) | |
|
||||
| variables.rs:527:5:527:22 | variable_shadow2(...) | variables.rs:528:5:528:19 | ExprStmt | |
|
||||
| variables.rs:527:5:527:23 | ExprStmt | variables.rs:527:5:527:20 | variable_shadow2 | |
|
||||
| variables.rs:528:5:528:16 | let_pattern1 | variables.rs:528:5:528:18 | let_pattern1(...) | |
|
||||
| variables.rs:528:5:528:18 | let_pattern1(...) | variables.rs:529:5:529:19 | ExprStmt | |
|
||||
| variables.rs:528:5:528:19 | ExprStmt | variables.rs:528:5:528:16 | let_pattern1 | |
|
||||
| variables.rs:529:5:529:16 | let_pattern2 | variables.rs:529:5:529:18 | let_pattern2(...) | |
|
||||
| variables.rs:529:5:529:18 | let_pattern2(...) | variables.rs:530:5:530:19 | ExprStmt | |
|
||||
| variables.rs:529:5:529:19 | ExprStmt | variables.rs:529:5:529:16 | let_pattern2 | |
|
||||
| variables.rs:530:5:530:16 | let_pattern3 | variables.rs:530:5:530:18 | let_pattern3(...) | |
|
||||
| variables.rs:530:5:530:18 | let_pattern3(...) | variables.rs:531:5:531:19 | ExprStmt | |
|
||||
| variables.rs:530:5:530:19 | ExprStmt | variables.rs:530:5:530:16 | let_pattern3 | |
|
||||
| variables.rs:531:5:531:16 | let_pattern4 | variables.rs:531:5:531:18 | let_pattern4(...) | |
|
||||
| variables.rs:531:5:531:18 | let_pattern4(...) | variables.rs:532:5:532:21 | ExprStmt | |
|
||||
| variables.rs:531:5:531:19 | ExprStmt | variables.rs:531:5:531:16 | let_pattern4 | |
|
||||
| variables.rs:532:5:532:18 | match_pattern1 | variables.rs:532:5:532:20 | match_pattern1(...) | |
|
||||
| variables.rs:532:5:532:20 | match_pattern1(...) | variables.rs:533:5:533:21 | ExprStmt | |
|
||||
| variables.rs:532:5:532:21 | ExprStmt | variables.rs:532:5:532:18 | match_pattern1 | |
|
||||
| variables.rs:533:5:533:18 | match_pattern2 | variables.rs:533:5:533:20 | match_pattern2(...) | |
|
||||
| variables.rs:533:5:533:20 | match_pattern2(...) | variables.rs:534:5:534:21 | ExprStmt | |
|
||||
| variables.rs:533:5:533:21 | ExprStmt | variables.rs:533:5:533:18 | match_pattern2 | |
|
||||
| variables.rs:534:5:534:18 | match_pattern3 | variables.rs:534:5:534:20 | match_pattern3(...) | |
|
||||
| variables.rs:534:5:534:20 | match_pattern3(...) | variables.rs:535:5:535:21 | ExprStmt | |
|
||||
| variables.rs:534:5:534:21 | ExprStmt | variables.rs:534:5:534:18 | match_pattern3 | |
|
||||
| variables.rs:535:5:535:18 | match_pattern4 | variables.rs:535:5:535:20 | match_pattern4(...) | |
|
||||
| variables.rs:535:5:535:20 | match_pattern4(...) | variables.rs:536:5:536:21 | ExprStmt | |
|
||||
| variables.rs:535:5:535:21 | ExprStmt | variables.rs:535:5:535:18 | match_pattern4 | |
|
||||
| variables.rs:536:5:536:18 | match_pattern5 | variables.rs:536:5:536:20 | match_pattern5(...) | |
|
||||
| variables.rs:536:5:536:20 | match_pattern5(...) | variables.rs:537:5:537:21 | ExprStmt | |
|
||||
| variables.rs:536:5:536:21 | ExprStmt | variables.rs:536:5:536:18 | match_pattern5 | |
|
||||
| variables.rs:537:5:537:18 | match_pattern6 | variables.rs:537:5:537:20 | match_pattern6(...) | |
|
||||
| variables.rs:537:5:537:20 | match_pattern6(...) | variables.rs:538:5:538:21 | ExprStmt | |
|
||||
| variables.rs:537:5:537:21 | ExprStmt | variables.rs:537:5:537:18 | match_pattern6 | |
|
||||
| variables.rs:538:5:538:18 | match_pattern7 | variables.rs:538:5:538:20 | match_pattern7(...) | |
|
||||
| variables.rs:538:5:538:20 | match_pattern7(...) | variables.rs:539:5:539:21 | ExprStmt | |
|
||||
| variables.rs:538:5:538:21 | ExprStmt | variables.rs:538:5:538:18 | match_pattern7 | |
|
||||
| variables.rs:539:5:539:18 | match_pattern8 | variables.rs:539:5:539:20 | match_pattern8(...) | |
|
||||
| variables.rs:539:5:539:20 | match_pattern8(...) | variables.rs:540:5:540:21 | ExprStmt | |
|
||||
| variables.rs:539:5:539:21 | ExprStmt | variables.rs:539:5:539:18 | match_pattern8 | |
|
||||
| variables.rs:540:5:540:18 | match_pattern9 | variables.rs:540:5:540:20 | match_pattern9(...) | |
|
||||
| variables.rs:540:5:540:20 | match_pattern9(...) | variables.rs:541:5:541:36 | ExprStmt | |
|
||||
| variables.rs:540:5:540:21 | ExprStmt | variables.rs:540:5:540:18 | match_pattern9 | |
|
||||
| variables.rs:541:5:541:18 | param_pattern1 | variables.rs:541:20:541:22 | "a" | |
|
||||
| variables.rs:541:5:541:35 | param_pattern1(...) | variables.rs:542:5:542:37 | ExprStmt | |
|
||||
| variables.rs:541:5:541:36 | ExprStmt | variables.rs:541:5:541:18 | param_pattern1 | |
|
||||
| variables.rs:541:20:541:22 | "a" | variables.rs:541:26:541:28 | "b" | |
|
||||
| variables.rs:541:25:541:34 | TupleExpr | variables.rs:541:5:541:35 | param_pattern1(...) | |
|
||||
| variables.rs:541:26:541:28 | "b" | variables.rs:541:31:541:33 | "c" | |
|
||||
| variables.rs:541:31:541:33 | "c" | variables.rs:541:25:541:34 | TupleExpr | |
|
||||
| variables.rs:542:5:542:18 | param_pattern2 | variables.rs:542:20:542:31 | ...::Left | |
|
||||
| variables.rs:542:5:542:36 | param_pattern2(...) | variables.rs:543:5:543:26 | ExprStmt | |
|
||||
| variables.rs:542:5:542:37 | ExprStmt | variables.rs:542:5:542:18 | param_pattern2 | |
|
||||
| variables.rs:542:20:542:31 | ...::Left | variables.rs:542:33:542:34 | 45 | |
|
||||
| variables.rs:542:20:542:35 | ...::Left(...) | variables.rs:542:5:542:36 | param_pattern2(...) | |
|
||||
| variables.rs:542:33:542:34 | 45 | variables.rs:542:20:542:35 | ...::Left(...) | |
|
||||
| variables.rs:543:5:543:23 | destruct_assignment | variables.rs:543:5:543:25 | destruct_assignment(...) | |
|
||||
| variables.rs:543:5:543:25 | destruct_assignment(...) | variables.rs:544:5:544:23 | ExprStmt | |
|
||||
| variables.rs:543:5:543:26 | ExprStmt | variables.rs:543:5:543:23 | destruct_assignment | |
|
||||
| variables.rs:544:5:544:20 | closure_variable | variables.rs:544:5:544:22 | closure_variable(...) | |
|
||||
| variables.rs:544:5:544:22 | closure_variable(...) | variables.rs:545:5:545:19 | ExprStmt | |
|
||||
| variables.rs:544:5:544:23 | ExprStmt | variables.rs:544:5:544:20 | closure_variable | |
|
||||
| variables.rs:545:5:545:16 | for_variable | variables.rs:545:5:545:18 | for_variable(...) | |
|
||||
| variables.rs:545:5:545:18 | for_variable(...) | variables.rs:546:5:546:17 | ExprStmt | |
|
||||
| variables.rs:545:5:545:19 | ExprStmt | variables.rs:545:5:545:16 | for_variable | |
|
||||
| variables.rs:546:5:546:14 | add_assign | variables.rs:546:5:546:16 | add_assign(...) | |
|
||||
| variables.rs:546:5:546:16 | add_assign(...) | variables.rs:547:5:547:13 | ExprStmt | |
|
||||
| variables.rs:546:5:546:17 | ExprStmt | variables.rs:546:5:546:14 | add_assign | |
|
||||
| variables.rs:547:5:547:10 | mutate | variables.rs:547:5:547:12 | mutate(...) | |
|
||||
| variables.rs:547:5:547:12 | mutate(...) | variables.rs:548:5:548:17 | ExprStmt | |
|
||||
| variables.rs:547:5:547:13 | ExprStmt | variables.rs:547:5:547:10 | mutate | |
|
||||
| variables.rs:548:5:548:14 | mutate_arg | variables.rs:548:5:548:16 | mutate_arg(...) | |
|
||||
| variables.rs:548:5:548:16 | mutate_arg(...) | variables.rs:549:5:549:12 | ExprStmt | |
|
||||
| variables.rs:548:5:548:17 | ExprStmt | variables.rs:548:5:548:14 | mutate_arg | |
|
||||
| variables.rs:549:5:549:9 | alias | variables.rs:549:5:549:11 | alias(...) | |
|
||||
| variables.rs:549:5:549:11 | alias(...) | variables.rs:550:5:550:18 | ExprStmt | |
|
||||
| variables.rs:549:5:549:12 | ExprStmt | variables.rs:549:5:549:9 | alias | |
|
||||
| variables.rs:550:5:550:15 | capture_mut | variables.rs:550:5:550:17 | capture_mut(...) | |
|
||||
| variables.rs:550:5:550:17 | capture_mut(...) | variables.rs:551:5:551:20 | ExprStmt | |
|
||||
| variables.rs:550:5:550:18 | ExprStmt | variables.rs:550:5:550:15 | capture_mut | |
|
||||
| variables.rs:551:5:551:17 | capture_immut | variables.rs:551:5:551:19 | capture_immut(...) | |
|
||||
| variables.rs:551:5:551:19 | capture_immut(...) | variables.rs:552:5:552:26 | ExprStmt | |
|
||||
| variables.rs:551:5:551:20 | ExprStmt | variables.rs:551:5:551:17 | capture_immut | |
|
||||
| variables.rs:552:5:552:23 | async_block_capture | variables.rs:552:5:552:25 | async_block_capture(...) | |
|
||||
| variables.rs:552:5:552:25 | async_block_capture(...) | variables.rs:553:5:553:14 | ExprStmt | |
|
||||
| variables.rs:552:5:552:26 | ExprStmt | variables.rs:552:5:552:23 | async_block_capture | |
|
||||
| variables.rs:553:5:553:11 | structs | variables.rs:553:5:553:13 | structs(...) | |
|
||||
| variables.rs:553:5:553:13 | structs(...) | variables.rs:554:5:554:14 | ExprStmt | |
|
||||
| variables.rs:553:5:553:14 | ExprStmt | variables.rs:553:5:553:11 | structs | |
|
||||
| variables.rs:554:5:554:11 | ref_arg | variables.rs:554:5:554:13 | ref_arg(...) | |
|
||||
| variables.rs:554:5:554:13 | ref_arg(...) | variables.rs:555:5:555:30 | ExprStmt | |
|
||||
| variables.rs:554:5:554:14 | ExprStmt | variables.rs:554:5:554:11 | ref_arg | |
|
||||
| variables.rs:555:5:555:27 | ref_methodcall_receiver | variables.rs:555:5:555:29 | ref_methodcall_receiver(...) | |
|
||||
| variables.rs:555:5:555:29 | ref_methodcall_receiver(...) | variables.rs:522:11:556:1 | { ... } | |
|
||||
| variables.rs:555:5:555:30 | ExprStmt | variables.rs:555:5:555:27 | ref_methodcall_receiver | |
|
||||
| variables.rs:502:19:502:20 | &x | variables.rs:502:5:502:21 | print_i64_ref(...) | |
|
||||
| variables.rs:502:20:502:20 | x | variables.rs:502:19:502:20 | &x | |
|
||||
| variables.rs:503:5:503:13 | print_i64 | variables.rs:503:15:503:15 | x | |
|
||||
| variables.rs:503:5:503:16 | print_i64(...) | variables.rs:505:5:505:15 | let ... = 17 | |
|
||||
| variables.rs:503:5:503:17 | ExprStmt | variables.rs:503:5:503:13 | print_i64 | |
|
||||
| variables.rs:503:15:503:15 | x | variables.rs:503:5:503:16 | print_i64(...) | |
|
||||
| variables.rs:505:5:505:15 | let ... = 17 | variables.rs:505:13:505:14 | 17 | |
|
||||
| variables.rs:505:9:505:9 | z | variables.rs:506:5:506:22 | ExprStmt | match |
|
||||
| variables.rs:505:13:505:14 | 17 | variables.rs:505:9:505:9 | z | |
|
||||
| variables.rs:506:5:506:17 | print_i64_ref | variables.rs:506:20:506:20 | z | |
|
||||
| variables.rs:506:5:506:21 | print_i64_ref(...) | variables.rs:500:14:507:1 | { ... } | |
|
||||
| variables.rs:506:5:506:22 | ExprStmt | variables.rs:506:5:506:17 | print_i64_ref | |
|
||||
| variables.rs:506:19:506:20 | &z | variables.rs:506:5:506:21 | print_i64_ref(...) | |
|
||||
| variables.rs:506:20:506:20 | z | variables.rs:506:19:506:20 | &z | |
|
||||
| variables.rs:514:3:516:3 | enter fn bar | variables.rs:514:15:514:18 | self | |
|
||||
| variables.rs:514:3:516:3 | exit fn bar (normal) | variables.rs:514:3:516:3 | exit fn bar | |
|
||||
| variables.rs:514:10:514:18 | SelfParam | variables.rs:515:5:515:32 | ExprStmt | |
|
||||
| variables.rs:514:15:514:18 | self | variables.rs:514:10:514:18 | SelfParam | |
|
||||
| variables.rs:514:21:516:3 | { ... } | variables.rs:514:3:516:3 | exit fn bar (normal) | |
|
||||
| variables.rs:515:5:515:9 | * ... | variables.rs:515:29:515:29 | 3 | |
|
||||
| variables.rs:515:5:515:31 | ... = ... | variables.rs:514:21:516:3 | { ... } | |
|
||||
| variables.rs:515:5:515:32 | ExprStmt | variables.rs:515:6:515:9 | self | |
|
||||
| variables.rs:515:6:515:9 | self | variables.rs:515:5:515:9 | * ... | |
|
||||
| variables.rs:515:13:515:31 | MyStruct {...} | variables.rs:515:5:515:31 | ... = ... | |
|
||||
| variables.rs:515:29:515:29 | 3 | variables.rs:515:13:515:31 | MyStruct {...} | |
|
||||
| variables.rs:519:1:524:1 | enter fn ref_methodcall_receiver | variables.rs:520:3:520:34 | let ... = ... | |
|
||||
| variables.rs:519:1:524:1 | exit fn ref_methodcall_receiver (normal) | variables.rs:519:1:524:1 | exit fn ref_methodcall_receiver | |
|
||||
| variables.rs:519:30:524:1 | { ... } | variables.rs:519:1:524:1 | exit fn ref_methodcall_receiver (normal) | |
|
||||
| variables.rs:520:3:520:34 | let ... = ... | variables.rs:520:31:520:31 | 1 | |
|
||||
| variables.rs:520:7:520:11 | a | variables.rs:521:3:521:10 | ExprStmt | match |
|
||||
| variables.rs:520:15:520:33 | MyStruct {...} | variables.rs:520:7:520:11 | a | |
|
||||
| variables.rs:520:31:520:31 | 1 | variables.rs:520:15:520:33 | MyStruct {...} | |
|
||||
| variables.rs:521:3:521:3 | a | variables.rs:521:3:521:9 | ... .bar(...) | |
|
||||
| variables.rs:521:3:521:9 | ... .bar(...) | variables.rs:523:3:523:19 | ExprStmt | |
|
||||
| variables.rs:521:3:521:10 | ExprStmt | variables.rs:521:3:521:3 | a | |
|
||||
| variables.rs:523:3:523:11 | print_i64 | variables.rs:523:13:523:13 | a | |
|
||||
| variables.rs:523:3:523:18 | print_i64(...) | variables.rs:519:30:524:1 | { ... } | |
|
||||
| variables.rs:523:3:523:19 | ExprStmt | variables.rs:523:3:523:11 | print_i64 | |
|
||||
| variables.rs:523:13:523:13 | a | variables.rs:523:13:523:17 | a.val | |
|
||||
| variables.rs:523:13:523:17 | a.val | variables.rs:523:3:523:18 | print_i64(...) | |
|
||||
| variables.rs:526:1:560:1 | enter fn main | variables.rs:527:5:527:25 | ExprStmt | |
|
||||
| variables.rs:526:1:560:1 | exit fn main (normal) | variables.rs:526:1:560:1 | exit fn main | |
|
||||
| variables.rs:526:11:560:1 | { ... } | variables.rs:526:1:560:1 | exit fn main (normal) | |
|
||||
| variables.rs:527:5:527:22 | immutable_variable | variables.rs:527:5:527:24 | immutable_variable(...) | |
|
||||
| variables.rs:527:5:527:24 | immutable_variable(...) | variables.rs:528:5:528:23 | ExprStmt | |
|
||||
| variables.rs:527:5:527:25 | ExprStmt | variables.rs:527:5:527:22 | immutable_variable | |
|
||||
| variables.rs:528:5:528:20 | mutable_variable | variables.rs:528:5:528:22 | mutable_variable(...) | |
|
||||
| variables.rs:528:5:528:22 | mutable_variable(...) | variables.rs:529:5:529:40 | ExprStmt | |
|
||||
| variables.rs:528:5:528:23 | ExprStmt | variables.rs:528:5:528:20 | mutable_variable | |
|
||||
| variables.rs:529:5:529:37 | mutable_variable_immutable_borrow | variables.rs:529:5:529:39 | mutable_variable_immutable_borrow(...) | |
|
||||
| variables.rs:529:5:529:39 | mutable_variable_immutable_borrow(...) | variables.rs:530:5:530:23 | ExprStmt | |
|
||||
| variables.rs:529:5:529:40 | ExprStmt | variables.rs:529:5:529:37 | mutable_variable_immutable_borrow | |
|
||||
| variables.rs:530:5:530:20 | variable_shadow1 | variables.rs:530:5:530:22 | variable_shadow1(...) | |
|
||||
| variables.rs:530:5:530:22 | variable_shadow1(...) | variables.rs:531:5:531:23 | ExprStmt | |
|
||||
| variables.rs:530:5:530:23 | ExprStmt | variables.rs:530:5:530:20 | variable_shadow1 | |
|
||||
| variables.rs:531:5:531:20 | variable_shadow2 | variables.rs:531:5:531:22 | variable_shadow2(...) | |
|
||||
| variables.rs:531:5:531:22 | variable_shadow2(...) | variables.rs:532:5:532:19 | ExprStmt | |
|
||||
| variables.rs:531:5:531:23 | ExprStmt | variables.rs:531:5:531:20 | variable_shadow2 | |
|
||||
| variables.rs:532:5:532:16 | let_pattern1 | variables.rs:532:5:532:18 | let_pattern1(...) | |
|
||||
| variables.rs:532:5:532:18 | let_pattern1(...) | variables.rs:533:5:533:19 | ExprStmt | |
|
||||
| variables.rs:532:5:532:19 | ExprStmt | variables.rs:532:5:532:16 | let_pattern1 | |
|
||||
| variables.rs:533:5:533:16 | let_pattern2 | variables.rs:533:5:533:18 | let_pattern2(...) | |
|
||||
| variables.rs:533:5:533:18 | let_pattern2(...) | variables.rs:534:5:534:19 | ExprStmt | |
|
||||
| variables.rs:533:5:533:19 | ExprStmt | variables.rs:533:5:533:16 | let_pattern2 | |
|
||||
| variables.rs:534:5:534:16 | let_pattern3 | variables.rs:534:5:534:18 | let_pattern3(...) | |
|
||||
| variables.rs:534:5:534:18 | let_pattern3(...) | variables.rs:535:5:535:19 | ExprStmt | |
|
||||
| variables.rs:534:5:534:19 | ExprStmt | variables.rs:534:5:534:16 | let_pattern3 | |
|
||||
| variables.rs:535:5:535:16 | let_pattern4 | variables.rs:535:5:535:18 | let_pattern4(...) | |
|
||||
| variables.rs:535:5:535:18 | let_pattern4(...) | variables.rs:536:5:536:21 | ExprStmt | |
|
||||
| variables.rs:535:5:535:19 | ExprStmt | variables.rs:535:5:535:16 | let_pattern4 | |
|
||||
| variables.rs:536:5:536:18 | match_pattern1 | variables.rs:536:5:536:20 | match_pattern1(...) | |
|
||||
| variables.rs:536:5:536:20 | match_pattern1(...) | variables.rs:537:5:537:21 | ExprStmt | |
|
||||
| variables.rs:536:5:536:21 | ExprStmt | variables.rs:536:5:536:18 | match_pattern1 | |
|
||||
| variables.rs:537:5:537:18 | match_pattern2 | variables.rs:537:5:537:20 | match_pattern2(...) | |
|
||||
| variables.rs:537:5:537:20 | match_pattern2(...) | variables.rs:538:5:538:21 | ExprStmt | |
|
||||
| variables.rs:537:5:537:21 | ExprStmt | variables.rs:537:5:537:18 | match_pattern2 | |
|
||||
| variables.rs:538:5:538:18 | match_pattern3 | variables.rs:538:5:538:20 | match_pattern3(...) | |
|
||||
| variables.rs:538:5:538:20 | match_pattern3(...) | variables.rs:539:5:539:21 | ExprStmt | |
|
||||
| variables.rs:538:5:538:21 | ExprStmt | variables.rs:538:5:538:18 | match_pattern3 | |
|
||||
| variables.rs:539:5:539:18 | match_pattern4 | variables.rs:539:5:539:20 | match_pattern4(...) | |
|
||||
| variables.rs:539:5:539:20 | match_pattern4(...) | variables.rs:540:5:540:21 | ExprStmt | |
|
||||
| variables.rs:539:5:539:21 | ExprStmt | variables.rs:539:5:539:18 | match_pattern4 | |
|
||||
| variables.rs:540:5:540:18 | match_pattern5 | variables.rs:540:5:540:20 | match_pattern5(...) | |
|
||||
| variables.rs:540:5:540:20 | match_pattern5(...) | variables.rs:541:5:541:21 | ExprStmt | |
|
||||
| variables.rs:540:5:540:21 | ExprStmt | variables.rs:540:5:540:18 | match_pattern5 | |
|
||||
| variables.rs:541:5:541:18 | match_pattern6 | variables.rs:541:5:541:20 | match_pattern6(...) | |
|
||||
| variables.rs:541:5:541:20 | match_pattern6(...) | variables.rs:542:5:542:21 | ExprStmt | |
|
||||
| variables.rs:541:5:541:21 | ExprStmt | variables.rs:541:5:541:18 | match_pattern6 | |
|
||||
| variables.rs:542:5:542:18 | match_pattern7 | variables.rs:542:5:542:20 | match_pattern7(...) | |
|
||||
| variables.rs:542:5:542:20 | match_pattern7(...) | variables.rs:543:5:543:21 | ExprStmt | |
|
||||
| variables.rs:542:5:542:21 | ExprStmt | variables.rs:542:5:542:18 | match_pattern7 | |
|
||||
| variables.rs:543:5:543:18 | match_pattern8 | variables.rs:543:5:543:20 | match_pattern8(...) | |
|
||||
| variables.rs:543:5:543:20 | match_pattern8(...) | variables.rs:544:5:544:21 | ExprStmt | |
|
||||
| variables.rs:543:5:543:21 | ExprStmt | variables.rs:543:5:543:18 | match_pattern8 | |
|
||||
| variables.rs:544:5:544:18 | match_pattern9 | variables.rs:544:5:544:20 | match_pattern9(...) | |
|
||||
| variables.rs:544:5:544:20 | match_pattern9(...) | variables.rs:545:5:545:36 | ExprStmt | |
|
||||
| variables.rs:544:5:544:21 | ExprStmt | variables.rs:544:5:544:18 | match_pattern9 | |
|
||||
| variables.rs:545:5:545:18 | param_pattern1 | variables.rs:545:20:545:22 | "a" | |
|
||||
| variables.rs:545:5:545:35 | param_pattern1(...) | variables.rs:546:5:546:37 | ExprStmt | |
|
||||
| variables.rs:545:5:545:36 | ExprStmt | variables.rs:545:5:545:18 | param_pattern1 | |
|
||||
| variables.rs:545:20:545:22 | "a" | variables.rs:545:26:545:28 | "b" | |
|
||||
| variables.rs:545:25:545:34 | TupleExpr | variables.rs:545:5:545:35 | param_pattern1(...) | |
|
||||
| variables.rs:545:26:545:28 | "b" | variables.rs:545:31:545:33 | "c" | |
|
||||
| variables.rs:545:31:545:33 | "c" | variables.rs:545:25:545:34 | TupleExpr | |
|
||||
| variables.rs:546:5:546:18 | param_pattern2 | variables.rs:546:20:546:31 | ...::Left | |
|
||||
| variables.rs:546:5:546:36 | param_pattern2(...) | variables.rs:547:5:547:26 | ExprStmt | |
|
||||
| variables.rs:546:5:546:37 | ExprStmt | variables.rs:546:5:546:18 | param_pattern2 | |
|
||||
| variables.rs:546:20:546:31 | ...::Left | variables.rs:546:33:546:34 | 45 | |
|
||||
| variables.rs:546:20:546:35 | ...::Left(...) | variables.rs:546:5:546:36 | param_pattern2(...) | |
|
||||
| variables.rs:546:33:546:34 | 45 | variables.rs:546:20:546:35 | ...::Left(...) | |
|
||||
| variables.rs:547:5:547:23 | destruct_assignment | variables.rs:547:5:547:25 | destruct_assignment(...) | |
|
||||
| variables.rs:547:5:547:25 | destruct_assignment(...) | variables.rs:548:5:548:23 | ExprStmt | |
|
||||
| variables.rs:547:5:547:26 | ExprStmt | variables.rs:547:5:547:23 | destruct_assignment | |
|
||||
| variables.rs:548:5:548:20 | closure_variable | variables.rs:548:5:548:22 | closure_variable(...) | |
|
||||
| variables.rs:548:5:548:22 | closure_variable(...) | variables.rs:549:5:549:19 | ExprStmt | |
|
||||
| variables.rs:548:5:548:23 | ExprStmt | variables.rs:548:5:548:20 | closure_variable | |
|
||||
| variables.rs:549:5:549:16 | for_variable | variables.rs:549:5:549:18 | for_variable(...) | |
|
||||
| variables.rs:549:5:549:18 | for_variable(...) | variables.rs:550:5:550:17 | ExprStmt | |
|
||||
| variables.rs:549:5:549:19 | ExprStmt | variables.rs:549:5:549:16 | for_variable | |
|
||||
| variables.rs:550:5:550:14 | add_assign | variables.rs:550:5:550:16 | add_assign(...) | |
|
||||
| variables.rs:550:5:550:16 | add_assign(...) | variables.rs:551:5:551:13 | ExprStmt | |
|
||||
| variables.rs:550:5:550:17 | ExprStmt | variables.rs:550:5:550:14 | add_assign | |
|
||||
| variables.rs:551:5:551:10 | mutate | variables.rs:551:5:551:12 | mutate(...) | |
|
||||
| variables.rs:551:5:551:12 | mutate(...) | variables.rs:552:5:552:17 | ExprStmt | |
|
||||
| variables.rs:551:5:551:13 | ExprStmt | variables.rs:551:5:551:10 | mutate | |
|
||||
| variables.rs:552:5:552:14 | mutate_arg | variables.rs:552:5:552:16 | mutate_arg(...) | |
|
||||
| variables.rs:552:5:552:16 | mutate_arg(...) | variables.rs:553:5:553:12 | ExprStmt | |
|
||||
| variables.rs:552:5:552:17 | ExprStmt | variables.rs:552:5:552:14 | mutate_arg | |
|
||||
| variables.rs:553:5:553:9 | alias | variables.rs:553:5:553:11 | alias(...) | |
|
||||
| variables.rs:553:5:553:11 | alias(...) | variables.rs:554:5:554:18 | ExprStmt | |
|
||||
| variables.rs:553:5:553:12 | ExprStmt | variables.rs:553:5:553:9 | alias | |
|
||||
| variables.rs:554:5:554:15 | capture_mut | variables.rs:554:5:554:17 | capture_mut(...) | |
|
||||
| variables.rs:554:5:554:17 | capture_mut(...) | variables.rs:555:5:555:20 | ExprStmt | |
|
||||
| variables.rs:554:5:554:18 | ExprStmt | variables.rs:554:5:554:15 | capture_mut | |
|
||||
| variables.rs:555:5:555:17 | capture_immut | variables.rs:555:5:555:19 | capture_immut(...) | |
|
||||
| variables.rs:555:5:555:19 | capture_immut(...) | variables.rs:556:5:556:26 | ExprStmt | |
|
||||
| variables.rs:555:5:555:20 | ExprStmt | variables.rs:555:5:555:17 | capture_immut | |
|
||||
| variables.rs:556:5:556:23 | async_block_capture | variables.rs:556:5:556:25 | async_block_capture(...) | |
|
||||
| variables.rs:556:5:556:25 | async_block_capture(...) | variables.rs:557:5:557:14 | ExprStmt | |
|
||||
| variables.rs:556:5:556:26 | ExprStmt | variables.rs:556:5:556:23 | async_block_capture | |
|
||||
| variables.rs:557:5:557:11 | structs | variables.rs:557:5:557:13 | structs(...) | |
|
||||
| variables.rs:557:5:557:13 | structs(...) | variables.rs:558:5:558:14 | ExprStmt | |
|
||||
| variables.rs:557:5:557:14 | ExprStmt | variables.rs:557:5:557:11 | structs | |
|
||||
| variables.rs:558:5:558:11 | ref_arg | variables.rs:558:5:558:13 | ref_arg(...) | |
|
||||
| variables.rs:558:5:558:13 | ref_arg(...) | variables.rs:559:5:559:30 | ExprStmt | |
|
||||
| variables.rs:558:5:558:14 | ExprStmt | variables.rs:558:5:558:11 | ref_arg | |
|
||||
| variables.rs:559:5:559:27 | ref_methodcall_receiver | variables.rs:559:5:559:29 | ref_methodcall_receiver(...) | |
|
||||
| variables.rs:559:5:559:29 | ref_methodcall_receiver(...) | variables.rs:526:11:560:1 | { ... } | |
|
||||
| variables.rs:559:5:559:30 | ExprStmt | variables.rs:559:5:559:27 | ref_methodcall_receiver | |
|
||||
breakTarget
|
||||
continueTarget
|
||||
|
||||
@@ -5,8 +5,8 @@ nonSsaVariable
|
||||
| variables.rs:379:13:379:13 | z |
|
||||
| variables.rs:392:13:392:13 | x |
|
||||
| variables.rs:426:13:426:13 | z |
|
||||
| variables.rs:488:13:488:13 | a |
|
||||
| variables.rs:516:11:516:11 | a |
|
||||
| variables.rs:492:13:492:13 | a |
|
||||
| variables.rs:520:11:520:11 | a |
|
||||
definition
|
||||
| variables.rs:3:14:3:14 | s | variables.rs:3:14:3:14 | s |
|
||||
| variables.rs:7:14:7:14 | i | variables.rs:7:14:7:14 | i |
|
||||
@@ -134,8 +134,11 @@ definition
|
||||
| variables.rs:461:13:461:14 | b1 | variables.rs:461:13:461:14 | b1 |
|
||||
| variables.rs:461:24:461:25 | b2 | variables.rs:461:24:461:25 | b2 |
|
||||
| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x |
|
||||
| variables.rs:497:9:497:9 | x | variables.rs:497:9:497:9 | x |
|
||||
| variables.rs:501:9:501:9 | z | variables.rs:501:9:501:9 | z |
|
||||
| variables.rs:482:15:482:23 | SelfParam | variables.rs:482:20:482:23 | self |
|
||||
| variables.rs:486:11:486:14 | SelfParam | variables.rs:486:11:486:14 | self |
|
||||
| variables.rs:501:9:501:9 | x | variables.rs:501:9:501:9 | x |
|
||||
| variables.rs:505:9:505:9 | z | variables.rs:505:9:505:9 | z |
|
||||
| variables.rs:514:10:514:18 | SelfParam | variables.rs:514:15:514:18 | self |
|
||||
read
|
||||
| variables.rs:3:14:3:14 | s | variables.rs:3:14:3:14 | s | variables.rs:4:20:4:20 | s |
|
||||
| variables.rs:7:14:7:14 | i | variables.rs:7:14:7:14 | i | variables.rs:8:20:8:20 | i |
|
||||
@@ -257,7 +260,10 @@ read
|
||||
| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:466:19:466:19 | x |
|
||||
| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:470:19:470:19 | x |
|
||||
| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:472:19:472:19 | x |
|
||||
| variables.rs:497:9:497:9 | x | variables.rs:497:9:497:9 | x | variables.rs:499:15:499:15 | x |
|
||||
| variables.rs:482:15:482:23 | SelfParam | variables.rs:482:20:482:23 | self | variables.rs:483:16:483:19 | self |
|
||||
| variables.rs:486:11:486:14 | SelfParam | variables.rs:486:11:486:14 | self | variables.rs:487:9:487:12 | self |
|
||||
| variables.rs:501:9:501:9 | x | variables.rs:501:9:501:9 | x | variables.rs:503:15:503:15 | x |
|
||||
| variables.rs:514:10:514:18 | SelfParam | variables.rs:514:15:514:18 | self | variables.rs:515:6:515:9 | self |
|
||||
firstRead
|
||||
| variables.rs:3:14:3:14 | s | variables.rs:3:14:3:14 | s | variables.rs:4:20:4:20 | s |
|
||||
| variables.rs:7:14:7:14 | i | variables.rs:7:14:7:14 | i | variables.rs:8:20:8:20 | i |
|
||||
@@ -356,7 +362,10 @@ firstRead
|
||||
| variables.rs:461:24:461:25 | b2 | variables.rs:461:24:461:25 | b2 | variables.rs:469:8:469:9 | b2 |
|
||||
| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:464:19:464:19 | x |
|
||||
| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:466:19:466:19 | x |
|
||||
| variables.rs:497:9:497:9 | x | variables.rs:497:9:497:9 | x | variables.rs:499:15:499:15 | x |
|
||||
| variables.rs:482:15:482:23 | SelfParam | variables.rs:482:20:482:23 | self | variables.rs:483:16:483:19 | self |
|
||||
| variables.rs:486:11:486:14 | SelfParam | variables.rs:486:11:486:14 | self | variables.rs:487:9:487:12 | self |
|
||||
| variables.rs:501:9:501:9 | x | variables.rs:501:9:501:9 | x | variables.rs:503:15:503:15 | x |
|
||||
| variables.rs:514:10:514:18 | SelfParam | variables.rs:514:15:514:18 | self | variables.rs:515:6:515:9 | self |
|
||||
lastRead
|
||||
| variables.rs:3:14:3:14 | s | variables.rs:3:14:3:14 | s | variables.rs:4:20:4:20 | s |
|
||||
| variables.rs:7:14:7:14 | i | variables.rs:7:14:7:14 | i | variables.rs:8:20:8:20 | i |
|
||||
@@ -456,7 +465,10 @@ lastRead
|
||||
| variables.rs:461:24:461:25 | b2 | variables.rs:461:24:461:25 | b2 | variables.rs:469:8:469:9 | b2 |
|
||||
| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:470:19:470:19 | x |
|
||||
| variables.rs:462:9:462:9 | x | variables.rs:462:9:462:9 | x | variables.rs:472:19:472:19 | x |
|
||||
| variables.rs:497:9:497:9 | x | variables.rs:497:9:497:9 | x | variables.rs:499:15:499:15 | x |
|
||||
| variables.rs:482:15:482:23 | SelfParam | variables.rs:482:20:482:23 | self | variables.rs:483:16:483:19 | self |
|
||||
| variables.rs:486:11:486:14 | SelfParam | variables.rs:486:11:486:14 | self | variables.rs:487:9:487:12 | self |
|
||||
| variables.rs:501:9:501:9 | x | variables.rs:501:9:501:9 | x | variables.rs:503:15:503:15 | x |
|
||||
| variables.rs:514:10:514:18 | SelfParam | variables.rs:514:15:514:18 | self | variables.rs:515:6:515:9 | self |
|
||||
adjacentReads
|
||||
| variables.rs:35:9:35:10 | x3 | variables.rs:35:9:35:10 | x3 | variables.rs:36:15:36:16 | x3 | variables.rs:38:9:38:10 | x3 |
|
||||
| variables.rs:43:9:43:10 | x4 | variables.rs:43:9:43:10 | x4 | variables.rs:44:15:44:16 | x4 | variables.rs:49:15:49:16 | x4 |
|
||||
|
||||
@@ -95,10 +95,13 @@ variable
|
||||
| variables.rs:461:13:461:14 | b1 |
|
||||
| variables.rs:461:24:461:25 | b2 |
|
||||
| variables.rs:462:9:462:9 | x |
|
||||
| variables.rs:488:13:488:13 | a |
|
||||
| variables.rs:497:9:497:9 | x |
|
||||
| variables.rs:501:9:501:9 | z |
|
||||
| variables.rs:516:11:516:11 | a |
|
||||
| variables.rs:482:20:482:23 | self |
|
||||
| variables.rs:486:11:486:14 | self |
|
||||
| variables.rs:492:13:492:13 | a |
|
||||
| variables.rs:501:9:501:9 | x |
|
||||
| variables.rs:505:9:505:9 | z |
|
||||
| variables.rs:514:15:514:18 | self |
|
||||
| variables.rs:520:11:520:11 | a |
|
||||
variableAccess
|
||||
| variables.rs:4:20:4:20 | s | variables.rs:3:14:3:14 | s |
|
||||
| variables.rs:8:20:8:20 | i | variables.rs:7:14:7:14 | i |
|
||||
@@ -246,16 +249,19 @@ variableAccess
|
||||
| variables.rs:469:8:469:9 | b2 | variables.rs:461:24:461:25 | b2 |
|
||||
| variables.rs:470:19:470:19 | x | variables.rs:462:9:462:9 | x |
|
||||
| variables.rs:472:19:472:19 | x | variables.rs:462:9:462:9 | x |
|
||||
| variables.rs:489:15:489:15 | a | variables.rs:488:13:488:13 | a |
|
||||
| variables.rs:490:5:490:5 | a | variables.rs:488:13:488:13 | a |
|
||||
| variables.rs:491:15:491:15 | a | variables.rs:488:13:488:13 | a |
|
||||
| variables.rs:492:5:492:5 | a | variables.rs:488:13:488:13 | a |
|
||||
| variables.rs:493:15:493:15 | a | variables.rs:488:13:488:13 | a |
|
||||
| variables.rs:498:20:498:20 | x | variables.rs:497:9:497:9 | x |
|
||||
| variables.rs:499:15:499:15 | x | variables.rs:497:9:497:9 | x |
|
||||
| variables.rs:502:20:502:20 | z | variables.rs:501:9:501:9 | z |
|
||||
| variables.rs:517:3:517:3 | a | variables.rs:516:11:516:11 | a |
|
||||
| variables.rs:519:13:519:13 | a | variables.rs:516:11:516:11 | a |
|
||||
| variables.rs:483:16:483:19 | self | variables.rs:482:20:482:23 | self |
|
||||
| variables.rs:487:9:487:12 | self | variables.rs:486:11:486:14 | self |
|
||||
| variables.rs:493:15:493:15 | a | variables.rs:492:13:492:13 | a |
|
||||
| variables.rs:494:5:494:5 | a | variables.rs:492:13:492:13 | a |
|
||||
| variables.rs:495:15:495:15 | a | variables.rs:492:13:492:13 | a |
|
||||
| variables.rs:496:5:496:5 | a | variables.rs:492:13:492:13 | a |
|
||||
| variables.rs:497:15:497:15 | a | variables.rs:492:13:492:13 | a |
|
||||
| variables.rs:502:20:502:20 | x | variables.rs:501:9:501:9 | x |
|
||||
| variables.rs:503:15:503:15 | x | variables.rs:501:9:501:9 | x |
|
||||
| variables.rs:506:20:506:20 | z | variables.rs:505:9:505:9 | z |
|
||||
| variables.rs:515:6:515:9 | self | variables.rs:514:15:514:18 | self |
|
||||
| variables.rs:521:3:521:3 | a | variables.rs:520:11:520:11 | a |
|
||||
| variables.rs:523:13:523:13 | a | variables.rs:520:11:520:11 | a |
|
||||
variableWriteAccess
|
||||
| variables.rs:23:5:23:6 | x2 | variables.rs:21:13:21:14 | x2 |
|
||||
| variables.rs:30:5:30:5 | x | variables.rs:28:13:28:13 | x |
|
||||
@@ -266,7 +272,7 @@ variableWriteAccess
|
||||
| variables.rs:438:9:438:9 | i | variables.rs:436:13:436:13 | i |
|
||||
| variables.rs:450:9:450:9 | x | variables.rs:446:13:446:13 | x |
|
||||
| variables.rs:454:9:454:9 | x | variables.rs:446:13:446:13 | x |
|
||||
| variables.rs:492:5:492:5 | a | variables.rs:488:13:488:13 | a |
|
||||
| variables.rs:496:5:496:5 | a | variables.rs:492:13:492:13 | a |
|
||||
variableReadAccess
|
||||
| variables.rs:4:20:4:20 | s | variables.rs:3:14:3:14 | s |
|
||||
| variables.rs:8:20:8:20 | i | variables.rs:7:14:7:14 | i |
|
||||
@@ -396,13 +402,16 @@ variableReadAccess
|
||||
| variables.rs:469:8:469:9 | b2 | variables.rs:461:24:461:25 | b2 |
|
||||
| variables.rs:470:19:470:19 | x | variables.rs:462:9:462:9 | x |
|
||||
| variables.rs:472:19:472:19 | x | variables.rs:462:9:462:9 | x |
|
||||
| variables.rs:489:15:489:15 | a | variables.rs:488:13:488:13 | a |
|
||||
| variables.rs:490:5:490:5 | a | variables.rs:488:13:488:13 | a |
|
||||
| variables.rs:491:15:491:15 | a | variables.rs:488:13:488:13 | a |
|
||||
| variables.rs:493:15:493:15 | a | variables.rs:488:13:488:13 | a |
|
||||
| variables.rs:499:15:499:15 | x | variables.rs:497:9:497:9 | x |
|
||||
| variables.rs:517:3:517:3 | a | variables.rs:516:11:516:11 | a |
|
||||
| variables.rs:519:13:519:13 | a | variables.rs:516:11:516:11 | a |
|
||||
| variables.rs:483:16:483:19 | self | variables.rs:482:20:482:23 | self |
|
||||
| variables.rs:487:9:487:12 | self | variables.rs:486:11:486:14 | self |
|
||||
| variables.rs:493:15:493:15 | a | variables.rs:492:13:492:13 | a |
|
||||
| variables.rs:494:5:494:5 | a | variables.rs:492:13:492:13 | a |
|
||||
| variables.rs:495:15:495:15 | a | variables.rs:492:13:492:13 | a |
|
||||
| variables.rs:497:15:497:15 | a | variables.rs:492:13:492:13 | a |
|
||||
| variables.rs:503:15:503:15 | x | variables.rs:501:9:501:9 | x |
|
||||
| variables.rs:515:6:515:9 | self | variables.rs:514:15:514:18 | self |
|
||||
| variables.rs:521:3:521:3 | a | variables.rs:520:11:520:11 | a |
|
||||
| variables.rs:523:13:523:13 | a | variables.rs:520:11:520:11 | a |
|
||||
variableInitializer
|
||||
| variables.rs:16:9:16:10 | x1 | variables.rs:16:14:16:16 | "a" |
|
||||
| variables.rs:21:13:21:14 | x2 | variables.rs:21:18:21:18 | 4 |
|
||||
@@ -450,10 +459,10 @@ variableInitializer
|
||||
| variables.rs:437:9:437:13 | block | variables.rs:437:17:439:5 | { ... } |
|
||||
| variables.rs:446:13:446:13 | x | variables.rs:446:17:446:17 | 1 |
|
||||
| variables.rs:462:9:462:9 | x | variables.rs:462:13:462:13 | 1 |
|
||||
| variables.rs:488:13:488:13 | a | variables.rs:488:17:488:35 | MyStruct {...} |
|
||||
| variables.rs:497:9:497:9 | x | variables.rs:497:13:497:14 | 16 |
|
||||
| variables.rs:501:9:501:9 | z | variables.rs:501:13:501:14 | 17 |
|
||||
| variables.rs:516:11:516:11 | a | variables.rs:516:15:516:33 | MyStruct {...} |
|
||||
| variables.rs:492:13:492:13 | a | variables.rs:492:17:492:35 | MyStruct {...} |
|
||||
| variables.rs:501:9:501:9 | x | variables.rs:501:13:501:14 | 16 |
|
||||
| variables.rs:505:9:505:9 | z | variables.rs:505:13:505:14 | 17 |
|
||||
| variables.rs:520:11:520:11 | a | variables.rs:520:15:520:33 | MyStruct {...} |
|
||||
capturedVariable
|
||||
| variables.rs:400:9:400:9 | x |
|
||||
| variables.rs:410:13:410:13 | x |
|
||||
|
||||
@@ -117,7 +117,7 @@ fn match_pattern1() {
|
||||
=>
|
||||
{
|
||||
print_i64(y1)// $ read_access=y1_2
|
||||
}
|
||||
}
|
||||
None => print_str("NONE"),
|
||||
}
|
||||
|
||||
@@ -480,7 +480,11 @@ struct MyStruct {
|
||||
|
||||
impl MyStruct {
|
||||
fn my_get(&mut self) -> i64 {
|
||||
return self.val;
|
||||
return self.val; // $ read_access=self
|
||||
}
|
||||
|
||||
fn id(self) -> Self {
|
||||
self // $ read_access=self
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,7 +512,7 @@ trait Bar {
|
||||
|
||||
impl MyStruct {
|
||||
fn bar(&mut self) {
|
||||
*self = MyStruct { val: 3 };
|
||||
*self = MyStruct { val: 3 }; // $ read_access=self
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,3 +5,4 @@ extractionWarning
|
||||
| does_not_compile.rs:2:21:2:20 | expected SEMICOLON |
|
||||
| does_not_compile.rs:2:26:2:25 | expected SEMICOLON |
|
||||
| error.rs:2:5:2:17 | An error! |
|
||||
| my_macro.rs:17:9:17:27 | macro expansion failed: could not resolve macro 'myUndefinedMacro' |
|
||||
|
||||
@@ -4,3 +4,4 @@
|
||||
| does_not_compile.rs:2:21:2:20 | expected SEMICOLON | Extraction warning in does_not_compile.rs with message expected SEMICOLON | 1 |
|
||||
| does_not_compile.rs:2:26:2:25 | expected SEMICOLON | Extraction warning in does_not_compile.rs with message expected SEMICOLON | 1 |
|
||||
| error.rs:2:5:2:17 | An error! | Extraction warning in error.rs with message An error! | 1 |
|
||||
| my_macro.rs:17:9:17:27 | macro expansion failed: could not resolve macro 'myUndefinedMacro' | Extraction warning in my_macro.rs with message macro expansion failed: could not resolve macro 'myUndefinedMacro' | 1 |
|
||||
|
||||
@@ -1 +1 @@
|
||||
| 59 |
|
||||
| 60 |
|
||||
|
||||
@@ -1 +1 @@
|
||||
| 59 |
|
||||
| 60 |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
| my_struct.rs:0:0:0:0 | my_struct.rs | 20 |
|
||||
| comments.rs:0:0:0:0 | comments.rs | 13 |
|
||||
| main.rs:0:0:0:0 | main.rs | 8 |
|
||||
| my_macro.rs:0:0:0:0 | my_macro.rs | 7 |
|
||||
| my_macro.rs:0:0:0:0 | my_macro.rs | 8 |
|
||||
| lib.rs:0:0:0:0 | lib.rs | 5 |
|
||||
| does_not_compile.rs:0:0:0:0 | does_not_compile.rs | 3 |
|
||||
| error.rs:0:0:0:0 | error.rs | 3 |
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
| Elements extracted | 375 |
|
||||
| Elements extracted | 382 |
|
||||
| Elements unextracted | 0 |
|
||||
| Extraction errors | 0 |
|
||||
| Extraction warnings | 6 |
|
||||
| Extraction warnings | 7 |
|
||||
| Files extracted - total | 8 |
|
||||
| Files extracted - with errors | 2 |
|
||||
| Files extracted - without errors | 6 |
|
||||
| Files extracted - with errors | 3 |
|
||||
| Files extracted - without errors | 5 |
|
||||
| Inconsistencies - AST | 0 |
|
||||
| Inconsistencies - CFG | 0 |
|
||||
| Inconsistencies - data flow | 0 |
|
||||
| Lines of code extracted | 59 |
|
||||
| Lines of user code extracted | 59 |
|
||||
| Lines of code extracted | 60 |
|
||||
| Lines of user code extracted | 60 |
|
||||
| Macro calls - resolved | 8 |
|
||||
| Macro calls - total | 9 |
|
||||
| Macro calls - unresolved | 1 |
|
||||
| Taint sources - active | 0 |
|
||||
| Taint sources - total | 0 |
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
| my_macro.rs:17:9:17:27 | myUndefinedMacro!... | Macro call was not resolved to a target. |
|
||||
@@ -0,0 +1 @@
|
||||
queries/diagnostics/UnresolvedMacroCalls.ql
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* total lines in this file: 18
|
||||
* of which code: 10
|
||||
* total lines in this file: 19
|
||||
* of which code: 11
|
||||
* of which only comments: 6
|
||||
* of which blank: 2
|
||||
*/
|
||||
@@ -14,5 +14,6 @@ macro_rules! myMacro {
|
||||
pub fn my_func() {
|
||||
if true {
|
||||
myMacro!();
|
||||
myUndefinedMacro!();
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user