mirror of
https://github.com/github/codeql.git
synced 2025-12-16 08:43:11 +01:00
Merge branch 'main' into java-kotlin-sensitive-logging-substring-barriers
This commit is contained in:
2469
cpp/downgrades/a42ce5fc943254097f85471b94ae2247e819104a/old.dbscheme
Normal file
2469
cpp/downgrades/a42ce5fc943254097f85471b94ae2247e819104a/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
description: Add databaseMetadata and overlayChangedFiles relations
|
||||
compatibility: full
|
||||
databaseMetadata.rel: delete
|
||||
overlayChangedFiles.rel: delete
|
||||
@@ -21,3 +21,4 @@ dataExtensions:
|
||||
- ext/deallocation/*.model.yml
|
||||
- ext/allocation/*.model.yml
|
||||
warnOnImplicitThis: true
|
||||
compileForOverlayEval: true
|
||||
|
||||
@@ -2078,38 +2078,151 @@ predicate localExprFlow(Expr e1, Expr e2) {
|
||||
localExprFlowPlus(e1, e2)
|
||||
}
|
||||
|
||||
/**
|
||||
* A canonical representation of a field.
|
||||
*
|
||||
* For performance reasons we want a unique `Content` that represents
|
||||
* a given field across any template instantiation of a class.
|
||||
*
|
||||
* This is possible in _almost_ all cases, but there are cases where it is
|
||||
* not possible to map between a field in the uninstantiated template to a
|
||||
* field in the instantiated template. This happens in the case of local class
|
||||
* definitions (because the local class is not the template that constructs
|
||||
* the instantiation - it is the enclosing function). So this abstract class
|
||||
* has two implementations: a non-local case (where we can represent a
|
||||
* canonical field as the field declaration from an uninstantiated class
|
||||
* template or a non-templated class), and a local case (where we simply use
|
||||
* the field from the instantiated class).
|
||||
*/
|
||||
abstract private class CanonicalField extends Field {
|
||||
/** Gets a field represented by this canonical field. */
|
||||
abstract Field getAField();
|
||||
|
||||
/**
|
||||
* Gets a class that declares a field represented by this canonical field.
|
||||
*/
|
||||
abstract Class getADeclaringType();
|
||||
|
||||
/**
|
||||
* Gets a type that this canonical field may have. Note that this may
|
||||
* not be a unique type. For example, consider this case:
|
||||
* ```
|
||||
* template<typename T>
|
||||
* struct S { T x; };
|
||||
*
|
||||
* S<int> s1;
|
||||
* S<char> s2;
|
||||
* ```
|
||||
* In this case the canonical field corresponding to `S::x` has two types:
|
||||
* `int` and `char`.
|
||||
*/
|
||||
Type getAType() { result = this.getAField().getType() }
|
||||
|
||||
Type getAnUnspecifiedType() { result = this.getAType().getUnspecifiedType() }
|
||||
}
|
||||
|
||||
private class NonLocalCanonicalField extends CanonicalField {
|
||||
Class declaringType;
|
||||
|
||||
NonLocalCanonicalField() {
|
||||
declaringType = this.getDeclaringType() and
|
||||
not declaringType.isFromTemplateInstantiation(_) and
|
||||
not declaringType.isLocal() // handled in LocalCanonicalField
|
||||
}
|
||||
|
||||
override Field getAField() {
|
||||
exists(Class c | result.getDeclaringType() = c |
|
||||
// Either the declaring class of the field is a template instantiation
|
||||
// that has been constructed from this canonical declaration
|
||||
c.isConstructedFrom(declaringType) and
|
||||
pragma[only_bind_out](result.getName()) = pragma[only_bind_out](this.getName())
|
||||
or
|
||||
// or this canonical declaration is not a template.
|
||||
not c.isConstructedFrom(_) and
|
||||
result = this
|
||||
)
|
||||
}
|
||||
|
||||
override Class getADeclaringType() {
|
||||
result = this.getDeclaringType()
|
||||
or
|
||||
result.isConstructedFrom(this.getDeclaringType())
|
||||
}
|
||||
}
|
||||
|
||||
private class LocalCanonicalField extends CanonicalField {
|
||||
Class declaringType;
|
||||
|
||||
LocalCanonicalField() {
|
||||
declaringType = this.getDeclaringType() and
|
||||
declaringType.isLocal()
|
||||
}
|
||||
|
||||
override Field getAField() { result = this }
|
||||
|
||||
override Class getADeclaringType() { result = declaringType }
|
||||
}
|
||||
|
||||
/**
|
||||
* A canonical representation of a `Union`. See `CanonicalField` for the explanation for
|
||||
* why we need a canonical representation.
|
||||
*/
|
||||
abstract private class CanonicalUnion extends Union {
|
||||
/** Gets a union represented by this canonical union. */
|
||||
abstract Union getAUnion();
|
||||
|
||||
/** Gets a canonical field of this canonical union. */
|
||||
CanonicalField getACanonicalField() { result.getDeclaringType() = this }
|
||||
}
|
||||
|
||||
private class NonLocalCanonicalUnion extends CanonicalUnion {
|
||||
NonLocalCanonicalUnion() { not this.isFromTemplateInstantiation(_) and not this.isLocal() }
|
||||
|
||||
override Union getAUnion() {
|
||||
result = this
|
||||
or
|
||||
result.isConstructedFrom(this)
|
||||
}
|
||||
}
|
||||
|
||||
private class LocalCanonicalUnion extends CanonicalUnion {
|
||||
LocalCanonicalUnion() { this.isLocal() }
|
||||
|
||||
override Union getAUnion() { result = this }
|
||||
}
|
||||
|
||||
bindingset[f]
|
||||
pragma[inline_late]
|
||||
private int getFieldSize(Field f) { result = f.getType().getSize() }
|
||||
private int getFieldSize(CanonicalField f) { result = max(f.getAType().getSize()) }
|
||||
|
||||
/**
|
||||
* Gets a field in the union `u` whose size
|
||||
* is `bytes` number of bytes.
|
||||
*/
|
||||
private Field getAFieldWithSize(Union u, int bytes) {
|
||||
result = u.getAField() and
|
||||
private CanonicalField getAFieldWithSize(CanonicalUnion u, int bytes) {
|
||||
result = u.getACanonicalField() and
|
||||
bytes = getFieldSize(result)
|
||||
}
|
||||
|
||||
cached
|
||||
private newtype TContent =
|
||||
TNonUnionContent(Field f, int indirectionIndex) {
|
||||
TNonUnionContent(CanonicalField f, int indirectionIndex) {
|
||||
// the indirection index for field content starts at 1 (because `TNonUnionContent` is thought of as
|
||||
// the address of the field, `FieldAddress` in the IR).
|
||||
indirectionIndex = [1 .. SsaImpl::getMaxIndirectionsForType(f.getUnspecifiedType())] and
|
||||
indirectionIndex = [1 .. max(SsaImpl::getMaxIndirectionsForType(f.getAnUnspecifiedType()))] and
|
||||
// Reads and writes of union fields are tracked using `UnionContent`.
|
||||
not f.getDeclaringType() instanceof Union
|
||||
} or
|
||||
TUnionContent(Union u, int bytes, int indirectionIndex) {
|
||||
exists(Field f |
|
||||
f = u.getAField() and
|
||||
TUnionContent(CanonicalUnion u, int bytes, int indirectionIndex) {
|
||||
exists(CanonicalField f |
|
||||
f = u.getACanonicalField() and
|
||||
bytes = getFieldSize(f) and
|
||||
// We key `UnionContent` by the union instead of its fields since a write to one
|
||||
// field can be read by any read of the union's fields. Again, the indirection index
|
||||
// is 1-based (because 0 is considered the address).
|
||||
indirectionIndex =
|
||||
[1 .. max(SsaImpl::getMaxIndirectionsForType(getAFieldWithSize(u, bytes)
|
||||
.getUnspecifiedType())
|
||||
.getAnUnspecifiedType())
|
||||
)]
|
||||
)
|
||||
} or
|
||||
@@ -2175,8 +2288,12 @@ class FieldContent extends Content, TFieldContent {
|
||||
|
||||
/**
|
||||
* Gets the field associated with this `Content`, if a unique one exists.
|
||||
*
|
||||
* For fields from template instantiations this predicate may still return
|
||||
* more than one field, but all the fields will be constructed from the same
|
||||
* template.
|
||||
*/
|
||||
final Field getField() { result = unique( | | this.getAField()) }
|
||||
Field getField() { none() } // overridden in subclasses
|
||||
|
||||
override int getIndirectionIndex() { none() } // overridden in subclasses
|
||||
|
||||
@@ -2187,32 +2304,33 @@ class FieldContent extends Content, TFieldContent {
|
||||
|
||||
/** A reference through a non-union instance field. */
|
||||
class NonUnionFieldContent extends FieldContent, TNonUnionContent {
|
||||
private Field f;
|
||||
private CanonicalField f;
|
||||
private int indirectionIndex;
|
||||
|
||||
NonUnionFieldContent() { this = TNonUnionContent(f, indirectionIndex) }
|
||||
|
||||
override string toString() { result = contentStars(this) + f.toString() }
|
||||
|
||||
override Field getAField() { result = f }
|
||||
final override Field getField() { result = f.getAField() }
|
||||
|
||||
override Field getAField() { result = this.getField() }
|
||||
|
||||
/** Gets the indirection index of this `FieldContent`. */
|
||||
override int getIndirectionIndex() { result = indirectionIndex }
|
||||
|
||||
override predicate impliesClearOf(Content c) {
|
||||
exists(FieldContent fc |
|
||||
fc = c and
|
||||
fc.getField() = f and
|
||||
exists(int i |
|
||||
c = TNonUnionContent(f, i) and
|
||||
// If `this` is `f` then `c` is cleared if it's of the
|
||||
// form `*f`, `**f`, etc.
|
||||
fc.getIndirectionIndex() >= indirectionIndex
|
||||
i >= indirectionIndex
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** A reference through an instance field of a union. */
|
||||
class UnionContent extends FieldContent, TUnionContent {
|
||||
private Union u;
|
||||
private CanonicalUnion u;
|
||||
private int indirectionIndex;
|
||||
private int bytes;
|
||||
|
||||
@@ -2220,24 +2338,31 @@ class UnionContent extends FieldContent, TUnionContent {
|
||||
|
||||
override string toString() { result = contentStars(this) + u.toString() }
|
||||
|
||||
final override Field getField() { result = unique( | | u.getACanonicalField()).getAField() }
|
||||
|
||||
/** Gets a field of the underlying union of this `UnionContent`, if any. */
|
||||
override Field getAField() { result = u.getAField() and getFieldSize(result) = bytes }
|
||||
override Field getAField() {
|
||||
exists(CanonicalField cf |
|
||||
cf = u.getACanonicalField() and
|
||||
result = cf.getAField() and
|
||||
getFieldSize(cf) = bytes
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the underlying union of this `UnionContent`. */
|
||||
Union getUnion() { result = u }
|
||||
Union getUnion() { result = u.getAUnion() }
|
||||
|
||||
/** Gets the indirection index of this `UnionContent`. */
|
||||
override int getIndirectionIndex() { result = indirectionIndex }
|
||||
|
||||
override predicate impliesClearOf(Content c) {
|
||||
exists(UnionContent uc |
|
||||
uc = c and
|
||||
uc.getUnion() = u and
|
||||
exists(int i |
|
||||
c = TUnionContent(u, _, i) and
|
||||
// If `this` is `u` then `c` is cleared if it's of the
|
||||
// form `*u`, `**u`, etc. (and we ignore `bytes` because
|
||||
// we know the entire union is overwritten because it's a
|
||||
// union).
|
||||
uc.getIndirectionIndex() >= indirectionIndex
|
||||
i >= indirectionIndex
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
/*- Compilations -*/
|
||||
|
||||
/**
|
||||
@@ -2378,6 +2379,24 @@ link_parent(
|
||||
int link_target : @link_target ref
|
||||
);
|
||||
|
||||
/**
|
||||
* The CLI will automatically emit applicable tuples for this table,
|
||||
* such as `databaseMetadata("isOverlay", "true")` when building an
|
||||
* overlay database.
|
||||
*/
|
||||
databaseMetadata(
|
||||
string metadataKey: string ref,
|
||||
string value: string ref
|
||||
);
|
||||
|
||||
/**
|
||||
* The CLI will automatically emit tuples for each new/modified/deleted file
|
||||
* when building an overlay database.
|
||||
*/
|
||||
overlayChangedFiles(
|
||||
string path: string ref
|
||||
);
|
||||
|
||||
/*- XML Files -*/
|
||||
|
||||
xmlEncoding(
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Add databaseMetadata and overlayChangedFiles relations
|
||||
compatibility: full
|
||||
@@ -142,6 +142,7 @@ postWithInFlow
|
||||
| simple.cpp:92:7:92:7 | i [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| simple.cpp:118:7:118:7 | i [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| simple.cpp:124:5:124:6 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| simple.cpp:167:9:167:9 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
viableImplInCallContextTooLarge
|
||||
uniqueParameterNodeAtPosition
|
||||
uniqueParameterNodePosition
|
||||
|
||||
@@ -308,3 +308,5 @@ WARNING: module 'DataFlow' has been deprecated and may be removed in future (par
|
||||
| simple.cpp:124:5:124:6 | * ... | AST only |
|
||||
| simple.cpp:131:14:131:14 | a | IR only |
|
||||
| simple.cpp:136:10:136:10 | a | IR only |
|
||||
| simple.cpp:167:9:167:9 | x | AST only |
|
||||
| simple.cpp:168:8:168:12 | u_int | IR only |
|
||||
|
||||
@@ -670,6 +670,8 @@
|
||||
| simple.cpp:131:14:131:14 | a |
|
||||
| simple.cpp:135:20:135:20 | q |
|
||||
| simple.cpp:136:10:136:10 | a |
|
||||
| simple.cpp:167:3:167:7 | u_int |
|
||||
| simple.cpp:168:8:168:12 | u_int |
|
||||
| struct_init.c:15:8:15:9 | ab |
|
||||
| struct_init.c:15:12:15:12 | a |
|
||||
| struct_init.c:16:8:16:9 | ab |
|
||||
|
||||
@@ -597,6 +597,8 @@ WARNING: module 'DataFlow' has been deprecated and may be removed in future (par
|
||||
| simple.cpp:118:7:118:7 | i |
|
||||
| simple.cpp:124:5:124:6 | * ... |
|
||||
| simple.cpp:135:20:135:20 | q |
|
||||
| simple.cpp:167:3:167:7 | u_int |
|
||||
| simple.cpp:167:9:167:9 | x |
|
||||
| struct_init.c:15:8:15:9 | ab |
|
||||
| struct_init.c:15:12:15:12 | a |
|
||||
| struct_init.c:16:8:16:9 | ab |
|
||||
|
||||
@@ -136,4 +136,36 @@ void alias_with_fields(bool b) {
|
||||
sink(a.i); // $ MISSING: ast,ir
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
union U_with_two_instantiations_of_different_size {
|
||||
int x;
|
||||
T y;
|
||||
};
|
||||
|
||||
struct LargeStruct {
|
||||
int data[64];
|
||||
};
|
||||
|
||||
void test_union_with_two_instantiations_of_different_sizes() {
|
||||
// A union's fields is partitioned into "chunks" for field-flow in order to
|
||||
// improve performance (so that a write to a field of a union does not flow
|
||||
// to too many reads that don't happen at runtime). The partitioning is based
|
||||
// the size of the types in the union. So a write to a field of size k only
|
||||
// flows to a read of size k.
|
||||
// Since field-flow is based on uninstantiated types a field can have
|
||||
// multiple sizes if the union is instantiated with types of
|
||||
// different sizes. So to compute the partition we pick the maximum size.
|
||||
// Because of this there are `Content`s corresponding to the union
|
||||
// `U_with_two_instantiations_of_different_size<T>`: The one for size
|
||||
// `sizeof(int)`, and the one for size `sizeof(LargeStruct)` (because
|
||||
// `LargeStruct` is larger than `int`). So the write to `x` writes to the
|
||||
// `Content` for size `sizeof(int)`, and the read of `y` reads from the
|
||||
// `Content` for size `sizeof(LargeStruct)`.
|
||||
U_with_two_instantiations_of_different_size<int> u_int;
|
||||
U_with_two_instantiations_of_different_size<LargeStruct> u_very_large;
|
||||
|
||||
u_int.x = user_input();
|
||||
sink(u_int.y); // $ MISSING: ir
|
||||
}
|
||||
|
||||
} // namespace Simple
|
||||
@@ -2,10 +2,10 @@
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | address && | SemanticStackVariable | | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | const __va_list_tag & | SemanticStackVariable | | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | const address & | SemanticStackVariable | | |
|
||||
| file://:0:0:0:0 | fp_offset | file://:0:0:0:0 | unsigned int | Field | | |
|
||||
| file://:0:0:0:0 | gp_offset | file://:0:0:0:0 | unsigned int | Field | | |
|
||||
| file://:0:0:0:0 | overflow_arg_area | file://:0:0:0:0 | void * | Field | | |
|
||||
| file://:0:0:0:0 | reg_save_area | file://:0:0:0:0 | void * | Field | | |
|
||||
| file://:0:0:0:0 | fp_offset | file://:0:0:0:0 | unsigned int | NonLocalCanonicalField | | |
|
||||
| file://:0:0:0:0 | gp_offset | file://:0:0:0:0 | unsigned int | NonLocalCanonicalField | | |
|
||||
| file://:0:0:0:0 | overflow_arg_area | file://:0:0:0:0 | void * | NonLocalCanonicalField | | |
|
||||
| file://:0:0:0:0 | reg_save_area | file://:0:0:0:0 | void * | NonLocalCanonicalField | | |
|
||||
| variables.cpp:1:12:1:12 | i | file://:0:0:0:0 | int | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:2:12:2:12 | i | file://:0:0:0:0 | int | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:3:12:3:12 | i | file://:0:0:0:0 | int | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
@@ -33,10 +33,10 @@
|
||||
| variables.cpp:37:6:37:8 | ap3 | file://:0:0:0:0 | int * | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:41:7:41:11 | local | file://:0:0:0:0 | char[] | LocalVariable, SemanticStackVariable | | |
|
||||
| variables.cpp:43:14:43:18 | local | file://:0:0:0:0 | int | GlobalLikeVariable, StaticLocalVariable | | static |
|
||||
| variables.cpp:48:9:48:12 | name | file://:0:0:0:0 | char * | Field | | |
|
||||
| variables.cpp:49:12:49:17 | number | file://:0:0:0:0 | long | Field | | |
|
||||
| variables.cpp:50:9:50:14 | street | file://:0:0:0:0 | char * | Field | | |
|
||||
| variables.cpp:51:9:51:12 | town | file://:0:0:0:0 | char * | Field | | |
|
||||
| variables.cpp:48:9:48:12 | name | file://:0:0:0:0 | char * | NonLocalCanonicalField | | |
|
||||
| variables.cpp:49:12:49:17 | number | file://:0:0:0:0 | long | NonLocalCanonicalField | | |
|
||||
| variables.cpp:50:9:50:14 | street | file://:0:0:0:0 | char * | NonLocalCanonicalField | | |
|
||||
| variables.cpp:51:9:51:12 | town | file://:0:0:0:0 | char * | NonLocalCanonicalField | | |
|
||||
| variables.cpp:52:16:52:22 | country | file://:0:0:0:0 | char * | MemberVariable, StaticStorageDurationVariable | | static |
|
||||
| variables.cpp:56:14:56:29 | externInFunction | file://:0:0:0:0 | int | GlobalLikeVariable, GlobalVariable, StaticStorageDurationVariable | | |
|
||||
| variables.cpp:60:10:60:17 | __func__ | file://:0:0:0:0 | const char[9] | GlobalLikeVariable, StaticInitializedStaticLocalVariable | | static |
|
||||
|
||||
@@ -12,6 +12,7 @@ ql/go/ql/src/Security/CWE-079/HtmlTemplateEscapingBypassXss.ql
|
||||
ql/go/ql/src/Security/CWE-079/ReflectedXss.ql
|
||||
ql/go/ql/src/Security/CWE-089/SqlInjection.ql
|
||||
ql/go/ql/src/Security/CWE-089/StringBreak.ql
|
||||
ql/go/ql/src/Security/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
ql/go/ql/src/Security/CWE-190/AllocationSizeOverflow.ql
|
||||
ql/go/ql/src/Security/CWE-209/StackTraceExposure.ql
|
||||
ql/go/ql/src/Security/CWE-295/DisabledCertificateCheck.ql
|
||||
@@ -26,6 +27,7 @@ ql/go/ql/src/Security/CWE-347/MissingJwtSignatureCheck.ql
|
||||
ql/go/ql/src/Security/CWE-352/ConstantOauth2State.ql
|
||||
ql/go/ql/src/Security/CWE-601/BadRedirectCheck.ql
|
||||
ql/go/ql/src/Security/CWE-601/OpenUrlRedirect.ql
|
||||
ql/go/ql/src/Security/CWE-614/CookieWithoutSecure.ql
|
||||
ql/go/ql/src/Security/CWE-640/EmailInjection.ql
|
||||
ql/go/ql/src/Security/CWE-643/XPathInjection.ql
|
||||
ql/go/ql/src/Security/CWE-681/IncorrectIntegerConversionQuery.ql
|
||||
|
||||
@@ -34,6 +34,7 @@ ql/go/ql/src/Security/CWE-079/HtmlTemplateEscapingBypassXss.ql
|
||||
ql/go/ql/src/Security/CWE-079/ReflectedXss.ql
|
||||
ql/go/ql/src/Security/CWE-089/SqlInjection.ql
|
||||
ql/go/ql/src/Security/CWE-089/StringBreak.ql
|
||||
ql/go/ql/src/Security/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
ql/go/ql/src/Security/CWE-117/LogInjection.ql
|
||||
ql/go/ql/src/Security/CWE-190/AllocationSizeOverflow.ql
|
||||
ql/go/ql/src/Security/CWE-209/StackTraceExposure.ql
|
||||
@@ -49,6 +50,7 @@ ql/go/ql/src/Security/CWE-347/MissingJwtSignatureCheck.ql
|
||||
ql/go/ql/src/Security/CWE-352/ConstantOauth2State.ql
|
||||
ql/go/ql/src/Security/CWE-601/BadRedirectCheck.ql
|
||||
ql/go/ql/src/Security/CWE-601/OpenUrlRedirect.ql
|
||||
ql/go/ql/src/Security/CWE-614/CookieWithoutSecure.ql
|
||||
ql/go/ql/src/Security/CWE-640/EmailInjection.ql
|
||||
ql/go/ql/src/Security/CWE-643/XPathInjection.ql
|
||||
ql/go/ql/src/Security/CWE-681/IncorrectIntegerConversionQuery.ql
|
||||
|
||||
@@ -12,6 +12,7 @@ ql/go/ql/src/Security/CWE-079/HtmlTemplateEscapingBypassXss.ql
|
||||
ql/go/ql/src/Security/CWE-079/ReflectedXss.ql
|
||||
ql/go/ql/src/Security/CWE-089/SqlInjection.ql
|
||||
ql/go/ql/src/Security/CWE-089/StringBreak.ql
|
||||
ql/go/ql/src/Security/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
ql/go/ql/src/Security/CWE-117/LogInjection.ql
|
||||
ql/go/ql/src/Security/CWE-190/AllocationSizeOverflow.ql
|
||||
ql/go/ql/src/Security/CWE-209/StackTraceExposure.ql
|
||||
@@ -27,6 +28,7 @@ ql/go/ql/src/Security/CWE-347/MissingJwtSignatureCheck.ql
|
||||
ql/go/ql/src/Security/CWE-352/ConstantOauth2State.ql
|
||||
ql/go/ql/src/Security/CWE-601/BadRedirectCheck.ql
|
||||
ql/go/ql/src/Security/CWE-601/OpenUrlRedirect.ql
|
||||
ql/go/ql/src/Security/CWE-614/CookieWithoutSecure.ql
|
||||
ql/go/ql/src/Security/CWE-640/EmailInjection.ql
|
||||
ql/go/ql/src/Security/CWE-643/XPathInjection.ql
|
||||
ql/go/ql/src/Security/CWE-681/IncorrectIntegerConversionQuery.ql
|
||||
|
||||
@@ -9,7 +9,6 @@ ql/go/ql/src/Security/CWE-079/StoredXss.ql
|
||||
ql/go/ql/src/Security/CWE-798/HardcodedCredentials.ql
|
||||
ql/go/ql/src/definitions.ql
|
||||
ql/go/ql/src/experimental/CWE-090/LDAPInjection.ql
|
||||
ql/go/ql/src/experimental/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
ql/go/ql/src/experimental/CWE-203/Timing.ql
|
||||
ql/go/ql/src/experimental/CWE-285/PamAuthBypass.ql
|
||||
ql/go/ql/src/experimental/CWE-287/ImproperLdapAuth.ql
|
||||
|
||||
@@ -41,6 +41,7 @@ import semmle.go.frameworks.ElazarlGoproxy
|
||||
import semmle.go.frameworks.Email
|
||||
import semmle.go.frameworks.Encoding
|
||||
import semmle.go.frameworks.Fasthttp
|
||||
import semmle.go.frameworks.Gin
|
||||
import semmle.go.frameworks.GinCors
|
||||
import semmle.go.frameworks.Glog
|
||||
import semmle.go.frameworks.GoJose
|
||||
|
||||
@@ -380,4 +380,96 @@ module Http {
|
||||
/** Gets a node that is used in a check that is tested before this handler is run. */
|
||||
predicate guardedBy(DataFlow::Node check) { super.guardedBy(check) }
|
||||
}
|
||||
|
||||
/** Provides a class for modeling new HTTP response cookie write APIs. */
|
||||
module CookieWrite {
|
||||
/**
|
||||
* A write of an HTTP Cookie to an HTTP response.
|
||||
*
|
||||
* Extend this class to model new APIs. If you want to refine existing API models,
|
||||
* extend `HTTP::CookieWrite` instead.
|
||||
*/
|
||||
abstract class Range extends DataFlow::Node {
|
||||
/** Gets the name of the cookie written. */
|
||||
abstract DataFlow::Node getName();
|
||||
|
||||
/** Gets the value of the cookie written. */
|
||||
abstract DataFlow::Node getValue();
|
||||
|
||||
/** Gets the `Secure` attribute of the cookie written. */
|
||||
abstract DataFlow::Node getSecure();
|
||||
|
||||
/** Gets the `HttpOnly` attribute of the cookie written. */
|
||||
abstract DataFlow::Node getHttpOnly();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A write of an HTTP Cookie to an HTTP response.
|
||||
*
|
||||
* Extend this class to refine existing API models. If you want to model new APIs,
|
||||
* extend `HTTP::CookieWrite::Range` instead.
|
||||
*/
|
||||
class CookieWrite extends DataFlow::Node instanceof CookieWrite::Range {
|
||||
/** Gets the name of the cookie written. */
|
||||
DataFlow::Node getName() { result = super.getName() }
|
||||
|
||||
/** Gets the value of the cookie written. */
|
||||
DataFlow::Node getValue() { result = super.getValue() }
|
||||
|
||||
/** Gets the `Secure` attribute of the cookie written. */
|
||||
DataFlow::Node getSecure() { result = super.getSecure() }
|
||||
|
||||
/** Gets the `HttpOnly` attribute of the cookie written. */
|
||||
DataFlow::Node getHttpOnly() { result = super.getHttpOnly() }
|
||||
}
|
||||
|
||||
/** Provides a class for modeling the new APIs for writes to options of an HTTP cookie. */
|
||||
module CookieOptionWrite {
|
||||
/**
|
||||
* A write to an option of an HTTP cookie object.
|
||||
*
|
||||
* Extend this class to model new APIs. If you want to refine existing API models,
|
||||
* extend `HTTP::CookieOptionWrite` instead.
|
||||
*/
|
||||
abstract class Range extends DataFlow::Node {
|
||||
/** Gets the node representing the cookie object for the options being set. */
|
||||
abstract DataFlow::Node getCookieOutput();
|
||||
|
||||
/** Gets the name of the cookie represented, if any. */
|
||||
abstract DataFlow::Node getName();
|
||||
|
||||
/** Gets the value of the cookie represented, if any. */
|
||||
abstract DataFlow::Node getValue();
|
||||
|
||||
/** Gets the `Secure` attribute of the cookie represented, if any. */
|
||||
abstract DataFlow::Node getSecure();
|
||||
|
||||
/** Gets the `HttpOnly` attribute of the cookie represented, if any. */
|
||||
abstract DataFlow::Node getHttpOnly();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A write to an option of an HTTP cookie object.
|
||||
*
|
||||
* Extend this class to refine existing API models. If you want to model new APIs,
|
||||
* extend `HTTP::CookieOptionWrite::Range` instead.
|
||||
*/
|
||||
class CookieOptionWrite extends DataFlow::Node instanceof CookieOptionWrite::Range {
|
||||
/** Gets the node representing the cookie object for the options being set. */
|
||||
DataFlow::Node getCookieOutput() { result = super.getCookieOutput() }
|
||||
|
||||
/** Gets the name of the cookie represented, if any. */
|
||||
DataFlow::Node getName() { result = super.getName() }
|
||||
|
||||
/** Gets the value of the cookie represented, if any. */
|
||||
DataFlow::Node getValue() { result = super.getValue() }
|
||||
|
||||
/** Gets the `Secure` attribute of the cookie represented, if any. */
|
||||
DataFlow::Node getSecure() { result = super.getSecure() }
|
||||
|
||||
/** Gets the `HttpOnly` attribute of the cookie represented, if any. */
|
||||
DataFlow::Node getHttpOnly() { result = super.getHttpOnly() }
|
||||
}
|
||||
}
|
||||
|
||||
24
go/ql/lib/semmle/go/frameworks/Gin.qll
Normal file
24
go/ql/lib/semmle/go/frameworks/Gin.qll
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Provides classes for modeling the `github.com/gin-gonic/gin` package.
|
||||
*/
|
||||
|
||||
import go
|
||||
import semmle.go.concepts.HTTP
|
||||
|
||||
/** Provides models for the `gin-gonic/gin` package. */
|
||||
module Gin {
|
||||
/** Gets the package name `github.com/gin-gonic/gin`. */
|
||||
string packagePath() { result = package("github.com/gin-gonic/gin", "") }
|
||||
|
||||
private class GinCookieWrite extends Http::CookieWrite::Range, DataFlow::MethodCallNode {
|
||||
GinCookieWrite() { this.getTarget().hasQualifiedName(packagePath(), "Context", "SetCookie") }
|
||||
|
||||
override DataFlow::Node getName() { result = this.getArgument(0) }
|
||||
|
||||
override DataFlow::Node getValue() { result = this.getArgument(1) }
|
||||
|
||||
override DataFlow::Node getSecure() { result = this.getArgument(5) }
|
||||
|
||||
override DataFlow::Node getHttpOnly() { result = this.getArgument(6) }
|
||||
}
|
||||
}
|
||||
@@ -293,4 +293,38 @@ module NetHttp {
|
||||
|
||||
override DataFlow::Node getAPathArgument() { result = this.getArgument(2) }
|
||||
}
|
||||
|
||||
private class CookieWrite extends Http::CookieWrite::Range, DataFlow::CallNode {
|
||||
CookieWrite() { this.getTarget().hasQualifiedName(package("net/http", ""), "SetCookie") }
|
||||
|
||||
override DataFlow::Node getName() { result = this.getArgument(1) }
|
||||
|
||||
override DataFlow::Node getValue() { result = this.getArgument(1) }
|
||||
|
||||
override DataFlow::Node getSecure() { result = this.getArgument(1) }
|
||||
|
||||
override DataFlow::Node getHttpOnly() { result = this.getArgument(1) }
|
||||
}
|
||||
|
||||
private class CookieFieldWrite extends Http::CookieOptionWrite::Range {
|
||||
DataFlow::Node written;
|
||||
string fieldName;
|
||||
|
||||
CookieFieldWrite() {
|
||||
exists(Write w, Field f |
|
||||
f.hasQualifiedName(package("net/http", ""), "Cookie", fieldName) and
|
||||
w.writesField(this, f, written)
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getCookieOutput() { result = this }
|
||||
|
||||
override DataFlow::Node getName() { fieldName = "Name" and result = written }
|
||||
|
||||
override DataFlow::Node getValue() { fieldName = "Value" and result = written }
|
||||
|
||||
override DataFlow::Node getSecure() { fieldName = "Secure" and result = written }
|
||||
|
||||
override DataFlow::Node getHttpOnly() { fieldName = "HttpOnly" and result = written }
|
||||
}
|
||||
}
|
||||
|
||||
77
go/ql/lib/semmle/go/security/CookieWithoutHttpOnly.qll
Normal file
77
go/ql/lib/semmle/go/security/CookieWithoutHttpOnly.qll
Normal file
@@ -0,0 +1,77 @@
|
||||
/** Provides classes and predicates for identifying HTTP cookies without the `HttpOnly` attribute. */
|
||||
|
||||
import go
|
||||
import semmle.go.concepts.HTTP
|
||||
import semmle.go.dataflow.DataFlow
|
||||
|
||||
private module SensitiveCookieNameConfig implements DataFlow::ConfigSig {
|
||||
/**
|
||||
* Holds if `source` is an expression with a name or literal value `val` indicating a sensitive cookie.
|
||||
*/
|
||||
additional predicate isSource(DataFlow::Node source, string val) {
|
||||
(
|
||||
val = source.asExpr().getStringValue() or
|
||||
val = source.asExpr().(Name).getTarget().getName()
|
||||
) and
|
||||
val.regexpMatch("(?i).*(session|login|token|user|auth|credential).*") and
|
||||
not val.regexpMatch("(?i).*(xsrf|csrf|forgery).*")
|
||||
}
|
||||
|
||||
predicate isSource(DataFlow::Node source) { isSource(source, _) }
|
||||
|
||||
additional predicate isSink(DataFlow::Node sink, Http::CookieWrite cw) { sink = cw.getName() }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { isSink(sink, _) }
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(Http::CookieOptionWrite co | co.getName() = pred and co.getCookieOutput() = succ)
|
||||
}
|
||||
}
|
||||
|
||||
/** Tracks flow from sensitive names to HTTP cookie writes. */
|
||||
module SensitiveCookieNameFlow = TaintTracking::Global<SensitiveCookieNameConfig>;
|
||||
|
||||
private module BooleanCookieHttpOnlyConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source.getType().getUnderlyingType() instanceof BoolType
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { exists(Http::CookieWrite cw | sink = cw.getHttpOnly()) }
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(Http::CookieOptionWrite co | co.getHttpOnly() = pred and co.getCookieOutput() = succ)
|
||||
}
|
||||
}
|
||||
|
||||
/** Tracks flow from boolean expressions to the `HttpOnly` attribute of HTTP cookie writes. */
|
||||
module BooleanCookieHttpOnlyFlow = TaintTracking::Global<BooleanCookieHttpOnlyConfig>;
|
||||
|
||||
/** Holds if `cw` has the `HttpOnly` attribute left at its default value of `false`. */
|
||||
predicate isNonHttpOnlyDefault(Http::CookieWrite cw) {
|
||||
not BooleanCookieHttpOnlyFlow::flowTo(cw.getHttpOnly())
|
||||
}
|
||||
|
||||
/** Holds if `cw` has the `HttpOnly` attribute explicitly set to `false`, from the expression `boolFalse`. */
|
||||
predicate isNonHttpOnlyDirect(Http::CookieWrite cw, Expr boolFalse) {
|
||||
BooleanCookieHttpOnlyFlow::flow(DataFlow::exprNode(boolFalse), cw.getHttpOnly()) and
|
||||
boolFalse.getBoolValue() = false
|
||||
}
|
||||
|
||||
/** Holds if `cw` has the `HttpOnly` attribute set to `false`, either explicitly or by default. */
|
||||
predicate isNonHttpOnlyCookie(Http::CookieWrite cw) {
|
||||
isNonHttpOnlyDefault(cw) or
|
||||
isNonHttpOnlyDirect(cw, _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `cw` has the sensitive name `name`, from the expression `nameExpr`.
|
||||
* `source` and `sink` represent the data flow path from the sensitive name expression to the cookie write.
|
||||
*/
|
||||
predicate isSensitiveCookie(
|
||||
Http::CookieWrite cw, string name, SensitiveCookieNameFlow::PathNode source,
|
||||
SensitiveCookieNameFlow::PathNode sink
|
||||
) {
|
||||
SensitiveCookieNameFlow::flowPath(source, sink) and
|
||||
SensitiveCookieNameConfig::isSource(source.getNode(), name) and
|
||||
SensitiveCookieNameConfig::isSink(sink.getNode(), cw)
|
||||
}
|
||||
37
go/ql/lib/semmle/go/security/CookieWithoutSecure.qll
Normal file
37
go/ql/lib/semmle/go/security/CookieWithoutSecure.qll
Normal file
@@ -0,0 +1,37 @@
|
||||
/** Provides classes and predicates for identifying HTTP cookies without the `Secure` attribute. */
|
||||
|
||||
import go
|
||||
import semmle.go.concepts.HTTP
|
||||
import semmle.go.dataflow.DataFlow
|
||||
|
||||
private module BooleanCookieSecureConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source.getType().getUnderlyingType() instanceof BoolType
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { exists(Http::CookieWrite cw | sink = cw.getSecure()) }
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(Http::CookieOptionWrite co | co.getSecure() = pred and co.getCookieOutput() = succ)
|
||||
}
|
||||
}
|
||||
|
||||
/** Tracks flow from boolean expressions to the `Secure` attribute of HTTP cookie writes. */
|
||||
module BooleanCookieSecureFlow = TaintTracking::Global<BooleanCookieSecureConfig>;
|
||||
|
||||
/** Holds if `cw` has the `Secure` attribute left at its default value of `false`. */
|
||||
predicate isInsecureDefault(Http::CookieWrite cw) {
|
||||
not BooleanCookieSecureFlow::flowTo(cw.getSecure())
|
||||
}
|
||||
|
||||
/** Holds if `cw` has the `Secure` attribute explicitly set to `false`, from the expression `boolFalse`. */
|
||||
predicate isInsecureDirect(Http::CookieWrite cw, Expr boolFalse) {
|
||||
BooleanCookieSecureFlow::flow(DataFlow::exprNode(boolFalse), cw.getSecure()) and
|
||||
boolFalse.getBoolValue() = false
|
||||
}
|
||||
|
||||
/** Holds if `cw` has the `Secure` attribute set to `false`, either explicitly or by default. */
|
||||
predicate isInsecureCookie(Http::CookieWrite cw) {
|
||||
isInsecureDefault(cw) or
|
||||
isInsecureDirect(cw, _)
|
||||
}
|
||||
34
go/ql/src/Security/CWE-1004/CookieWithoutHttpOnly.qhelp
Normal file
34
go/ql/src/Security/CWE-1004/CookieWithoutHttpOnly.qhelp
Normal file
@@ -0,0 +1,34 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>Cookies without the <code>HttpOnly</code> flag set are accessible to client-side scripts such as JavaScript running in the same origin.
|
||||
In case of a Cross-Site Scripting (XSS) vulnerability, the cookie can be stolen by a malicious script.
|
||||
If a sensitive cookie does not need to be accessed directly by client-side JS, the <code>HttpOnly</code> flag should be set.</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
Set the <code>HttpOnly</code> flag to <code>true</code> for authentication cookies to ensure they are not accessible to client-side scripts.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
In the following example, in the case marked BAD, the <code>HttpOnly</code> flag is not set, so the default value of <code>false</code> is used.
|
||||
In the case marked GOOD, the <code>HttpOnly</code> flag is set to <code>true</code>.
|
||||
</p>
|
||||
<sample src="examples/CookieWithoutHttpOnly.go"/>
|
||||
|
||||
|
||||
</example>
|
||||
|
||||
<references>
|
||||
|
||||
<li>MDN: <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie">Set-Cookie</a> Header.</li>
|
||||
<li>PortSwigger: <a href="https://portswigger.net/kb/issues/00500600_cookie-without-httponly-flag-set">Cookie without HttpOnly flag set</a></li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
25
go/ql/src/Security/CWE-1004/CookieWithoutHttpOnly.ql
Normal file
25
go/ql/src/Security/CWE-1004/CookieWithoutHttpOnly.ql
Normal file
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* @name Cookie 'HttpOnly' attribute is not set to true
|
||||
* @description Sensitive cookies without the `HttpOnly` property set are accessible by client-side scripts such as JavaScript.
|
||||
* This makes them more vulnerable to being stolen by an XSS attack.
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @precision high
|
||||
* @security-severity 5.0
|
||||
* @id go/cookie-httponly-not-set
|
||||
* @tags security
|
||||
* external/cwe/cwe-1004
|
||||
*/
|
||||
|
||||
import go
|
||||
import semmle.go.security.CookieWithoutHttpOnly
|
||||
import SensitiveCookieNameFlow::PathGraph
|
||||
|
||||
from
|
||||
Http::CookieWrite cw, string name, SensitiveCookieNameFlow::PathNode source,
|
||||
SensitiveCookieNameFlow::PathNode sink
|
||||
where
|
||||
isSensitiveCookie(cw, name, source, sink) and
|
||||
isNonHttpOnlyCookie(cw)
|
||||
select cw, source, sink, "Sensitive cookie $@ does not set HttpOnly attribute to true.", source,
|
||||
name
|
||||
@@ -0,0 +1,22 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func handlerBad(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
}
|
||||
http.SetCookie(w, &c) // BAD: The HttpOnly flag is set to false by default.
|
||||
}
|
||||
|
||||
func handlerGood(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
HttpOnly: true,
|
||||
}
|
||||
http.SetCookie(w, &c) // GOOD: The HttpOnly flag is set to true.
|
||||
}
|
||||
35
go/ql/src/Security/CWE-614/CookieWithoutSecure.qhelp
Normal file
35
go/ql/src/Security/CWE-614/CookieWithoutSecure.qhelp
Normal file
@@ -0,0 +1,35 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>Cookies without the <code>Secure</code> flag set may be transmitted using HTTP instead of HTTPS.
|
||||
This leaves them vulnerable to being read by a third party attacker. If a sensitive cookie such as a session
|
||||
key is intercepted this way, it would allow the attacker to perform actions on a user's behalf.</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
Set the <code>Secure</code> flag to <code>true</code> to ensure cookies are only transmitted over secure HTTPS connections.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
In the following example, in the case marked BAD, the <code>Secure</code> flag is set to <code>false</code> by default.
|
||||
In the case marked GOOD, the <code>Secure</code> flag is set to <code>true</code>.
|
||||
</p>
|
||||
<sample src="examples/CookieWithoutSecure.go"/>
|
||||
|
||||
|
||||
</example>
|
||||
|
||||
<references>
|
||||
|
||||
<li>MDN: <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie">Set-Cookie</a> Header.</li>
|
||||
<li>Detectify: <a href="https://support.detectify.com/support/solutions/articles/48001048982-cookie-lack-secure-flag">Cookie lack Secure flag</a>.</li>
|
||||
<li>PortSwigger: <a href="https://portswigger.net/kb/issues/00500200_tls-cookie-without-secure-flag-set">TLS cookie without secure flag set</a>.</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
19
go/ql/src/Security/CWE-614/CookieWithoutSecure.ql
Normal file
19
go/ql/src/Security/CWE-614/CookieWithoutSecure.ql
Normal file
@@ -0,0 +1,19 @@
|
||||
/**
|
||||
* @name Cookie 'Secure' attribute is not set to true
|
||||
* @description Cookies without the `Secure` flag may be sent in cleartext.
|
||||
* This makes them vulnerable to be intercepted by an attacker.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @precision high
|
||||
* @security-severity 4.0
|
||||
* @id go/cookie-secure-not-set
|
||||
* @tags security
|
||||
* external/cwe/cwe-614
|
||||
*/
|
||||
|
||||
import go
|
||||
import semmle.go.security.CookieWithoutSecure
|
||||
|
||||
from Http::CookieWrite cw
|
||||
where isInsecureCookie(cw)
|
||||
select cw, "Cookie does not set Secure attribute to true."
|
||||
22
go/ql/src/Security/CWE-614/examples/CookieWithoutSecure.go
Normal file
22
go/ql/src/Security/CWE-614/examples/CookieWithoutSecure.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func handlerBad(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
}
|
||||
http.SetCookie(w, &c) // BAD: The Secure flag is set to false by default.
|
||||
}
|
||||
|
||||
func handlerGood(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
Secure: true,
|
||||
}
|
||||
http.SetCookie(w, &c) // GOOD: The Secure flag is set to true.
|
||||
}
|
||||
5
go/ql/src/change-notes/2025-11-10-insecure-cookie.md
Normal file
5
go/ql/src/change-notes/2025-11-10-insecure-cookie.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
* The `go/cookie-http-only-not-set` query has been promoted from the experimental query pack. This query was originally contributed to the experimental query pack by @edvraa.
|
||||
* A new query `go/cookie-secure-not-set` has been added to detect cookies without the `Secure` flag set.
|
||||
@@ -1,245 +0,0 @@
|
||||
import go
|
||||
|
||||
private class NetHttpCookieType extends Type {
|
||||
NetHttpCookieType() { this.hasQualifiedName(package("net/http", ""), "Cookie") }
|
||||
}
|
||||
|
||||
private class GinContextSetCookieMethod extends Method {
|
||||
GinContextSetCookieMethod() {
|
||||
this.hasQualifiedName(package("github.com/gin-gonic/gin", ""), "Context", "SetCookie")
|
||||
}
|
||||
}
|
||||
|
||||
private class GorillaSessionOptionsField extends Field {
|
||||
GorillaSessionOptionsField() {
|
||||
this.hasQualifiedName(package("github.com/gorilla/sessions", ""), "Session", "Options")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A simplistic points-to alternative: given a struct creation and a field name, get the values that field can be assigned.
|
||||
*
|
||||
* Assumptions:
|
||||
* - we don't reassign the variable that the creation is stored in
|
||||
* - we always access the creation through the same variable it is initially assigned to
|
||||
*
|
||||
* This should cover most typical patterns...
|
||||
*/
|
||||
private DataFlow::Node getValueForFieldWrite(StructLit sl, string field) {
|
||||
exists(Write w, DataFlow::Node base, Field f |
|
||||
f.getName() = field and
|
||||
w.writesFieldPreUpdate(base, f, result) and
|
||||
(
|
||||
sl = base.asExpr()
|
||||
or
|
||||
base.asExpr() instanceof VariableName and
|
||||
base.getAPredecessor*().asExpr() = sl
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the expression or its value has a sensitive name
|
||||
*/
|
||||
private predicate isAuthVariable(Expr expr) {
|
||||
exists(string val |
|
||||
(
|
||||
val = expr.getStringValue() or
|
||||
val = expr.(Name).getTarget().getName()
|
||||
) and
|
||||
val.regexpMatch("(?i).*(session|login|token|user|auth|credential).*") and
|
||||
not val.regexpMatch("(?i).*(xsrf|csrf|forgery).*")
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A cookie passed as the second parameter to `net/http.SetCookie`.
|
||||
*/
|
||||
private class SetCookieSink extends DataFlow::Node {
|
||||
SetCookieSink() {
|
||||
exists(DataFlow::CallNode cn |
|
||||
cn.getTarget().hasQualifiedName(package("net/http", ""), "SetCookie") and
|
||||
this = cn.getArgument(1)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private module NameToNetHttpCookieTrackingConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { isAuthVariable(source.asExpr()) }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof SetCookieSink }
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(StructLit sl |
|
||||
sl.getType() instanceof NetHttpCookieType and
|
||||
getValueForFieldWrite(sl, "Name") = pred and
|
||||
sl = succ.asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Tracks taint flow from sensitive names to `net/http.SetCookie`. */
|
||||
module NameToNetHttpCookieTrackingFlow = TaintTracking::Global<NameToNetHttpCookieTrackingConfig>;
|
||||
|
||||
private module BoolToNetHttpCookieTrackingConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source.getType().getUnderlyingType() instanceof BoolType
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof SetCookieSink }
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(StructLit sl |
|
||||
sl.getType() instanceof NetHttpCookieType and
|
||||
getValueForFieldWrite(sl, "HttpOnly") = pred and
|
||||
sl = succ.asExpr()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks taint flow from a `bool` assigned to `HttpOnly` to
|
||||
* `net/http.SetCookie`.
|
||||
*/
|
||||
module BoolToNetHttpCookieTrackingFlow = TaintTracking::Global<BoolToNetHttpCookieTrackingConfig>;
|
||||
|
||||
private module BoolToGinSetCookieTrackingConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source.getBoolValue() = false }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(DataFlow::MethodCallNode mcn |
|
||||
mcn.getTarget() instanceof GinContextSetCookieMethod and
|
||||
mcn.getArgument(6) = sink and
|
||||
exists(DataFlow::Node nameArg |
|
||||
NameToGinSetCookieTrackingFlow::flowTo(nameArg) and
|
||||
mcn.getArgument(0) = nameArg
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() {
|
||||
any() // Merged with other flows in CookieWithoutHttpOnly.ql
|
||||
}
|
||||
|
||||
Location getASelectedSourceLocation(DataFlow::Node source) { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks data flow from `HttpOnly` set to `false` to
|
||||
* `gin-gonic/gin.Context.SetCookie`.
|
||||
*/
|
||||
module BoolToGinSetCookieTrackingFlow = DataFlow::Global<BoolToGinSetCookieTrackingConfig>;
|
||||
|
||||
private module NameToGinSetCookieTrackingConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { isAuthVariable(source.asExpr()) }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(DataFlow::MethodCallNode mcn |
|
||||
mcn.getTarget() instanceof GinContextSetCookieMethod and
|
||||
mcn.getArgument(0) = sink
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks taint flow from sensitive names to `gin-gonic/gin.Context.SetCookie`.
|
||||
*/
|
||||
private module NameToGinSetCookieTrackingFlow = DataFlow::Global<NameToGinSetCookieTrackingConfig>;
|
||||
|
||||
/**
|
||||
* The receiver of `gorilla/sessions.Session.Save` call.
|
||||
*/
|
||||
private class GorillaSessionSaveSink extends DataFlow::Node {
|
||||
GorillaSessionSaveSink() {
|
||||
exists(DataFlow::MethodCallNode mcn |
|
||||
this = mcn.getReceiver() and
|
||||
mcn.getTarget()
|
||||
.hasQualifiedName(package("github.com/gorilla/sessions", ""), "Session", "Save")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class GorillaStoreSaveSink extends DataFlow::Node {
|
||||
GorillaStoreSaveSink() {
|
||||
exists(DataFlow::MethodCallNode mcn |
|
||||
this = mcn.getArgument(2) and
|
||||
mcn.getTarget()
|
||||
.hasQualifiedName(package("github.com/gorilla/sessions", ""), "CookieStore", "Save")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private module GorillaCookieStoreSaveTrackingConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source
|
||||
.(DataFlow::CallNode)
|
||||
.getTarget()
|
||||
.hasQualifiedName(package("github.com/gorilla/sessions", ""), "NewCookieStore")
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
sink instanceof GorillaSessionSaveSink or
|
||||
sink instanceof GorillaStoreSaveSink
|
||||
}
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(DataFlow::MethodCallNode cn |
|
||||
cn.getTarget()
|
||||
.hasQualifiedName(package("github.com/gorilla/sessions", ""), "CookieStore", "Get") and
|
||||
pred = cn.getReceiver() and
|
||||
succ = cn.getResult(0)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks data flow from gorilla cookie store creation to
|
||||
* `gorilla/sessions.Session.Save`.
|
||||
*/
|
||||
module GorillaCookieStoreSaveTrackingFlow = DataFlow::Global<GorillaCookieStoreSaveTrackingConfig>;
|
||||
|
||||
private module GorillaSessionOptionsTrackingConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
exists(StructLit sl |
|
||||
sl.getType().hasQualifiedName(package("github.com/gorilla/sessions", ""), "Options") and
|
||||
source.asExpr() = sl
|
||||
)
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof GorillaSessionSaveSink }
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(GorillaSessionOptionsField f, DataFlow::Write w | w.writesField(succ, f, pred))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks taint flow from session options to
|
||||
* `gorilla/sessions.Session.Save`.
|
||||
*/
|
||||
module GorillaSessionOptionsTrackingFlow =
|
||||
TaintTracking::Global<GorillaSessionOptionsTrackingConfig>;
|
||||
|
||||
private module BoolToGorillaSessionOptionsTrackingConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source.getType().getUnderlyingType() instanceof BoolType
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof GorillaSessionSaveSink }
|
||||
|
||||
predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
exists(StructLit sl |
|
||||
getValueForFieldWrite(sl, "HttpOnly") = pred and
|
||||
sl = succ.asExpr()
|
||||
)
|
||||
or
|
||||
exists(GorillaSessionOptionsField f, DataFlow::Write w | w.writesField(succ, f, pred))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tracks taint flow from a `bool` assigned to `HttpOnly` to
|
||||
* `gorilla/sessions.Session.Save`.
|
||||
*/
|
||||
module BoolToGorillaSessionOptionsTrackingFlow =
|
||||
TaintTracking::Global<BoolToGorillaSessionOptionsTrackingConfig>;
|
||||
@@ -1,42 +0,0 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
Cookies without <code>HttpOnly</code> attribute are accessible to JavaScript running in the same origin. In case of
|
||||
Cross-Site Scripting (XSS) vulnerability the cookie can be stolen by malicious script.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
Protect sensitive cookies, such as related to authentication, by setting <code>HttpOnly</code> to <code>true</code> to make
|
||||
them not accessible to JavaScript.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
|
||||
<p>
|
||||
In the following example the default <code>HttpOnly</code> value is <code>false</code>.
|
||||
</p>
|
||||
|
||||
<sample src="CookieWithoutHttpOnlyBad.go" />
|
||||
|
||||
<p>
|
||||
In the example below <code>HttpOnly</code> is set to <code>true</code>.
|
||||
</p>
|
||||
|
||||
<sample src="CookieWithoutHttpOnlyGood.go" />
|
||||
|
||||
</example>
|
||||
|
||||
<references>
|
||||
|
||||
<li><a href="https://golang.org/pkg/net/http/#Cookie">type Cookie,</a></li>
|
||||
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie">Set-Cookie</a> Header,</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -1,99 +0,0 @@
|
||||
/**
|
||||
* @name 'HttpOnly' attribute is not set to true
|
||||
* @description Omitting the 'HttpOnly' attribute for security sensitive data allows
|
||||
* malicious JavaScript to steal it in case of XSS vulnerability. Always set
|
||||
* 'HttpOnly' to 'true' to authentication related cookie to make it
|
||||
* not accessible by JavaScript.
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @precision high
|
||||
* @id go/cookie-httponly-not-set
|
||||
* @tags security
|
||||
* experimental
|
||||
* external/cwe/cwe-1004
|
||||
*/
|
||||
|
||||
import go
|
||||
import AuthCookie
|
||||
|
||||
module NetHttpCookieTrackingFlow =
|
||||
DataFlow::MergePathGraph<NameToNetHttpCookieTrackingFlow::PathNode,
|
||||
BoolToNetHttpCookieTrackingFlow::PathNode, NameToNetHttpCookieTrackingFlow::PathGraph,
|
||||
BoolToNetHttpCookieTrackingFlow::PathGraph>;
|
||||
|
||||
module GorillaTrackingFlow =
|
||||
DataFlow::MergePathGraph3<GorillaCookieStoreSaveTrackingFlow::PathNode,
|
||||
GorillaSessionOptionsTrackingFlow::PathNode, BoolToGorillaSessionOptionsTrackingFlow::PathNode,
|
||||
GorillaCookieStoreSaveTrackingFlow::PathGraph, GorillaSessionOptionsTrackingFlow::PathGraph,
|
||||
BoolToGorillaSessionOptionsTrackingFlow::PathGraph>;
|
||||
|
||||
module MergedFlow =
|
||||
DataFlow::MergePathGraph3<NetHttpCookieTrackingFlow::PathNode,
|
||||
BoolToGinSetCookieTrackingFlow::PathNode, GorillaTrackingFlow::PathNode,
|
||||
NetHttpCookieTrackingFlow::PathGraph, BoolToGinSetCookieTrackingFlow::PathGraph,
|
||||
GorillaTrackingFlow::PathGraph>;
|
||||
|
||||
import MergedFlow::PathGraph
|
||||
|
||||
/** Holds if `HttpOnly` of `net/http.SetCookie` is set to `false` or not set (default value is used). */
|
||||
predicate isNetHttpCookieFlow(
|
||||
NetHttpCookieTrackingFlow::PathNode source, NetHttpCookieTrackingFlow::PathNode sink
|
||||
) {
|
||||
exists(
|
||||
NameToNetHttpCookieTrackingFlow::PathNode sensitiveName,
|
||||
NameToNetHttpCookieTrackingFlow::PathNode setCookieSink
|
||||
|
|
||||
NameToNetHttpCookieTrackingFlow::flowPath(sensitiveName, setCookieSink) and
|
||||
(
|
||||
not BoolToNetHttpCookieTrackingFlow::flowTo(sink.getNode()) and
|
||||
source.asPathNode1() = sensitiveName and
|
||||
sink.asPathNode1() = setCookieSink
|
||||
or
|
||||
BoolToNetHttpCookieTrackingFlow::flowPath(source.asPathNode2(), sink.asPathNode2()) and
|
||||
source.getNode().getBoolValue() = false and
|
||||
setCookieSink.getNode() = sink.getNode()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there is gorilla cookie store creation to `Save` path and
|
||||
* `HttpOnly` is set to `false` or not set (default value is used).
|
||||
*/
|
||||
predicate isGorillaSessionsCookieFlow(
|
||||
GorillaTrackingFlow::PathNode source, GorillaTrackingFlow::PathNode sink
|
||||
) {
|
||||
exists(
|
||||
GorillaCookieStoreSaveTrackingFlow::PathNode cookieStoreCreate,
|
||||
GorillaCookieStoreSaveTrackingFlow::PathNode sessionSave
|
||||
|
|
||||
GorillaCookieStoreSaveTrackingFlow::flowPath(cookieStoreCreate, sessionSave) and
|
||||
(
|
||||
not GorillaSessionOptionsTrackingFlow::flowTo(sink.getNode()) and
|
||||
source.asPathNode1() = cookieStoreCreate and
|
||||
sink.asPathNode1() = sessionSave
|
||||
or
|
||||
exists(GorillaTrackingFlow::PathNode options, GorillaTrackingFlow::PathNode sessionSave2 |
|
||||
GorillaSessionOptionsTrackingFlow::flowPath(options.asPathNode2(),
|
||||
sessionSave2.asPathNode2()) and
|
||||
(
|
||||
not BoolToGorillaSessionOptionsTrackingFlow::flowTo(sink.getNode()) and
|
||||
sink = sessionSave2 and
|
||||
source = options and
|
||||
sessionSave.getNode() = sessionSave2.getNode()
|
||||
or
|
||||
BoolToGorillaSessionOptionsTrackingFlow::flowPath(source.asPathNode3(), sink.asPathNode3()) and
|
||||
source.getNode().getBoolValue() = false and
|
||||
sink.getNode() = sessionSave.getNode()
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
from MergedFlow::PathNode source, MergedFlow::PathNode sink
|
||||
where
|
||||
isNetHttpCookieFlow(source.asPathNode1(), sink.asPathNode1()) or
|
||||
BoolToGinSetCookieTrackingFlow::flowPath(source.asPathNode2(), sink.asPathNode2()) or
|
||||
isGorillaSessionsCookieFlow(source.asPathNode3(), sink.asPathNode3())
|
||||
select sink.getNode(), source, sink, "Cookie attribute 'HttpOnly' is not set to true."
|
||||
@@ -1,17 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func handler(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
}
|
||||
http.SetCookie(w, &c)
|
||||
}
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/", handler)
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func handler(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
HttpOnly: true,
|
||||
}
|
||||
http.SetCookie(w, &c)
|
||||
}
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/", handler)
|
||||
}
|
||||
@@ -1,432 +0,0 @@
|
||||
edges
|
||||
| CookieWithoutHttpOnly.go:11:7:14:2 | struct literal | CookieWithoutHttpOnly.go:15:20:15:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:11:7:14:2 | struct literal | CookieWithoutHttpOnly.go:15:21:15:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:12:10:12:18 | "session" | CookieWithoutHttpOnly.go:11:7:14:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | CookieWithoutHttpOnly.go:15:20:15:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:15:21:15:21 | c | CookieWithoutHttpOnly.go:15:20:15:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:15:21:15:21 | c | CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | CookieWithoutHttpOnly.go:24:21:24:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | CookieWithoutHttpOnly.go:24:21:24:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:20:13:20:21 | "session" | CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:22:13:22:17 | false | CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:24:21:24:21 | c | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:24:21:24:21 | c | CookieWithoutHttpOnly.go:24:20:24:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:24:21:24:21 | c | CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:24:21:24:21 | c | CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | CookieWithoutHttpOnly.go:33:21:33:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | CookieWithoutHttpOnly.go:33:21:33:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:29:13:29:21 | "session" | CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:31:13:31:16 | true | CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:33:21:33:21 | c | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:33:21:33:21 | c | CookieWithoutHttpOnly.go:33:20:33:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:33:21:33:21 | c | CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:33:21:33:21 | c | CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | CookieWithoutHttpOnly.go:42:21:42:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | CookieWithoutHttpOnly.go:42:21:42:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:38:10:38:18 | "session" | CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:41:15:41:18 | true | CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:42:21:42:21 | c | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:42:21:42:21 | c | CookieWithoutHttpOnly.go:42:20:42:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:42:21:42:21 | c | CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:42:21:42:21 | c | CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | CookieWithoutHttpOnly.go:51:21:51:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | CookieWithoutHttpOnly.go:51:21:51:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:47:10:47:18 | "session" | CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:50:15:50:19 | false | CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:51:21:51:21 | c | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:51:21:51:21 | c | CookieWithoutHttpOnly.go:51:20:51:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:51:21:51:21 | c | CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:51:21:51:21 | c | CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:55:2:55:4 | definition of val | CookieWithoutHttpOnly.go:59:13:59:15 | val | provenance | |
|
||||
| CookieWithoutHttpOnly.go:55:9:55:13 | false | CookieWithoutHttpOnly.go:59:13:59:15 | val | provenance | |
|
||||
| CookieWithoutHttpOnly.go:56:7:60:2 | struct literal | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:56:7:60:2 | struct literal | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:56:7:60:2 | struct literal | CookieWithoutHttpOnly.go:61:21:61:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:56:7:60:2 | struct literal | CookieWithoutHttpOnly.go:61:21:61:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:57:13:57:21 | "session" | CookieWithoutHttpOnly.go:56:7:60:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:59:13:59:15 | val | CookieWithoutHttpOnly.go:56:7:60:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:61:21:61:21 | c | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:61:21:61:21 | c | CookieWithoutHttpOnly.go:61:20:61:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:61:21:61:21 | c | CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:61:21:61:21 | c | CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:65:2:65:4 | definition of val | CookieWithoutHttpOnly.go:69:13:69:15 | val | provenance | |
|
||||
| CookieWithoutHttpOnly.go:65:9:65:12 | true | CookieWithoutHttpOnly.go:69:13:69:15 | val | provenance | |
|
||||
| CookieWithoutHttpOnly.go:66:7:70:2 | struct literal | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:66:7:70:2 | struct literal | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:66:7:70:2 | struct literal | CookieWithoutHttpOnly.go:71:21:71:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:66:7:70:2 | struct literal | CookieWithoutHttpOnly.go:71:21:71:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:67:13:67:21 | "session" | CookieWithoutHttpOnly.go:66:7:70:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:69:13:69:15 | val | CookieWithoutHttpOnly.go:66:7:70:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:71:21:71:21 | c | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:71:21:71:21 | c | CookieWithoutHttpOnly.go:71:20:71:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:71:21:71:21 | c | CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:71:21:71:21 | c | CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:75:2:75:4 | definition of val | CookieWithoutHttpOnly.go:80:15:80:17 | val | provenance | |
|
||||
| CookieWithoutHttpOnly.go:75:9:75:12 | true | CookieWithoutHttpOnly.go:80:15:80:17 | val | provenance | |
|
||||
| CookieWithoutHttpOnly.go:76:7:79:2 | struct literal | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:76:7:79:2 | struct literal | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:76:7:79:2 | struct literal | CookieWithoutHttpOnly.go:81:21:81:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:76:7:79:2 | struct literal | CookieWithoutHttpOnly.go:81:21:81:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:77:10:77:18 | "session" | CookieWithoutHttpOnly.go:76:7:79:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:80:15:80:17 | val | CookieWithoutHttpOnly.go:76:7:79:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:81:21:81:21 | c | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:81:21:81:21 | c | CookieWithoutHttpOnly.go:81:20:81:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:81:21:81:21 | c | CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:81:21:81:21 | c | CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:85:2:85:4 | definition of val | CookieWithoutHttpOnly.go:90:15:90:17 | val | provenance | |
|
||||
| CookieWithoutHttpOnly.go:85:9:85:13 | false | CookieWithoutHttpOnly.go:90:15:90:17 | val | provenance | |
|
||||
| CookieWithoutHttpOnly.go:86:7:89:2 | struct literal | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:86:7:89:2 | struct literal | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:86:7:89:2 | struct literal | CookieWithoutHttpOnly.go:91:21:91:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:86:7:89:2 | struct literal | CookieWithoutHttpOnly.go:91:21:91:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:87:10:87:18 | "session" | CookieWithoutHttpOnly.go:86:7:89:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:90:15:90:17 | val | CookieWithoutHttpOnly.go:86:7:89:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:91:21:91:21 | c | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:91:21:91:21 | c | CookieWithoutHttpOnly.go:91:20:91:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:91:21:91:21 | c | CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:91:21:91:21 | c | CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:95:7:98:2 | struct literal | CookieWithoutHttpOnly.go:100:20:100:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:95:7:98:2 | struct literal | CookieWithoutHttpOnly.go:100:21:100:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:99:15:99:19 | false | CookieWithoutHttpOnly.go:95:7:98:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | CookieWithoutHttpOnly.go:100:20:100:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:100:21:100:21 | c | CookieWithoutHttpOnly.go:100:20:100:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:100:21:100:21 | c | CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:104:10:104:18 | "session" | CookieWithoutHttpOnly.go:106:10:106:13 | name | provenance | |
|
||||
| CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | CookieWithoutHttpOnly.go:110:21:110:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | CookieWithoutHttpOnly.go:110:21:110:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:106:10:106:13 | name | CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:109:15:109:19 | false | CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:110:21:110:21 | c | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:110:21:110:21 | c | CookieWithoutHttpOnly.go:110:20:110:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:110:21:110:21 | c | CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:110:21:110:21 | c | CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:114:13:114:24 | "login_name" | CookieWithoutHttpOnly.go:116:10:116:16 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:115:7:118:2 | struct literal | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:115:7:118:2 | struct literal | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:115:7:118:2 | struct literal | CookieWithoutHttpOnly.go:120:21:120:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:115:7:118:2 | struct literal | CookieWithoutHttpOnly.go:120:21:120:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:116:10:116:16 | session | CookieWithoutHttpOnly.go:115:7:118:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:119:15:119:19 | false | CookieWithoutHttpOnly.go:115:7:118:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:120:21:120:21 | c | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:120:21:120:21 | c | CookieWithoutHttpOnly.go:120:20:120:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:120:21:120:21 | c | CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:120:21:120:21 | c | CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:126:16:126:20 | store | provenance | |
|
||||
| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:134:16:134:20 | store | provenance | |
|
||||
| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:146:16:146:20 | store | provenance | |
|
||||
| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:158:16:158:20 | store | provenance | |
|
||||
| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:170:16:170:20 | store | provenance | |
|
||||
| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:183:16:183:20 | store | provenance | |
|
||||
| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:195:16:195:20 | store | provenance | |
|
||||
| CookieWithoutHttpOnly.go:126:2:126:43 | ... := ...[0] | CookieWithoutHttpOnly.go:129:2:129:8 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:126:16:126:20 | store | CookieWithoutHttpOnly.go:126:2:126:43 | ... := ...[0] | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:133:2:133:9 | definition of httpOnly | CookieWithoutHttpOnly.go:139:13:139:20 | httpOnly | provenance | |
|
||||
| CookieWithoutHttpOnly.go:133:14:133:18 | false | CookieWithoutHttpOnly.go:139:13:139:20 | httpOnly | provenance | |
|
||||
| CookieWithoutHttpOnly.go:134:2:134:43 | ... := ...[0] | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:134:16:134:20 | store | CookieWithoutHttpOnly.go:134:2:134:43 | ... := ...[0] | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:142:2:142:8 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference [postupdate] | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference [postupdate] | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:137:20:140:2 | &... | CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | CookieWithoutHttpOnly.go:137:20:140:2 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | CookieWithoutHttpOnly.go:137:20:140:2 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:139:13:139:20 | httpOnly | CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:146:2:146:43 | ... := ...[0] | CookieWithoutHttpOnly.go:153:2:153:8 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:146:16:146:20 | store | CookieWithoutHttpOnly.go:146:2:146:43 | ... := ...[0] | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:149:2:149:8 | session [postupdate] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:149:2:149:8 | session [postupdate] [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:149:2:149:8 | session [postupdate] | CookieWithoutHttpOnly.go:153:2:153:8 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:149:2:149:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:153:2:153:8 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:149:20:151:2 | &... | CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference [postupdate] | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:149:20:151:2 | &... | CookieWithoutHttpOnly.go:149:2:149:8 | session [postupdate] | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:149:21:151:2 | struct literal | CookieWithoutHttpOnly.go:149:20:151:2 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:157:2:157:9 | definition of httpOnly | CookieWithoutHttpOnly.go:163:13:163:20 | httpOnly | provenance | |
|
||||
| CookieWithoutHttpOnly.go:157:14:157:17 | true | CookieWithoutHttpOnly.go:163:13:163:20 | httpOnly | provenance | |
|
||||
| CookieWithoutHttpOnly.go:158:2:158:43 | ... := ...[0] | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:158:16:158:20 | store | CookieWithoutHttpOnly.go:158:2:158:43 | ... := ...[0] | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:166:2:166:8 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference [postupdate] | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference [postupdate] | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:161:20:164:2 | &... | CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:161:21:164:2 | struct literal | CookieWithoutHttpOnly.go:161:20:164:2 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:161:21:164:2 | struct literal | CookieWithoutHttpOnly.go:161:20:164:2 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:163:13:163:20 | httpOnly | CookieWithoutHttpOnly.go:161:21:164:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:169:56:169:63 | argument corresponding to httpOnly | CookieWithoutHttpOnly.go:175:13:175:20 | httpOnly | provenance | |
|
||||
| CookieWithoutHttpOnly.go:169:56:169:63 | definition of httpOnly | CookieWithoutHttpOnly.go:175:13:175:20 | httpOnly | provenance | |
|
||||
| CookieWithoutHttpOnly.go:170:2:170:43 | ... := ...[0] | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:170:16:170:20 | store | CookieWithoutHttpOnly.go:170:2:170:43 | ... := ...[0] | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference [postupdate] | CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] [pointer] | CookieWithoutHttpOnly.go:178:2:178:8 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference [postupdate] | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference [postupdate] | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:173:20:176:2 | &... | CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:173:21:176:2 | struct literal | CookieWithoutHttpOnly.go:173:20:176:2 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:173:21:176:2 | struct literal | CookieWithoutHttpOnly.go:173:20:176:2 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:175:13:175:20 | httpOnly | CookieWithoutHttpOnly.go:173:21:176:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:183:2:183:43 | ... := ...[0] | CookieWithoutHttpOnly.go:191:19:191:25 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:183:16:183:20 | store | CookieWithoutHttpOnly.go:183:2:183:43 | ... := ...[0] | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:195:2:195:43 | ... := ...[0] | CookieWithoutHttpOnly.go:202:19:202:25 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:195:16:195:20 | store | CookieWithoutHttpOnly.go:195:2:195:43 | ... := ...[0] | provenance | Config |
|
||||
nodes
|
||||
| CookieWithoutHttpOnly.go:11:7:14:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:12:10:12:18 | "session" | semmle.label | "session" |
|
||||
| CookieWithoutHttpOnly.go:15:20:15:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:15:20:15:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:15:21:15:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:19:7:23:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:20:13:20:21 | "session" | semmle.label | "session" |
|
||||
| CookieWithoutHttpOnly.go:22:13:22:17 | false | semmle.label | false |
|
||||
| CookieWithoutHttpOnly.go:24:20:24:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:24:20:24:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:24:20:24:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:24:21:24:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:24:21:24:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:28:7:32:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:29:13:29:21 | "session" | semmle.label | "session" |
|
||||
| CookieWithoutHttpOnly.go:31:13:31:16 | true | semmle.label | true |
|
||||
| CookieWithoutHttpOnly.go:33:20:33:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:33:20:33:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:33:20:33:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:33:21:33:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:33:21:33:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:37:7:40:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:38:10:38:18 | "session" | semmle.label | "session" |
|
||||
| CookieWithoutHttpOnly.go:41:15:41:18 | true | semmle.label | true |
|
||||
| CookieWithoutHttpOnly.go:42:20:42:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:42:20:42:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:42:20:42:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:42:21:42:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:42:21:42:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:46:7:49:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:47:10:47:18 | "session" | semmle.label | "session" |
|
||||
| CookieWithoutHttpOnly.go:50:15:50:19 | false | semmle.label | false |
|
||||
| CookieWithoutHttpOnly.go:51:20:51:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:51:20:51:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:51:20:51:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:51:21:51:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:51:21:51:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:55:2:55:4 | definition of val | semmle.label | definition of val |
|
||||
| CookieWithoutHttpOnly.go:55:9:55:13 | false | semmle.label | false |
|
||||
| CookieWithoutHttpOnly.go:56:7:60:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:56:7:60:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:57:13:57:21 | "session" | semmle.label | "session" |
|
||||
| CookieWithoutHttpOnly.go:59:13:59:15 | val | semmle.label | val |
|
||||
| CookieWithoutHttpOnly.go:61:20:61:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:61:20:61:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:61:20:61:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:61:21:61:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:61:21:61:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:65:2:65:4 | definition of val | semmle.label | definition of val |
|
||||
| CookieWithoutHttpOnly.go:65:9:65:12 | true | semmle.label | true |
|
||||
| CookieWithoutHttpOnly.go:66:7:70:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:66:7:70:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:67:13:67:21 | "session" | semmle.label | "session" |
|
||||
| CookieWithoutHttpOnly.go:69:13:69:15 | val | semmle.label | val |
|
||||
| CookieWithoutHttpOnly.go:71:20:71:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:71:20:71:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:71:20:71:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:71:21:71:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:71:21:71:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:75:2:75:4 | definition of val | semmle.label | definition of val |
|
||||
| CookieWithoutHttpOnly.go:75:9:75:12 | true | semmle.label | true |
|
||||
| CookieWithoutHttpOnly.go:76:7:79:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:76:7:79:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:77:10:77:18 | "session" | semmle.label | "session" |
|
||||
| CookieWithoutHttpOnly.go:80:15:80:17 | val | semmle.label | val |
|
||||
| CookieWithoutHttpOnly.go:81:20:81:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:81:20:81:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:81:20:81:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:81:21:81:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:81:21:81:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:85:2:85:4 | definition of val | semmle.label | definition of val |
|
||||
| CookieWithoutHttpOnly.go:85:9:85:13 | false | semmle.label | false |
|
||||
| CookieWithoutHttpOnly.go:86:7:89:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:86:7:89:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:87:10:87:18 | "session" | semmle.label | "session" |
|
||||
| CookieWithoutHttpOnly.go:90:15:90:17 | val | semmle.label | val |
|
||||
| CookieWithoutHttpOnly.go:91:20:91:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:91:20:91:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:91:20:91:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:91:21:91:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:91:21:91:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:95:7:98:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:99:15:99:19 | false | semmle.label | false |
|
||||
| CookieWithoutHttpOnly.go:100:20:100:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:100:20:100:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:100:21:100:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:104:10:104:18 | "session" | semmle.label | "session" |
|
||||
| CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:105:7:108:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:106:10:106:13 | name | semmle.label | name |
|
||||
| CookieWithoutHttpOnly.go:109:15:109:19 | false | semmle.label | false |
|
||||
| CookieWithoutHttpOnly.go:110:20:110:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:110:20:110:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:110:20:110:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:110:21:110:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:110:21:110:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:114:13:114:24 | "login_name" | semmle.label | "login_name" |
|
||||
| CookieWithoutHttpOnly.go:115:7:118:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:115:7:118:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:116:10:116:16 | session | semmle.label | session |
|
||||
| CookieWithoutHttpOnly.go:119:15:119:19 | false | semmle.label | false |
|
||||
| CookieWithoutHttpOnly.go:120:20:120:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:120:20:120:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:120:20:120:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:120:21:120:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:120:21:120:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | semmle.label | call to NewCookieStore |
|
||||
| CookieWithoutHttpOnly.go:126:2:126:43 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||
| CookieWithoutHttpOnly.go:126:16:126:20 | store | semmle.label | store |
|
||||
| CookieWithoutHttpOnly.go:129:2:129:8 | session | semmle.label | session |
|
||||
| CookieWithoutHttpOnly.go:133:2:133:9 | definition of httpOnly | semmle.label | definition of httpOnly |
|
||||
| CookieWithoutHttpOnly.go:133:14:133:18 | false | semmle.label | false |
|
||||
| CookieWithoutHttpOnly.go:134:2:134:43 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||
| CookieWithoutHttpOnly.go:134:16:134:20 | store | semmle.label | store |
|
||||
| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] |
|
||||
| CookieWithoutHttpOnly.go:137:2:137:8 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] |
|
||||
| CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] | semmle.label | session [postupdate] |
|
||||
| CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] | semmle.label | session [postupdate] |
|
||||
| CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] |
|
||||
| CookieWithoutHttpOnly.go:137:2:137:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] |
|
||||
| CookieWithoutHttpOnly.go:137:20:140:2 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:137:20:140:2 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:137:21:140:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:139:13:139:20 | httpOnly | semmle.label | httpOnly |
|
||||
| CookieWithoutHttpOnly.go:142:2:142:8 | session | semmle.label | session |
|
||||
| CookieWithoutHttpOnly.go:142:2:142:8 | session | semmle.label | session |
|
||||
| CookieWithoutHttpOnly.go:142:2:142:8 | session | semmle.label | session |
|
||||
| CookieWithoutHttpOnly.go:146:2:146:43 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||
| CookieWithoutHttpOnly.go:146:16:146:20 | store | semmle.label | store |
|
||||
| CookieWithoutHttpOnly.go:149:2:149:8 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] |
|
||||
| CookieWithoutHttpOnly.go:149:2:149:8 | session [postupdate] | semmle.label | session [postupdate] |
|
||||
| CookieWithoutHttpOnly.go:149:2:149:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] |
|
||||
| CookieWithoutHttpOnly.go:149:20:151:2 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:149:21:151:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:153:2:153:8 | session | semmle.label | session |
|
||||
| CookieWithoutHttpOnly.go:153:2:153:8 | session | semmle.label | session |
|
||||
| CookieWithoutHttpOnly.go:157:2:157:9 | definition of httpOnly | semmle.label | definition of httpOnly |
|
||||
| CookieWithoutHttpOnly.go:157:14:157:17 | true | semmle.label | true |
|
||||
| CookieWithoutHttpOnly.go:158:2:158:43 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||
| CookieWithoutHttpOnly.go:158:16:158:20 | store | semmle.label | store |
|
||||
| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] |
|
||||
| CookieWithoutHttpOnly.go:161:2:161:8 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] |
|
||||
| CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] | semmle.label | session [postupdate] |
|
||||
| CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] | semmle.label | session [postupdate] |
|
||||
| CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] |
|
||||
| CookieWithoutHttpOnly.go:161:2:161:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] |
|
||||
| CookieWithoutHttpOnly.go:161:20:164:2 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:161:20:164:2 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:161:21:164:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:161:21:164:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:163:13:163:20 | httpOnly | semmle.label | httpOnly |
|
||||
| CookieWithoutHttpOnly.go:166:2:166:8 | session | semmle.label | session |
|
||||
| CookieWithoutHttpOnly.go:166:2:166:8 | session | semmle.label | session |
|
||||
| CookieWithoutHttpOnly.go:166:2:166:8 | session | semmle.label | session |
|
||||
| CookieWithoutHttpOnly.go:169:56:169:63 | argument corresponding to httpOnly | semmle.label | argument corresponding to httpOnly |
|
||||
| CookieWithoutHttpOnly.go:169:56:169:63 | definition of httpOnly | semmle.label | definition of httpOnly |
|
||||
| CookieWithoutHttpOnly.go:170:2:170:43 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||
| CookieWithoutHttpOnly.go:170:16:170:20 | store | semmle.label | store |
|
||||
| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] |
|
||||
| CookieWithoutHttpOnly.go:173:2:173:8 | implicit dereference [postupdate] | semmle.label | implicit dereference [postupdate] |
|
||||
| CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] | semmle.label | session [postupdate] |
|
||||
| CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] | semmle.label | session [postupdate] |
|
||||
| CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] |
|
||||
| CookieWithoutHttpOnly.go:173:2:173:8 | session [postupdate] [pointer] | semmle.label | session [postupdate] [pointer] |
|
||||
| CookieWithoutHttpOnly.go:173:20:176:2 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:173:20:176:2 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:173:21:176:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:173:21:176:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:175:13:175:20 | httpOnly | semmle.label | httpOnly |
|
||||
| CookieWithoutHttpOnly.go:178:2:178:8 | session | semmle.label | session |
|
||||
| CookieWithoutHttpOnly.go:178:2:178:8 | session | semmle.label | session |
|
||||
| CookieWithoutHttpOnly.go:178:2:178:8 | session | semmle.label | session |
|
||||
| CookieWithoutHttpOnly.go:183:2:183:43 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||
| CookieWithoutHttpOnly.go:183:16:183:20 | store | semmle.label | store |
|
||||
| CookieWithoutHttpOnly.go:191:19:191:25 | session | semmle.label | session |
|
||||
| CookieWithoutHttpOnly.go:195:2:195:43 | ... := ...[0] | semmle.label | ... := ...[0] |
|
||||
| CookieWithoutHttpOnly.go:195:16:195:20 | store | semmle.label | store |
|
||||
| CookieWithoutHttpOnly.go:202:19:202:25 | session | semmle.label | session |
|
||||
| CookieWithoutHttpOnly.go:214:66:214:70 | false | semmle.label | false |
|
||||
subpaths
|
||||
#select
|
||||
| CookieWithoutHttpOnly.go:15:20:15:21 | &... | CookieWithoutHttpOnly.go:12:10:12:18 | "session" | CookieWithoutHttpOnly.go:15:20:15:21 | &... | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
| CookieWithoutHttpOnly.go:24:20:24:21 | &... | CookieWithoutHttpOnly.go:22:13:22:17 | false | CookieWithoutHttpOnly.go:24:20:24:21 | &... | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
| CookieWithoutHttpOnly.go:51:20:51:21 | &... | CookieWithoutHttpOnly.go:50:15:50:19 | false | CookieWithoutHttpOnly.go:51:20:51:21 | &... | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
| CookieWithoutHttpOnly.go:61:20:61:21 | &... | CookieWithoutHttpOnly.go:55:9:55:13 | false | CookieWithoutHttpOnly.go:61:20:61:21 | &... | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
| CookieWithoutHttpOnly.go:91:20:91:21 | &... | CookieWithoutHttpOnly.go:85:9:85:13 | false | CookieWithoutHttpOnly.go:91:20:91:21 | &... | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
| CookieWithoutHttpOnly.go:110:20:110:21 | &... | CookieWithoutHttpOnly.go:109:15:109:19 | false | CookieWithoutHttpOnly.go:110:20:110:21 | &... | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
| CookieWithoutHttpOnly.go:120:20:120:21 | &... | CookieWithoutHttpOnly.go:119:15:119:19 | false | CookieWithoutHttpOnly.go:120:20:120:21 | &... | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
| CookieWithoutHttpOnly.go:129:2:129:8 | session | CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:129:2:129:8 | session | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
| CookieWithoutHttpOnly.go:142:2:142:8 | session | CookieWithoutHttpOnly.go:133:14:133:18 | false | CookieWithoutHttpOnly.go:142:2:142:8 | session | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
| CookieWithoutHttpOnly.go:153:2:153:8 | session | CookieWithoutHttpOnly.go:149:21:151:2 | struct literal | CookieWithoutHttpOnly.go:153:2:153:8 | session | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
| CookieWithoutHttpOnly.go:191:19:191:25 | session | CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:191:19:191:25 | session | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
| CookieWithoutHttpOnly.go:202:19:202:25 | session | CookieWithoutHttpOnly.go:123:13:123:49 | call to NewCookieStore | CookieWithoutHttpOnly.go:202:19:202:25 | session | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
| CookieWithoutHttpOnly.go:214:66:214:70 | false | CookieWithoutHttpOnly.go:214:66:214:70 | false | CookieWithoutHttpOnly.go:214:66:214:70 | false | Cookie attribute 'HttpOnly' is not set to true. |
|
||||
@@ -1,219 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gorilla/sessions"
|
||||
)
|
||||
|
||||
func handler1(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
}
|
||||
http.SetCookie(w, &c) // BAD: HttpOnly set to false by default
|
||||
}
|
||||
|
||||
func handler2(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
HttpOnly: false,
|
||||
}
|
||||
http.SetCookie(w, &c) // BAD: HttpOnly explicitly set to false
|
||||
}
|
||||
|
||||
func handler3(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
HttpOnly: true,
|
||||
}
|
||||
http.SetCookie(w, &c) // GOOD: HttpOnly explicitly set to true
|
||||
}
|
||||
|
||||
func handler4(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
}
|
||||
c.HttpOnly = true
|
||||
http.SetCookie(w, &c) // GOOD: HttpOnly explicitly set to true
|
||||
}
|
||||
|
||||
func handler5(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
}
|
||||
c.HttpOnly = false
|
||||
http.SetCookie(w, &c) // BAD: HttpOnly explicitly set to false
|
||||
}
|
||||
|
||||
func handler6(w http.ResponseWriter, r *http.Request) {
|
||||
val := false
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
HttpOnly: val,
|
||||
}
|
||||
http.SetCookie(w, &c) // BAD: HttpOnly explicitly set to false
|
||||
}
|
||||
|
||||
func handler7(w http.ResponseWriter, r *http.Request) {
|
||||
val := true
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
HttpOnly: val,
|
||||
}
|
||||
http.SetCookie(w, &c) // GOOD: HttpOnly explicitly set to true
|
||||
}
|
||||
|
||||
func handler8(w http.ResponseWriter, r *http.Request) {
|
||||
val := true
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
}
|
||||
c.HttpOnly = val
|
||||
http.SetCookie(w, &c) // GOOD: HttpOnly explicitly set to true
|
||||
}
|
||||
|
||||
func handler9(w http.ResponseWriter, r *http.Request) {
|
||||
val := false
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
}
|
||||
c.HttpOnly = val
|
||||
http.SetCookie(w, &c) // BAD: HttpOnly explicitly set to false
|
||||
}
|
||||
|
||||
func handler10(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "consent",
|
||||
Value: "1",
|
||||
}
|
||||
c.HttpOnly = false
|
||||
http.SetCookie(w, &c) // GOOD: Name is not auth related
|
||||
}
|
||||
|
||||
func handler11(w http.ResponseWriter, r *http.Request) {
|
||||
name := "session"
|
||||
c := http.Cookie{
|
||||
Name: name,
|
||||
Value: "secret",
|
||||
}
|
||||
c.HttpOnly = false
|
||||
http.SetCookie(w, &c) // BAD: auth related name
|
||||
}
|
||||
|
||||
func handler12(w http.ResponseWriter, r *http.Request) {
|
||||
session := "login_name"
|
||||
c := http.Cookie{
|
||||
Name: session,
|
||||
Value: "secret",
|
||||
}
|
||||
c.HttpOnly = false
|
||||
http.SetCookie(w, &c) // BAD: auth related name
|
||||
}
|
||||
|
||||
var store = sessions.NewCookieStore([]byte("aa"))
|
||||
|
||||
func handler13(w http.ResponseWriter, r *http.Request) {
|
||||
session, _ := store.Get(r, "session-name")
|
||||
session.Values["foo"] = "secret"
|
||||
|
||||
session.Save(r, w) // BAD: Default options are set (false)
|
||||
}
|
||||
|
||||
func handler14(w http.ResponseWriter, r *http.Request) {
|
||||
httpOnly := false
|
||||
session, _ := store.Get(r, "session-name")
|
||||
session.Values["foo"] = "secret"
|
||||
|
||||
session.Options = &sessions.Options{
|
||||
MaxAge: -1,
|
||||
HttpOnly: httpOnly,
|
||||
}
|
||||
|
||||
session.Save(r, w) // BAD: Explicitly set to false
|
||||
}
|
||||
|
||||
func handler15(w http.ResponseWriter, r *http.Request) {
|
||||
session, _ := store.Get(r, "session-name")
|
||||
session.Values["foo"] = "secret"
|
||||
|
||||
session.Options = &sessions.Options{
|
||||
MaxAge: -1,
|
||||
}
|
||||
|
||||
session.Save(r, w) // BAD: default (false) is used
|
||||
}
|
||||
|
||||
func handler16(w http.ResponseWriter, r *http.Request) {
|
||||
httpOnly := true
|
||||
session, _ := store.Get(r, "session-name")
|
||||
session.Values["foo"] = "secret"
|
||||
|
||||
session.Options = &sessions.Options{
|
||||
MaxAge: -1,
|
||||
HttpOnly: httpOnly,
|
||||
}
|
||||
|
||||
session.Save(r, w) // GOOD: value is true
|
||||
}
|
||||
|
||||
func handler17(w http.ResponseWriter, r *http.Request, httpOnly bool) {
|
||||
session, _ := store.Get(r, "session-name")
|
||||
session.Values["foo"] = "secret"
|
||||
|
||||
session.Options = &sessions.Options{
|
||||
MaxAge: -1,
|
||||
HttpOnly: httpOnly,
|
||||
}
|
||||
|
||||
session.Save(r, w) // GOOD: value is unknown
|
||||
}
|
||||
|
||||
func handler18(w http.ResponseWriter, r *http.Request) {
|
||||
httpOnly := false
|
||||
session, _ := store.Get(r, "session-name")
|
||||
session.Values["foo"] = "secret"
|
||||
|
||||
session.Options = &sessions.Options{
|
||||
MaxAge: -1,
|
||||
HttpOnly: httpOnly,
|
||||
}
|
||||
|
||||
store.Save(r, w, session) // BAD: Explicitly set to false
|
||||
}
|
||||
|
||||
func handler19(w http.ResponseWriter, r *http.Request) {
|
||||
session, _ := store.Get(r, "session-name")
|
||||
session.Values["foo"] = "secret"
|
||||
|
||||
session.Options = &sessions.Options{
|
||||
MaxAge: -1,
|
||||
}
|
||||
|
||||
store.Save(r, w, session) // BAD: default (false) is used
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
router := gin.Default()
|
||||
|
||||
router.GET("/cookie", func(c *gin.Context) {
|
||||
|
||||
_, err := c.Cookie("session")
|
||||
|
||||
if err != nil {
|
||||
c.SetCookie("session", "test", 3600, "/", "localhost", false, false) // BAD: httpOnly set to false
|
||||
}
|
||||
})
|
||||
|
||||
router.Run()
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
experimental/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
75
go/ql/test/experimental/CWE-1004/vendor/github.com/gorilla/sessions/stub.go
generated
vendored
75
go/ql/test/experimental/CWE-1004/vendor/github.com/gorilla/sessions/stub.go
generated
vendored
@@ -1,75 +0,0 @@
|
||||
// Code generated by depstubber. DO NOT EDIT.
|
||||
// This is a simple stub for github.com/gorilla/sessions, strictly for use in testing.
|
||||
|
||||
// See the LICENSE file for information about the licensing of the original library.
|
||||
// Source: github.com/gorilla/sessions (exports: CookieStore; functions: NewCookieStore)
|
||||
|
||||
// Package sessions is a stub of github.com/gorilla/sessions, generated by depstubber.
|
||||
package sessions
|
||||
|
||||
import (
|
||||
http "net/http"
|
||||
)
|
||||
|
||||
type CookieStore struct {
|
||||
Codecs []interface{}
|
||||
Options *Options
|
||||
}
|
||||
|
||||
func (_ *CookieStore) Get(_ *http.Request, _ string) (*Session, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *CookieStore) MaxAge(_ int) {}
|
||||
|
||||
func (_ *CookieStore) New(_ *http.Request, _ string) (*Session, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *CookieStore) Save(_ *http.Request, _ http.ResponseWriter, _ *Session) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewCookieStore(_ ...[]byte) *CookieStore {
|
||||
return nil
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
Path string
|
||||
Domain string
|
||||
MaxAge int
|
||||
Secure bool
|
||||
HttpOnly bool
|
||||
SameSite http.SameSite
|
||||
}
|
||||
|
||||
type Session struct {
|
||||
ID string
|
||||
Values map[interface{}]interface{}
|
||||
Options *Options
|
||||
IsNew bool
|
||||
}
|
||||
|
||||
func (_ *Session) AddFlash(_ interface{}, _ ...string) {}
|
||||
|
||||
func (_ *Session) Flashes(_ ...string) []interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Session) Name() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Session) Save(_ *http.Request, _ http.ResponseWriter) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Session) Store() Store {
|
||||
return nil
|
||||
}
|
||||
|
||||
type Store interface {
|
||||
Get(_ *http.Request, _ string) (*Session, error)
|
||||
New(_ *http.Request, _ string) (*Session, error)
|
||||
Save(_ *http.Request, _ http.ResponseWriter, _ *Session) error
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
# github.com/gin-gonic/gin v1.7.1
|
||||
## explicit
|
||||
github.com/gin-gonic/gin
|
||||
# github.com/gorilla/sessions v1.2.1
|
||||
## explicit
|
||||
github.com/gorilla/sessions
|
||||
@@ -0,0 +1,139 @@
|
||||
#select
|
||||
| CookieWithoutHttpOnly.go:14:2:14:22 | call to SetCookie | CookieWithoutHttpOnly.go:11:10:11:18 | "session" | CookieWithoutHttpOnly.go:14:20:14:21 | &... | Sensitive cookie $@ does not set HttpOnly attribute to true. | CookieWithoutHttpOnly.go:11:10:11:18 | "session" | session |
|
||||
| CookieWithoutHttpOnly.go:23:2:23:22 | call to SetCookie | CookieWithoutHttpOnly.go:19:13:19:21 | "session" | CookieWithoutHttpOnly.go:23:20:23:21 | &... | Sensitive cookie $@ does not set HttpOnly attribute to true. | CookieWithoutHttpOnly.go:19:13:19:21 | "session" | session |
|
||||
| CookieWithoutHttpOnly.go:50:2:50:22 | call to SetCookie | CookieWithoutHttpOnly.go:46:10:46:18 | "session" | CookieWithoutHttpOnly.go:50:20:50:21 | &... | Sensitive cookie $@ does not set HttpOnly attribute to true. | CookieWithoutHttpOnly.go:46:10:46:18 | "session" | session |
|
||||
| CookieWithoutHttpOnly.go:60:2:60:22 | call to SetCookie | CookieWithoutHttpOnly.go:56:13:56:21 | "session" | CookieWithoutHttpOnly.go:60:20:60:21 | &... | Sensitive cookie $@ does not set HttpOnly attribute to true. | CookieWithoutHttpOnly.go:56:13:56:21 | "session" | session |
|
||||
| CookieWithoutHttpOnly.go:90:2:90:22 | call to SetCookie | CookieWithoutHttpOnly.go:86:10:86:18 | "session" | CookieWithoutHttpOnly.go:90:20:90:21 | &... | Sensitive cookie $@ does not set HttpOnly attribute to true. | CookieWithoutHttpOnly.go:86:10:86:18 | "session" | session |
|
||||
| CookieWithoutHttpOnly.go:109:2:109:22 | call to SetCookie | CookieWithoutHttpOnly.go:103:10:103:18 | "session" | CookieWithoutHttpOnly.go:109:20:109:21 | &... | Sensitive cookie $@ does not set HttpOnly attribute to true. | CookieWithoutHttpOnly.go:103:10:103:18 | "session" | session |
|
||||
| CookieWithoutHttpOnly.go:119:2:119:22 | call to SetCookie | CookieWithoutHttpOnly.go:113:13:113:24 | "login_name" | CookieWithoutHttpOnly.go:119:20:119:21 | &... | Sensitive cookie $@ does not set HttpOnly attribute to true. | CookieWithoutHttpOnly.go:113:13:113:24 | "login_name" | login_name |
|
||||
| CookieWithoutHttpOnly.go:119:2:119:22 | call to SetCookie | CookieWithoutHttpOnly.go:115:10:115:16 | session | CookieWithoutHttpOnly.go:119:20:119:21 | &... | Sensitive cookie $@ does not set HttpOnly attribute to true. | CookieWithoutHttpOnly.go:115:10:115:16 | session | session |
|
||||
| CookieWithoutHttpOnly.go:131:4:131:71 | call to SetCookie | CookieWithoutHttpOnly.go:131:16:131:24 | "session" | CookieWithoutHttpOnly.go:131:16:131:24 | "session" | Sensitive cookie $@ does not set HttpOnly attribute to true. | CookieWithoutHttpOnly.go:131:16:131:24 | "session" | session |
|
||||
edges
|
||||
| CookieWithoutHttpOnly.go:10:7:13:2 | struct literal | CookieWithoutHttpOnly.go:14:20:14:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:10:7:13:2 | struct literal | CookieWithoutHttpOnly.go:14:21:14:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:11:10:11:18 | "session" | CookieWithoutHttpOnly.go:10:7:13:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:14:20:14:21 | &... [pointer] | CookieWithoutHttpOnly.go:14:20:14:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:14:21:14:21 | c | CookieWithoutHttpOnly.go:14:20:14:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:14:21:14:21 | c | CookieWithoutHttpOnly.go:14:20:14:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:18:7:22:2 | struct literal | CookieWithoutHttpOnly.go:23:20:23:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:18:7:22:2 | struct literal | CookieWithoutHttpOnly.go:23:21:23:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:19:13:19:21 | "session" | CookieWithoutHttpOnly.go:18:7:22:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:23:20:23:21 | &... [pointer] | CookieWithoutHttpOnly.go:23:20:23:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:23:21:23:21 | c | CookieWithoutHttpOnly.go:23:20:23:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:23:21:23:21 | c | CookieWithoutHttpOnly.go:23:20:23:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:27:7:31:2 | struct literal | CookieWithoutHttpOnly.go:32:20:32:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:27:7:31:2 | struct literal | CookieWithoutHttpOnly.go:32:21:32:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:28:13:28:21 | "session" | CookieWithoutHttpOnly.go:27:7:31:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:32:20:32:21 | &... [pointer] | CookieWithoutHttpOnly.go:32:20:32:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:32:21:32:21 | c | CookieWithoutHttpOnly.go:32:20:32:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:32:21:32:21 | c | CookieWithoutHttpOnly.go:32:20:32:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:36:7:39:2 | struct literal | CookieWithoutHttpOnly.go:41:20:41:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:36:7:39:2 | struct literal | CookieWithoutHttpOnly.go:41:21:41:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:37:10:37:18 | "session" | CookieWithoutHttpOnly.go:36:7:39:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:41:20:41:21 | &... [pointer] | CookieWithoutHttpOnly.go:41:20:41:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:41:21:41:21 | c | CookieWithoutHttpOnly.go:41:20:41:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:41:21:41:21 | c | CookieWithoutHttpOnly.go:41:20:41:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:45:7:48:2 | struct literal | CookieWithoutHttpOnly.go:50:20:50:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:45:7:48:2 | struct literal | CookieWithoutHttpOnly.go:50:21:50:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:46:10:46:18 | "session" | CookieWithoutHttpOnly.go:45:7:48:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:50:20:50:21 | &... [pointer] | CookieWithoutHttpOnly.go:50:20:50:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:50:21:50:21 | c | CookieWithoutHttpOnly.go:50:20:50:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:50:21:50:21 | c | CookieWithoutHttpOnly.go:50:20:50:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:55:7:59:2 | struct literal | CookieWithoutHttpOnly.go:60:20:60:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:55:7:59:2 | struct literal | CookieWithoutHttpOnly.go:60:21:60:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:56:13:56:21 | "session" | CookieWithoutHttpOnly.go:55:7:59:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:60:20:60:21 | &... [pointer] | CookieWithoutHttpOnly.go:60:20:60:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:60:21:60:21 | c | CookieWithoutHttpOnly.go:60:20:60:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:60:21:60:21 | c | CookieWithoutHttpOnly.go:60:20:60:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:65:7:69:2 | struct literal | CookieWithoutHttpOnly.go:70:20:70:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:65:7:69:2 | struct literal | CookieWithoutHttpOnly.go:70:21:70:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:66:13:66:21 | "session" | CookieWithoutHttpOnly.go:65:7:69:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:70:20:70:21 | &... [pointer] | CookieWithoutHttpOnly.go:70:20:70:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:70:21:70:21 | c | CookieWithoutHttpOnly.go:70:20:70:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:70:21:70:21 | c | CookieWithoutHttpOnly.go:70:20:70:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:75:7:78:2 | struct literal | CookieWithoutHttpOnly.go:80:20:80:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:75:7:78:2 | struct literal | CookieWithoutHttpOnly.go:80:21:80:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:76:10:76:18 | "session" | CookieWithoutHttpOnly.go:75:7:78:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:80:20:80:21 | &... [pointer] | CookieWithoutHttpOnly.go:80:20:80:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:80:21:80:21 | c | CookieWithoutHttpOnly.go:80:20:80:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:80:21:80:21 | c | CookieWithoutHttpOnly.go:80:20:80:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:85:7:88:2 | struct literal | CookieWithoutHttpOnly.go:90:20:90:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:85:7:88:2 | struct literal | CookieWithoutHttpOnly.go:90:21:90:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:86:10:86:18 | "session" | CookieWithoutHttpOnly.go:85:7:88:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:90:20:90:21 | &... [pointer] | CookieWithoutHttpOnly.go:90:20:90:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:90:21:90:21 | c | CookieWithoutHttpOnly.go:90:20:90:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:90:21:90:21 | c | CookieWithoutHttpOnly.go:90:20:90:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:103:10:103:18 | "session" | CookieWithoutHttpOnly.go:105:10:105:13 | name | provenance | |
|
||||
| CookieWithoutHttpOnly.go:104:7:107:2 | struct literal | CookieWithoutHttpOnly.go:109:20:109:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:104:7:107:2 | struct literal | CookieWithoutHttpOnly.go:109:21:109:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:105:10:105:13 | name | CookieWithoutHttpOnly.go:104:7:107:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:109:20:109:21 | &... [pointer] | CookieWithoutHttpOnly.go:109:20:109:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:109:21:109:21 | c | CookieWithoutHttpOnly.go:109:20:109:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:109:21:109:21 | c | CookieWithoutHttpOnly.go:109:20:109:21 | &... [pointer] | provenance | |
|
||||
| CookieWithoutHttpOnly.go:113:13:113:24 | "login_name" | CookieWithoutHttpOnly.go:115:10:115:16 | session | provenance | |
|
||||
| CookieWithoutHttpOnly.go:114:7:117:2 | struct literal | CookieWithoutHttpOnly.go:119:20:119:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:114:7:117:2 | struct literal | CookieWithoutHttpOnly.go:119:21:119:21 | c | provenance | |
|
||||
| CookieWithoutHttpOnly.go:115:10:115:16 | session | CookieWithoutHttpOnly.go:114:7:117:2 | struct literal | provenance | Config |
|
||||
| CookieWithoutHttpOnly.go:119:20:119:21 | &... [pointer] | CookieWithoutHttpOnly.go:119:20:119:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:119:21:119:21 | c | CookieWithoutHttpOnly.go:119:20:119:21 | &... | provenance | |
|
||||
| CookieWithoutHttpOnly.go:119:21:119:21 | c | CookieWithoutHttpOnly.go:119:20:119:21 | &... [pointer] | provenance | |
|
||||
nodes
|
||||
| CookieWithoutHttpOnly.go:10:7:13:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:11:10:11:18 | "session" | semmle.label | "session" |
|
||||
| CookieWithoutHttpOnly.go:14:20:14:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:14:20:14:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:14:21:14:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:18:7:22:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:19:13:19:21 | "session" | semmle.label | "session" |
|
||||
| CookieWithoutHttpOnly.go:23:20:23:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:23:20:23:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:23:21:23:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:27:7:31:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:28:13:28:21 | "session" | semmle.label | "session" |
|
||||
| CookieWithoutHttpOnly.go:32:20:32:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:32:20:32:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:32:21:32:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:36:7:39:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:37:10:37:18 | "session" | semmle.label | "session" |
|
||||
| CookieWithoutHttpOnly.go:41:20:41:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:41:20:41:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:41:21:41:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:45:7:48:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:46:10:46:18 | "session" | semmle.label | "session" |
|
||||
| CookieWithoutHttpOnly.go:50:20:50:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:50:20:50:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:50:21:50:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:55:7:59:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:56:13:56:21 | "session" | semmle.label | "session" |
|
||||
| CookieWithoutHttpOnly.go:60:20:60:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:60:20:60:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:60:21:60:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:65:7:69:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:66:13:66:21 | "session" | semmle.label | "session" |
|
||||
| CookieWithoutHttpOnly.go:70:20:70:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:70:20:70:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:70:21:70:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:75:7:78:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:76:10:76:18 | "session" | semmle.label | "session" |
|
||||
| CookieWithoutHttpOnly.go:80:20:80:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:80:20:80:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:80:21:80:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:85:7:88:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:86:10:86:18 | "session" | semmle.label | "session" |
|
||||
| CookieWithoutHttpOnly.go:90:20:90:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:90:20:90:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:90:21:90:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:103:10:103:18 | "session" | semmle.label | "session" |
|
||||
| CookieWithoutHttpOnly.go:104:7:107:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:105:10:105:13 | name | semmle.label | name |
|
||||
| CookieWithoutHttpOnly.go:109:20:109:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:109:20:109:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:109:21:109:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:113:13:113:24 | "login_name" | semmle.label | "login_name" |
|
||||
| CookieWithoutHttpOnly.go:114:7:117:2 | struct literal | semmle.label | struct literal |
|
||||
| CookieWithoutHttpOnly.go:115:10:115:16 | session | semmle.label | session |
|
||||
| CookieWithoutHttpOnly.go:119:20:119:21 | &... | semmle.label | &... |
|
||||
| CookieWithoutHttpOnly.go:119:20:119:21 | &... [pointer] | semmle.label | &... [pointer] |
|
||||
| CookieWithoutHttpOnly.go:119:21:119:21 | c | semmle.label | c |
|
||||
| CookieWithoutHttpOnly.go:131:16:131:24 | "session" | semmle.label | "session" |
|
||||
subpaths
|
||||
@@ -0,0 +1,136 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func handler1(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session", // $ Source
|
||||
Value: "secret",
|
||||
}
|
||||
http.SetCookie(w, &c) // $ Alert // BAD: HttpOnly set to false by default
|
||||
}
|
||||
|
||||
func handler2(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session", // $ Source
|
||||
Value: "secret",
|
||||
HttpOnly: false,
|
||||
}
|
||||
http.SetCookie(w, &c) // $ Alert // BAD: HttpOnly explicitly set to false
|
||||
}
|
||||
|
||||
func handler3(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
HttpOnly: true,
|
||||
}
|
||||
http.SetCookie(w, &c) // GOOD: HttpOnly explicitly set to true
|
||||
}
|
||||
|
||||
func handler4(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
}
|
||||
c.HttpOnly = true
|
||||
http.SetCookie(w, &c) // GOOD: HttpOnly explicitly set to true
|
||||
}
|
||||
|
||||
func handler5(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session", // $ Source
|
||||
Value: "secret",
|
||||
}
|
||||
c.HttpOnly = false
|
||||
http.SetCookie(w, &c) // $ Alert // BAD: HttpOnly explicitly set to false
|
||||
}
|
||||
|
||||
func handler6(w http.ResponseWriter, r *http.Request) {
|
||||
val := false
|
||||
c := http.Cookie{
|
||||
Name: "session", // $ Source
|
||||
Value: "secret",
|
||||
HttpOnly: val,
|
||||
}
|
||||
http.SetCookie(w, &c) // $ Alert // BAD: HttpOnly explicitly set to false
|
||||
}
|
||||
|
||||
func handler7(w http.ResponseWriter, r *http.Request) {
|
||||
val := true
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
HttpOnly: val,
|
||||
}
|
||||
http.SetCookie(w, &c) // GOOD: HttpOnly explicitly set to true
|
||||
}
|
||||
|
||||
func handler8(w http.ResponseWriter, r *http.Request) {
|
||||
val := true
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
}
|
||||
c.HttpOnly = val
|
||||
http.SetCookie(w, &c) // GOOD: HttpOnly explicitly set to true
|
||||
}
|
||||
|
||||
func handler9(w http.ResponseWriter, r *http.Request) {
|
||||
val := false
|
||||
c := http.Cookie{
|
||||
Name: "session", // $ Source
|
||||
Value: "secret",
|
||||
}
|
||||
c.HttpOnly = val
|
||||
http.SetCookie(w, &c) // $ Alert //BAD: HttpOnly explicitly set to false
|
||||
}
|
||||
|
||||
func handler10(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "consent",
|
||||
Value: "1",
|
||||
}
|
||||
c.HttpOnly = false
|
||||
http.SetCookie(w, &c) // GOOD: Name is not auth related
|
||||
}
|
||||
|
||||
func handler11(w http.ResponseWriter, r *http.Request) {
|
||||
name := "session" // $ Source
|
||||
c := http.Cookie{
|
||||
Name: name,
|
||||
Value: "secret",
|
||||
}
|
||||
c.HttpOnly = false
|
||||
http.SetCookie(w, &c) // $ Alert // BAD: auth related name
|
||||
}
|
||||
|
||||
func handler12(w http.ResponseWriter, r *http.Request) {
|
||||
session := "login_name" // $ Source
|
||||
c := http.Cookie{
|
||||
Name: session, // $ Source
|
||||
Value: "secret",
|
||||
}
|
||||
c.HttpOnly = false
|
||||
http.SetCookie(w, &c) // $ Alert // BAD: auth related name
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
router := gin.Default()
|
||||
|
||||
router.GET("/cookie", func(c *gin.Context) {
|
||||
|
||||
_, err := c.Cookie("session")
|
||||
|
||||
if err != nil {
|
||||
c.SetCookie("session", "test", 3600, "/", "localhost", false, false) // $ Alert // BAD: httpOnly set to false
|
||||
}
|
||||
})
|
||||
|
||||
router.Run()
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
query: Security/CWE-1004/CookieWithoutHttpOnly.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
@@ -4,5 +4,4 @@ go 1.14
|
||||
|
||||
require (
|
||||
github.com/gin-gonic/gin v1.7.1
|
||||
github.com/gorilla/sessions v1.2.1
|
||||
)
|
||||
3
go/ql/test/query-tests/Security/CWE-1004/vendor/modules.txt
vendored
Normal file
3
go/ql/test/query-tests/Security/CWE-1004/vendor/modules.txt
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# github.com/gin-gonic/gin v1.7.1
|
||||
## explicit
|
||||
github.com/gin-gonic/gin
|
||||
@@ -0,0 +1,6 @@
|
||||
| CookieWithoutSecure.go:14:2:14:22 | call to SetCookie | Cookie does not set Secure attribute to true. |
|
||||
| CookieWithoutSecure.go:23:2:23:22 | call to SetCookie | Cookie does not set Secure attribute to true. |
|
||||
| CookieWithoutSecure.go:50:2:50:22 | call to SetCookie | Cookie does not set Secure attribute to true. |
|
||||
| CookieWithoutSecure.go:60:2:60:22 | call to SetCookie | Cookie does not set Secure attribute to true. |
|
||||
| CookieWithoutSecure.go:90:2:90:22 | call to SetCookie | Cookie does not set Secure attribute to true. |
|
||||
| CookieWithoutSecure.go:102:4:102:71 | call to SetCookie | Cookie does not set Secure attribute to true. |
|
||||
107
go/ql/test/query-tests/Security/CWE-614/CookieWithoutSecure.go
Normal file
107
go/ql/test/query-tests/Security/CWE-614/CookieWithoutSecure.go
Normal file
@@ -0,0 +1,107 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func handler1(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session", // $ Source
|
||||
Value: "secret",
|
||||
}
|
||||
http.SetCookie(w, &c) // $ Alert // BAD: Secure set to false by default
|
||||
}
|
||||
|
||||
func handler2(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session", // $ Source
|
||||
Value: "secret",
|
||||
Secure: false,
|
||||
}
|
||||
http.SetCookie(w, &c) // $ Alert // BAD: Secure explicitly set to false
|
||||
}
|
||||
|
||||
func handler3(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
Secure: true,
|
||||
}
|
||||
http.SetCookie(w, &c) // GOOD: Secure explicitly set to true
|
||||
}
|
||||
|
||||
func handler4(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
}
|
||||
c.Secure = true
|
||||
http.SetCookie(w, &c) // GOOD: Secure explicitly set to true
|
||||
}
|
||||
|
||||
func handler5(w http.ResponseWriter, r *http.Request) {
|
||||
c := http.Cookie{
|
||||
Name: "session", // $ Source
|
||||
Value: "secret",
|
||||
}
|
||||
c.Secure = false
|
||||
http.SetCookie(w, &c) // $ Alert // BAD: Secure explicitly set to false
|
||||
}
|
||||
|
||||
func handler6(w http.ResponseWriter, r *http.Request) {
|
||||
val := false
|
||||
c := http.Cookie{
|
||||
Name: "session", // $ Source
|
||||
Value: "secret",
|
||||
Secure: val,
|
||||
}
|
||||
http.SetCookie(w, &c) // $ Alert // BAD: Secure explicitly set to false
|
||||
}
|
||||
|
||||
func handler7(w http.ResponseWriter, r *http.Request) {
|
||||
val := true
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
Secure: val,
|
||||
}
|
||||
http.SetCookie(w, &c) // GOOD: Secure explicitly set to true
|
||||
}
|
||||
|
||||
func handler8(w http.ResponseWriter, r *http.Request) {
|
||||
val := true
|
||||
c := http.Cookie{
|
||||
Name: "session",
|
||||
Value: "secret",
|
||||
}
|
||||
c.Secure = val
|
||||
http.SetCookie(w, &c) // GOOD: Secure explicitly set to true
|
||||
}
|
||||
|
||||
func handler9(w http.ResponseWriter, r *http.Request) {
|
||||
val := false
|
||||
c := http.Cookie{
|
||||
Name: "session", // $ Source
|
||||
Value: "secret",
|
||||
}
|
||||
c.Secure = val
|
||||
http.SetCookie(w, &c) // $ Alert //BAD: Secure explicitly set to false
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
router := gin.Default()
|
||||
|
||||
router.GET("/cookie", func(c *gin.Context) {
|
||||
|
||||
_, err := c.Cookie("session")
|
||||
|
||||
if err != nil {
|
||||
c.SetCookie("session", "test", 3600, "/", "localhost", false, false) // $ Alert // BAD: Secure set to false
|
||||
}
|
||||
})
|
||||
|
||||
router.Run()
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
query: Security/CWE-614/CookieWithoutSecure.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
7
go/ql/test/query-tests/Security/CWE-614/go.mod
Normal file
7
go/ql/test/query-tests/Security/CWE-614/go.mod
Normal file
@@ -0,0 +1,7 @@
|
||||
module example.com/m
|
||||
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/gin-gonic/gin v1.7.1
|
||||
)
|
||||
21
go/ql/test/query-tests/Security/CWE-614/vendor/github.com/gin-gonic/gin/LICENSE
generated
vendored
Normal file
21
go/ql/test/query-tests/Security/CWE-614/vendor/github.com/gin-gonic/gin/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Manuel Martínez-Almeida
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
12
go/ql/test/query-tests/Security/CWE-614/vendor/github.com/gin-gonic/gin/binding/stub.go
generated
vendored
Normal file
12
go/ql/test/query-tests/Security/CWE-614/vendor/github.com/gin-gonic/gin/binding/stub.go
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
// Code generated by depstubber. DO NOT EDIT.
|
||||
// This is a simple stub for github.com/gin-gonic/gin/binding, strictly for use in testing.
|
||||
|
||||
// See the LICENSE file for information about the licensing of the original library.
|
||||
// Source: github.com/gin-gonic/gin/binding (exports: ; functions: YAML)
|
||||
|
||||
// Package binding is a stub of github.com/gin-gonic/gin/binding, generated by depstubber.
|
||||
package binding
|
||||
|
||||
import ()
|
||||
|
||||
var YAML interface{} = nil
|
||||
677
go/ql/test/query-tests/Security/CWE-614/vendor/github.com/gin-gonic/gin/stub.go
generated
vendored
Normal file
677
go/ql/test/query-tests/Security/CWE-614/vendor/github.com/gin-gonic/gin/stub.go
generated
vendored
Normal file
@@ -0,0 +1,677 @@
|
||||
// Code generated by depstubber. DO NOT EDIT.
|
||||
// This is a simple stub for github.com/gin-gonic/gin, strictly for use in testing.
|
||||
|
||||
// See the LICENSE file for information about the licensing of the original library.
|
||||
// Source: github.com/gin-gonic/gin (exports: Context; functions: Default)
|
||||
|
||||
// Package gin is a stub of github.com/gin-gonic/gin, generated by depstubber.
|
||||
package gin
|
||||
|
||||
import (
|
||||
bufio "bufio"
|
||||
template "html/template"
|
||||
io "io"
|
||||
multipart "mime/multipart"
|
||||
net "net"
|
||||
http "net/http"
|
||||
time "time"
|
||||
)
|
||||
|
||||
type Context struct {
|
||||
Request *http.Request
|
||||
Writer ResponseWriter
|
||||
Params Params
|
||||
Keys map[string]interface{}
|
||||
Errors interface{}
|
||||
Accepted []string
|
||||
}
|
||||
|
||||
func (_ *Context) Abort() {}
|
||||
|
||||
func (_ *Context) AbortWithError(_ int, _ error) *Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) AbortWithStatus(_ int) {}
|
||||
|
||||
func (_ *Context) AbortWithStatusJSON(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) AsciiJSON(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) Bind(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindHeader(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindJSON(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindQuery(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindUri(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindWith(_ interface{}, _ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindXML(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) BindYAML(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ClientIP() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) ContentType() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) Cookie(_ string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
func (_ *Context) Copy() *Context {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Data(_ int, _ string, _ []byte) {}
|
||||
|
||||
func (_ *Context) DataFromReader(_ int, _ int64, _ string, _ io.Reader, _ map[string]string) {}
|
||||
|
||||
func (_ *Context) Deadline() (time.Time, bool) {
|
||||
return time.Time{}, false
|
||||
}
|
||||
|
||||
func (_ *Context) DefaultPostForm(_ string, _ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) DefaultQuery(_ string, _ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) Done() <-chan struct{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Err() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Error(_ error) *Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) File(_ string) {}
|
||||
|
||||
func (_ *Context) FileAttachment(_ string, _ string) {}
|
||||
|
||||
func (_ *Context) FileFromFS(_ string, _ http.FileSystem) {}
|
||||
|
||||
func (_ *Context) FormFile(_ string) (*multipart.FileHeader, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Context) FullPath() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) Get(_ string) (interface{}, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (_ *Context) GetBool(_ string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Context) GetDuration(_ string) time.Duration {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (_ *Context) GetFloat64(_ string) float64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (_ *Context) GetHeader(_ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) GetInt(_ string) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (_ *Context) GetInt64(_ string) int64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (_ *Context) GetPostForm(_ string) (string, bool) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
func (_ *Context) GetPostFormArray(_ string) ([]string, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (_ *Context) GetPostFormMap(_ string) (map[string]string, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (_ *Context) GetQuery(_ string) (string, bool) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
func (_ *Context) GetQueryArray(_ string) ([]string, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (_ *Context) GetQueryMap(_ string) (map[string]string, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (_ *Context) GetRawData() ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Context) GetString(_ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) GetStringMap(_ string) map[string]interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) GetStringMapString(_ string) map[string]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) GetStringMapStringSlice(_ string) map[string][]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) GetStringSlice(_ string) []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) GetTime(_ string) time.Time {
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
func (_ *Context) GetUint(_ string) uint {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (_ *Context) GetUint64(_ string) uint64 {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (_ *Context) HTML(_ int, _ string, _ interface{}) {}
|
||||
|
||||
func (_ *Context) Handler() HandlerFunc {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) HandlerName() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) HandlerNames() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Header(_ string, _ string) {}
|
||||
|
||||
func (_ *Context) IndentedJSON(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) IsAborted() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Context) IsWebsocket() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Context) JSON(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) JSONP(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) MultipartForm() (*multipart.Form, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Context) MustBindWith(_ interface{}, _ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) MustGet(_ string) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Negotiate(_ int, _ Negotiate) {}
|
||||
|
||||
func (_ *Context) NegotiateFormat(_ ...string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) Next() {}
|
||||
|
||||
func (_ *Context) Param(_ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) PostForm(_ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) PostFormArray(_ string) []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) PostFormMap(_ string) map[string]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ProtoBuf(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) PureJSON(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) Query(_ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Context) QueryArray(_ string) []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) QueryMap(_ string) map[string]string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Redirect(_ int, _ string) {}
|
||||
|
||||
func (_ *Context) RemoteIP() (net.IP, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (_ *Context) Render(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) SSEvent(_ string, _ interface{}) {}
|
||||
|
||||
func (_ *Context) SaveUploadedFile(_ *multipart.FileHeader, _ string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) SecureJSON(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) Set(_ string, _ interface{}) {}
|
||||
|
||||
func (_ *Context) SetAccepted(_ ...string) {}
|
||||
|
||||
func (_ *Context) SetCookie(_ string, _ string, _ int, _ string, _ string, _ bool, _ bool) {}
|
||||
|
||||
func (_ *Context) SetSameSite(_ http.SameSite) {}
|
||||
|
||||
func (_ *Context) ShouldBind(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindBodyWith(_ interface{}, _ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindHeader(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindJSON(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindQuery(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindUri(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindWith(_ interface{}, _ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindXML(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) ShouldBindYAML(_ interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) Status(_ int) {}
|
||||
|
||||
func (_ *Context) Stream(_ func(io.Writer) bool) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Context) String(_ int, _ string, _ ...interface{}) {}
|
||||
|
||||
func (_ *Context) Value(_ interface{}) interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Context) XML(_ int, _ interface{}) {}
|
||||
|
||||
func (_ *Context) YAML(_ int, _ interface{}) {}
|
||||
|
||||
func Default() *Engine {
|
||||
return nil
|
||||
}
|
||||
|
||||
type Engine struct {
|
||||
RouterGroup RouterGroup
|
||||
RedirectTrailingSlash bool
|
||||
RedirectFixedPath bool
|
||||
HandleMethodNotAllowed bool
|
||||
ForwardedByClientIP bool
|
||||
RemoteIPHeaders []string
|
||||
TrustedProxies []string
|
||||
AppEngine bool
|
||||
UseRawPath bool
|
||||
UnescapePathValues bool
|
||||
MaxMultipartMemory int64
|
||||
RemoveExtraSlash bool
|
||||
HTMLRender interface{}
|
||||
FuncMap template.FuncMap
|
||||
}
|
||||
|
||||
func (_ *Engine) Any(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) BasePath() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Engine) DELETE(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) Delims(_ string, _ string) *Engine {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) GET(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) Group(_ string, _ ...HandlerFunc) *RouterGroup {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) HEAD(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) Handle(_ string, _ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) HandleContext(_ *Context) {}
|
||||
|
||||
func (_ *Engine) LoadHTMLFiles(_ ...string) {}
|
||||
|
||||
func (_ *Engine) LoadHTMLGlob(_ string) {}
|
||||
|
||||
func (_ *Engine) NoMethod(_ ...HandlerFunc) {}
|
||||
|
||||
func (_ *Engine) NoRoute(_ ...HandlerFunc) {}
|
||||
|
||||
func (_ *Engine) OPTIONS(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) PATCH(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) POST(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) PUT(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) Routes() RoutesInfo {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) Run(_ ...string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) RunFd(_ int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) RunListener(_ net.Listener) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) RunTLS(_ string, _ string, _ string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) RunUnix(_ string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) SecureJsonPrefix(_ string) *Engine {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) ServeHTTP(_ http.ResponseWriter, _ *http.Request) {}
|
||||
|
||||
func (_ *Engine) SetFuncMap(_ template.FuncMap) {}
|
||||
|
||||
func (_ *Engine) SetHTMLTemplate(_ *template.Template) {}
|
||||
|
||||
func (_ *Engine) Static(_ string, _ string) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) StaticFS(_ string, _ http.FileSystem) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) StaticFile(_ string, _ string) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Engine) Use(_ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
type Error struct {
|
||||
Err error
|
||||
Type ErrorType
|
||||
Meta interface{}
|
||||
}
|
||||
|
||||
func (_ Error) Error() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *Error) IsType(_ ErrorType) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (_ *Error) JSON() interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Error) MarshalJSON() ([]byte, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *Error) SetMeta(_ interface{}) *Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Error) SetType(_ ErrorType) *Error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *Error) Unwrap() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type ErrorType uint64
|
||||
|
||||
type HandlerFunc func(*Context)
|
||||
|
||||
type HandlersChain []HandlerFunc
|
||||
|
||||
func (_ HandlersChain) Last() HandlerFunc {
|
||||
return nil
|
||||
}
|
||||
|
||||
type IRoutes interface {
|
||||
Any(_ string, _ ...HandlerFunc) IRoutes
|
||||
DELETE(_ string, _ ...HandlerFunc) IRoutes
|
||||
GET(_ string, _ ...HandlerFunc) IRoutes
|
||||
HEAD(_ string, _ ...HandlerFunc) IRoutes
|
||||
Handle(_ string, _ string, _ ...HandlerFunc) IRoutes
|
||||
OPTIONS(_ string, _ ...HandlerFunc) IRoutes
|
||||
PATCH(_ string, _ ...HandlerFunc) IRoutes
|
||||
POST(_ string, _ ...HandlerFunc) IRoutes
|
||||
PUT(_ string, _ ...HandlerFunc) IRoutes
|
||||
Static(_ string, _ string) IRoutes
|
||||
StaticFS(_ string, _ http.FileSystem) IRoutes
|
||||
StaticFile(_ string, _ string) IRoutes
|
||||
Use(_ ...HandlerFunc) IRoutes
|
||||
}
|
||||
|
||||
type Negotiate struct {
|
||||
Offered []string
|
||||
HTMLName string
|
||||
HTMLData interface{}
|
||||
JSONData interface{}
|
||||
XMLData interface{}
|
||||
YAMLData interface{}
|
||||
Data interface{}
|
||||
}
|
||||
|
||||
type Param struct {
|
||||
Key string
|
||||
Value string
|
||||
}
|
||||
|
||||
type Params []Param
|
||||
|
||||
func (_ Params) ByName(_ string) string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ Params) Get(_ string) (string, bool) {
|
||||
return "", false
|
||||
}
|
||||
|
||||
type ResponseWriter interface {
|
||||
CloseNotify() <-chan bool
|
||||
Flush()
|
||||
Header() http.Header
|
||||
Hijack() (net.Conn, *bufio.ReadWriter, error)
|
||||
Pusher() http.Pusher
|
||||
Size() int
|
||||
Status() int
|
||||
Write(_ []byte) (int, error)
|
||||
WriteHeader(_ int)
|
||||
WriteHeaderNow()
|
||||
WriteString(_ string) (int, error)
|
||||
Written() bool
|
||||
}
|
||||
|
||||
type RouteInfo struct {
|
||||
Method string
|
||||
Path string
|
||||
Handler string
|
||||
HandlerFunc HandlerFunc
|
||||
}
|
||||
|
||||
type RouterGroup struct {
|
||||
Handlers HandlersChain
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) Any(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) BasePath() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) DELETE(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) GET(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) Group(_ string, _ ...HandlerFunc) *RouterGroup {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) HEAD(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) Handle(_ string, _ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) OPTIONS(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) PATCH(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) POST(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) PUT(_ string, _ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) Static(_ string, _ string) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) StaticFS(_ string, _ http.FileSystem) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) StaticFile(_ string, _ string) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_ *RouterGroup) Use(_ ...HandlerFunc) IRoutes {
|
||||
return nil
|
||||
}
|
||||
|
||||
type RoutesInfo []RouteInfo
|
||||
3
go/ql/test/query-tests/Security/CWE-614/vendor/modules.txt
vendored
Normal file
3
go/ql/test/query-tests/Security/CWE-614/vendor/modules.txt
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# github.com/gin-gonic/gin v1.7.1
|
||||
## explicit
|
||||
github.com/gin-gonic/gin
|
||||
@@ -86,6 +86,8 @@ pragma[nomagic]
|
||||
private predicate constantIntegerExpr(Expr e, int val) {
|
||||
e.(CompileTimeConstantExpr).getIntValue() = val
|
||||
or
|
||||
e.(LongLiteral).getValue().toInt() = val
|
||||
or
|
||||
exists(SsaExplicitWrite v, Expr src |
|
||||
e = v.getARead() and
|
||||
src = v.getValue() and
|
||||
|
||||
@@ -2,7 +2,7 @@ import rust
|
||||
import codeql.rust.internal.PathResolution
|
||||
import utils.test.PathResolutionInlineExpectationsTest
|
||||
|
||||
query predicate resolveDollarCrate(RelevantPath p, Crate c) {
|
||||
query predicate resolveDollarCrate(PathExt p, Crate c) {
|
||||
c = resolvePath(p) and
|
||||
p.isDollarCrate() and
|
||||
p.fromSource() and
|
||||
|
||||
@@ -11,6 +11,7 @@ ql/rust/ql/src/queries/diagnostics/UnresolvedMacroCalls.ql
|
||||
ql/rust/ql/src/queries/security/CWE-020/RegexInjection.ql
|
||||
ql/rust/ql/src/queries/security/CWE-022/TaintedPath.ql
|
||||
ql/rust/ql/src/queries/security/CWE-089/SqlInjection.ql
|
||||
ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
|
||||
ql/rust/ql/src/queries/security/CWE-311/CleartextTransmission.ql
|
||||
ql/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
|
||||
ql/rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.ql
|
||||
|
||||
@@ -12,6 +12,7 @@ ql/rust/ql/src/queries/security/CWE-020/RegexInjection.ql
|
||||
ql/rust/ql/src/queries/security/CWE-022/TaintedPath.ql
|
||||
ql/rust/ql/src/queries/security/CWE-089/SqlInjection.ql
|
||||
ql/rust/ql/src/queries/security/CWE-117/LogInjection.ql
|
||||
ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
|
||||
ql/rust/ql/src/queries/security/CWE-311/CleartextTransmission.ql
|
||||
ql/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
|
||||
ql/rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.ql
|
||||
|
||||
@@ -12,6 +12,7 @@ ql/rust/ql/src/queries/security/CWE-020/RegexInjection.ql
|
||||
ql/rust/ql/src/queries/security/CWE-022/TaintedPath.ql
|
||||
ql/rust/ql/src/queries/security/CWE-089/SqlInjection.ql
|
||||
ql/rust/ql/src/queries/security/CWE-117/LogInjection.ql
|
||||
ql/rust/ql/src/queries/security/CWE-295/DisabledCertificateCheck.ql
|
||||
ql/rust/ql/src/queries/security/CWE-311/CleartextTransmission.ql
|
||||
ql/rust/ql/src/queries/security/CWE-312/CleartextLogging.ql
|
||||
ql/rust/ql/src/queries/security/CWE-312/CleartextStorageDatabase.ql
|
||||
|
||||
4
rust/ql/lib/change-notes/2025-11-21-fs.md
Normal file
4
rust/ql/lib/change-notes/2025-11-21-fs.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added more detailed models for `std::fs` and `std::path`.
|
||||
@@ -1,5 +1,6 @@
|
||||
private import codeql.util.Boolean
|
||||
private import codeql.rust.controlflow.ControlFlowGraph
|
||||
private import codeql.rust.elements.internal.VariableImpl::Impl as VariableImpl
|
||||
private import rust
|
||||
|
||||
newtype TCompletion =
|
||||
@@ -123,13 +124,7 @@ class BooleanCompletion extends ConditionalCompletion, TBooleanCompletion {
|
||||
*/
|
||||
private predicate cannotCauseMatchFailure(Pat pat) {
|
||||
pat instanceof RangePat or
|
||||
// Identifier patterns that are in fact path patterns can cause failures. For
|
||||
// instance `None`. Only if an `@ ...` part is present can we be sure that
|
||||
// it's an actual identifier pattern. As a heuristic, if the identifier starts
|
||||
// with a lower case letter, then we assume that it's an identifier. This
|
||||
// works for code that follows the Rust naming convention for enums and
|
||||
// constants.
|
||||
pat = any(IdentPat p | p.hasPat() or p.getName().getText().charAt(0).isLowercase()) or
|
||||
pat = any(IdentPat p | p.hasPat() or VariableImpl::variableDecl(_, p.getName(), _)) or
|
||||
pat instanceof WildcardPat or
|
||||
pat instanceof RestPat or
|
||||
pat instanceof RefPat or
|
||||
|
||||
@@ -82,7 +82,7 @@ module Impl {
|
||||
}
|
||||
|
||||
private predicate callHasTraitQualifier(CallExpr call, Trait qualifier) {
|
||||
exists(RelevantPath qualifierPath |
|
||||
exists(PathExt qualifierPath |
|
||||
callHasQualifier(call, _, qualifierPath) and
|
||||
qualifier = resolvePath(qualifierPath) and
|
||||
// When the qualifier is `Self` and resolves to a trait, it's inside a
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
*/
|
||||
|
||||
private import codeql.rust.elements.internal.generated.Const
|
||||
private import codeql.rust.elements.internal.AstNodeImpl::Impl as AstNodeImpl
|
||||
private import codeql.rust.elements.internal.IdentPatImpl::Impl as IdentPatImpl
|
||||
private import codeql.rust.elements.internal.PathExprImpl::Impl as PathExprImpl
|
||||
private import codeql.rust.internal.PathResolution
|
||||
|
||||
@@ -36,14 +38,30 @@ module Impl {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class ConstAccess extends PathExprImpl::PathExpr {
|
||||
private Const c;
|
||||
|
||||
ConstAccess() { c = resolvePath(this.getPath()) }
|
||||
|
||||
abstract class ConstAccess extends AstNodeImpl::AstNode {
|
||||
/** Gets the constant being accessed. */
|
||||
Const getConst() { result = c }
|
||||
abstract Const getConst();
|
||||
|
||||
override string getAPrimaryQlClass() { result = "ConstAccess" }
|
||||
}
|
||||
|
||||
private class PathExprConstAccess extends ConstAccess, PathExprImpl::PathExpr {
|
||||
private Const c;
|
||||
|
||||
PathExprConstAccess() { c = resolvePath(this.getPath()) }
|
||||
|
||||
override Const getConst() { result = c }
|
||||
|
||||
override string getAPrimaryQlClass() { result = ConstAccess.super.getAPrimaryQlClass() }
|
||||
}
|
||||
|
||||
private class IdentPatConstAccess extends ConstAccess, IdentPatImpl::IdentPat {
|
||||
private Const c;
|
||||
|
||||
IdentPatConstAccess() { c = resolvePath(this) }
|
||||
|
||||
override Const getConst() { result = c }
|
||||
|
||||
override string getAPrimaryQlClass() { result = ConstAccess.super.getAPrimaryQlClass() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ module Impl {
|
||||
|
||||
override string toStringImpl() { result = this.getName() }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "FormatTemplateVariableAccess" }
|
||||
|
||||
/** Gets the name of the variable */
|
||||
string getName() { result = argument.getName() }
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* INTERNAL: Do not use.
|
||||
*/
|
||||
|
||||
private import rust
|
||||
private import codeql.rust.elements.internal.generated.PathExpr
|
||||
|
||||
/**
|
||||
@@ -25,5 +26,11 @@ module Impl {
|
||||
override string toStringImpl() { result = this.toAbbreviatedString() }
|
||||
|
||||
override string toAbbreviatedString() { result = this.getPath().toStringImpl() }
|
||||
|
||||
override string getAPrimaryQlClass() {
|
||||
if this instanceof VariableAccess
|
||||
then result = "VariableAccess"
|
||||
else result = super.getAPrimaryQlClass()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
private import rust
|
||||
private import codeql.rust.controlflow.ControlFlowGraph
|
||||
private import codeql.rust.internal.PathResolution as PathResolution
|
||||
private import codeql.rust.elements.internal.generated.ParentChild as ParentChild
|
||||
private import codeql.rust.elements.internal.AstNodeImpl::Impl as AstNodeImpl
|
||||
private import codeql.rust.elements.internal.PathImpl::Impl as PathImpl
|
||||
private import codeql.rust.elements.internal.PathExprBaseImpl::Impl as PathExprBaseImpl
|
||||
private import codeql.rust.elements.internal.FormatTemplateVariableAccessImpl::Impl as FormatTemplateVariableAccessImpl
|
||||
private import codeql.util.DenseRank
|
||||
|
||||
@@ -98,7 +99,7 @@ module Impl {
|
||||
* pattern.
|
||||
*/
|
||||
cached
|
||||
private predicate variableDecl(AstNode definingNode, Name name, string text) {
|
||||
predicate variableDecl(AstNode definingNode, Name name, string text) {
|
||||
Cached::ref() and
|
||||
exists(SelfParam sp |
|
||||
name = sp.getName() and
|
||||
@@ -117,11 +118,7 @@ module Impl {
|
||||
not exists(getOutermostEnclosingOrPat(pat)) and definingNode = name
|
||||
) and
|
||||
text = name.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 text.charAt(0).isUppercase() and
|
||||
not PathResolution::identPatIsResolvable(pat) 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.getAParam().getPat() = pat) and
|
||||
@@ -666,7 +663,7 @@ module Impl {
|
||||
}
|
||||
|
||||
/** A variable access. */
|
||||
class VariableAccess extends PathExprBaseImpl::PathExprBase {
|
||||
class VariableAccess extends PathExprBase {
|
||||
private string name;
|
||||
private Variable v;
|
||||
|
||||
@@ -677,10 +674,6 @@ module Impl {
|
||||
|
||||
/** Holds if this access is a capture. */
|
||||
predicate isCapture() { this.getEnclosingCfgScope() != v.getEnclosingCfgScope() }
|
||||
|
||||
override string toStringImpl() { result = name }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "VariableAccess" }
|
||||
}
|
||||
|
||||
/** Holds if `e` occurs in the LHS of an assignment or compound assignment. */
|
||||
@@ -722,7 +715,7 @@ module Impl {
|
||||
}
|
||||
|
||||
/** A nested function access. */
|
||||
class NestedFunctionAccess extends PathExprBaseImpl::PathExprBase {
|
||||
class NestedFunctionAccess extends PathExprBase {
|
||||
private Function f;
|
||||
|
||||
NestedFunctionAccess() { nestedFunctionAccess(_, f, this) }
|
||||
|
||||
9
rust/ql/lib/codeql/rust/frameworks/native-tls.model.yml
Normal file
9
rust/ql/lib/codeql/rust/frameworks/native-tls.model.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/rust-all
|
||||
extensible: sinkModel
|
||||
data:
|
||||
- ["<native_tls::TlsConnectorBuilder>::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
|
||||
- ["<native_tls::TlsConnectorBuilder>::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
|
||||
- ["<async_native_tls::connect::TlsConnector>::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
|
||||
- ["<async_native_tls::connect::TlsConnector>::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
|
||||
@@ -11,6 +11,10 @@ extensions:
|
||||
data:
|
||||
- ["<reqwest::async_impl::client::Client>::request", "Argument[1]", "request-url", "manual"]
|
||||
- ["<reqwest::blocking::client::Client>::request", "Argument[1]", "request-url", "manual"]
|
||||
- ["<reqwest::async_impl::client::ClientBuilder>::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
|
||||
- ["<reqwest::async_impl::client::ClientBuilder>::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
|
||||
- ["<reqwest::blocking::client::ClientBuilder>::danger_accept_invalid_certs", "Argument[0]", "disable-certificate", "manual"]
|
||||
- ["<reqwest::blocking::client::ClientBuilder>::danger_accept_invalid_hostnames", "Argument[0]", "disable-certificate", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/rust-all
|
||||
extensible: summaryModel
|
||||
|
||||
@@ -60,6 +60,7 @@ extensions:
|
||||
- ["core::ptr::dangling", "ReturnValue", "pointer-invalidate", "manual"]
|
||||
- ["core::ptr::dangling_mut", "ReturnValue", "pointer-invalidate", "manual"]
|
||||
- ["core::ptr::null", "ReturnValue", "pointer-invalidate", "manual"]
|
||||
- ["core::ptr::null_mut", "ReturnValue", "pointer-invalidate", "manual"]
|
||||
- ["v8::primitives::null", "ReturnValue", "pointer-invalidate", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/rust-all
|
||||
|
||||
@@ -3,14 +3,27 @@ extensions:
|
||||
pack: codeql/rust-all
|
||||
extensible: sourceModel
|
||||
data:
|
||||
- ["std::fs::exists", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
|
||||
- ["std::fs::read", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
|
||||
- ["std::fs::read_dir", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
|
||||
- ["std::fs::read_to_string", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
|
||||
- ["std::fs::read_link", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
|
||||
- ["std::fs::metadata", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
|
||||
- ["std::fs::symlink_metadata", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
|
||||
- ["<std::fs::DirEntry>::path", "ReturnValue", "file", "manual"]
|
||||
- ["<std::fs::DirEntry>::file_name", "ReturnValue", "file", "manual"]
|
||||
- ["<std::fs::File>::open", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
|
||||
- ["<std::fs::File>::open_buffered", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
|
||||
- ["<std::fs::OpenOptions>::open", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
|
||||
- ["<std::path::Path>::exists", "ReturnValue", "file", "manual"]
|
||||
- ["<std::path::Path>::try_exists", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
|
||||
- ["<std::path::Path>::is_file", "ReturnValue", "file", "manual"]
|
||||
- ["<std::path::Path>::is_dir", "ReturnValue", "file", "manual"]
|
||||
- ["<std::path::Path>::is_symlink", "ReturnValue", "file", "manual"]
|
||||
- ["<std::path::Path>::metadata", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
|
||||
- ["<std::path::Path>::symlink_metadata", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
|
||||
- ["<std::path::Path>::read_dir", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
|
||||
- ["<std::path::Path>::read_link", "ReturnValue.Field[core::result::Result::Ok(0)]", "file", "manual"]
|
||||
- addsTo:
|
||||
pack: codeql/rust-all
|
||||
extensible: sinkModel
|
||||
@@ -68,3 +81,12 @@ extensions:
|
||||
- ["<std::path::Path>::with_extension", "Argument[Self].Reference", "ReturnValue", "taint", "manual"]
|
||||
- ["<std::path::Path>::with_file_name", "Argument[Self].Reference", "ReturnValue", "taint", "manual"]
|
||||
- ["<std::path::Path>::with_file_name", "Argument[0]", "ReturnValue", "taint", "manual"]
|
||||
- ["<std::fs::Metadata>::accessed", "Argument[self].Reference", "ReturnValue.Field[core::result::Result::Ok(0)]", "taint", "manual"]
|
||||
- ["<std::fs::Metadata>::created", "Argument[self].Reference", "ReturnValue.Field[core::result::Result::Ok(0)]", "taint", "manual"]
|
||||
- ["<std::fs::Metadata>::file_type", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
|
||||
- ["<std::fs::Metadata>::is_file", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
|
||||
- ["<std::fs::Metadata>::is_dir", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
|
||||
- ["<std::fs::Metadata>::is_symlink", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
|
||||
- ["<std::fs::Metadata>::len", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
|
||||
- ["<std::fs::Metadata>::modified", "Argument[self].Reference", "ReturnValue.Field[core::result::Result::Ok(0)]", "taint", "manual"]
|
||||
- ["<std::fs::Metadata>::permissions", "Argument[self].Reference", "ReturnValue", "taint", "manual"]
|
||||
|
||||
@@ -115,13 +115,11 @@ module Stages {
|
||||
predicate backref() {
|
||||
1 = 1
|
||||
or
|
||||
exists(resolvePath(_))
|
||||
exists(resolvePathIgnoreVariableShadowing(_))
|
||||
or
|
||||
exists(any(ItemNode i).getASuccessor(_, _, _))
|
||||
or
|
||||
exists(any(ImplOrTraitItemNode i).getASelfPath())
|
||||
or
|
||||
any(TypeParamItemNode i).hasTraitBound()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,9 @@ private module Cached {
|
||||
TFormatArgsArgIndex(Expr e) { e = any(FormatArgsArg a).getExpr() } or
|
||||
TItemNode(ItemNode i)
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate isMacroCallLocation(Location loc) { loc = any(MacroCall m).getLocation() }
|
||||
|
||||
/**
|
||||
* Gets an element, of kind `kind`, that element `use` uses, if any.
|
||||
*/
|
||||
@@ -44,7 +47,7 @@ private module Cached {
|
||||
Definition definitionOf(Use use, string kind) {
|
||||
result = use.getDefinition() and
|
||||
kind = use.getUseType() and
|
||||
not result.getLocation() = any(MacroCall m).getLocation()
|
||||
not isMacroCallLocation(result.getLocation())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,49 @@
|
||||
/**
|
||||
* Provides functionality for resolving paths, using the predicate `resolvePath`.
|
||||
*
|
||||
* Path resolution needs to happen before variable resolution, because otherwise
|
||||
* we cannot know whether an identifier pattern binds a new variable or whether it
|
||||
* refers to a constructor or constant:
|
||||
*
|
||||
* ```rust
|
||||
* let x = ...; // `x` is only a variable if it does not resolve to a constructor/constant
|
||||
* ```
|
||||
*
|
||||
* Even though variable names typically start with a lowercase letter and constructors
|
||||
* with an uppercase letter, this is not enforced by the Rust language.
|
||||
*
|
||||
* Variables may shadow declarations, so variable resolution also needs to affect
|
||||
* path resolution:
|
||||
*
|
||||
* ```rust
|
||||
* fn foo() {} // (1)
|
||||
*
|
||||
* fn bar() {
|
||||
* let f = foo; // `foo` here refers to (1) via path resolution
|
||||
* let foo = f(); // (2)
|
||||
* foo // `foo` here refers to (2) via variable resolution
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* So it may seem that path resolution and variable resolution must happen in mutual
|
||||
* recursion, but we would like to keep the inherently global path resolution logic
|
||||
* separate from the inherently local variable resolution logic. We achieve this by
|
||||
*
|
||||
* - First computing global path resolution, where variable shadowing is ignored,
|
||||
* exposed as the internal predicate `resolvePathIgnoreVariableShadowing`.
|
||||
* - `resolvePathIgnoreVariableShadowing` is sufficient to determine whether an
|
||||
* identifier pattern resolves to a constructor/constant, since if it does, it cannot
|
||||
* be shadowed by a variable. We expose this as the predicate `identPatIsResolvable`.
|
||||
* - Variable resolution can then be computed as a local property, using only the
|
||||
* global information from `identPatIsResolvable`.
|
||||
* - Finally, path resolution can be computed by restricting
|
||||
* `resolvePathIgnoreVariableShadowing` to paths that are not resolvable via
|
||||
* variable resolution.
|
||||
*/
|
||||
|
||||
private import rust
|
||||
private import codeql.rust.elements.internal.generated.ParentChild
|
||||
private import codeql.rust.elements.internal.AstNodeImpl::Impl as AstNodeImpl
|
||||
private import codeql.rust.elements.internal.CallExprImpl::Impl as CallExprImpl
|
||||
private import codeql.rust.internal.CachedStages
|
||||
private import codeql.rust.frameworks.stdlib.Builtins as Builtins
|
||||
@@ -184,7 +224,7 @@ abstract class ItemNode extends Locatable {
|
||||
pragma[nomagic]
|
||||
final Attr getAttr(string name) {
|
||||
result = this.getAnAttr() and
|
||||
result.getMeta().getPath().(RelevantPath).isUnqualified(name)
|
||||
result.getMeta().getPath().(PathExt).isUnqualified(name)
|
||||
}
|
||||
|
||||
final predicate hasAttr(string name) { exists(this.getAttr(name)) }
|
||||
@@ -1159,34 +1199,6 @@ final class TypeParamItemNode extends TypeItemNode instanceof TypeParam {
|
||||
|
||||
ItemNode resolveABound() { result = resolvePath(this.getABoundPath()) }
|
||||
|
||||
/**
|
||||
* Holds if this type parameter has a trait bound. Examples:
|
||||
*
|
||||
* ```rust
|
||||
* impl<T> Foo<T> { ... } // has no trait bound
|
||||
*
|
||||
* impl<T: Trait> Foo<T> { ... } // has trait bound
|
||||
*
|
||||
* impl<T> Foo<T> where T: Trait { ... } // has trait bound
|
||||
* ```
|
||||
*/
|
||||
cached
|
||||
predicate hasTraitBound() { Stages::PathResolutionStage::ref() and exists(this.getABoundPath()) }
|
||||
|
||||
/**
|
||||
* Holds if this type parameter has no trait bound. Examples:
|
||||
*
|
||||
* ```rust
|
||||
* impl<T> Foo<T> { ... } // has no trait bound
|
||||
*
|
||||
* impl<T: Trait> Foo<T> { ... } // has trait bound
|
||||
*
|
||||
* impl<T> Foo<T> where T: Trait { ... } // has trait bound
|
||||
* ```
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate hasNoTraitBound() { not this.hasTraitBound() }
|
||||
|
||||
override string getName() { result = TypeParam.super.getName().getText() }
|
||||
|
||||
override Namespace getNamespace() { result.isType() }
|
||||
@@ -1525,20 +1537,22 @@ private predicate declares(ItemNode item, Namespace ns, string name) {
|
||||
)
|
||||
}
|
||||
|
||||
/** A path that does not access a local variable. */
|
||||
class RelevantPath extends Path {
|
||||
RelevantPath() { not this = any(VariableAccess va).(PathExpr).getPath() }
|
||||
/**
|
||||
* A `Path` or an `IdentPat`.
|
||||
*
|
||||
* `IdentPat`s are included in order to resolve unqualified references to
|
||||
* constructors in patterns.
|
||||
*/
|
||||
abstract class PathExt extends AstNode {
|
||||
abstract string getText();
|
||||
|
||||
/** Holds if this is an unqualified path with the textual value `name`. */
|
||||
pragma[nomagic]
|
||||
predicate isUnqualified(string name) {
|
||||
not exists(this.getQualifier()) and
|
||||
not exists(UseTree tree |
|
||||
tree.hasPath() and
|
||||
this = getAUseTreeUseTree(tree).getPath().getQualifier*()
|
||||
) and
|
||||
name = this.getText()
|
||||
}
|
||||
abstract predicate isUnqualified(string name);
|
||||
|
||||
abstract Path getQualifier();
|
||||
|
||||
abstract string toStringDebug();
|
||||
|
||||
/**
|
||||
* Holds if this is an unqualified path with the textual value `name` and
|
||||
@@ -1560,6 +1574,33 @@ class RelevantPath extends Path {
|
||||
predicate isDollarCrate() { this.isUnqualified("$crate", _) }
|
||||
}
|
||||
|
||||
private class PathExtPath extends PathExt instanceof Path {
|
||||
override string getText() { result = Path.super.getText() }
|
||||
|
||||
override predicate isUnqualified(string name) {
|
||||
not exists(Path.super.getQualifier()) and
|
||||
not exists(UseTree tree |
|
||||
tree.hasPath() and
|
||||
this = getAUseTreeUseTree(tree).getPath().getQualifier*()
|
||||
) and
|
||||
name = Path.super.getText()
|
||||
}
|
||||
|
||||
override Path getQualifier() { result = Path.super.getQualifier() }
|
||||
|
||||
override string toStringDebug() { result = Path.super.toStringDebug() }
|
||||
}
|
||||
|
||||
private class PathExtIdentPat extends PathExt, IdentPat {
|
||||
override string getText() { result = this.getName().getText() }
|
||||
|
||||
override predicate isUnqualified(string name) { name = this.getText() }
|
||||
|
||||
override Path getQualifier() { none() }
|
||||
|
||||
override string toStringDebug() { result = this.getText() }
|
||||
}
|
||||
|
||||
private predicate isModule(ItemNode m) { m instanceof Module }
|
||||
|
||||
/** Holds if source file `source` contains the module `m`. */
|
||||
@@ -1583,7 +1624,7 @@ private ItemNode getOuterScope(ItemNode i) {
|
||||
pragma[nomagic]
|
||||
private predicate unqualifiedPathLookup(ItemNode ancestor, string name, Namespace ns, ItemNode encl) {
|
||||
// lookup in the immediately enclosing item
|
||||
exists(RelevantPath path |
|
||||
exists(PathExt path |
|
||||
path.isUnqualified(name, encl) and
|
||||
ancestor = encl and
|
||||
not name = ["crate", "$crate", "super", "self"]
|
||||
@@ -1619,7 +1660,7 @@ private ItemNode getASuccessor(
|
||||
|
||||
private predicate isSourceFile(ItemNode source) { source instanceof SourceFileItemNode }
|
||||
|
||||
private predicate hasCratePath(ItemNode i) { any(RelevantPath path).isCratePath(_, i) }
|
||||
private predicate hasCratePath(ItemNode i) { any(PathExt path).isCratePath(_, i) }
|
||||
|
||||
private predicate hasChild(ItemNode parent, ItemNode child) { child.getImmediateParent() = parent }
|
||||
|
||||
@@ -1631,7 +1672,7 @@ private predicate sourceFileHasCratePathTc(ItemNode i1, ItemNode i2) =
|
||||
* `name` may be looked up inside `ancestor`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate keywordLookup(ItemNode ancestor, string name, RelevantPath p) {
|
||||
private predicate keywordLookup(ItemNode ancestor, string name, PathExt p) {
|
||||
// For `crate`, jump directly to the root module
|
||||
exists(ItemNode i | p.isCratePath(name, i) |
|
||||
ancestor instanceof SourceFile and
|
||||
@@ -1645,7 +1686,7 @@ private predicate keywordLookup(ItemNode ancestor, string name, RelevantPath p)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private ItemNode unqualifiedPathLookup(RelevantPath p, Namespace ns, SuccessorKind kind) {
|
||||
private ItemNode unqualifiedPathLookup(PathExt p, Namespace ns, SuccessorKind kind) {
|
||||
exists(ItemNode ancestor, string name |
|
||||
result = getASuccessor(ancestor, pragma[only_bind_into](name), ns, kind, _) and
|
||||
kind.isInternalOrBoth()
|
||||
@@ -1660,7 +1701,7 @@ private ItemNode unqualifiedPathLookup(RelevantPath p, Namespace ns, SuccessorKi
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate isUnqualifiedSelfPath(RelevantPath path) { path.isUnqualified("Self") }
|
||||
private predicate isUnqualifiedSelfPath(PathExt path) { path.isUnqualified("Self") }
|
||||
|
||||
/** Provides the input to `TraitIsVisible`. */
|
||||
signature predicate relevantTraitVisibleSig(Element element, Trait trait);
|
||||
@@ -1743,14 +1784,14 @@ private module DollarCrateResolution {
|
||||
isDollarCrateSupportedMacroExpansion(_, expansion)
|
||||
}
|
||||
|
||||
private predicate isDollarCratePath(RelevantPath p) { p.isDollarCrate() }
|
||||
private predicate isDollarCratePath(PathExt p) { p.isDollarCrate() }
|
||||
|
||||
private predicate isInDollarCrateMacroExpansion(RelevantPath p, AstNode expansion) =
|
||||
private predicate isInDollarCrateMacroExpansion(PathExt p, AstNode expansion) =
|
||||
doublyBoundedFastTC(hasParent/2, isDollarCratePath/1, isDollarCrateSupportedMacroExpansion/1)(p,
|
||||
expansion)
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate isInDollarCrateMacroExpansionFromFile(File macroDefFile, RelevantPath p) {
|
||||
private predicate isInDollarCrateMacroExpansionFromFile(File macroDefFile, PathExt p) {
|
||||
exists(Path macroDefPath, AstNode expansion |
|
||||
isDollarCrateSupportedMacroExpansion(macroDefPath, expansion) and
|
||||
isInDollarCrateMacroExpansion(p, expansion) and
|
||||
@@ -1765,17 +1806,17 @@ private module DollarCrateResolution {
|
||||
* calls.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate resolveDollarCrate(RelevantPath p, CrateItemNode crate) {
|
||||
predicate resolveDollarCrate(PathExt p, CrateItemNode crate) {
|
||||
isInDollarCrateMacroExpansionFromFile(crate.getASourceFile().getFile(), p)
|
||||
}
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private ItemNode resolvePathCand0(RelevantPath path, Namespace ns) {
|
||||
private ItemNode resolvePathCand0(PathExt path, Namespace ns) {
|
||||
exists(ItemNode res |
|
||||
res = unqualifiedPathLookup(path, ns, _) and
|
||||
if
|
||||
not any(RelevantPath parent).getQualifier() = path and
|
||||
not any(PathExt parent).getQualifier() = path and
|
||||
isUnqualifiedSelfPath(path) and
|
||||
res instanceof ImplItemNode
|
||||
then result = res.(ImplItemNodeImpl).resolveSelfTyCand()
|
||||
@@ -1790,13 +1831,16 @@ private ItemNode resolvePathCand0(RelevantPath path, Namespace ns) {
|
||||
result = resolveUseTreeListItem(_, _, path, _) and
|
||||
ns = result.getNamespace()
|
||||
or
|
||||
result = resolveBuiltin(path.getSegment().getTypeRepr()) and
|
||||
not path.getSegment().hasTraitTypeRepr() and
|
||||
ns.isType()
|
||||
exists(PathSegment seg |
|
||||
seg = path.(Path).getSegment() and
|
||||
result = resolveBuiltin(seg.getTypeRepr()) and
|
||||
not seg.hasTraitTypeRepr() and
|
||||
ns.isType()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private ItemNode resolvePathCandQualifier(RelevantPath qualifier, RelevantPath path, string name) {
|
||||
private ItemNode resolvePathCandQualifier(PathExt qualifier, PathExt path, string name) {
|
||||
qualifier = path.getQualifier() and
|
||||
result = resolvePathCand(qualifier) and
|
||||
name = path.getText()
|
||||
@@ -1844,9 +1888,7 @@ private predicate checkQualifiedVisibility(
|
||||
* qualifier of `path` and `qualifier` resolves to `q`, if any.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private ItemNode resolvePathCandQualified(
|
||||
RelevantPath qualifier, ItemNode q, RelevantPath path, Namespace ns
|
||||
) {
|
||||
private ItemNode resolvePathCandQualified(PathExt qualifier, ItemNode q, PathExt path, Namespace ns) {
|
||||
exists(string name, SuccessorKind kind, UseOption useOpt |
|
||||
q = resolvePathCandQualifier(qualifier, path, name) and
|
||||
result = getASuccessor(q, name, ns, kind, useOpt) and
|
||||
@@ -1855,12 +1897,14 @@ private ItemNode resolvePathCandQualified(
|
||||
}
|
||||
|
||||
/** Holds if path `p` must be looked up in namespace `n`. */
|
||||
private predicate pathUsesNamespace(Path p, Namespace n) {
|
||||
private predicate pathUsesNamespace(PathExt p, Namespace n) {
|
||||
n.isValue() and
|
||||
(
|
||||
p = any(PathExpr pe).getPath()
|
||||
or
|
||||
p = any(TupleStructPat tsp).getPath()
|
||||
or
|
||||
p instanceof PathExtIdentPat
|
||||
)
|
||||
or
|
||||
n.isType() and
|
||||
@@ -1936,7 +1980,7 @@ private predicate macroUseEdge(
|
||||
* result in non-monotonic recursion.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private ItemNode resolvePathCand(RelevantPath path) {
|
||||
private ItemNode resolvePathCand(PathExt path) {
|
||||
exists(Namespace ns |
|
||||
result = resolvePathCand0(path, ns) and
|
||||
if path = any(ImplItemNode i).getSelfPath()
|
||||
@@ -1949,7 +1993,13 @@ private ItemNode resolvePathCand(RelevantPath path) {
|
||||
else
|
||||
if path = any(PathTypeRepr p).getPath()
|
||||
then result instanceof TypeItemNode
|
||||
else any()
|
||||
else
|
||||
if path instanceof IdentPat
|
||||
then
|
||||
result instanceof VariantItemNode or
|
||||
result instanceof StructItemNode or
|
||||
result instanceof ConstItemNode
|
||||
else any()
|
||||
|
|
||||
pathUsesNamespace(path, ns)
|
||||
or
|
||||
@@ -1966,7 +2016,7 @@ private ItemNode resolvePathCand(RelevantPath path) {
|
||||
}
|
||||
|
||||
/** Get a trait that should be visible when `path` resolves to `node`, if any. */
|
||||
private Trait getResolvePathTraitUsed(RelevantPath path, AssocItemNode node) {
|
||||
private Trait getResolvePathTraitUsed(PathExt path, AssocItemNode node) {
|
||||
exists(TypeItemNode type, ImplItemNodeImpl impl |
|
||||
node = resolvePathCandQualified(_, type, path, _) and
|
||||
typeImplEdge(type, impl, _, _, node, _) and
|
||||
@@ -1978,9 +2028,9 @@ private predicate pathTraitUsed(Element path, Trait trait) {
|
||||
trait = getResolvePathTraitUsed(path, _)
|
||||
}
|
||||
|
||||
/** Gets the item that `path` resolves to, if any. */
|
||||
/** INTERNAL: Do not use; use `resolvePath` instead. */
|
||||
cached
|
||||
ItemNode resolvePath(RelevantPath path) {
|
||||
ItemNode resolvePathIgnoreVariableShadowing(PathExt path) {
|
||||
result = resolvePathCand(path) and
|
||||
not path = any(Path parent | exists(resolvePathCand(parent))).getQualifier() and
|
||||
(
|
||||
@@ -1993,29 +2043,43 @@ ItemNode resolvePath(RelevantPath path) {
|
||||
or
|
||||
// if `path` is the qualifier of a resolvable `parent`, then we should
|
||||
// resolve `path` to something consistent with what `parent` resolves to
|
||||
exists(RelevantPath parent |
|
||||
resolvePathCandQualified(path, result, parent, _) = resolvePath(parent)
|
||||
exists(PathExt parent |
|
||||
resolvePathCandQualified(path, result, parent, _) = resolvePathIgnoreVariableShadowing(parent)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isUseTreeSubPath(UseTree tree, RelevantPath path) {
|
||||
/**
|
||||
* Holds if `ip` resolves to some constructor or constant.
|
||||
*/
|
||||
// use `forceLocal` once we implement overlay support
|
||||
pragma[nomagic]
|
||||
predicate identPatIsResolvable(IdentPat ip) { exists(resolvePathIgnoreVariableShadowing(ip)) }
|
||||
|
||||
/** Gets the item that `path` resolves to, if any. */
|
||||
pragma[nomagic]
|
||||
ItemNode resolvePath(PathExt path) {
|
||||
result = resolvePathIgnoreVariableShadowing(path) and
|
||||
not path = any(VariableAccess va).(PathExpr).getPath()
|
||||
}
|
||||
|
||||
private predicate isUseTreeSubPath(UseTree tree, PathExt path) {
|
||||
path = tree.getPath()
|
||||
or
|
||||
exists(RelevantPath mid |
|
||||
exists(PathExt mid |
|
||||
isUseTreeSubPath(tree, mid) and
|
||||
path = mid.getQualifier()
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate isUseTreeSubPathUnqualified(UseTree tree, RelevantPath path, string name) {
|
||||
private predicate isUseTreeSubPathUnqualified(UseTree tree, PathExt path, string name) {
|
||||
isUseTreeSubPath(tree, path) and
|
||||
not exists(path.getQualifier()) and
|
||||
name = path.getText()
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private ItemNode resolveUseTreeListItem(Use use, UseTree tree, RelevantPath path, SuccessorKind kind) {
|
||||
private ItemNode resolveUseTreeListItem(Use use, UseTree tree, PathExt path, SuccessorKind kind) {
|
||||
exists(UseOption useOpt | checkQualifiedVisibility(use, result, kind, useOpt) |
|
||||
exists(UseTree midTree, ItemNode mid, string name |
|
||||
mid = resolveUseTreeListItem(use, midTree) and
|
||||
@@ -2032,9 +2096,7 @@ private ItemNode resolveUseTreeListItem(Use use, UseTree tree, RelevantPath path
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private ItemNode resolveUseTreeListItemQualifier(
|
||||
Use use, UseTree tree, RelevantPath path, string name
|
||||
) {
|
||||
private ItemNode resolveUseTreeListItemQualifier(Use use, UseTree tree, PathExt path, string name) {
|
||||
result = resolveUseTreeListItem(use, tree, path.getQualifier(), _) and
|
||||
name = path.getText()
|
||||
}
|
||||
@@ -2189,7 +2251,7 @@ private module Debug {
|
||||
}
|
||||
|
||||
predicate debugUnqualifiedPathLookup(
|
||||
RelevantPath p, string name, Namespace ns, ItemNode ancestor, string path
|
||||
PathExt p, string name, Namespace ns, ItemNode ancestor, string path
|
||||
) {
|
||||
p = getRelevantLocatable() and
|
||||
exists(ItemNode encl |
|
||||
@@ -2199,14 +2261,19 @@ private module Debug {
|
||||
path = p.toStringDebug()
|
||||
}
|
||||
|
||||
ItemNode debugUnqualifiedPathLookup(PathExt p, Namespace ns, SuccessorKind kind) {
|
||||
p = getRelevantLocatable() and
|
||||
result = unqualifiedPathLookup(p, ns, kind)
|
||||
}
|
||||
|
||||
predicate debugItemNode(ItemNode item) { item = getRelevantLocatable() }
|
||||
|
||||
ItemNode debugResolvePath(RelevantPath path) {
|
||||
ItemNode debugResolvePath(PathExt path) {
|
||||
path = getRelevantLocatable() and
|
||||
result = resolvePath(path)
|
||||
}
|
||||
|
||||
ItemNode debugResolveUseTreeListItem(Use use, UseTree tree, RelevantPath path, SuccessorKind kind) {
|
||||
ItemNode debugResolveUseTreeListItem(Use use, UseTree tree, PathExt path, SuccessorKind kind) {
|
||||
use = getRelevantLocatable() and
|
||||
result = resolveUseTreeListItem(use, tree, path, kind)
|
||||
}
|
||||
|
||||
@@ -352,7 +352,7 @@ module ArgsAreInstantiationsOf<ArgsAreInstantiationsOfInputSig Input> {
|
||||
|
|
||||
rnk = 0
|
||||
or
|
||||
argsAreInstantiationsOfFromIndex(call, abs, f, rnk - 1)
|
||||
argsAreInstantiationsOfToIndex(call, abs, f, rnk - 1)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -361,15 +361,15 @@ module ArgsAreInstantiationsOf<ArgsAreInstantiationsOfInputSig Input> {
|
||||
}
|
||||
}
|
||||
|
||||
private module ArgIsInstantiationOfFromIndex =
|
||||
private module ArgIsInstantiationOfToIndex =
|
||||
ArgIsInstantiationOf<CallAndPos, ArgIsInstantiationOfInput>;
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate argsAreInstantiationsOfFromIndex(
|
||||
private predicate argsAreInstantiationsOfToIndex(
|
||||
Input::Call call, ImplOrTraitItemNode i, Function f, int rnk
|
||||
) {
|
||||
exists(FunctionPosition pos |
|
||||
ArgIsInstantiationOfFromIndex::argIsInstantiationOf(MkCallAndPos(call, pos), i, _) and
|
||||
ArgIsInstantiationOfToIndex::argIsInstantiationOf(MkCallAndPos(call, pos), i, _) and
|
||||
call.hasTargetCand(i, f) and
|
||||
toCheckRanked(i, f, pos, rnk)
|
||||
)
|
||||
@@ -382,7 +382,7 @@ module ArgsAreInstantiationsOf<ArgsAreInstantiationsOfInputSig Input> {
|
||||
pragma[nomagic]
|
||||
predicate argsAreInstantiationsOf(Input::Call call, ImplOrTraitItemNode i, Function f) {
|
||||
exists(int rnk |
|
||||
argsAreInstantiationsOfFromIndex(call, i, f, rnk) and
|
||||
argsAreInstantiationsOfToIndex(call, i, f, rnk) and
|
||||
rnk = max(int r | toCheckRanked(i, f, _, r))
|
||||
)
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ private import codeql.rust.dataflow.FlowSource
|
||||
private import codeql.rust.dataflow.FlowSink
|
||||
private import codeql.rust.Concepts
|
||||
private import codeql.rust.dataflow.internal.Node
|
||||
private import codeql.rust.security.Barriers as Barriers
|
||||
|
||||
/**
|
||||
* Provides default sources, sinks and barriers for detecting accesses to
|
||||
@@ -59,4 +60,10 @@ module AccessInvalidPointer {
|
||||
private class ModelsAsDataSink extends Sink {
|
||||
ModelsAsDataSink() { sinkNode(this, "pointer-access") }
|
||||
}
|
||||
|
||||
/**
|
||||
* A barrier for invalid pointer access vulnerabilities for values checked to
|
||||
* be non-`null`.
|
||||
*/
|
||||
private class NotNullCheckBarrier extends Barrier instanceof Barriers::NotNullCheckBarrier { }
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import rust
|
||||
private import codeql.rust.dataflow.DataFlow
|
||||
private import codeql.rust.internal.TypeInference as TypeInference
|
||||
private import codeql.rust.internal.Type
|
||||
private import codeql.rust.controlflow.ControlFlowGraph as Cfg
|
||||
private import codeql.rust.controlflow.CfgNodes as CfgNodes
|
||||
private import codeql.rust.frameworks.stdlib.Builtins as Builtins
|
||||
|
||||
/**
|
||||
@@ -40,3 +42,25 @@ class IntegralOrBooleanTypeBarrier extends DataFlow::Node {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if guard expression `g` having result `branch` indicates that the
|
||||
* sub-expression `e` is not null. For example when `ptr.is_null()` is
|
||||
* `false`, we have that `ptr` is not null.
|
||||
*/
|
||||
private predicate notNullCheck(AstNode g, Expr e, boolean branch) {
|
||||
exists(MethodCallExpr call |
|
||||
call.getStaticTarget().getName().getText() = "is_null" and
|
||||
g = call and
|
||||
e = call.getReceiver() and
|
||||
branch = false
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A node representing a value checked to be non-null. This may be an
|
||||
* appropriate taint flow barrier for some queries.
|
||||
*/
|
||||
class NotNullCheckBarrier extends DataFlow::Node {
|
||||
NotNullCheckBarrier() { this = DataFlow::BarrierGuard<notNullCheck/3>::getABarrierNode() }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Provides classes and predicates for reasoning about disabled certificate
|
||||
* check vulnerabilities.
|
||||
*/
|
||||
|
||||
import rust
|
||||
private import codeql.rust.dataflow.DataFlow
|
||||
private import codeql.rust.dataflow.FlowSink
|
||||
private import codeql.rust.Concepts
|
||||
private import codeql.rust.dataflow.internal.Node as Node
|
||||
|
||||
/**
|
||||
* Provides default sinks for detecting disabled certificate check
|
||||
* vulnerabilities, as well as extension points for adding your own.
|
||||
*/
|
||||
module DisabledCertificateCheckExtensions {
|
||||
/**
|
||||
* A data flow sink for disabled certificate check vulnerabilities.
|
||||
*/
|
||||
abstract class Sink extends QuerySink::Range {
|
||||
override string getSinkType() { result = "DisabledCertificateCheck" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A sink for disabled certificate check vulnerabilities from model data.
|
||||
*/
|
||||
private class ModelsAsDataSink extends Sink {
|
||||
ModelsAsDataSink() { sinkNode(this, "disable-certificate") }
|
||||
}
|
||||
|
||||
/**
|
||||
* A heuristic sink for disabled certificate check vulnerabilities based on function names.
|
||||
*/
|
||||
private class HeuristicSink extends Sink {
|
||||
HeuristicSink() {
|
||||
exists(CallExprBase fc |
|
||||
fc.getStaticTarget().(Function).getName().getText() =
|
||||
["danger_accept_invalid_certs", "danger_accept_invalid_hostnames"] and
|
||||
fc.getArg(0) = this.asExpr() and
|
||||
// don't duplicate modeled sinks
|
||||
not exists(ModelsAsDataSink s | s.(Node::FlowSummaryNode).getSinkElement().getCall() = fc)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
* Added a new query `rust/disabled-certificate-check`, to detect disabled TLS certificate checks.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The `rust/access-invalid-pointer` query has been improved with new flow sources and barriers.
|
||||
@@ -0,0 +1,42 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>
|
||||
The <code>danger_accept_invalid_certs</code> option on TLS connectors and HTTP clients controls whether certificate verification is performed. If this option is set to <code>true</code>, the client will accept any certificate, making it susceptible to man-in-the-middle attacks.
|
||||
</p>
|
||||
<p>
|
||||
Similarly, the <code>danger_accept_invalid_hostnames</code> option controls whether hostname verification is performed. If this option is set to <code>true</code>, the client will accept any valid certificate regardless of the site that certificate is for, again making it susceptible to man-in-the-middle attacks.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
Do not set <code>danger_accept_invalid_certs</code> or <code>danger_accept_invalid_hostnames</code> to <code>true</code>, except in controlled environments such as tests. In production, always ensure certificate and hostname verification is enabled to prevent security risks.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
The following code snippet shows a function that creates an HTTP client with certificate verification disabled:
|
||||
</p>
|
||||
<sample src="DisabledCertificateCheckBad.rs"/>
|
||||
<p>
|
||||
In production code, always configure clients to verify certificates:
|
||||
</p>
|
||||
<sample src="DisabledCertificateCheckGood.rs"/>
|
||||
</example>
|
||||
<references>
|
||||
<li>
|
||||
Rust native-tls crate: <a href="https://docs.rs/native-tls/latest/native_tls/struct.TlsConnectorBuilder.html">TlsConnectorBuilder</a>.
|
||||
</li>
|
||||
<li>
|
||||
Rust reqwest crate: <a href="https://docs.rs/reqwest/latest/reqwest/struct.ClientBuilder.html">ClientBuilder</a>.
|
||||
</li>
|
||||
<li>
|
||||
SSL.com: <a href="https://www.ssl.com/article/browsers-and-certificate-validation/">Browsers and Certificate Validation</a>.
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @name Disabled TLS certificate check
|
||||
* @description An application that disables TLS certificate checking is more vulnerable to
|
||||
* man-in-the-middle attacks.
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 7.5
|
||||
* @precision high
|
||||
* @id rust/disabled-certificate-check
|
||||
* @tags security
|
||||
* external/cwe/cwe-295
|
||||
*/
|
||||
|
||||
import rust
|
||||
import codeql.rust.dataflow.DataFlow
|
||||
import codeql.rust.dataflow.TaintTracking
|
||||
import codeql.rust.security.DisabledCertificateCheckExtensions
|
||||
import codeql.rust.Concepts
|
||||
|
||||
/**
|
||||
* A taint configuration for disabled TLS certificate checks.
|
||||
*/
|
||||
module DisabledCertificateCheckConfig implements DataFlow::ConfigSig {
|
||||
import DisabledCertificateCheckExtensions
|
||||
|
||||
predicate isSource(DataFlow::Node node) {
|
||||
// the constant `true`
|
||||
node.asExpr().(BooleanLiteralExpr).getTextValue() = "true"
|
||||
or
|
||||
// a value controlled by a potential attacker
|
||||
node instanceof ActiveThreatModelSource
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node node) { node instanceof Sink }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
}
|
||||
|
||||
module DisabledCertificateCheckFlow = TaintTracking::Global<DisabledCertificateCheckConfig>;
|
||||
|
||||
import DisabledCertificateCheckFlow::PathGraph
|
||||
|
||||
from
|
||||
DisabledCertificateCheckFlow::PathNode sourceNode, DisabledCertificateCheckFlow::PathNode sinkNode
|
||||
where DisabledCertificateCheckFlow::flowPath(sourceNode, sinkNode)
|
||||
select sinkNode.getNode(), sourceNode, sinkNode,
|
||||
"Disabling TLS certificate validation can expose the application to man-in-the-middle attacks."
|
||||
@@ -0,0 +1,6 @@
|
||||
// BAD: Disabling certificate validation in Rust
|
||||
|
||||
let _client = reqwest::Client::builder()
|
||||
.danger_accept_invalid_certs(true) // disables certificate validation
|
||||
.build()
|
||||
.unwrap();
|
||||
@@ -0,0 +1,10 @@
|
||||
// GOOD: Certificate validation is enabled (default)
|
||||
|
||||
let _client = reqwest::Client::builder()
|
||||
.danger_accept_invalid_certs(false) // certificate validation enabled explicitly
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let _client = native_tls::TlsConnector::builder() // certificate validation enabled by default
|
||||
.build()
|
||||
.unwrap();
|
||||
@@ -22,11 +22,13 @@ import AccessInvalidPointerFlow::PathGraph
|
||||
* A data flow configuration for accesses to invalid pointers.
|
||||
*/
|
||||
module AccessInvalidPointerConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node node) { node instanceof AccessInvalidPointer::Source }
|
||||
import AccessInvalidPointer
|
||||
|
||||
predicate isSink(DataFlow::Node node) { node instanceof AccessInvalidPointer::Sink }
|
||||
predicate isSource(DataFlow::Node node) { node instanceof Source }
|
||||
|
||||
predicate isBarrier(DataFlow::Node barrier) { barrier instanceof AccessInvalidPointer::Barrier }
|
||||
predicate isSink(DataFlow::Node node) { node instanceof Sink }
|
||||
|
||||
predicate isBarrier(DataFlow::Node barrier) { barrier instanceof Barrier }
|
||||
|
||||
predicate isBarrierOut(DataFlow::Node node) {
|
||||
// make sinks barriers so that we only report the closest instance
|
||||
|
||||
@@ -22,6 +22,7 @@ private import codeql.rust.security.AccessInvalidPointerExtensions
|
||||
private import codeql.rust.security.CleartextLoggingExtensions
|
||||
private import codeql.rust.security.CleartextStorageDatabaseExtensions
|
||||
private import codeql.rust.security.CleartextTransmissionExtensions
|
||||
private import codeql.rust.security.DisabledCertificateCheckExtensions
|
||||
private import codeql.rust.security.HardcodedCryptographicValueExtensions
|
||||
private import codeql.rust.security.InsecureCookieExtensions
|
||||
private import codeql.rust.security.LogInjectionExtensions
|
||||
|
||||
@@ -660,7 +660,7 @@ macro_expansion.rs:
|
||||
# 71| getSegment(): [PathSegment] i32
|
||||
# 71| getIdentifier(): [NameRef] i32
|
||||
# 72| getTailExpr(): [CastExpr] a as ...
|
||||
# 72| getExpr(): [PathExpr,VariableAccess] a
|
||||
# 72| getExpr(): [VariableAccess] a
|
||||
# 72| getPath(): [Path] a
|
||||
# 72| getSegment(): [PathSegment] a
|
||||
# 72| getIdentifier(): [NameRef] a
|
||||
@@ -738,7 +738,7 @@ macro_expansion.rs:
|
||||
# 84| getFunctionBody(): [BlockExpr] { ... }
|
||||
# 84| getStmtList(): [StmtList] StmtList
|
||||
# 84| getTailExpr(): [MatchExpr] match self { ... }
|
||||
# 83| getScrutinee(): [PathExpr,VariableAccess] self
|
||||
# 83| getScrutinee(): [VariableAccess] self
|
||||
# 83| getPath(): [Path] self
|
||||
# 83| getSegment(): [PathSegment] self
|
||||
# 83| getIdentifier(): [NameRef] self
|
||||
@@ -751,7 +751,7 @@ macro_expansion.rs:
|
||||
# 85| getArgList(): [ArgList] ArgList
|
||||
# 83| getArg(0): [StringLiteralExpr] "field"
|
||||
# 85| getArg(1): [RefExpr] &field
|
||||
# 85| getExpr(): [PathExpr,VariableAccess] field
|
||||
# 85| getExpr(): [VariableAccess] field
|
||||
# 85| getPath(): [Path] field
|
||||
# 85| getSegment(): [PathSegment] field
|
||||
# 85| getIdentifier(): [NameRef] field
|
||||
@@ -760,7 +760,7 @@ macro_expansion.rs:
|
||||
# 83| getArgList(): [ArgList] ArgList
|
||||
# 83| getArg(0): [StringLiteralExpr] "MyDerive"
|
||||
# 83| getIdentifier(): [NameRef] debug_struct
|
||||
# 83| getReceiver(): [PathExpr,VariableAccess] f
|
||||
# 83| getReceiver(): [VariableAccess] f
|
||||
# 83| getPath(): [Path] f
|
||||
# 83| getSegment(): [PathSegment] f
|
||||
# 83| getIdentifier(): [NameRef] f
|
||||
@@ -836,11 +836,11 @@ macro_expansion.rs:
|
||||
# 89| getStmtList(): [StmtList] StmtList
|
||||
# 89| getTailExpr(): [MatchExpr] match ... { ... }
|
||||
# 88| getScrutinee(): [TupleExpr] TupleExpr
|
||||
# 88| getField(0): [PathExpr,VariableAccess] self
|
||||
# 88| getField(0): [VariableAccess] self
|
||||
# 88| getPath(): [Path] self
|
||||
# 88| getSegment(): [PathSegment] self
|
||||
# 88| getIdentifier(): [NameRef] self
|
||||
# 88| getField(1): [PathExpr,VariableAccess] other
|
||||
# 88| getField(1): [VariableAccess] other
|
||||
# 88| getPath(): [Path] other
|
||||
# 88| getSegment(): [PathSegment] other
|
||||
# 88| getIdentifier(): [NameRef] other
|
||||
@@ -1076,7 +1076,7 @@ proc_macro.rs:
|
||||
# 6| getMacroCallExpansion(): [MatchExpr] match ... { ... }
|
||||
# 6| getScrutinee(): [CallExpr] ...::parse::<...>(...)
|
||||
# 6| getArgList(): [ArgList] ArgList
|
||||
# 6| getArg(0): [PathExpr,VariableAccess] attr
|
||||
# 6| getArg(0): [VariableAccess] attr
|
||||
# 6| getPath(): [Path] attr
|
||||
# 6| getSegment(): [PathSegment] attr
|
||||
# 6| getIdentifier(): [NameRef] attr
|
||||
@@ -1098,7 +1098,7 @@ proc_macro.rs:
|
||||
# 6| getIdentifier(): [NameRef] parse
|
||||
# 6| getMatchArmList(): [MatchArmList] MatchArmList
|
||||
# 6| getArm(0): [MatchArm] ... => data
|
||||
# 6| getExpr(): [PathExpr,VariableAccess] data
|
||||
# 6| getExpr(): [VariableAccess] data
|
||||
# 6| getPath(): [Path] data
|
||||
# 6| getSegment(): [PathSegment] data
|
||||
# 6| getIdentifier(): [NameRef] data
|
||||
@@ -1124,7 +1124,7 @@ proc_macro.rs:
|
||||
# 6| getArg(0): [MethodCallExpr] err.to_compile_error()
|
||||
# 6| getArgList(): [ArgList] ArgList
|
||||
# 6| getIdentifier(): [NameRef] to_compile_error
|
||||
# 6| getReceiver(): [PathExpr,VariableAccess] err
|
||||
# 6| getReceiver(): [VariableAccess] err
|
||||
# 6| getPath(): [Path] err
|
||||
# 6| getSegment(): [PathSegment] err
|
||||
# 6| getIdentifier(): [NameRef] err
|
||||
@@ -1168,7 +1168,7 @@ proc_macro.rs:
|
||||
# 7| getMacroCallExpansion(): [MatchExpr] match ... { ... }
|
||||
# 7| getScrutinee(): [CallExpr] ...::parse::<...>(...)
|
||||
# 7| getArgList(): [ArgList] ArgList
|
||||
# 7| getArg(0): [PathExpr,VariableAccess] item
|
||||
# 7| getArg(0): [VariableAccess] item
|
||||
# 7| getPath(): [Path] item
|
||||
# 7| getSegment(): [PathSegment] item
|
||||
# 7| getIdentifier(): [NameRef] item
|
||||
@@ -1190,7 +1190,7 @@ proc_macro.rs:
|
||||
# 7| getIdentifier(): [NameRef] parse
|
||||
# 7| getMatchArmList(): [MatchArmList] MatchArmList
|
||||
# 7| getArm(0): [MatchArm] ... => data
|
||||
# 7| getExpr(): [PathExpr,VariableAccess] data
|
||||
# 7| getExpr(): [VariableAccess] data
|
||||
# 7| getPath(): [Path] data
|
||||
# 7| getSegment(): [PathSegment] data
|
||||
# 7| getIdentifier(): [NameRef] data
|
||||
@@ -1216,7 +1216,7 @@ proc_macro.rs:
|
||||
# 7| getArg(0): [MethodCallExpr] err.to_compile_error()
|
||||
# 7| getArgList(): [ArgList] ArgList
|
||||
# 7| getIdentifier(): [NameRef] to_compile_error
|
||||
# 7| getReceiver(): [PathExpr,VariableAccess] err
|
||||
# 7| getReceiver(): [VariableAccess] err
|
||||
# 7| getPath(): [Path] err
|
||||
# 7| getSegment(): [PathSegment] err
|
||||
# 7| getIdentifier(): [NameRef] err
|
||||
@@ -1273,7 +1273,7 @@ proc_macro.rs:
|
||||
# 10| getInitializer(): [MethodCallExpr] ast.clone()
|
||||
# 10| getArgList(): [ArgList] ArgList
|
||||
# 10| getIdentifier(): [NameRef] clone
|
||||
# 10| getReceiver(): [PathExpr,VariableAccess] ast
|
||||
# 10| getReceiver(): [VariableAccess] ast
|
||||
# 10| getPath(): [Path] ast
|
||||
# 10| getSegment(): [PathSegment] ast
|
||||
# 10| getIdentifier(): [NameRef] ast
|
||||
@@ -1283,7 +1283,7 @@ proc_macro.rs:
|
||||
# 11| getExpr(): [AssignmentExpr] ... = ...
|
||||
# 11| getLhs(): [FieldExpr] ... .ident
|
||||
# 11| getContainer(): [FieldExpr] new_ast.sig
|
||||
# 11| getContainer(): [PathExpr,VariableAccess] new_ast
|
||||
# 11| getContainer(): [VariableAccess] new_ast
|
||||
# 11| getPath(): [Path] new_ast
|
||||
# 11| getSegment(): [PathSegment] new_ast
|
||||
# 11| getIdentifier(): [NameRef] new_ast
|
||||
@@ -1320,14 +1320,14 @@ proc_macro.rs:
|
||||
# 11| getArg(0): [FormatArgsArg] FormatArgsArg
|
||||
# 11| getExpr(): [FieldExpr] ... .ident
|
||||
# 11| getContainer(): [FieldExpr] ast.sig
|
||||
# 11| getContainer(): [PathExpr,VariableAccess] ast
|
||||
# 11| getContainer(): [VariableAccess] ast
|
||||
# 11| getPath(): [Path] ast
|
||||
# 11| getSegment(): [PathSegment] ast
|
||||
# 11| getIdentifier(): [NameRef] ast
|
||||
# 11| getIdentifier(): [NameRef] sig
|
||||
# 11| getIdentifier(): [NameRef] ident
|
||||
# 11| getArg(1): [FormatArgsArg] FormatArgsArg
|
||||
# 11| getExpr(): [PathExpr,VariableAccess] i
|
||||
# 11| getExpr(): [VariableAccess] i
|
||||
# 11| getPath(): [Path] i
|
||||
# 11| getSegment(): [PathSegment] i
|
||||
# 11| getIdentifier(): [NameRef] i
|
||||
@@ -1359,7 +1359,7 @@ proc_macro.rs:
|
||||
# 11| getIdentifier(): [NameRef] span
|
||||
# 11| getReceiver(): [FieldExpr] ... .ident
|
||||
# 11| getContainer(): [FieldExpr] ast.sig
|
||||
# 11| getContainer(): [PathExpr,VariableAccess] ast
|
||||
# 11| getContainer(): [VariableAccess] ast
|
||||
# 11| getPath(): [Path] ast
|
||||
# 11| getSegment(): [PathSegment] ast
|
||||
# 11| getIdentifier(): [NameRef] ast
|
||||
@@ -1375,14 +1375,14 @@ proc_macro.rs:
|
||||
# 11| getIdentifier(): [NameRef] Ident
|
||||
# 11| getSegment(): [PathSegment] new
|
||||
# 11| getIdentifier(): [NameRef] new
|
||||
# 12| getTailExpr(): [PathExpr,VariableAccess] new_ast
|
||||
# 12| getTailExpr(): [VariableAccess] new_ast
|
||||
# 12| getPath(): [Path] new_ast
|
||||
# 12| getSegment(): [PathSegment] new_ast
|
||||
# 12| getIdentifier(): [NameRef] new_ast
|
||||
# 9| getIdentifier(): [NameRef] map
|
||||
# 8| getReceiver(): [ParenExpr] (...)
|
||||
# 8| getExpr(): [RangeExpr] 0..number
|
||||
# 8| getEnd(): [PathExpr,VariableAccess] number
|
||||
# 8| getEnd(): [VariableAccess] number
|
||||
# 8| getPath(): [Path] number
|
||||
# 8| getSegment(): [PathSegment] number
|
||||
# 8| getIdentifier(): [NameRef] number
|
||||
@@ -1614,7 +1614,7 @@ proc_macro.rs:
|
||||
# 16| getInitializer(): [MethodCallExpr] items.quote_into_iter()
|
||||
# 15| getArgList(): [ArgList] ArgList
|
||||
# 15| getIdentifier(): [NameRef] quote_into_iter
|
||||
# 16| getReceiver(): [PathExpr,VariableAccess] items
|
||||
# 16| getReceiver(): [VariableAccess] items
|
||||
# 16| getPath(): [Path] items
|
||||
# 16| getSegment(): [PathSegment] items
|
||||
# 16| getIdentifier(): [NameRef] items
|
||||
@@ -1625,11 +1625,11 @@ proc_macro.rs:
|
||||
# 15| getName(): [Name] i
|
||||
# 15| getStatement(1): [LetStmt] let ... = ...
|
||||
# 15| getInitializer(): [BinaryExpr] ... | ...
|
||||
# 15| getLhs(): [PathExpr,VariableAccess] has_iter
|
||||
# 15| getLhs(): [VariableAccess] has_iter
|
||||
# 15| getPath(): [Path] has_iter
|
||||
# 15| getSegment(): [PathSegment] has_iter
|
||||
# 15| getIdentifier(): [NameRef] has_iter
|
||||
# 15| getRhs(): [PathExpr,VariableAccess] i
|
||||
# 15| getRhs(): [VariableAccess] i
|
||||
# 15| getPath(): [Path] i
|
||||
# 15| getSegment(): [PathSegment] i
|
||||
# 15| getIdentifier(): [NameRef] i
|
||||
@@ -1646,7 +1646,7 @@ proc_macro.rs:
|
||||
# 16| getTokenTree(): [TokenTree] TokenTree
|
||||
# 15| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
|
||||
# 15| getStatement(3): [LetStmt] let _ = has_iter
|
||||
# 15| getInitializer(): [PathExpr,VariableAccess] has_iter
|
||||
# 15| getInitializer(): [VariableAccess] has_iter
|
||||
# 15| getPath(): [Path] has_iter
|
||||
# 15| getSegment(): [PathSegment] has_iter
|
||||
# 15| getIdentifier(): [NameRef] has_iter
|
||||
@@ -1764,7 +1764,7 @@ proc_macro.rs:
|
||||
# 16| getScrutinee(): [MethodCallExpr] items.next()
|
||||
# 15| getArgList(): [ArgList] ArgList
|
||||
# 15| getIdentifier(): [NameRef] next
|
||||
# 16| getReceiver(): [PathExpr,VariableAccess] items
|
||||
# 16| getReceiver(): [VariableAccess] items
|
||||
# 16| getPath(): [Path] items
|
||||
# 16| getSegment(): [PathSegment] items
|
||||
# 16| getIdentifier(): [NameRef] items
|
||||
@@ -1772,7 +1772,7 @@ proc_macro.rs:
|
||||
# 15| getArm(0): [MatchArm] ... => ...
|
||||
# 15| getExpr(): [CallExpr] ...::RepInterp(...)
|
||||
# 15| getArgList(): [ArgList] ArgList
|
||||
# 15| getArg(0): [PathExpr] _x
|
||||
# 15| getArg(0): [VariableAccess] _x
|
||||
# 15| getPath(): [Path] _x
|
||||
# 15| getSegment(): [PathSegment] _x
|
||||
# 15| getIdentifier(): [NameRef] _x
|
||||
@@ -1876,12 +1876,12 @@ proc_macro.rs:
|
||||
# 16| getExpr(): [CallExpr] ...::to_tokens(...)
|
||||
# 16| getArgList(): [ArgList] ArgList
|
||||
# 16| getArg(0): [RefExpr] &items
|
||||
# 16| getExpr(): [PathExpr,VariableAccess] items
|
||||
# 16| getExpr(): [VariableAccess] items
|
||||
# 16| getPath(): [Path] items
|
||||
# 16| getSegment(): [PathSegment] items
|
||||
# 16| getIdentifier(): [NameRef] items
|
||||
# 15| getArg(1): [RefExpr] &mut _s
|
||||
# 15| getExpr(): [PathExpr] _s
|
||||
# 15| getExpr(): [VariableAccess] _s
|
||||
# 15| getPath(): [Path] _s
|
||||
# 15| getSegment(): [PathSegment] _s
|
||||
# 15| getIdentifier(): [NameRef] _s
|
||||
@@ -1993,7 +1993,7 @@ proc_macro.rs:
|
||||
# 15| getIdentifier(): [NameRef] quote_token_with_context
|
||||
# 16| getTokenTree(): [TokenTree] TokenTree
|
||||
# 15| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
|
||||
# 15| getTailExpr(): [PathExpr] _s
|
||||
# 15| getTailExpr(): [VariableAccess] _s
|
||||
# 15| getPath(): [Path] _s
|
||||
# 15| getSegment(): [PathSegment] _s
|
||||
# 15| getIdentifier(): [NameRef] _s
|
||||
@@ -2040,7 +2040,7 @@ proc_macro.rs:
|
||||
# 22| getMacroCallExpansion(): [MatchExpr] match ... { ... }
|
||||
# 22| getScrutinee(): [CallExpr] ...::parse::<...>(...)
|
||||
# 22| getArgList(): [ArgList] ArgList
|
||||
# 22| getArg(0): [PathExpr,VariableAccess] item
|
||||
# 22| getArg(0): [VariableAccess] item
|
||||
# 22| getPath(): [Path] item
|
||||
# 22| getSegment(): [PathSegment] item
|
||||
# 22| getIdentifier(): [NameRef] item
|
||||
@@ -2062,7 +2062,7 @@ proc_macro.rs:
|
||||
# 22| getIdentifier(): [NameRef] parse
|
||||
# 22| getMatchArmList(): [MatchArmList] MatchArmList
|
||||
# 22| getArm(0): [MatchArm] ... => data
|
||||
# 22| getExpr(): [PathExpr,VariableAccess] data
|
||||
# 22| getExpr(): [VariableAccess] data
|
||||
# 22| getPath(): [Path] data
|
||||
# 22| getSegment(): [PathSegment] data
|
||||
# 22| getIdentifier(): [NameRef] data
|
||||
@@ -2088,7 +2088,7 @@ proc_macro.rs:
|
||||
# 22| getArg(0): [MethodCallExpr] err.to_compile_error()
|
||||
# 22| getArgList(): [ArgList] ArgList
|
||||
# 22| getIdentifier(): [NameRef] to_compile_error
|
||||
# 22| getReceiver(): [PathExpr,VariableAccess] err
|
||||
# 22| getReceiver(): [VariableAccess] err
|
||||
# 22| getPath(): [Path] err
|
||||
# 22| getSegment(): [PathSegment] err
|
||||
# 22| getIdentifier(): [NameRef] err
|
||||
@@ -2123,7 +2123,7 @@ proc_macro.rs:
|
||||
# 23| getInitializer(): [MethodCallExpr] ast.clone()
|
||||
# 23| getArgList(): [ArgList] ArgList
|
||||
# 23| getIdentifier(): [NameRef] clone
|
||||
# 23| getReceiver(): [PathExpr,VariableAccess] ast
|
||||
# 23| getReceiver(): [VariableAccess] ast
|
||||
# 23| getPath(): [Path] ast
|
||||
# 23| getSegment(): [PathSegment] ast
|
||||
# 23| getIdentifier(): [NameRef] ast
|
||||
@@ -2133,7 +2133,7 @@ proc_macro.rs:
|
||||
# 24| getExpr(): [AssignmentExpr] ... = ...
|
||||
# 24| getLhs(): [FieldExpr] ... .ident
|
||||
# 24| getContainer(): [FieldExpr] new_ast.sig
|
||||
# 24| getContainer(): [PathExpr,VariableAccess] new_ast
|
||||
# 24| getContainer(): [VariableAccess] new_ast
|
||||
# 24| getPath(): [Path] new_ast
|
||||
# 24| getSegment(): [PathSegment] new_ast
|
||||
# 24| getIdentifier(): [NameRef] new_ast
|
||||
@@ -2170,7 +2170,7 @@ proc_macro.rs:
|
||||
# 24| getArg(0): [FormatArgsArg] FormatArgsArg
|
||||
# 24| getExpr(): [FieldExpr] ... .ident
|
||||
# 24| getContainer(): [FieldExpr] ast.sig
|
||||
# 24| getContainer(): [PathExpr,VariableAccess] ast
|
||||
# 24| getContainer(): [VariableAccess] ast
|
||||
# 24| getPath(): [Path] ast
|
||||
# 24| getSegment(): [PathSegment] ast
|
||||
# 24| getIdentifier(): [NameRef] ast
|
||||
@@ -2203,7 +2203,7 @@ proc_macro.rs:
|
||||
# 24| getIdentifier(): [NameRef] span
|
||||
# 24| getReceiver(): [FieldExpr] ... .ident
|
||||
# 24| getContainer(): [FieldExpr] ast.sig
|
||||
# 24| getContainer(): [PathExpr,VariableAccess] ast
|
||||
# 24| getContainer(): [VariableAccess] ast
|
||||
# 24| getPath(): [Path] ast
|
||||
# 24| getSegment(): [PathSegment] ast
|
||||
# 24| getIdentifier(): [NameRef] ast
|
||||
@@ -2317,12 +2317,12 @@ proc_macro.rs:
|
||||
# 26| getExpr(): [CallExpr] ...::to_tokens(...)
|
||||
# 26| getArgList(): [ArgList] ArgList
|
||||
# 26| getArg(0): [RefExpr] &ast
|
||||
# 26| getExpr(): [PathExpr,VariableAccess] ast
|
||||
# 26| getExpr(): [VariableAccess] ast
|
||||
# 26| getPath(): [Path] ast
|
||||
# 26| getSegment(): [PathSegment] ast
|
||||
# 26| getIdentifier(): [NameRef] ast
|
||||
# 25| getArg(1): [RefExpr] &mut _s
|
||||
# 25| getExpr(): [PathExpr] _s
|
||||
# 25| getExpr(): [VariableAccess] _s
|
||||
# 25| getPath(): [Path] _s
|
||||
# 25| getSegment(): [PathSegment] _s
|
||||
# 25| getIdentifier(): [NameRef] _s
|
||||
@@ -2362,12 +2362,12 @@ proc_macro.rs:
|
||||
# 27| getExpr(): [CallExpr] ...::to_tokens(...)
|
||||
# 27| getArgList(): [ArgList] ArgList
|
||||
# 27| getArg(0): [RefExpr] &new_ast
|
||||
# 27| getExpr(): [PathExpr,VariableAccess] new_ast
|
||||
# 27| getExpr(): [VariableAccess] new_ast
|
||||
# 27| getPath(): [Path] new_ast
|
||||
# 27| getSegment(): [PathSegment] new_ast
|
||||
# 27| getIdentifier(): [NameRef] new_ast
|
||||
# 25| getArg(1): [RefExpr] &mut _s
|
||||
# 25| getExpr(): [PathExpr] _s
|
||||
# 25| getExpr(): [VariableAccess] _s
|
||||
# 25| getPath(): [Path] _s
|
||||
# 25| getSegment(): [PathSegment] _s
|
||||
# 25| getIdentifier(): [NameRef] _s
|
||||
@@ -2424,7 +2424,7 @@ proc_macro.rs:
|
||||
# 25| getIdentifier(): [NameRef] quote_token_with_context
|
||||
# 27| getTokenTree(): [TokenTree] TokenTree
|
||||
# 25| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
|
||||
# 25| getTailExpr(): [PathExpr] _s
|
||||
# 25| getTailExpr(): [VariableAccess] _s
|
||||
# 25| getPath(): [Path] _s
|
||||
# 25| getSegment(): [PathSegment] _s
|
||||
# 25| getIdentifier(): [NameRef] _s
|
||||
@@ -2504,7 +2504,7 @@ proc_macro.rs:
|
||||
# 38| getMacroCallExpansion(): [MatchExpr] match ... { ... }
|
||||
# 38| getScrutinee(): [CallExpr] ...::parse::<...>(...)
|
||||
# 38| getArgList(): [ArgList] ArgList
|
||||
# 38| getArg(0): [PathExpr,VariableAccess] input
|
||||
# 38| getArg(0): [VariableAccess] input
|
||||
# 38| getPath(): [Path] input
|
||||
# 38| getSegment(): [PathSegment] input
|
||||
# 38| getIdentifier(): [NameRef] input
|
||||
@@ -2526,7 +2526,7 @@ proc_macro.rs:
|
||||
# 38| getIdentifier(): [NameRef] parse
|
||||
# 38| getMatchArmList(): [MatchArmList] MatchArmList
|
||||
# 38| getArm(0): [MatchArm] ... => data
|
||||
# 38| getExpr(): [PathExpr,VariableAccess] data
|
||||
# 38| getExpr(): [VariableAccess] data
|
||||
# 38| getPath(): [Path] data
|
||||
# 38| getSegment(): [PathSegment] data
|
||||
# 38| getIdentifier(): [NameRef] data
|
||||
@@ -2552,7 +2552,7 @@ proc_macro.rs:
|
||||
# 38| getArg(0): [MethodCallExpr] err.to_compile_error()
|
||||
# 38| getArgList(): [ArgList] ArgList
|
||||
# 38| getIdentifier(): [NameRef] to_compile_error
|
||||
# 38| getReceiver(): [PathExpr,VariableAccess] err
|
||||
# 38| getReceiver(): [VariableAccess] err
|
||||
# 38| getPath(): [Path] err
|
||||
# 38| getSegment(): [PathSegment] err
|
||||
# 38| getIdentifier(): [NameRef] err
|
||||
@@ -2586,7 +2586,7 @@ proc_macro.rs:
|
||||
# 39| getStatement(1): [LetStmt] let ... = ...
|
||||
# 39| getInitializer(): [RefExpr] &...
|
||||
# 39| getExpr(): [FieldExpr] ast.ident
|
||||
# 39| getContainer(): [PathExpr,VariableAccess] ast
|
||||
# 39| getContainer(): [VariableAccess] ast
|
||||
# 39| getPath(): [Path] ast
|
||||
# 39| getSegment(): [PathSegment] ast
|
||||
# 39| getIdentifier(): [NameRef] ast
|
||||
@@ -2623,7 +2623,7 @@ proc_macro.rs:
|
||||
# 40| getTokenTree(): [TokenTree] TokenTree
|
||||
# 40| getMacroCallExpansion(): [FormatArgsExpr] FormatArgsExpr
|
||||
# 40| getArg(0): [FormatArgsArg] FormatArgsArg
|
||||
# 40| getExpr(): [PathExpr,VariableAccess] name
|
||||
# 40| getExpr(): [VariableAccess] name
|
||||
# 40| getPath(): [Path] name
|
||||
# 40| getSegment(): [PathSegment] name
|
||||
# 40| getIdentifier(): [NameRef] name
|
||||
@@ -2652,7 +2652,7 @@ proc_macro.rs:
|
||||
# 40| getArg(1): [MethodCallExpr] name.span()
|
||||
# 40| getArgList(): [ArgList] ArgList
|
||||
# 40| getIdentifier(): [NameRef] span
|
||||
# 40| getReceiver(): [PathExpr,VariableAccess] name
|
||||
# 40| getReceiver(): [VariableAccess] name
|
||||
# 40| getPath(): [Path] name
|
||||
# 40| getSegment(): [PathSegment] name
|
||||
# 40| getIdentifier(): [NameRef] name
|
||||
@@ -2776,7 +2776,7 @@ proc_macro.rs:
|
||||
# 42| getExpr(): [CallExpr] ...::push_ident(...)
|
||||
# 42| getArgList(): [ArgList] ArgList
|
||||
# 41| getArg(0): [RefExpr] &mut _s
|
||||
# 41| getExpr(): [PathExpr] _s
|
||||
# 41| getExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -2812,12 +2812,12 @@ proc_macro.rs:
|
||||
# 42| getExpr(): [CallExpr] ...::to_tokens(...)
|
||||
# 42| getArgList(): [ArgList] ArgList
|
||||
# 42| getArg(0): [RefExpr] &const_ident
|
||||
# 42| getExpr(): [PathExpr,VariableAccess] const_ident
|
||||
# 42| getExpr(): [VariableAccess] const_ident
|
||||
# 42| getPath(): [Path] const_ident
|
||||
# 42| getSegment(): [PathSegment] const_ident
|
||||
# 42| getIdentifier(): [NameRef] const_ident
|
||||
# 41| getArg(1): [RefExpr] &mut _s
|
||||
# 41| getExpr(): [PathExpr] _s
|
||||
# 41| getExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -2867,7 +2867,7 @@ proc_macro.rs:
|
||||
# 41| getExpr(): [CallExpr] ...::push_colon(...)
|
||||
# 41| getArgList(): [ArgList] ArgList
|
||||
# 41| getArg(0): [RefExpr] &mut _s
|
||||
# 41| getExpr(): [PathExpr] _s
|
||||
# 41| getExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -2906,7 +2906,7 @@ proc_macro.rs:
|
||||
# 42| getExpr(): [CallExpr] ...::push_ident(...)
|
||||
# 42| getArgList(): [ArgList] ArgList
|
||||
# 41| getArg(0): [RefExpr] &mut _s
|
||||
# 41| getExpr(): [PathExpr] _s
|
||||
# 41| getExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -2952,7 +2952,7 @@ proc_macro.rs:
|
||||
# 41| getExpr(): [CallExpr] ...::push_eq(...)
|
||||
# 41| getArgList(): [ArgList] ArgList
|
||||
# 41| getArg(0): [RefExpr] &mut _s
|
||||
# 41| getExpr(): [PathExpr] _s
|
||||
# 41| getExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -2991,7 +2991,7 @@ proc_macro.rs:
|
||||
# 42| getExpr(): [CallExpr] ...::parse(...)
|
||||
# 42| getArgList(): [ArgList] ArgList
|
||||
# 41| getArg(0): [RefExpr] &mut _s
|
||||
# 41| getExpr(): [PathExpr] _s
|
||||
# 41| getExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -3037,7 +3037,7 @@ proc_macro.rs:
|
||||
# 41| getExpr(): [CallExpr] ...::push_semi(...)
|
||||
# 41| getArgList(): [ArgList] ArgList
|
||||
# 41| getArg(0): [RefExpr] &mut _s
|
||||
# 41| getExpr(): [PathExpr] _s
|
||||
# 41| getExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -3076,7 +3076,7 @@ proc_macro.rs:
|
||||
# 44| getExpr(): [CallExpr] ...::push_ident(...)
|
||||
# 44| getArgList(): [ArgList] ArgList
|
||||
# 41| getArg(0): [RefExpr] &mut _s
|
||||
# 41| getExpr(): [PathExpr] _s
|
||||
# 41| getExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -3122,7 +3122,7 @@ proc_macro.rs:
|
||||
# 44| getExpr(): [CallExpr] ...::push_ident(...)
|
||||
# 44| getArgList(): [ArgList] ArgList
|
||||
# 41| getArg(0): [RefExpr] &mut _s
|
||||
# 41| getExpr(): [PathExpr] _s
|
||||
# 41| getExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -3168,7 +3168,7 @@ proc_macro.rs:
|
||||
# 44| getExpr(): [CallExpr] ...::push_ident(...)
|
||||
# 44| getArgList(): [ArgList] ArgList
|
||||
# 41| getArg(0): [RefExpr] &mut _s
|
||||
# 41| getExpr(): [PathExpr] _s
|
||||
# 41| getExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -3204,12 +3204,12 @@ proc_macro.rs:
|
||||
# 44| getExpr(): [CallExpr] ...::to_tokens(...)
|
||||
# 44| getArgList(): [ArgList] ArgList
|
||||
# 44| getArg(0): [RefExpr] &name
|
||||
# 44| getExpr(): [PathExpr,VariableAccess] name
|
||||
# 44| getExpr(): [VariableAccess] name
|
||||
# 44| getPath(): [Path] name
|
||||
# 44| getSegment(): [PathSegment] name
|
||||
# 44| getIdentifier(): [NameRef] name
|
||||
# 41| getArg(1): [RefExpr] &mut _s
|
||||
# 41| getExpr(): [PathExpr] _s
|
||||
# 41| getExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -3259,7 +3259,7 @@ proc_macro.rs:
|
||||
# 45| getExpr(): [CallExpr] ...::push_group(...)
|
||||
# 45| getArgList(): [ArgList] ArgList
|
||||
# 41| getArg(0): [RefExpr] &mut _s
|
||||
# 41| getExpr(): [PathExpr] _s
|
||||
# 41| getExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -3384,7 +3384,7 @@ proc_macro.rs:
|
||||
# 45| getExpr(): [CallExpr] ...::push_ident(...)
|
||||
# 45| getArgList(): [ArgList] ArgList
|
||||
# 41| getArg(0): [RefExpr] &mut _s
|
||||
# 41| getExpr(): [PathExpr] _s
|
||||
# 41| getExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -3430,7 +3430,7 @@ proc_macro.rs:
|
||||
# 45| getExpr(): [CallExpr] ...::push_ident(...)
|
||||
# 45| getArgList(): [ArgList] ArgList
|
||||
# 41| getArg(0): [RefExpr] &mut _s
|
||||
# 41| getExpr(): [PathExpr] _s
|
||||
# 41| getExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -3476,7 +3476,7 @@ proc_macro.rs:
|
||||
# 41| getExpr(): [CallExpr] ...::push_group(...)
|
||||
# 41| getArgList(): [ArgList] ArgList
|
||||
# 41| getArg(0): [RefExpr] &mut _s
|
||||
# 41| getExpr(): [PathExpr] _s
|
||||
# 41| getExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -3552,7 +3552,7 @@ proc_macro.rs:
|
||||
# 41| getExpr(): [CallExpr] ...::push_rarrow(...)
|
||||
# 41| getArgList(): [ArgList] ArgList
|
||||
# 41| getArg(0): [RefExpr] &mut _s
|
||||
# 41| getExpr(): [PathExpr] _s
|
||||
# 41| getExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -3591,7 +3591,7 @@ proc_macro.rs:
|
||||
# 45| getExpr(): [CallExpr] ...::push_ident(...)
|
||||
# 45| getArgList(): [ArgList] ArgList
|
||||
# 41| getArg(0): [RefExpr] &mut _s
|
||||
# 41| getExpr(): [PathExpr] _s
|
||||
# 41| getExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -3637,7 +3637,7 @@ proc_macro.rs:
|
||||
# 46| getExpr(): [CallExpr] ...::push_group(...)
|
||||
# 46| getArgList(): [ArgList] ArgList
|
||||
# 41| getArg(0): [RefExpr] &mut _s
|
||||
# 41| getExpr(): [PathExpr] _s
|
||||
# 41| getExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -3687,12 +3687,12 @@ proc_macro.rs:
|
||||
# 46| getExpr(): [CallExpr] ...::to_tokens(...)
|
||||
# 46| getArgList(): [ArgList] ArgList
|
||||
# 46| getArg(0): [RefExpr] &const_ident
|
||||
# 46| getExpr(): [PathExpr,VariableAccess] const_ident
|
||||
# 46| getExpr(): [VariableAccess] const_ident
|
||||
# 46| getPath(): [Path] const_ident
|
||||
# 46| getSegment(): [PathSegment] const_ident
|
||||
# 46| getIdentifier(): [NameRef] const_ident
|
||||
# 41| getArg(1): [RefExpr] &mut _s
|
||||
# 41| getExpr(): [PathExpr] _s
|
||||
# 41| getExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -3706,7 +3706,7 @@ proc_macro.rs:
|
||||
# 41| getIdentifier(): [NameRef] ToTokens
|
||||
# 41| getSegment(): [PathSegment] to_tokens
|
||||
# 41| getIdentifier(): [NameRef] to_tokens
|
||||
# 41| getTailExpr(): [PathExpr] _s
|
||||
# 41| getTailExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -3752,7 +3752,7 @@ proc_macro.rs:
|
||||
# 41| getIdentifier(): [NameRef] quote_token_with_context
|
||||
# 45| getTokenTree(): [TokenTree] TokenTree
|
||||
# 41| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
|
||||
# 41| getTailExpr(): [PathExpr] _s
|
||||
# 41| getTailExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
@@ -3798,7 +3798,7 @@ proc_macro.rs:
|
||||
# 41| getIdentifier(): [NameRef] quote_token_with_context
|
||||
# 44| getTokenTree(): [TokenTree] TokenTree
|
||||
# 41| getMacroCallExpansion(): [MacroBlockExpr] MacroBlockExpr
|
||||
# 41| getTailExpr(): [PathExpr] _s
|
||||
# 41| getTailExpr(): [VariableAccess] _s
|
||||
# 41| getPath(): [Path] _s
|
||||
# 41| getSegment(): [PathSegment] _s
|
||||
# 41| getIdentifier(): [NameRef] _s
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
| test.rs:17:31:17:38 | ...::read | Flow source 'FileSource' of type file (DEFAULT). |
|
||||
| test.rs:22:22:22:39 | ...::read_to_string | Flow source 'FileSource' of type file (DEFAULT). |
|
||||
| test.rs:22:22:22:39 | ...::read_to_string | Flow source 'FileSource' of type file (DEFAULT). |
|
||||
| test.rs:26:18:26:29 | ...::read_dir | Flow source 'FileSource' of type file (DEFAULT). |
|
||||
| test.rs:29:22:29:25 | path | Flow source 'FileSource' of type file (DEFAULT). |
|
||||
| test.rs:43:27:43:35 | file_name | Flow source 'FileSource' of type file (DEFAULT). |
|
||||
| test.rs:51:52:51:59 | read_dir | Flow source 'FileSource' of type file (DEFAULT). |
|
||||
| test.rs:54:22:54:25 | path | Flow source 'FileSource' of type file (DEFAULT). |
|
||||
| test.rs:55:27:55:35 | file_name | Flow source 'FileSource' of type file (DEFAULT). |
|
||||
| test.rs:65:22:65:34 | ...::read_link | Flow source 'FileSource' of type file (DEFAULT). |
|
||||
|
||||
@@ -23,7 +23,7 @@ fn test_fs() -> Result<(), Box<dyn std::error::Error>> {
|
||||
sink(buffer); // $ hasTaintFlow="file.txt"
|
||||
}
|
||||
|
||||
for entry in fs::read_dir("directory")? {
|
||||
for entry in fs::read_dir("directory")? { // $ Alert[rust/summary/taint-sources]
|
||||
let e = entry?;
|
||||
|
||||
let path = e.path(); // $ Alert[rust/summary/taint-sources]
|
||||
@@ -48,7 +48,7 @@ fn test_fs() -> Result<(), Box<dyn std::error::Error>> {
|
||||
sink(file_name.clone().as_encoded_bytes()); // $ MISSING: hasTaintFlow
|
||||
sink(file_name); // $ hasTaintFlow
|
||||
}
|
||||
for entry in std::path::Path::new("directory").read_dir()? {
|
||||
for entry in std::path::Path::new("directory").read_dir()? { // $ Alert[rust/summary/taint-sources]
|
||||
let e = entry?;
|
||||
|
||||
let path = e.path(); // $ Alert[rust/summary/taint-sources]
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
| struct Array | |
|
||||
| struct Ptr | |
|
||||
| struct PtrMut | |
|
||||
| struct Ref | |
|
||||
| struct RefMut | |
|
||||
| struct Slice | |
|
||||
| struct Tuple0 | |
|
||||
| struct Tuple1 | |
|
||||
|
||||
@@ -790,6 +790,49 @@ mod impl_with_attribute_macro {
|
||||
} // impl_with_attribute_macro::test
|
||||
}
|
||||
|
||||
mod patterns {
|
||||
#[rustfmt::skip]
|
||||
pub fn test() -> Option<i32> { // $ item=Option $ item=i32
|
||||
let x = Some(42); // $ item=Some
|
||||
let y : Option<i32> = match x { // $ item=Option $ item=i32
|
||||
Some(y) => { // $ item=Some
|
||||
None // $ item=None
|
||||
}
|
||||
None => // $ item=None
|
||||
None // $ item=None
|
||||
};
|
||||
match y {
|
||||
N0ne => // local variable
|
||||
N0ne
|
||||
}
|
||||
} // patterns::test
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn test2() -> Option<i32> { // $ item=Option $ item=i32
|
||||
let test_alias = test; // $ item=patterns::test
|
||||
let test = test_alias();
|
||||
test
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
const z: i32 // $ item=i32
|
||||
= 0; // constz
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn test3() {
|
||||
let x = Some(0); // $ item=Some
|
||||
match x {
|
||||
Some(x) // $ item=Some
|
||||
=> x,
|
||||
_ => 0
|
||||
};
|
||||
match x {
|
||||
Some(z) => z, // $ item=Some item=constz
|
||||
_ => 0
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
my::nested::nested1::nested2::f(); // $ item=I4
|
||||
my::f(); // $ item=I38
|
||||
@@ -826,4 +869,5 @@ fn main() {
|
||||
AStruct::z_on_type(); // $ item=I124
|
||||
AStruct {}.z_on_instance(); // $ item=I123 item=I125
|
||||
impl_with_attribute_macro::test(); // $ item=impl_with_attribute_macro::test
|
||||
patterns::test(); // $ item=patterns::test
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ mod
|
||||
| main.rs:629:1:697:1 | mod m24 |
|
||||
| main.rs:714:1:766:1 | mod associated_types |
|
||||
| main.rs:772:1:791:1 | mod impl_with_attribute_macro |
|
||||
| main.rs:793:1:834:1 | mod patterns |
|
||||
| my2/mod.rs:1:1:1:16 | mod nested2 |
|
||||
| my2/mod.rs:20:1:20:12 | mod my3 |
|
||||
| my2/mod.rs:22:1:23:10 | mod mymod |
|
||||
@@ -72,7 +73,7 @@ resolvePath
|
||||
| main.rs:37:17:37:24 | ...::f | main.rs:26:9:28:9 | fn f |
|
||||
| main.rs:39:17:39:23 | println | {EXTERNAL LOCATION} | MacroRules |
|
||||
| main.rs:40:17:40:17 | f | main.rs:26:9:28:9 | fn f |
|
||||
| main.rs:47:9:47:13 | super | main.rs:1:1:829:2 | SourceFile |
|
||||
| main.rs:47:9:47:13 | super | main.rs:1:1:873:2 | SourceFile |
|
||||
| main.rs:47:9:47:17 | ...::m1 | main.rs:20:1:44:1 | mod m1 |
|
||||
| main.rs:47:9:47:21 | ...::m2 | main.rs:25:5:43:5 | mod m2 |
|
||||
| main.rs:47:9:47:24 | ...::g | main.rs:30:9:34:9 | fn g |
|
||||
@@ -87,7 +88,7 @@ resolvePath
|
||||
| main.rs:68:17:68:19 | Foo | main.rs:66:9:66:21 | struct Foo |
|
||||
| main.rs:71:13:71:15 | Foo | main.rs:60:5:60:17 | struct Foo |
|
||||
| main.rs:73:5:73:5 | f | main.rs:62:5:69:5 | fn f |
|
||||
| main.rs:75:5:75:8 | self | main.rs:1:1:829:2 | SourceFile |
|
||||
| main.rs:75:5:75:8 | self | main.rs:1:1:873:2 | SourceFile |
|
||||
| main.rs:75:5:75:11 | ...::i | main.rs:78:1:90:1 | fn i |
|
||||
| main.rs:79:5:79:11 | println | {EXTERNAL LOCATION} | MacroRules |
|
||||
| main.rs:81:13:81:15 | Foo | main.rs:55:1:55:13 | struct Foo |
|
||||
@@ -109,7 +110,7 @@ resolvePath
|
||||
| main.rs:112:9:112:15 | println | {EXTERNAL LOCATION} | MacroRules |
|
||||
| main.rs:118:9:118:15 | println | {EXTERNAL LOCATION} | MacroRules |
|
||||
| main.rs:122:9:122:15 | println | {EXTERNAL LOCATION} | MacroRules |
|
||||
| main.rs:125:13:125:17 | super | main.rs:1:1:829:2 | SourceFile |
|
||||
| main.rs:125:13:125:17 | super | main.rs:1:1:873:2 | SourceFile |
|
||||
| main.rs:125:13:125:21 | ...::m5 | main.rs:110:1:114:1 | mod m5 |
|
||||
| main.rs:126:9:126:9 | f | main.rs:111:5:113:5 | fn f |
|
||||
| main.rs:126:9:126:9 | f | main.rs:117:5:119:5 | fn f |
|
||||
@@ -397,77 +398,97 @@ resolvePath
|
||||
| main.rs:781:21:781:23 | i64 | {EXTERNAL LOCATION} | struct i64 |
|
||||
| main.rs:783:11:783:13 | i64 | {EXTERNAL LOCATION} | struct i64 |
|
||||
| main.rs:789:17:789:19 | Foo | main.rs:774:5:774:15 | struct Foo |
|
||||
| main.rs:794:5:794:6 | my | main.rs:1:1:1:7 | mod my |
|
||||
| main.rs:794:5:794:14 | ...::nested | my.rs:1:1:1:15 | mod nested |
|
||||
| main.rs:794:5:794:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 |
|
||||
| main.rs:794:5:794:32 | ...::nested2 | my/nested.rs:2:5:11:5 | mod nested2 |
|
||||
| main.rs:794:5:794:35 | ...::f | my/nested.rs:3:9:5:9 | fn f |
|
||||
| main.rs:795:5:795:6 | my | main.rs:1:1:1:7 | mod my |
|
||||
| main.rs:795:5:795:9 | ...::f | my.rs:5:1:7:1 | fn f |
|
||||
| main.rs:796:5:796:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 |
|
||||
| main.rs:796:5:796:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 |
|
||||
| main.rs:796:5:796:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 |
|
||||
| main.rs:796:5:796:32 | ...::f | my2/nested2.rs:3:9:5:9 | fn f |
|
||||
| main.rs:797:5:797:5 | f | my2/nested2.rs:3:9:5:9 | fn f |
|
||||
| main.rs:798:5:798:5 | g | my2/nested2.rs:7:9:9:9 | fn g |
|
||||
| main.rs:799:5:799:9 | crate | main.rs:0:0:0:0 | Crate(main@0.0.1) |
|
||||
| main.rs:799:5:799:12 | ...::h | main.rs:57:1:76:1 | fn h |
|
||||
| main.rs:800:5:800:6 | m1 | main.rs:20:1:44:1 | mod m1 |
|
||||
| main.rs:800:5:800:10 | ...::m2 | main.rs:25:5:43:5 | mod m2 |
|
||||
| main.rs:800:5:800:13 | ...::g | main.rs:30:9:34:9 | fn g |
|
||||
| main.rs:801:5:801:6 | m1 | main.rs:20:1:44:1 | mod m1 |
|
||||
| main.rs:801:5:801:10 | ...::m2 | main.rs:25:5:43:5 | mod m2 |
|
||||
| main.rs:801:5:801:14 | ...::m3 | main.rs:36:9:42:9 | mod m3 |
|
||||
| main.rs:801:5:801:17 | ...::h | main.rs:37:27:41:13 | fn h |
|
||||
| main.rs:802:5:802:6 | m4 | main.rs:46:1:53:1 | mod m4 |
|
||||
| main.rs:802:5:802:9 | ...::i | main.rs:49:5:52:5 | fn i |
|
||||
| main.rs:803:5:803:5 | h | main.rs:57:1:76:1 | fn h |
|
||||
| main.rs:804:5:804:11 | f_alias | my2/nested2.rs:3:9:5:9 | fn f |
|
||||
| main.rs:805:5:805:11 | g_alias | my2/nested2.rs:7:9:9:9 | fn g |
|
||||
| main.rs:806:5:806:5 | j | main.rs:104:1:108:1 | fn j |
|
||||
| main.rs:807:5:807:6 | m6 | main.rs:116:1:128:1 | mod m6 |
|
||||
| main.rs:807:5:807:9 | ...::g | main.rs:121:5:127:5 | fn g |
|
||||
| main.rs:808:5:808:6 | m7 | main.rs:130:1:149:1 | mod m7 |
|
||||
| main.rs:808:5:808:9 | ...::f | main.rs:141:5:148:5 | fn f |
|
||||
| main.rs:809:5:809:6 | m8 | main.rs:151:1:205:1 | mod m8 |
|
||||
| main.rs:809:5:809:9 | ...::g | main.rs:189:5:204:5 | fn g |
|
||||
| main.rs:810:5:810:6 | m9 | main.rs:207:1:215:1 | mod m9 |
|
||||
| main.rs:810:5:810:9 | ...::f | main.rs:210:5:214:5 | fn f |
|
||||
| main.rs:811:5:811:7 | m11 | main.rs:238:1:275:1 | mod m11 |
|
||||
| main.rs:811:5:811:10 | ...::f | main.rs:243:5:246:5 | fn f |
|
||||
| main.rs:812:5:812:7 | m15 | main.rs:306:1:375:1 | mod m15 |
|
||||
| main.rs:812:5:812:10 | ...::f | main.rs:362:5:374:5 | fn f |
|
||||
| main.rs:813:5:813:7 | m16 | main.rs:377:1:469:1 | mod m16 |
|
||||
| main.rs:813:5:813:10 | ...::f | main.rs:444:5:468:5 | fn f |
|
||||
| main.rs:814:5:814:20 | trait_visibility | main.rs:471:1:521:1 | mod trait_visibility |
|
||||
| main.rs:814:5:814:23 | ...::f | main.rs:498:5:520:5 | fn f |
|
||||
| main.rs:815:5:815:7 | m17 | main.rs:523:1:553:1 | mod m17 |
|
||||
| main.rs:815:5:815:10 | ...::f | main.rs:547:5:552:5 | fn f |
|
||||
| main.rs:816:5:816:11 | nested6 | my2/nested2.rs:14:5:18:5 | mod nested6 |
|
||||
| main.rs:816:5:816:14 | ...::f | my2/nested2.rs:15:9:17:9 | fn f |
|
||||
| main.rs:817:5:817:11 | nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 |
|
||||
| main.rs:817:5:817:14 | ...::f | my2/nested2.rs:23:9:25:9 | fn f |
|
||||
| main.rs:818:5:818:7 | my3 | my2/mod.rs:20:1:20:12 | mod my3 |
|
||||
| main.rs:818:5:818:10 | ...::f | my2/my3/mod.rs:1:1:5:1 | fn f |
|
||||
| main.rs:819:5:819:12 | nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f |
|
||||
| main.rs:820:5:820:12 | my_alias | main.rs:1:1:1:7 | mod my |
|
||||
| main.rs:820:5:820:22 | ...::nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f |
|
||||
| main.rs:821:5:821:7 | m18 | main.rs:555:1:573:1 | mod m18 |
|
||||
| main.rs:821:5:821:12 | ...::m19 | main.rs:560:5:572:5 | mod m19 |
|
||||
| main.rs:821:5:821:17 | ...::m20 | main.rs:565:9:571:9 | mod m20 |
|
||||
| main.rs:821:5:821:20 | ...::g | main.rs:566:13:570:13 | fn g |
|
||||
| main.rs:822:5:822:7 | m23 | main.rs:602:1:627:1 | mod m23 |
|
||||
| main.rs:822:5:822:10 | ...::f | main.rs:622:5:626:5 | fn f |
|
||||
| main.rs:823:5:823:7 | m24 | main.rs:629:1:697:1 | mod m24 |
|
||||
| main.rs:823:5:823:10 | ...::f | main.rs:683:5:696:5 | fn f |
|
||||
| main.rs:824:5:824:8 | zelf | main.rs:0:0:0:0 | Crate(main@0.0.1) |
|
||||
| main.rs:824:5:824:11 | ...::h | main.rs:57:1:76:1 | fn h |
|
||||
| main.rs:825:5:825:13 | z_changed | main.rs:702:1:702:9 | fn z_changed |
|
||||
| main.rs:826:5:826:11 | AStruct | main.rs:704:1:704:17 | struct AStruct |
|
||||
| main.rs:826:5:826:22 | ...::z_on_type | main.rs:708:5:708:17 | fn z_on_type |
|
||||
| main.rs:827:5:827:11 | AStruct | main.rs:704:1:704:17 | struct AStruct |
|
||||
| main.rs:828:5:828:29 | impl_with_attribute_macro | main.rs:772:1:791:1 | mod impl_with_attribute_macro |
|
||||
| main.rs:828:5:828:35 | ...::test | main.rs:787:5:790:5 | fn test |
|
||||
| main.rs:795:22:795:32 | Option::<...> | {EXTERNAL LOCATION} | enum Option |
|
||||
| main.rs:795:29:795:31 | i32 | {EXTERNAL LOCATION} | struct i32 |
|
||||
| main.rs:796:17:796:20 | Some | {EXTERNAL LOCATION} | Some |
|
||||
| main.rs:797:17:797:27 | Option::<...> | {EXTERNAL LOCATION} | enum Option |
|
||||
| main.rs:797:24:797:26 | i32 | {EXTERNAL LOCATION} | struct i32 |
|
||||
| main.rs:798:13:798:16 | Some | {EXTERNAL LOCATION} | Some |
|
||||
| main.rs:799:17:799:20 | None | {EXTERNAL LOCATION} | None |
|
||||
| main.rs:801:13:801:16 | None | {EXTERNAL LOCATION} | None |
|
||||
| main.rs:802:17:802:20 | None | {EXTERNAL LOCATION} | None |
|
||||
| main.rs:811:19:811:29 | Option::<...> | {EXTERNAL LOCATION} | enum Option |
|
||||
| main.rs:811:26:811:28 | i32 | {EXTERNAL LOCATION} | struct i32 |
|
||||
| main.rs:812:26:812:29 | test | main.rs:794:5:808:5 | fn test |
|
||||
| main.rs:818:14:818:16 | i32 | {EXTERNAL LOCATION} | struct i32 |
|
||||
| main.rs:823:17:823:20 | Some | {EXTERNAL LOCATION} | Some |
|
||||
| main.rs:825:13:825:16 | Some | {EXTERNAL LOCATION} | Some |
|
||||
| main.rs:830:13:830:16 | Some | {EXTERNAL LOCATION} | Some |
|
||||
| main.rs:830:18:830:18 | z | main.rs:817:5:819:12 | Const |
|
||||
| main.rs:830:24:830:24 | z | main.rs:817:5:819:12 | Const |
|
||||
| main.rs:837:5:837:6 | my | main.rs:1:1:1:7 | mod my |
|
||||
| main.rs:837:5:837:14 | ...::nested | my.rs:1:1:1:15 | mod nested |
|
||||
| main.rs:837:5:837:23 | ...::nested1 | my/nested.rs:1:1:17:1 | mod nested1 |
|
||||
| main.rs:837:5:837:32 | ...::nested2 | my/nested.rs:2:5:11:5 | mod nested2 |
|
||||
| main.rs:837:5:837:35 | ...::f | my/nested.rs:3:9:5:9 | fn f |
|
||||
| main.rs:838:5:838:6 | my | main.rs:1:1:1:7 | mod my |
|
||||
| main.rs:838:5:838:9 | ...::f | my.rs:5:1:7:1 | fn f |
|
||||
| main.rs:839:5:839:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 |
|
||||
| main.rs:839:5:839:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 |
|
||||
| main.rs:839:5:839:29 | ...::nested4 | my2/nested2.rs:2:5:10:5 | mod nested4 |
|
||||
| main.rs:839:5:839:32 | ...::f | my2/nested2.rs:3:9:5:9 | fn f |
|
||||
| main.rs:840:5:840:5 | f | my2/nested2.rs:3:9:5:9 | fn f |
|
||||
| main.rs:841:5:841:5 | g | my2/nested2.rs:7:9:9:9 | fn g |
|
||||
| main.rs:842:5:842:9 | crate | main.rs:0:0:0:0 | Crate(main@0.0.1) |
|
||||
| main.rs:842:5:842:12 | ...::h | main.rs:57:1:76:1 | fn h |
|
||||
| main.rs:843:5:843:6 | m1 | main.rs:20:1:44:1 | mod m1 |
|
||||
| main.rs:843:5:843:10 | ...::m2 | main.rs:25:5:43:5 | mod m2 |
|
||||
| main.rs:843:5:843:13 | ...::g | main.rs:30:9:34:9 | fn g |
|
||||
| main.rs:844:5:844:6 | m1 | main.rs:20:1:44:1 | mod m1 |
|
||||
| main.rs:844:5:844:10 | ...::m2 | main.rs:25:5:43:5 | mod m2 |
|
||||
| main.rs:844:5:844:14 | ...::m3 | main.rs:36:9:42:9 | mod m3 |
|
||||
| main.rs:844:5:844:17 | ...::h | main.rs:37:27:41:13 | fn h |
|
||||
| main.rs:845:5:845:6 | m4 | main.rs:46:1:53:1 | mod m4 |
|
||||
| main.rs:845:5:845:9 | ...::i | main.rs:49:5:52:5 | fn i |
|
||||
| main.rs:846:5:846:5 | h | main.rs:57:1:76:1 | fn h |
|
||||
| main.rs:847:5:847:11 | f_alias | my2/nested2.rs:3:9:5:9 | fn f |
|
||||
| main.rs:848:5:848:11 | g_alias | my2/nested2.rs:7:9:9:9 | fn g |
|
||||
| main.rs:849:5:849:5 | j | main.rs:104:1:108:1 | fn j |
|
||||
| main.rs:850:5:850:6 | m6 | main.rs:116:1:128:1 | mod m6 |
|
||||
| main.rs:850:5:850:9 | ...::g | main.rs:121:5:127:5 | fn g |
|
||||
| main.rs:851:5:851:6 | m7 | main.rs:130:1:149:1 | mod m7 |
|
||||
| main.rs:851:5:851:9 | ...::f | main.rs:141:5:148:5 | fn f |
|
||||
| main.rs:852:5:852:6 | m8 | main.rs:151:1:205:1 | mod m8 |
|
||||
| main.rs:852:5:852:9 | ...::g | main.rs:189:5:204:5 | fn g |
|
||||
| main.rs:853:5:853:6 | m9 | main.rs:207:1:215:1 | mod m9 |
|
||||
| main.rs:853:5:853:9 | ...::f | main.rs:210:5:214:5 | fn f |
|
||||
| main.rs:854:5:854:7 | m11 | main.rs:238:1:275:1 | mod m11 |
|
||||
| main.rs:854:5:854:10 | ...::f | main.rs:243:5:246:5 | fn f |
|
||||
| main.rs:855:5:855:7 | m15 | main.rs:306:1:375:1 | mod m15 |
|
||||
| main.rs:855:5:855:10 | ...::f | main.rs:362:5:374:5 | fn f |
|
||||
| main.rs:856:5:856:7 | m16 | main.rs:377:1:469:1 | mod m16 |
|
||||
| main.rs:856:5:856:10 | ...::f | main.rs:444:5:468:5 | fn f |
|
||||
| main.rs:857:5:857:20 | trait_visibility | main.rs:471:1:521:1 | mod trait_visibility |
|
||||
| main.rs:857:5:857:23 | ...::f | main.rs:498:5:520:5 | fn f |
|
||||
| main.rs:858:5:858:7 | m17 | main.rs:523:1:553:1 | mod m17 |
|
||||
| main.rs:858:5:858:10 | ...::f | main.rs:547:5:552:5 | fn f |
|
||||
| main.rs:859:5:859:11 | nested6 | my2/nested2.rs:14:5:18:5 | mod nested6 |
|
||||
| main.rs:859:5:859:14 | ...::f | my2/nested2.rs:15:9:17:9 | fn f |
|
||||
| main.rs:860:5:860:11 | nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 |
|
||||
| main.rs:860:5:860:14 | ...::f | my2/nested2.rs:23:9:25:9 | fn f |
|
||||
| main.rs:861:5:861:7 | my3 | my2/mod.rs:20:1:20:12 | mod my3 |
|
||||
| main.rs:861:5:861:10 | ...::f | my2/my3/mod.rs:1:1:5:1 | fn f |
|
||||
| main.rs:862:5:862:12 | nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f |
|
||||
| main.rs:863:5:863:12 | my_alias | main.rs:1:1:1:7 | mod my |
|
||||
| main.rs:863:5:863:22 | ...::nested_f | my/my4/my5/mod.rs:1:1:3:1 | fn f |
|
||||
| main.rs:864:5:864:7 | m18 | main.rs:555:1:573:1 | mod m18 |
|
||||
| main.rs:864:5:864:12 | ...::m19 | main.rs:560:5:572:5 | mod m19 |
|
||||
| main.rs:864:5:864:17 | ...::m20 | main.rs:565:9:571:9 | mod m20 |
|
||||
| main.rs:864:5:864:20 | ...::g | main.rs:566:13:570:13 | fn g |
|
||||
| main.rs:865:5:865:7 | m23 | main.rs:602:1:627:1 | mod m23 |
|
||||
| main.rs:865:5:865:10 | ...::f | main.rs:622:5:626:5 | fn f |
|
||||
| main.rs:866:5:866:7 | m24 | main.rs:629:1:697:1 | mod m24 |
|
||||
| main.rs:866:5:866:10 | ...::f | main.rs:683:5:696:5 | fn f |
|
||||
| main.rs:867:5:867:8 | zelf | main.rs:0:0:0:0 | Crate(main@0.0.1) |
|
||||
| main.rs:867:5:867:11 | ...::h | main.rs:57:1:76:1 | fn h |
|
||||
| main.rs:868:5:868:13 | z_changed | main.rs:702:1:702:9 | fn z_changed |
|
||||
| main.rs:869:5:869:11 | AStruct | main.rs:704:1:704:17 | struct AStruct |
|
||||
| main.rs:869:5:869:22 | ...::z_on_type | main.rs:708:5:708:17 | fn z_on_type |
|
||||
| main.rs:870:5:870:11 | AStruct | main.rs:704:1:704:17 | struct AStruct |
|
||||
| main.rs:871:5:871:29 | impl_with_attribute_macro | main.rs:772:1:791:1 | mod impl_with_attribute_macro |
|
||||
| main.rs:871:5:871:35 | ...::test | main.rs:787:5:790:5 | fn test |
|
||||
| main.rs:872:5:872:12 | patterns | main.rs:793:1:834:1 | mod patterns |
|
||||
| main.rs:872:5:872:18 | ...::test | main.rs:794:5:808:5 | fn test |
|
||||
| my2/mod.rs:4:5:4:11 | println | {EXTERNAL LOCATION} | MacroRules |
|
||||
| my2/mod.rs:5:5:5:11 | nested2 | my2/mod.rs:1:1:1:16 | mod nested2 |
|
||||
| my2/mod.rs:5:5:5:20 | ...::nested3 | my2/nested2.rs:1:1:11:1 | mod nested3 |
|
||||
@@ -493,7 +514,7 @@ resolvePath
|
||||
| my2/my3/mod.rs:3:5:3:5 | g | my2/mod.rs:3:1:6:1 | fn g |
|
||||
| my2/my3/mod.rs:4:5:4:5 | h | main.rs:57:1:76:1 | fn h |
|
||||
| my2/my3/mod.rs:7:5:7:9 | super | my2/mod.rs:1:1:25:34 | SourceFile |
|
||||
| my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:829:2 | SourceFile |
|
||||
| my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:873:2 | SourceFile |
|
||||
| my2/my3/mod.rs:7:5:7:19 | ...::h | main.rs:57:1:76:1 | fn h |
|
||||
| my2/my3/mod.rs:8:5:8:9 | super | my2/mod.rs:1:1:25:34 | SourceFile |
|
||||
| my2/my3/mod.rs:8:5:8:12 | ...::g | my2/mod.rs:3:1:6:1 | fn g |
|
||||
|
||||
@@ -5,7 +5,7 @@ import TestUtils
|
||||
|
||||
query predicate mod(Module m) { toBeTested(m) }
|
||||
|
||||
query predicate resolvePath(Path p, ItemNode i) {
|
||||
query predicate resolvePath(PathExt p, ItemNode i) {
|
||||
toBeTested(p) and
|
||||
not p.isFromMacroExpansion() and
|
||||
i = resolvePath(p)
|
||||
|
||||
@@ -1798,145 +1798,216 @@ edges
|
||||
| main.rs:753:5:753:16 | print_i64(...) | main.rs:744:18:754:1 | { ... } | |
|
||||
| main.rs:753:5:753:17 | ExprStmt | main.rs:753:5:753:13 | print_i64 | |
|
||||
| main.rs:753:15:753:15 | x | main.rs:753:5:753:16 | print_i64(...) | |
|
||||
| main.rs:756:1:800:1 | enter fn main | main.rs:757:5:757:25 | ExprStmt | |
|
||||
| main.rs:756:1:800:1 | exit fn main (normal) | main.rs:756:1:800:1 | exit fn main | |
|
||||
| main.rs:756:11:800:1 | { ... } | main.rs:756:1:800:1 | exit fn main (normal) | |
|
||||
| main.rs:757:5:757:22 | immutable_variable | main.rs:757:5:757:24 | immutable_variable(...) | |
|
||||
| main.rs:757:5:757:24 | immutable_variable(...) | main.rs:758:5:758:23 | ExprStmt | |
|
||||
| main.rs:757:5:757:25 | ExprStmt | main.rs:757:5:757:22 | immutable_variable | |
|
||||
| main.rs:758:5:758:20 | mutable_variable | main.rs:758:5:758:22 | mutable_variable(...) | |
|
||||
| main.rs:758:5:758:22 | mutable_variable(...) | main.rs:759:5:759:40 | ExprStmt | |
|
||||
| main.rs:758:5:758:23 | ExprStmt | main.rs:758:5:758:20 | mutable_variable | |
|
||||
| main.rs:759:5:759:37 | mutable_variable_immutable_borrow | main.rs:759:5:759:39 | mutable_variable_immutable_borrow(...) | |
|
||||
| main.rs:759:5:759:39 | mutable_variable_immutable_borrow(...) | main.rs:760:5:760:23 | ExprStmt | |
|
||||
| main.rs:759:5:759:40 | ExprStmt | main.rs:759:5:759:37 | mutable_variable_immutable_borrow | |
|
||||
| main.rs:760:5:760:20 | variable_shadow1 | main.rs:760:5:760:22 | variable_shadow1(...) | |
|
||||
| main.rs:760:5:760:22 | variable_shadow1(...) | main.rs:761:5:761:23 | ExprStmt | |
|
||||
| main.rs:760:5:760:23 | ExprStmt | main.rs:760:5:760:20 | variable_shadow1 | |
|
||||
| main.rs:761:5:761:20 | variable_shadow2 | main.rs:761:5:761:22 | variable_shadow2(...) | |
|
||||
| main.rs:761:5:761:22 | variable_shadow2(...) | main.rs:762:5:762:19 | ExprStmt | |
|
||||
| main.rs:761:5:761:23 | ExprStmt | main.rs:761:5:761:20 | variable_shadow2 | |
|
||||
| main.rs:762:5:762:16 | let_pattern1 | main.rs:762:5:762:18 | let_pattern1(...) | |
|
||||
| main.rs:762:5:762:18 | let_pattern1(...) | main.rs:763:5:763:19 | ExprStmt | |
|
||||
| main.rs:762:5:762:19 | ExprStmt | main.rs:762:5:762:16 | let_pattern1 | |
|
||||
| main.rs:763:5:763:16 | let_pattern2 | main.rs:763:5:763:18 | let_pattern2(...) | |
|
||||
| main.rs:763:5:763:18 | let_pattern2(...) | main.rs:764:5:764:19 | ExprStmt | |
|
||||
| main.rs:763:5:763:19 | ExprStmt | main.rs:763:5:763:16 | let_pattern2 | |
|
||||
| main.rs:764:5:764:16 | let_pattern3 | main.rs:764:5:764:18 | let_pattern3(...) | |
|
||||
| main.rs:764:5:764:18 | let_pattern3(...) | main.rs:765:5:765:19 | ExprStmt | |
|
||||
| main.rs:764:5:764:19 | ExprStmt | main.rs:764:5:764:16 | let_pattern3 | |
|
||||
| main.rs:765:5:765:16 | let_pattern4 | main.rs:765:5:765:18 | let_pattern4(...) | |
|
||||
| main.rs:765:5:765:18 | let_pattern4(...) | main.rs:766:5:766:21 | ExprStmt | |
|
||||
| main.rs:765:5:765:19 | ExprStmt | main.rs:765:5:765:16 | let_pattern4 | |
|
||||
| main.rs:766:5:766:18 | match_pattern1 | main.rs:766:5:766:20 | match_pattern1(...) | |
|
||||
| main.rs:766:5:766:20 | match_pattern1(...) | main.rs:767:5:767:21 | ExprStmt | |
|
||||
| main.rs:766:5:766:21 | ExprStmt | main.rs:766:5:766:18 | match_pattern1 | |
|
||||
| main.rs:767:5:767:18 | match_pattern2 | main.rs:767:5:767:20 | match_pattern2(...) | |
|
||||
| main.rs:767:5:767:20 | match_pattern2(...) | main.rs:768:5:768:21 | ExprStmt | |
|
||||
| main.rs:767:5:767:21 | ExprStmt | main.rs:767:5:767:18 | match_pattern2 | |
|
||||
| main.rs:768:5:768:18 | match_pattern3 | main.rs:768:5:768:20 | match_pattern3(...) | |
|
||||
| main.rs:768:5:768:20 | match_pattern3(...) | main.rs:769:5:769:21 | ExprStmt | |
|
||||
| main.rs:768:5:768:21 | ExprStmt | main.rs:768:5:768:18 | match_pattern3 | |
|
||||
| main.rs:769:5:769:18 | match_pattern4 | main.rs:769:5:769:20 | match_pattern4(...) | |
|
||||
| main.rs:769:5:769:20 | match_pattern4(...) | main.rs:770:5:770:21 | ExprStmt | |
|
||||
| main.rs:769:5:769:21 | ExprStmt | main.rs:769:5:769:18 | match_pattern4 | |
|
||||
| main.rs:770:5:770:18 | match_pattern5 | main.rs:770:5:770:20 | match_pattern5(...) | |
|
||||
| main.rs:770:5:770:20 | match_pattern5(...) | main.rs:771:5:771:21 | ExprStmt | |
|
||||
| main.rs:770:5:770:21 | ExprStmt | main.rs:770:5:770:18 | match_pattern5 | |
|
||||
| main.rs:771:5:771:18 | match_pattern6 | main.rs:771:5:771:20 | match_pattern6(...) | |
|
||||
| main.rs:771:5:771:20 | match_pattern6(...) | main.rs:772:5:772:21 | ExprStmt | |
|
||||
| main.rs:771:5:771:21 | ExprStmt | main.rs:771:5:771:18 | match_pattern6 | |
|
||||
| main.rs:772:5:772:18 | match_pattern7 | main.rs:772:5:772:20 | match_pattern7(...) | |
|
||||
| main.rs:772:5:772:20 | match_pattern7(...) | main.rs:773:5:773:21 | ExprStmt | |
|
||||
| main.rs:772:5:772:21 | ExprStmt | main.rs:772:5:772:18 | match_pattern7 | |
|
||||
| main.rs:773:5:773:18 | match_pattern8 | main.rs:773:5:773:20 | match_pattern8(...) | |
|
||||
| main.rs:773:5:773:20 | match_pattern8(...) | main.rs:774:5:774:21 | ExprStmt | |
|
||||
| main.rs:773:5:773:21 | ExprStmt | main.rs:773:5:773:18 | match_pattern8 | |
|
||||
| main.rs:774:5:774:18 | match_pattern9 | main.rs:774:5:774:20 | match_pattern9(...) | |
|
||||
| main.rs:774:5:774:20 | match_pattern9(...) | main.rs:775:5:775:22 | ExprStmt | |
|
||||
| main.rs:774:5:774:21 | ExprStmt | main.rs:774:5:774:18 | match_pattern9 | |
|
||||
| main.rs:775:5:775:19 | match_pattern10 | main.rs:775:5:775:21 | match_pattern10(...) | |
|
||||
| main.rs:775:5:775:21 | match_pattern10(...) | main.rs:776:5:776:22 | ExprStmt | |
|
||||
| main.rs:775:5:775:22 | ExprStmt | main.rs:775:5:775:19 | match_pattern10 | |
|
||||
| main.rs:776:5:776:19 | match_pattern11 | main.rs:776:5:776:21 | match_pattern11(...) | |
|
||||
| main.rs:776:5:776:21 | match_pattern11(...) | main.rs:777:5:777:22 | ExprStmt | |
|
||||
| main.rs:776:5:776:22 | ExprStmt | main.rs:776:5:776:19 | match_pattern11 | |
|
||||
| main.rs:777:5:777:19 | match_pattern12 | main.rs:777:5:777:21 | match_pattern12(...) | |
|
||||
| main.rs:777:5:777:21 | match_pattern12(...) | main.rs:778:5:778:22 | ExprStmt | |
|
||||
| main.rs:777:5:777:22 | ExprStmt | main.rs:777:5:777:19 | match_pattern12 | |
|
||||
| main.rs:778:5:778:19 | match_pattern13 | main.rs:778:5:778:21 | match_pattern13(...) | |
|
||||
| main.rs:778:5:778:21 | match_pattern13(...) | main.rs:779:5:779:22 | ExprStmt | |
|
||||
| main.rs:778:5:778:22 | ExprStmt | main.rs:778:5:778:19 | match_pattern13 | |
|
||||
| main.rs:779:5:779:19 | match_pattern14 | main.rs:779:5:779:21 | match_pattern14(...) | |
|
||||
| main.rs:779:5:779:21 | match_pattern14(...) | main.rs:780:5:780:22 | ExprStmt | |
|
||||
| main.rs:779:5:779:22 | ExprStmt | main.rs:779:5:779:19 | match_pattern14 | |
|
||||
| main.rs:780:5:780:19 | match_pattern15 | main.rs:780:5:780:21 | match_pattern15(...) | |
|
||||
| main.rs:780:5:780:21 | match_pattern15(...) | main.rs:781:5:781:22 | ExprStmt | |
|
||||
| main.rs:780:5:780:22 | ExprStmt | main.rs:780:5:780:19 | match_pattern15 | |
|
||||
| main.rs:781:5:781:19 | match_pattern16 | main.rs:781:5:781:21 | match_pattern16(...) | |
|
||||
| main.rs:781:5:781:21 | match_pattern16(...) | main.rs:782:5:782:36 | ExprStmt | |
|
||||
| main.rs:781:5:781:22 | ExprStmt | main.rs:781:5:781:19 | match_pattern16 | |
|
||||
| main.rs:782:5:782:18 | param_pattern1 | main.rs:782:20:782:22 | "a" | |
|
||||
| main.rs:782:5:782:35 | param_pattern1(...) | main.rs:783:5:783:37 | ExprStmt | |
|
||||
| main.rs:782:5:782:36 | ExprStmt | main.rs:782:5:782:18 | param_pattern1 | |
|
||||
| main.rs:782:20:782:22 | "a" | main.rs:782:26:782:28 | "b" | |
|
||||
| main.rs:782:25:782:34 | TupleExpr | main.rs:782:5:782:35 | param_pattern1(...) | |
|
||||
| main.rs:782:26:782:28 | "b" | main.rs:782:31:782:33 | "c" | |
|
||||
| main.rs:782:31:782:33 | "c" | main.rs:782:25:782:34 | TupleExpr | |
|
||||
| main.rs:783:5:783:18 | param_pattern2 | main.rs:783:20:783:31 | ...::Left | |
|
||||
| main.rs:783:5:783:36 | param_pattern2(...) | main.rs:784:5:784:26 | ExprStmt | |
|
||||
| main.rs:783:5:783:37 | ExprStmt | main.rs:783:5:783:18 | param_pattern2 | |
|
||||
| main.rs:783:20:783:31 | ...::Left | main.rs:783:33:783:34 | 45 | |
|
||||
| main.rs:783:20:783:35 | ...::Left(...) | main.rs:783:5:783:36 | param_pattern2(...) | |
|
||||
| main.rs:783:33:783:34 | 45 | main.rs:783:20:783:35 | ...::Left(...) | |
|
||||
| main.rs:784:5:784:23 | destruct_assignment | main.rs:784:5:784:25 | destruct_assignment(...) | |
|
||||
| main.rs:784:5:784:25 | destruct_assignment(...) | main.rs:785:5:785:23 | ExprStmt | |
|
||||
| main.rs:784:5:784:26 | ExprStmt | main.rs:784:5:784:23 | destruct_assignment | |
|
||||
| main.rs:785:5:785:20 | closure_variable | main.rs:785:5:785:22 | closure_variable(...) | |
|
||||
| main.rs:785:5:785:22 | closure_variable(...) | main.rs:786:5:786:22 | ExprStmt | |
|
||||
| main.rs:785:5:785:23 | ExprStmt | main.rs:785:5:785:20 | closure_variable | |
|
||||
| main.rs:786:5:786:19 | nested_function | main.rs:786:5:786:21 | nested_function(...) | |
|
||||
| main.rs:786:5:786:21 | nested_function(...) | main.rs:787:5:787:19 | ExprStmt | |
|
||||
| main.rs:786:5:786:22 | ExprStmt | main.rs:786:5:786:19 | nested_function | |
|
||||
| main.rs:787:5:787:16 | for_variable | main.rs:787:5:787:18 | for_variable(...) | |
|
||||
| main.rs:787:5:787:18 | for_variable(...) | main.rs:788:5:788:17 | ExprStmt | |
|
||||
| main.rs:787:5:787:19 | ExprStmt | main.rs:787:5:787:16 | for_variable | |
|
||||
| main.rs:788:5:788:14 | add_assign | main.rs:788:5:788:16 | add_assign(...) | |
|
||||
| main.rs:788:5:788:16 | add_assign(...) | main.rs:789:5:789:13 | ExprStmt | |
|
||||
| main.rs:788:5:788:17 | ExprStmt | main.rs:788:5:788:14 | add_assign | |
|
||||
| main.rs:789:5:789:10 | mutate | main.rs:789:5:789:12 | mutate(...) | |
|
||||
| main.rs:789:5:789:12 | mutate(...) | main.rs:790:5:790:17 | ExprStmt | |
|
||||
| main.rs:789:5:789:13 | ExprStmt | main.rs:789:5:789:10 | mutate | |
|
||||
| main.rs:790:5:790:14 | mutate_arg | main.rs:790:5:790:16 | mutate_arg(...) | |
|
||||
| main.rs:790:5:790:16 | mutate_arg(...) | main.rs:791:5:791:12 | ExprStmt | |
|
||||
| main.rs:790:5:790:17 | ExprStmt | main.rs:790:5:790:14 | mutate_arg | |
|
||||
| main.rs:791:5:791:9 | alias | main.rs:791:5:791:11 | alias(...) | |
|
||||
| main.rs:791:5:791:11 | alias(...) | main.rs:792:5:792:18 | ExprStmt | |
|
||||
| main.rs:791:5:791:12 | ExprStmt | main.rs:791:5:791:9 | alias | |
|
||||
| main.rs:792:5:792:15 | capture_mut | main.rs:792:5:792:17 | capture_mut(...) | |
|
||||
| main.rs:792:5:792:17 | capture_mut(...) | main.rs:793:5:793:20 | ExprStmt | |
|
||||
| main.rs:792:5:792:18 | ExprStmt | main.rs:792:5:792:15 | capture_mut | |
|
||||
| main.rs:793:5:793:17 | capture_immut | main.rs:793:5:793:19 | capture_immut(...) | |
|
||||
| main.rs:793:5:793:19 | capture_immut(...) | main.rs:794:5:794:26 | ExprStmt | |
|
||||
| main.rs:793:5:793:20 | ExprStmt | main.rs:793:5:793:17 | capture_immut | |
|
||||
| main.rs:794:5:794:23 | async_block_capture | main.rs:794:5:794:25 | async_block_capture(...) | |
|
||||
| main.rs:794:5:794:25 | async_block_capture(...) | main.rs:795:5:795:14 | ExprStmt | |
|
||||
| main.rs:794:5:794:26 | ExprStmt | main.rs:794:5:794:23 | async_block_capture | |
|
||||
| main.rs:795:5:795:11 | structs | main.rs:795:5:795:13 | structs(...) | |
|
||||
| main.rs:795:5:795:13 | structs(...) | main.rs:796:5:796:14 | ExprStmt | |
|
||||
| main.rs:795:5:795:14 | ExprStmt | main.rs:795:5:795:11 | structs | |
|
||||
| main.rs:796:5:796:11 | ref_arg | main.rs:796:5:796:13 | ref_arg(...) | |
|
||||
| main.rs:796:5:796:13 | ref_arg(...) | main.rs:797:5:797:30 | ExprStmt | |
|
||||
| main.rs:796:5:796:14 | ExprStmt | main.rs:796:5:796:11 | ref_arg | |
|
||||
| main.rs:797:5:797:27 | ref_methodcall_receiver | main.rs:797:5:797:29 | ref_methodcall_receiver(...) | |
|
||||
| main.rs:797:5:797:29 | ref_methodcall_receiver(...) | main.rs:798:5:798:23 | ExprStmt | |
|
||||
| main.rs:797:5:797:30 | ExprStmt | main.rs:797:5:797:27 | ref_methodcall_receiver | |
|
||||
| main.rs:798:5:798:20 | macro_invocation | main.rs:798:5:798:22 | macro_invocation(...) | |
|
||||
| main.rs:798:5:798:22 | macro_invocation(...) | main.rs:799:5:799:18 | ExprStmt | |
|
||||
| main.rs:798:5:798:23 | ExprStmt | main.rs:798:5:798:20 | macro_invocation | |
|
||||
| main.rs:799:5:799:15 | capture_phi | main.rs:799:5:799:17 | capture_phi(...) | |
|
||||
| main.rs:799:5:799:17 | capture_phi(...) | main.rs:756:11:800:1 | { ... } | |
|
||||
| main.rs:799:5:799:18 | ExprStmt | main.rs:799:5:799:15 | capture_phi | |
|
||||
| main.rs:757:5:772:5 | enter fn test | main.rs:759:9:759:25 | let ... = ... | |
|
||||
| main.rs:757:5:772:5 | exit fn test (normal) | main.rs:757:5:772:5 | exit fn test | |
|
||||
| main.rs:758:34:772:5 | { ... } | main.rs:757:5:772:5 | exit fn test (normal) | |
|
||||
| main.rs:759:9:759:25 | let ... = ... | main.rs:759:17:759:20 | Some | |
|
||||
| main.rs:759:13:759:13 | x | main.rs:759:13:759:13 | x | |
|
||||
| main.rs:759:13:759:13 | x | main.rs:760:9:767:10 | let ... = ... | match |
|
||||
| main.rs:759:17:759:20 | Some | main.rs:759:22:759:23 | 42 | |
|
||||
| main.rs:759:17:759:24 | Some(...) | main.rs:759:13:759:13 | x | |
|
||||
| main.rs:759:22:759:23 | 42 | main.rs:759:17:759:24 | Some(...) | |
|
||||
| main.rs:760:9:767:10 | let ... = ... | main.rs:761:19:761:19 | x | |
|
||||
| main.rs:760:13:760:13 | y | main.rs:760:13:760:13 | y | |
|
||||
| main.rs:760:13:760:13 | y | main.rs:768:15:768:15 | y | match |
|
||||
| main.rs:761:13:767:9 | match x { ... } | main.rs:760:13:760:13 | y | |
|
||||
| main.rs:761:19:761:19 | x | main.rs:762:13:762:19 | Some(...) | |
|
||||
| main.rs:762:13:762:19 | Some(...) | main.rs:762:18:762:18 | y | match |
|
||||
| main.rs:762:13:762:19 | Some(...) | main.rs:765:13:765:16 | None | no-match |
|
||||
| main.rs:762:18:762:18 | y | main.rs:762:18:762:18 | y | |
|
||||
| main.rs:762:18:762:18 | y | main.rs:763:17:763:20 | None | match |
|
||||
| main.rs:762:24:764:13 | { ... } | main.rs:761:13:767:9 | match x { ... } | |
|
||||
| main.rs:763:17:763:20 | None | main.rs:762:24:764:13 | { ... } | |
|
||||
| main.rs:765:13:765:16 | None | main.rs:765:13:765:16 | None | |
|
||||
| main.rs:765:13:765:16 | None | main.rs:766:17:766:20 | None | match |
|
||||
| main.rs:766:17:766:20 | None | main.rs:761:13:767:9 | match x { ... } | |
|
||||
| main.rs:768:9:771:9 | match y { ... } | main.rs:758:34:772:5 | { ... } | |
|
||||
| main.rs:768:15:768:15 | y | main.rs:769:13:769:16 | N0ne | |
|
||||
| main.rs:769:13:769:16 | N0ne | main.rs:769:13:769:16 | N0ne | |
|
||||
| main.rs:769:13:769:16 | N0ne | main.rs:770:17:770:20 | N0ne | match |
|
||||
| main.rs:770:17:770:20 | N0ne | main.rs:768:9:771:9 | match y { ... } | |
|
||||
| main.rs:774:5:781:5 | enter fn test2 | main.rs:776:9:777:17 | let ... = test | |
|
||||
| main.rs:774:5:781:5 | exit fn test2 (normal) | main.rs:774:5:781:5 | exit fn test2 | |
|
||||
| main.rs:775:31:781:5 | { ... } | main.rs:774:5:781:5 | exit fn test2 (normal) | |
|
||||
| main.rs:776:9:777:17 | let ... = test | main.rs:777:13:777:16 | test | |
|
||||
| main.rs:776:13:776:22 | test_alias | main.rs:776:13:776:22 | test_alias | |
|
||||
| main.rs:776:13:776:22 | test_alias | main.rs:778:9:779:25 | let ... = ... | match |
|
||||
| main.rs:777:13:777:16 | test | main.rs:776:13:776:22 | test_alias | |
|
||||
| main.rs:778:9:779:25 | let ... = ... | main.rs:779:13:779:22 | test_alias | |
|
||||
| main.rs:778:13:778:16 | test | main.rs:778:13:778:16 | test | |
|
||||
| main.rs:778:13:778:16 | test | main.rs:780:9:780:12 | test | match |
|
||||
| main.rs:779:13:779:22 | test_alias | main.rs:779:13:779:24 | test_alias(...) | |
|
||||
| main.rs:779:13:779:24 | test_alias(...) | main.rs:778:13:778:16 | test | |
|
||||
| main.rs:780:9:780:12 | test | main.rs:775:31:781:5 | { ... } | |
|
||||
| main.rs:785:5:798:5 | enter fn test3 | main.rs:787:9:787:24 | let ... = ... | |
|
||||
| main.rs:785:5:798:5 | exit fn test3 (normal) | main.rs:785:5:798:5 | exit fn test3 | |
|
||||
| main.rs:786:16:798:5 | { ... } | main.rs:785:5:798:5 | exit fn test3 (normal) | |
|
||||
| main.rs:787:9:787:24 | let ... = ... | main.rs:787:17:787:20 | Some | |
|
||||
| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x | |
|
||||
| main.rs:787:13:787:13 | x | main.rs:788:9:792:10 | ExprStmt | match |
|
||||
| main.rs:787:17:787:20 | Some | main.rs:787:22:787:22 | 0 | |
|
||||
| main.rs:787:17:787:23 | Some(...) | main.rs:787:13:787:13 | x | |
|
||||
| main.rs:787:22:787:22 | 0 | main.rs:787:17:787:23 | Some(...) | |
|
||||
| main.rs:788:9:792:9 | match x { ... } | main.rs:793:9:797:10 | ExprStmt | |
|
||||
| main.rs:788:9:792:10 | ExprStmt | main.rs:788:15:788:15 | x | |
|
||||
| main.rs:788:15:788:15 | x | main.rs:789:13:789:19 | Some(...) | |
|
||||
| main.rs:789:13:789:19 | Some(...) | main.rs:789:18:789:18 | x | match |
|
||||
| main.rs:789:13:789:19 | Some(...) | main.rs:791:13:791:13 | _ | no-match |
|
||||
| main.rs:789:18:789:18 | x | main.rs:789:18:789:18 | x | |
|
||||
| main.rs:789:18:789:18 | x | main.rs:790:20:790:20 | x | match |
|
||||
| main.rs:790:20:790:20 | x | main.rs:788:9:792:9 | match x { ... } | |
|
||||
| main.rs:791:13:791:13 | _ | main.rs:791:18:791:18 | 0 | match |
|
||||
| main.rs:791:18:791:18 | 0 | main.rs:788:9:792:9 | match x { ... } | |
|
||||
| main.rs:793:9:797:9 | match x { ... } | main.rs:786:16:798:5 | { ... } | |
|
||||
| main.rs:793:9:797:10 | ExprStmt | main.rs:793:15:793:15 | x | |
|
||||
| main.rs:793:15:793:15 | x | main.rs:794:13:794:19 | Some(...) | |
|
||||
| main.rs:794:13:794:19 | Some(...) | main.rs:794:18:794:18 | z | match |
|
||||
| main.rs:794:13:794:19 | Some(...) | main.rs:796:13:796:13 | _ | no-match |
|
||||
| main.rs:794:18:794:18 | z | main.rs:794:18:794:18 | z | |
|
||||
| main.rs:794:18:794:18 | z | main.rs:795:17:795:17 | z | match |
|
||||
| main.rs:794:18:794:18 | z | main.rs:796:13:796:13 | _ | no-match |
|
||||
| main.rs:795:17:795:17 | z | main.rs:793:9:797:9 | match x { ... } | |
|
||||
| main.rs:796:13:796:13 | _ | main.rs:796:18:796:18 | 0 | match |
|
||||
| main.rs:796:18:796:18 | 0 | main.rs:793:9:797:9 | match x { ... } | |
|
||||
| main.rs:801:1:845:1 | enter fn main | main.rs:802:5:802:25 | ExprStmt | |
|
||||
| main.rs:801:1:845:1 | exit fn main (normal) | main.rs:801:1:845:1 | exit fn main | |
|
||||
| main.rs:801:11:845:1 | { ... } | main.rs:801:1:845:1 | exit fn main (normal) | |
|
||||
| main.rs:802:5:802:22 | immutable_variable | main.rs:802:5:802:24 | immutable_variable(...) | |
|
||||
| main.rs:802:5:802:24 | immutable_variable(...) | main.rs:803:5:803:23 | ExprStmt | |
|
||||
| main.rs:802:5:802:25 | ExprStmt | main.rs:802:5:802:22 | immutable_variable | |
|
||||
| main.rs:803:5:803:20 | mutable_variable | main.rs:803:5:803:22 | mutable_variable(...) | |
|
||||
| main.rs:803:5:803:22 | mutable_variable(...) | main.rs:804:5:804:40 | ExprStmt | |
|
||||
| main.rs:803:5:803:23 | ExprStmt | main.rs:803:5:803:20 | mutable_variable | |
|
||||
| main.rs:804:5:804:37 | mutable_variable_immutable_borrow | main.rs:804:5:804:39 | mutable_variable_immutable_borrow(...) | |
|
||||
| main.rs:804:5:804:39 | mutable_variable_immutable_borrow(...) | main.rs:805:5:805:23 | ExprStmt | |
|
||||
| main.rs:804:5:804:40 | ExprStmt | main.rs:804:5:804:37 | mutable_variable_immutable_borrow | |
|
||||
| main.rs:805:5:805:20 | variable_shadow1 | main.rs:805:5:805:22 | variable_shadow1(...) | |
|
||||
| main.rs:805:5:805:22 | variable_shadow1(...) | main.rs:806:5:806:23 | ExprStmt | |
|
||||
| main.rs:805:5:805:23 | ExprStmt | main.rs:805:5:805:20 | variable_shadow1 | |
|
||||
| main.rs:806:5:806:20 | variable_shadow2 | main.rs:806:5:806:22 | variable_shadow2(...) | |
|
||||
| main.rs:806:5:806:22 | variable_shadow2(...) | main.rs:807:5:807:19 | ExprStmt | |
|
||||
| main.rs:806:5:806:23 | ExprStmt | main.rs:806:5:806:20 | variable_shadow2 | |
|
||||
| main.rs:807:5:807:16 | let_pattern1 | main.rs:807:5:807:18 | let_pattern1(...) | |
|
||||
| main.rs:807:5:807:18 | let_pattern1(...) | main.rs:808:5:808:19 | ExprStmt | |
|
||||
| main.rs:807:5:807:19 | ExprStmt | main.rs:807:5:807:16 | let_pattern1 | |
|
||||
| main.rs:808:5:808:16 | let_pattern2 | main.rs:808:5:808:18 | let_pattern2(...) | |
|
||||
| main.rs:808:5:808:18 | let_pattern2(...) | main.rs:809:5:809:19 | ExprStmt | |
|
||||
| main.rs:808:5:808:19 | ExprStmt | main.rs:808:5:808:16 | let_pattern2 | |
|
||||
| main.rs:809:5:809:16 | let_pattern3 | main.rs:809:5:809:18 | let_pattern3(...) | |
|
||||
| main.rs:809:5:809:18 | let_pattern3(...) | main.rs:810:5:810:19 | ExprStmt | |
|
||||
| main.rs:809:5:809:19 | ExprStmt | main.rs:809:5:809:16 | let_pattern3 | |
|
||||
| main.rs:810:5:810:16 | let_pattern4 | main.rs:810:5:810:18 | let_pattern4(...) | |
|
||||
| main.rs:810:5:810:18 | let_pattern4(...) | main.rs:811:5:811:21 | ExprStmt | |
|
||||
| main.rs:810:5:810:19 | ExprStmt | main.rs:810:5:810:16 | let_pattern4 | |
|
||||
| main.rs:811:5:811:18 | match_pattern1 | main.rs:811:5:811:20 | match_pattern1(...) | |
|
||||
| main.rs:811:5:811:20 | match_pattern1(...) | main.rs:812:5:812:21 | ExprStmt | |
|
||||
| main.rs:811:5:811:21 | ExprStmt | main.rs:811:5:811:18 | match_pattern1 | |
|
||||
| main.rs:812:5:812:18 | match_pattern2 | main.rs:812:5:812:20 | match_pattern2(...) | |
|
||||
| main.rs:812:5:812:20 | match_pattern2(...) | main.rs:813:5:813:21 | ExprStmt | |
|
||||
| main.rs:812:5:812:21 | ExprStmt | main.rs:812:5:812:18 | match_pattern2 | |
|
||||
| main.rs:813:5:813:18 | match_pattern3 | main.rs:813:5:813:20 | match_pattern3(...) | |
|
||||
| main.rs:813:5:813:20 | match_pattern3(...) | main.rs:814:5:814:21 | ExprStmt | |
|
||||
| main.rs:813:5:813:21 | ExprStmt | main.rs:813:5:813:18 | match_pattern3 | |
|
||||
| main.rs:814:5:814:18 | match_pattern4 | main.rs:814:5:814:20 | match_pattern4(...) | |
|
||||
| main.rs:814:5:814:20 | match_pattern4(...) | main.rs:815:5:815:21 | ExprStmt | |
|
||||
| main.rs:814:5:814:21 | ExprStmt | main.rs:814:5:814:18 | match_pattern4 | |
|
||||
| main.rs:815:5:815:18 | match_pattern5 | main.rs:815:5:815:20 | match_pattern5(...) | |
|
||||
| main.rs:815:5:815:20 | match_pattern5(...) | main.rs:816:5:816:21 | ExprStmt | |
|
||||
| main.rs:815:5:815:21 | ExprStmt | main.rs:815:5:815:18 | match_pattern5 | |
|
||||
| main.rs:816:5:816:18 | match_pattern6 | main.rs:816:5:816:20 | match_pattern6(...) | |
|
||||
| main.rs:816:5:816:20 | match_pattern6(...) | main.rs:817:5:817:21 | ExprStmt | |
|
||||
| main.rs:816:5:816:21 | ExprStmt | main.rs:816:5:816:18 | match_pattern6 | |
|
||||
| main.rs:817:5:817:18 | match_pattern7 | main.rs:817:5:817:20 | match_pattern7(...) | |
|
||||
| main.rs:817:5:817:20 | match_pattern7(...) | main.rs:818:5:818:21 | ExprStmt | |
|
||||
| main.rs:817:5:817:21 | ExprStmt | main.rs:817:5:817:18 | match_pattern7 | |
|
||||
| main.rs:818:5:818:18 | match_pattern8 | main.rs:818:5:818:20 | match_pattern8(...) | |
|
||||
| main.rs:818:5:818:20 | match_pattern8(...) | main.rs:819:5:819:21 | ExprStmt | |
|
||||
| main.rs:818:5:818:21 | ExprStmt | main.rs:818:5:818:18 | match_pattern8 | |
|
||||
| main.rs:819:5:819:18 | match_pattern9 | main.rs:819:5:819:20 | match_pattern9(...) | |
|
||||
| main.rs:819:5:819:20 | match_pattern9(...) | main.rs:820:5:820:22 | ExprStmt | |
|
||||
| main.rs:819:5:819:21 | ExprStmt | main.rs:819:5:819:18 | match_pattern9 | |
|
||||
| main.rs:820:5:820:19 | match_pattern10 | main.rs:820:5:820:21 | match_pattern10(...) | |
|
||||
| main.rs:820:5:820:21 | match_pattern10(...) | main.rs:821:5:821:22 | ExprStmt | |
|
||||
| main.rs:820:5:820:22 | ExprStmt | main.rs:820:5:820:19 | match_pattern10 | |
|
||||
| main.rs:821:5:821:19 | match_pattern11 | main.rs:821:5:821:21 | match_pattern11(...) | |
|
||||
| main.rs:821:5:821:21 | match_pattern11(...) | main.rs:822:5:822:22 | ExprStmt | |
|
||||
| main.rs:821:5:821:22 | ExprStmt | main.rs:821:5:821:19 | match_pattern11 | |
|
||||
| main.rs:822:5:822:19 | match_pattern12 | main.rs:822:5:822:21 | match_pattern12(...) | |
|
||||
| main.rs:822:5:822:21 | match_pattern12(...) | main.rs:823:5:823:22 | ExprStmt | |
|
||||
| main.rs:822:5:822:22 | ExprStmt | main.rs:822:5:822:19 | match_pattern12 | |
|
||||
| main.rs:823:5:823:19 | match_pattern13 | main.rs:823:5:823:21 | match_pattern13(...) | |
|
||||
| main.rs:823:5:823:21 | match_pattern13(...) | main.rs:824:5:824:22 | ExprStmt | |
|
||||
| main.rs:823:5:823:22 | ExprStmt | main.rs:823:5:823:19 | match_pattern13 | |
|
||||
| main.rs:824:5:824:19 | match_pattern14 | main.rs:824:5:824:21 | match_pattern14(...) | |
|
||||
| main.rs:824:5:824:21 | match_pattern14(...) | main.rs:825:5:825:22 | ExprStmt | |
|
||||
| main.rs:824:5:824:22 | ExprStmt | main.rs:824:5:824:19 | match_pattern14 | |
|
||||
| main.rs:825:5:825:19 | match_pattern15 | main.rs:825:5:825:21 | match_pattern15(...) | |
|
||||
| main.rs:825:5:825:21 | match_pattern15(...) | main.rs:826:5:826:22 | ExprStmt | |
|
||||
| main.rs:825:5:825:22 | ExprStmt | main.rs:825:5:825:19 | match_pattern15 | |
|
||||
| main.rs:826:5:826:19 | match_pattern16 | main.rs:826:5:826:21 | match_pattern16(...) | |
|
||||
| main.rs:826:5:826:21 | match_pattern16(...) | main.rs:827:5:827:36 | ExprStmt | |
|
||||
| main.rs:826:5:826:22 | ExprStmt | main.rs:826:5:826:19 | match_pattern16 | |
|
||||
| main.rs:827:5:827:18 | param_pattern1 | main.rs:827:20:827:22 | "a" | |
|
||||
| main.rs:827:5:827:35 | param_pattern1(...) | main.rs:828:5:828:37 | ExprStmt | |
|
||||
| main.rs:827:5:827:36 | ExprStmt | main.rs:827:5:827:18 | param_pattern1 | |
|
||||
| main.rs:827:20:827:22 | "a" | main.rs:827:26:827:28 | "b" | |
|
||||
| main.rs:827:25:827:34 | TupleExpr | main.rs:827:5:827:35 | param_pattern1(...) | |
|
||||
| main.rs:827:26:827:28 | "b" | main.rs:827:31:827:33 | "c" | |
|
||||
| main.rs:827:31:827:33 | "c" | main.rs:827:25:827:34 | TupleExpr | |
|
||||
| main.rs:828:5:828:18 | param_pattern2 | main.rs:828:20:828:31 | ...::Left | |
|
||||
| main.rs:828:5:828:36 | param_pattern2(...) | main.rs:829:5:829:26 | ExprStmt | |
|
||||
| main.rs:828:5:828:37 | ExprStmt | main.rs:828:5:828:18 | param_pattern2 | |
|
||||
| main.rs:828:20:828:31 | ...::Left | main.rs:828:33:828:34 | 45 | |
|
||||
| main.rs:828:20:828:35 | ...::Left(...) | main.rs:828:5:828:36 | param_pattern2(...) | |
|
||||
| main.rs:828:33:828:34 | 45 | main.rs:828:20:828:35 | ...::Left(...) | |
|
||||
| main.rs:829:5:829:23 | destruct_assignment | main.rs:829:5:829:25 | destruct_assignment(...) | |
|
||||
| main.rs:829:5:829:25 | destruct_assignment(...) | main.rs:830:5:830:23 | ExprStmt | |
|
||||
| main.rs:829:5:829:26 | ExprStmt | main.rs:829:5:829:23 | destruct_assignment | |
|
||||
| main.rs:830:5:830:20 | closure_variable | main.rs:830:5:830:22 | closure_variable(...) | |
|
||||
| main.rs:830:5:830:22 | closure_variable(...) | main.rs:831:5:831:22 | ExprStmt | |
|
||||
| main.rs:830:5:830:23 | ExprStmt | main.rs:830:5:830:20 | closure_variable | |
|
||||
| main.rs:831:5:831:19 | nested_function | main.rs:831:5:831:21 | nested_function(...) | |
|
||||
| main.rs:831:5:831:21 | nested_function(...) | main.rs:832:5:832:19 | ExprStmt | |
|
||||
| main.rs:831:5:831:22 | ExprStmt | main.rs:831:5:831:19 | nested_function | |
|
||||
| main.rs:832:5:832:16 | for_variable | main.rs:832:5:832:18 | for_variable(...) | |
|
||||
| main.rs:832:5:832:18 | for_variable(...) | main.rs:833:5:833:17 | ExprStmt | |
|
||||
| main.rs:832:5:832:19 | ExprStmt | main.rs:832:5:832:16 | for_variable | |
|
||||
| main.rs:833:5:833:14 | add_assign | main.rs:833:5:833:16 | add_assign(...) | |
|
||||
| main.rs:833:5:833:16 | add_assign(...) | main.rs:834:5:834:13 | ExprStmt | |
|
||||
| main.rs:833:5:833:17 | ExprStmt | main.rs:833:5:833:14 | add_assign | |
|
||||
| main.rs:834:5:834:10 | mutate | main.rs:834:5:834:12 | mutate(...) | |
|
||||
| main.rs:834:5:834:12 | mutate(...) | main.rs:835:5:835:17 | ExprStmt | |
|
||||
| main.rs:834:5:834:13 | ExprStmt | main.rs:834:5:834:10 | mutate | |
|
||||
| main.rs:835:5:835:14 | mutate_arg | main.rs:835:5:835:16 | mutate_arg(...) | |
|
||||
| main.rs:835:5:835:16 | mutate_arg(...) | main.rs:836:5:836:12 | ExprStmt | |
|
||||
| main.rs:835:5:835:17 | ExprStmt | main.rs:835:5:835:14 | mutate_arg | |
|
||||
| main.rs:836:5:836:9 | alias | main.rs:836:5:836:11 | alias(...) | |
|
||||
| main.rs:836:5:836:11 | alias(...) | main.rs:837:5:837:18 | ExprStmt | |
|
||||
| main.rs:836:5:836:12 | ExprStmt | main.rs:836:5:836:9 | alias | |
|
||||
| main.rs:837:5:837:15 | capture_mut | main.rs:837:5:837:17 | capture_mut(...) | |
|
||||
| main.rs:837:5:837:17 | capture_mut(...) | main.rs:838:5:838:20 | ExprStmt | |
|
||||
| main.rs:837:5:837:18 | ExprStmt | main.rs:837:5:837:15 | capture_mut | |
|
||||
| main.rs:838:5:838:17 | capture_immut | main.rs:838:5:838:19 | capture_immut(...) | |
|
||||
| main.rs:838:5:838:19 | capture_immut(...) | main.rs:839:5:839:26 | ExprStmt | |
|
||||
| main.rs:838:5:838:20 | ExprStmt | main.rs:838:5:838:17 | capture_immut | |
|
||||
| main.rs:839:5:839:23 | async_block_capture | main.rs:839:5:839:25 | async_block_capture(...) | |
|
||||
| main.rs:839:5:839:25 | async_block_capture(...) | main.rs:840:5:840:14 | ExprStmt | |
|
||||
| main.rs:839:5:839:26 | ExprStmt | main.rs:839:5:839:23 | async_block_capture | |
|
||||
| main.rs:840:5:840:11 | structs | main.rs:840:5:840:13 | structs(...) | |
|
||||
| main.rs:840:5:840:13 | structs(...) | main.rs:841:5:841:14 | ExprStmt | |
|
||||
| main.rs:840:5:840:14 | ExprStmt | main.rs:840:5:840:11 | structs | |
|
||||
| main.rs:841:5:841:11 | ref_arg | main.rs:841:5:841:13 | ref_arg(...) | |
|
||||
| main.rs:841:5:841:13 | ref_arg(...) | main.rs:842:5:842:30 | ExprStmt | |
|
||||
| main.rs:841:5:841:14 | ExprStmt | main.rs:841:5:841:11 | ref_arg | |
|
||||
| main.rs:842:5:842:27 | ref_methodcall_receiver | main.rs:842:5:842:29 | ref_methodcall_receiver(...) | |
|
||||
| main.rs:842:5:842:29 | ref_methodcall_receiver(...) | main.rs:843:5:843:23 | ExprStmt | |
|
||||
| main.rs:842:5:842:30 | ExprStmt | main.rs:842:5:842:27 | ref_methodcall_receiver | |
|
||||
| main.rs:843:5:843:20 | macro_invocation | main.rs:843:5:843:22 | macro_invocation(...) | |
|
||||
| main.rs:843:5:843:22 | macro_invocation(...) | main.rs:844:5:844:18 | ExprStmt | |
|
||||
| main.rs:843:5:843:23 | ExprStmt | main.rs:843:5:843:20 | macro_invocation | |
|
||||
| main.rs:844:5:844:15 | capture_phi | main.rs:844:5:844:17 | capture_phi(...) | |
|
||||
| main.rs:844:5:844:17 | capture_phi(...) | main.rs:801:11:845:1 | { ... } | |
|
||||
| main.rs:844:5:844:18 | ExprStmt | main.rs:844:5:844:15 | capture_phi | |
|
||||
breakTarget
|
||||
| main.rs:326:9:326:13 | break | main.rs:317:5:327:5 | while ... { ... } |
|
||||
continueTarget
|
||||
|
||||
@@ -196,6 +196,13 @@ definition
|
||||
| main.rs:748:17:750:9 | SSA phi(x) | main.rs:745:13:745:13 | x |
|
||||
| main.rs:749:13:749:13 | x | main.rs:745:13:745:13 | x |
|
||||
| main.rs:752:5:752:13 | <captured exit> x | main.rs:745:13:745:13 | x |
|
||||
| main.rs:759:13:759:13 | x | main.rs:759:13:759:13 | x |
|
||||
| main.rs:760:13:760:13 | y | main.rs:760:13:760:13 | y |
|
||||
| main.rs:769:13:769:16 | N0ne | main.rs:769:13:769:16 | N0ne |
|
||||
| main.rs:776:13:776:22 | test_alias | main.rs:776:13:776:22 | test_alias |
|
||||
| main.rs:778:13:778:16 | test | main.rs:778:13:778:16 | test |
|
||||
| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x |
|
||||
| main.rs:789:18:789:18 | x | main.rs:789:18:789:18 | x |
|
||||
read
|
||||
| main.rs:5:14:5:14 | s | main.rs:5:14:5:14 | s | main.rs:7:20:7:20 | s |
|
||||
| main.rs:10:14:10:14 | i | main.rs:10:14:10:14 | i | main.rs:12:20:12:20 | i |
|
||||
@@ -404,6 +411,14 @@ read
|
||||
| main.rs:746:13:746:15 | cap | main.rs:746:13:746:15 | cap | main.rs:752:5:752:7 | cap |
|
||||
| main.rs:746:20:746:20 | b | main.rs:746:20:746:20 | b | main.rs:748:20:748:20 | b |
|
||||
| main.rs:752:5:752:13 | <captured exit> x | main.rs:745:13:745:13 | x | main.rs:753:15:753:15 | x |
|
||||
| main.rs:759:13:759:13 | x | main.rs:759:13:759:13 | x | main.rs:761:19:761:19 | x |
|
||||
| main.rs:760:13:760:13 | y | main.rs:760:13:760:13 | y | main.rs:768:15:768:15 | y |
|
||||
| main.rs:769:13:769:16 | N0ne | main.rs:769:13:769:16 | N0ne | main.rs:770:17:770:20 | N0ne |
|
||||
| main.rs:776:13:776:22 | test_alias | main.rs:776:13:776:22 | test_alias | main.rs:779:13:779:22 | test_alias |
|
||||
| main.rs:778:13:778:16 | test | main.rs:778:13:778:16 | test | main.rs:780:9:780:12 | test |
|
||||
| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x | main.rs:788:15:788:15 | x |
|
||||
| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x | main.rs:793:15:793:15 | x |
|
||||
| main.rs:789:18:789:18 | x | main.rs:789:18:789:18 | x | main.rs:790:20:790:20 | x |
|
||||
firstRead
|
||||
| main.rs:5:14:5:14 | s | main.rs:5:14:5:14 | s | main.rs:7:20:7:20 | s |
|
||||
| main.rs:10:14:10:14 | i | main.rs:10:14:10:14 | i | main.rs:12:20:12:20 | i |
|
||||
@@ -570,6 +585,13 @@ firstRead
|
||||
| main.rs:746:13:746:15 | cap | main.rs:746:13:746:15 | cap | main.rs:752:5:752:7 | cap |
|
||||
| main.rs:746:20:746:20 | b | main.rs:746:20:746:20 | b | main.rs:748:20:748:20 | b |
|
||||
| main.rs:752:5:752:13 | <captured exit> x | main.rs:745:13:745:13 | x | main.rs:753:15:753:15 | x |
|
||||
| main.rs:759:13:759:13 | x | main.rs:759:13:759:13 | x | main.rs:761:19:761:19 | x |
|
||||
| main.rs:760:13:760:13 | y | main.rs:760:13:760:13 | y | main.rs:768:15:768:15 | y |
|
||||
| main.rs:769:13:769:16 | N0ne | main.rs:769:13:769:16 | N0ne | main.rs:770:17:770:20 | N0ne |
|
||||
| main.rs:776:13:776:22 | test_alias | main.rs:776:13:776:22 | test_alias | main.rs:779:13:779:22 | test_alias |
|
||||
| main.rs:778:13:778:16 | test | main.rs:778:13:778:16 | test | main.rs:780:9:780:12 | test |
|
||||
| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x | main.rs:788:15:788:15 | x |
|
||||
| main.rs:789:18:789:18 | x | main.rs:789:18:789:18 | x | main.rs:790:20:790:20 | x |
|
||||
adjacentReads
|
||||
| main.rs:27:5:27:6 | x2 | main.rs:25:13:25:14 | x2 | main.rs:28:15:28:16 | x2 | main.rs:29:10:29:11 | x2 |
|
||||
| main.rs:41:9:41:10 | x3 | main.rs:41:9:41:10 | x3 | main.rs:42:15:42:16 | x3 | main.rs:44:9:44:10 | x3 |
|
||||
@@ -616,6 +638,7 @@ adjacentReads
|
||||
| main.rs:676:13:676:13 | a | main.rs:676:13:676:13 | a | main.rs:677:15:677:15 | a | main.rs:678:5:678:5 | a |
|
||||
| main.rs:676:13:676:13 | a | main.rs:676:13:676:13 | a | main.rs:678:5:678:5 | a | main.rs:679:15:679:15 | a |
|
||||
| main.rs:685:9:685:9 | x | main.rs:685:9:685:9 | x | main.rs:686:20:686:20 | x | main.rs:687:15:687:15 | x |
|
||||
| main.rs:787:13:787:13 | x | main.rs:787:13:787:13 | x | main.rs:788:15:788:15 | x | main.rs:793:15:793:15 | x |
|
||||
phi
|
||||
| main.rs:210:9:210:44 | SSA phi(a3) | main.rs:210:9:210:44 | a3 | main.rs:210:22:210:23 | a3 |
|
||||
| main.rs:210:9:210:44 | SSA phi(a3) | main.rs:210:9:210:44 | a3 | main.rs:210:42:210:43 | a3 |
|
||||
@@ -773,3 +796,8 @@ assigns
|
||||
| main.rs:745:13:745:13 | x | main.rs:745:17:745:19 | 100 |
|
||||
| main.rs:746:13:746:15 | cap | main.rs:746:19:751:5 | \|...\| ... |
|
||||
| main.rs:749:13:749:13 | x | main.rs:749:17:749:19 | 200 |
|
||||
| main.rs:759:13:759:13 | x | main.rs:759:17:759:24 | Some(...) |
|
||||
| main.rs:760:13:760:13 | y | main.rs:761:13:767:9 | match x { ... } |
|
||||
| main.rs:776:13:776:22 | test_alias | main.rs:777:13:777:16 | test |
|
||||
| main.rs:778:13:778:16 | test | main.rs:779:13:779:24 | test_alias(...) |
|
||||
| main.rs:787:13:787:13 | x | main.rs:787:17:787:23 | Some(...) |
|
||||
|
||||
@@ -753,6 +753,51 @@ fn capture_phi() {
|
||||
print_i64(x); // $ read_access=x
|
||||
}
|
||||
|
||||
mod patterns {
|
||||
#[rustfmt::skip]
|
||||
pub fn test() -> Option<i32> {
|
||||
let x = Some(42); // x
|
||||
let y : Option<i32> = // y1
|
||||
match x { // $ read_access=x
|
||||
Some(y) => { // y2
|
||||
None
|
||||
}
|
||||
None =>
|
||||
None
|
||||
};
|
||||
match y { // $ read_access=y1
|
||||
N0ne => // n0ne
|
||||
N0ne // $ read_access=n0ne
|
||||
}
|
||||
}
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn test2() -> Option<i32> {
|
||||
let test_alias = // test_alias
|
||||
test;
|
||||
let test = // test
|
||||
test_alias(); // $ read_access=test_alias
|
||||
test // $ read_access=test
|
||||
}
|
||||
|
||||
const z: i32 = 0;
|
||||
|
||||
#[rustfmt::skip]
|
||||
fn test3() {
|
||||
let x = Some(0); // x1
|
||||
match x { // $ read_access=x1
|
||||
Some(x) // x2
|
||||
=> x, // $ read_access=x2
|
||||
_ => 0
|
||||
};
|
||||
match x { // $ read_access=x1
|
||||
Some(z) =>
|
||||
z,
|
||||
_ => 0
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
immutable_variable();
|
||||
mutable_variable();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user