Merge branch 'main' into fix/format-string-fp-in-printf-impl

This commit is contained in:
Kaixuan Li
2026-03-19 14:36:50 +08:00
committed by GitHub
40 changed files with 254 additions and 351 deletions

View File

@@ -4,7 +4,7 @@
* allows for a cross-site scripting vulnerability.
* @kind path-problem
* @problem.severity error
* @security-severity 6.1
* @security-severity 7.8
* @precision high
* @id cpp/cgi-xss
* @tags security

View File

@@ -0,0 +1,4 @@
---
category: queryMetadata
---
* The `@security-severity` metadata of `cpp/cgi-xss` has been increased from 6.1 (medium) to 7.8 (high).

View File

@@ -336,6 +336,22 @@ class ExtensionTypeExtensionMethod extends ExtensionMethodImpl {
ExtensionTypeExtensionMethod() { this.isInExtension() }
}
/**
* A non-static member with an initializer, for example a field `int Field = 0`.
*/
private class InitializedInstanceMember extends Member {
private AssignExpr ae;
InitializedInstanceMember() {
not this.isStatic() and
expr_parent_top_level(ae, _, this) and
not ae = getExpressionBody(_)
}
/** Gets the initializer expression. */
AssignExpr getInitializer() { result = ae }
}
/**
* An object initializer method.
*
@@ -347,6 +363,17 @@ class ExtensionTypeExtensionMethod extends ExtensionMethodImpl {
*/
class ObjectInitMethod extends Method {
ObjectInitMethod() { this.getName() = "<object initializer>" }
/**
* Holds if this object initializer method performs the initialization
* of a member via assignment `init`.
*/
predicate initializes(AssignExpr init) {
exists(InitializedInstanceMember m |
this.getDeclaringType().getAMember() = m and
init = m.getInitializer()
)
}
}
/**

View File

@@ -214,6 +214,8 @@ private module Cached {
parent*(enclosingStart(cfe), c.(Constructor).getInitializer())
or
parent*(cfe, c.(Constructor).getObjectInitializerCall())
or
parent*(cfe, any(AssignExpr init | c.(ObjectInitMethod).initializes(init)))
}
/** Holds if the enclosing statement of expression `e` is `s`. */

View File

@@ -10,42 +10,15 @@ private import semmle.code.csharp.ExprOrStmtParent
private import semmle.code.csharp.commons.Compilation
private module Initializers {
/**
* A non-static member with an initializer, for example a field `int Field = 0`.
*/
class InitializedInstanceMember extends Member {
private AssignExpr ae;
InitializedInstanceMember() {
not this.isStatic() and
expr_parent_top_level(ae, _, this) and
not ae = any(Callable c).getExpressionBody()
}
/** Gets the initializer expression. */
AssignExpr getInitializer() { result = ae }
}
/**
* Holds if `obinit` is an object initializer method that performs the initialization
* of a member via assignment `init`.
*/
predicate obinitInitializes(ObjectInitMethod obinit, AssignExpr init) {
exists(InitializedInstanceMember m |
obinit.getDeclaringType().getAMember() = m and
init = m.getInitializer()
)
}
/**
* Gets the `i`th member initializer expression for object initializer method `obinit`
* in compilation `comp`.
*/
AssignExpr initializedInstanceMemberOrder(ObjectInitMethod obinit, CompilationExt comp, int i) {
obinitInitializes(obinit, result) and
obinit.initializes(result) and
result =
rank[i + 1](AssignExpr ae0, Location l |
obinitInitializes(obinit, ae0) and
obinit.initializes(ae0) and
l = ae0.getLocation() and
getCompilation(l.getFile()) = comp
|
@@ -74,7 +47,7 @@ class CfgScope extends Element, @top_level_exprorstmt_parent {
any(Callable c |
c.(Constructor).hasInitializer()
or
Initializers::obinitInitializes(c, _)
c.(ObjectInitMethod).initializes(_)
or
c.hasBody()
)

View File

@@ -4,7 +4,7 @@
* allows for a cross-site scripting vulnerability.
* @kind path-problem
* @problem.severity error
* @security-severity 6.1
* @security-severity 7.8
* @precision high
* @id cs/web/xss
* @tags security

View File

@@ -4,7 +4,7 @@
* insertion of forged log entries by a malicious user.
* @kind path-problem
* @problem.severity error
* @security-severity 7.8
* @security-severity 6.1
* @precision high
* @id cs/log-forging
* @tags security

View File

@@ -0,0 +1,5 @@
---
category: queryMetadata
---
* The `@security-severity` metadata of `cs/log-forging` has been reduced from 7.8 (high) to 6.1 (medium).
* The `@security-severity` metadata of `cs/web/xss` has been increased from 6.1 (medium) to 7.8 (high).

View File

@@ -24,6 +24,7 @@
| ExactCallable.cs:15:25:15:35 | Run`2 | ExactCallable.cs:172:21:172:33 | MethodWithOut |
| ExactCallable.cs:15:25:15:35 | Run`2 | ExactCallable.cs:177:21:177:34 | MethodWithOut2 |
| ExactCallable.cs:182:21:182:22 | M1 | ExactCallable.cs:187:21:187:22 | M2 |
| TypeFlow.cs:3:7:3:14 | <object initializer> | TypeFlow.cs:22:20:22:22 | set_Prop |
| TypeFlow.cs:5:5:5:12 | TypeFlow | TypeFlow.cs:24:10:24:12 | Run |
| TypeFlow.cs:24:10:24:12 | Run | TypeFlow.cs:12:29:12:34 | Method |
| TypeFlow.cs:24:10:24:12 | Run | TypeFlow.cs:17:30:17:35 | Method |

View File

@@ -56,11 +56,11 @@ gvn
| StructuralComparison.cs:3:14:3:18 | this access | (kind:Expr(12),false,Class) |
| StructuralComparison.cs:3:14:3:18 | {...} | (kind:Stmt(1)) |
| StructuralComparison.cs:5:26:5:26 | access to field x | (kind:Expr(16),true,x) |
| StructuralComparison.cs:5:26:5:26 | this access | (kind:Expr(12)) |
| StructuralComparison.cs:5:26:5:26 | this access | (kind:Expr(12),false,Class) |
| StructuralComparison.cs:5:26:5:30 | ... = ... | ((kind:Expr(16),true,x) :: (0 :: (kind:Expr(63)))) |
| StructuralComparison.cs:5:30:5:30 | 0 | 0 |
| StructuralComparison.cs:6:26:6:26 | access to field y | (kind:Expr(16),true,y) |
| StructuralComparison.cs:6:26:6:26 | this access | (kind:Expr(12)) |
| StructuralComparison.cs:6:26:6:26 | this access | (kind:Expr(12),false,Class) |
| StructuralComparison.cs:6:26:6:30 | ... = ... | ((kind:Expr(16),true,y) :: (1 :: (kind:Expr(63)))) |
| StructuralComparison.cs:6:30:6:30 | 1 | 1 |
| StructuralComparison.cs:8:24:8:24 | 0 | 0 |

View File

@@ -5,7 +5,7 @@
* scripting vulnerability.
* @kind path-problem
* @problem.severity error
* @security-severity 6.1
* @security-severity 7.8
* @precision high
* @id go/html-template-escaping-bypass-xss
* @tags security

View File

@@ -4,7 +4,7 @@
* a cross-site scripting vulnerability.
* @kind path-problem
* @problem.severity error
* @security-severity 6.1
* @security-severity 7.8
* @precision high
* @id go/reflected-xss
* @tags security

View File

@@ -4,7 +4,7 @@
* a stored cross-site scripting vulnerability.
* @kind path-problem
* @problem.severity error
* @security-severity 6.1
* @security-severity 7.8
* @precision low
* @id go/stored-xss
* @tags security

View File

@@ -4,7 +4,7 @@
* insertion of forged log entries by a malicious user.
* @kind path-problem
* @problem.severity error
* @security-severity 7.8
* @security-severity 6.1
* @precision medium
* @id go/log-injection
* @tags security

View File

@@ -0,0 +1,5 @@
---
category: queryMetadata
---
* The `@security-severity` metadata of `go/log-injection` has been reduced from 7.8 (high) to 6.1 (medium).
* The `@security-severity` metadata of `go/html-template-escaping-bypass-xss`, `go/reflected-xss` and `go/stored-xss` has been increased from 6.1 (medium) to 7.8 (high).

View File

@@ -4,7 +4,7 @@
* @description Exposing a Java object in a WebView with a JavaScript interface can lead to malicious JavaScript controlling the application.
* @kind problem
* @problem.severity warning
* @security-severity 6.1
* @security-severity 7.8
* @precision medium
* @tags security
* external/cwe/cwe-079

View File

@@ -4,7 +4,7 @@
* @kind problem
* @id java/android/websettings-javascript-enabled
* @problem.severity warning
* @security-severity 6.1
* @security-severity 7.8
* @precision medium
* @tags security
* external/cwe/cwe-079

View File

@@ -4,7 +4,7 @@
* allows for a cross-site scripting vulnerability.
* @kind path-problem
* @problem.severity error
* @security-severity 6.1
* @security-severity 7.8
* @precision high
* @id java/xss
* @tags security

View File

@@ -4,7 +4,7 @@
* insertion of forged log entries by malicious users.
* @kind path-problem
* @problem.severity error
* @security-severity 7.8
* @security-severity 6.1
* @precision medium
* @id java/log-injection
* @tags security

View File

@@ -0,0 +1,5 @@
---
category: queryMetadata
---
* The `@security-severity` metadata of `java/log-injection` has been reduced from 7.8 (high) to 6.1 (medium).
* The `@security-severity` metadata of `java/android/webview-addjavascriptinterface`, `java/android/websettings-javascript-enabled` and `java/xss` has been increased from 6.1 (medium) to 7.8 (high).

View File

@@ -4,7 +4,7 @@
* cause a cross-site scripting vulnerability.
* @kind problem
* @problem.severity error
* @security-severity 6.1
* @security-severity 7.8
* @precision medium
* @id py/jinja2/autoescape-false
* @tags security

View File

@@ -4,7 +4,7 @@
* allows for a cross-site scripting vulnerability.
* @kind path-problem
* @problem.severity error
* @security-severity 6.1
* @security-severity 7.8
* @sub-severity high
* @precision high
* @id py/reflective-xss

View File

@@ -4,7 +4,7 @@
* insertion of forged log entries by a malicious user.
* @kind path-problem
* @problem.severity error
* @security-severity 7.8
* @security-severity 6.1
* @precision medium
* @id py/log-injection
* @tags security

View File

@@ -0,0 +1,5 @@
---
category: queryMetadata
---
* The `@security-severity` metadata of `py/log-injection` has been reduced from 7.8 (high) to 6.1 (medium).
* The `@security-severity` metadata of `py/jinja2/autoescape-false` and `py/reflective-xss` has been increased from 6.1 (medium) to 7.8 (high).

View File

@@ -0,0 +1,5 @@
---
category: queryMetadata
---
* The `@security-severity` metadata of `rb/log-injection` has been reduced from 7.8 (high) to 6.1 (medium).
* The `@security-severity` metadata of `rb/reflected-xss`, `rb/stored-xss` and `rb/html-constructed-from-input` has been increased from 6.1 (medium) to 7.8 (high).

View File

@@ -4,7 +4,7 @@
* allows for a cross-site scripting vulnerability.
* @kind path-problem
* @problem.severity error
* @security-severity 6.1
* @security-severity 7.8
* @sub-severity high
* @precision high
* @id rb/reflected-xss

View File

@@ -4,7 +4,7 @@
* a stored cross-site scripting vulnerability.
* @kind path-problem
* @problem.severity error
* @security-severity 6.1
* @security-severity 7.8
* @precision high
* @id rb/stored-xss
* @tags security

View File

@@ -4,7 +4,7 @@
* user to perform a cross-site scripting attack.
* @kind path-problem
* @problem.severity error
* @security-severity 6.1
* @security-severity 7.8
* @precision high
* @id rb/html-constructed-from-input
* @tags security

View File

@@ -4,7 +4,7 @@
* insertion of forged log entries by a malicious user.
* @kind path-problem
* @problem.severity error
* @security-severity 7.8
* @security-severity 6.1
* @precision medium
* @id rb/log-injection
* @tags security

View File

@@ -9,7 +9,12 @@ module Impl {
// For the type `FunctionPosition` used by type inference, we work with function-call syntax
// adjusted positions, so a call like `x.m(a, b, c)` needs positions `0` through `3`; for this
// reason, there is no `- 1` after `max(...)` below.
i in [0 .. max([any(ParamList l).getNumberOfParams(), any(ArgList l).getNumberOfArgs()])]
i in [0 .. max([
any(ParamList l).getNumberOfParams(),
any(ArgList l).getNumberOfArgs(),
any(StructFieldList l).getNumberOfFields() // Positions are used for struct expressions in type inference
]
)]
} or
TSelfArgumentPosition() or
TTypeQualifierArgumentPosition()

View File

@@ -50,5 +50,10 @@ module Impl {
or
result = this.getVariant().getStructField(name)
}
/** Gets the `i`th struct field of the instantiated struct or variant. */
StructField getNthStructField(int i) {
result = [this.getStruct().getNthStructField(i), this.getVariant().getNthStructField(i)]
}
}
}

View File

@@ -35,6 +35,12 @@ module Impl {
/** Gets a record field, if any. */
StructField getAStructField() { result = this.getStructField(_) }
/** Gets the `i`th struct field, if any. */
pragma[nomagic]
StructField getNthStructField(int i) {
result = this.getFieldList().(StructFieldList).getField(i)
}
/** Gets the `i`th tuple field, if any. */
pragma[nomagic]
TupleField getTupleField(int i) { result = this.getFieldList().(TupleFieldList).getField(i) }

View File

@@ -42,6 +42,13 @@ module Impl {
)
}
/** Gets the `i`th struct field of the instantiated struct or variant. */
StructField getNthStructField(int i) {
exists(PathResolution::ItemNode item | item = this.getResolvedPath(_) |
result = [item.(Struct).getNthStructField(i), item.(Variant).getNthStructField(i)]
)
}
/** Gets the struct pattern for the field `name`. */
pragma[nomagic]
StructPatField getPatField(string name) {

View File

@@ -32,6 +32,12 @@ module Impl {
result.getName().getText() = name
}
/** Gets the `i`th struct field, if any. */
pragma[nomagic]
StructField getNthStructField(int i) {
result = this.getFieldList().(StructFieldList).getField(i)
}
/** Gets the `i`th tuple field, if any. */
pragma[nomagic]
TupleField getTupleField(int i) { result = this.getFieldList().(TupleFieldList).getField(i) }

View File

@@ -872,188 +872,6 @@ private Type inferTypeEquality(AstNode n, TypePath path) {
)
}
/**
* A matching configuration for resolving types of struct expressions
* like `Foo { bar = baz }`.
*
* This also includes nullary struct expressions like `None`.
*/
private module StructExprMatchingInput implements MatchingInputSig {
private newtype TPos =
TFieldPos(string name) { exists(any(Declaration decl).getField(name)) } or
TStructPos()
class DeclarationPosition extends TPos {
string asFieldPos() { this = TFieldPos(result) }
predicate isStructPos() { this = TStructPos() }
string toString() {
result = this.asFieldPos()
or
this.isStructPos() and
result = "(struct)"
}
}
abstract class Declaration extends AstNode {
final TypeParameter getTypeParameter(TypeParameterPosition ppos) {
typeParamMatchPosition(this.getTypeItem().getGenericParamList().getATypeParam(), result, ppos)
}
abstract StructField getField(string name);
abstract TypeItem getTypeItem();
Type getDeclaredType(DeclarationPosition dpos, TypePath path) {
// type of a field
exists(TypeMention tp |
tp = this.getField(dpos.asFieldPos()).getTypeRepr() and
result = tp.getTypeAt(path)
)
or
// type parameter of the struct itself
dpos.isStructPos() and
result = this.getTypeParameter(_) and
path = TypePath::singleton(result)
or
// type of the struct or enum itself
dpos.isStructPos() and
path.isEmpty() and
result = TDataType(this.getTypeItem())
}
}
private class StructDecl extends Declaration, Struct {
StructDecl() { this.isStruct() or this.isUnit() }
override StructField getField(string name) { result = this.getStructField(name) }
override TypeItem getTypeItem() { result = this }
}
private class StructVariantDecl extends Declaration, Variant {
StructVariantDecl() { this.isStruct() or this.isUnit() }
override StructField getField(string name) { result = this.getStructField(name) }
override TypeItem getTypeItem() { result = this.getEnum() }
}
class AccessPosition = DeclarationPosition;
abstract class Access extends AstNode {
pragma[nomagic]
abstract AstNode getNodeAt(AccessPosition apos);
pragma[nomagic]
Type getInferredType(AccessPosition apos, TypePath path) {
result = inferType(this.getNodeAt(apos), path)
}
pragma[nomagic]
abstract Path getStructPath();
pragma[nomagic]
Declaration getTarget() { result = resolvePath(this.getStructPath()) }
pragma[nomagic]
Type getTypeArgument(TypeArgumentPosition apos, TypePath path) {
// Handle constructions that use `Self {...}` syntax
exists(TypeMention tm, TypePath path0 |
tm = this.getStructPath() and
result = tm.getTypeAt(path0) and
path0.isCons(TTypeParamTypeParameter(apos.asTypeParam()), path)
)
}
/**
* Holds if the return type of this struct expression at `path` may have to
* be inferred from the context.
*/
pragma[nomagic]
predicate hasUnknownTypeAt(DeclarationPosition pos, TypePath path) {
exists(Declaration d, TypeParameter tp |
d = this.getTarget() and
pos.isStructPos() and
tp = d.getDeclaredType(pos, path) and
not exists(DeclarationPosition fieldPos |
not fieldPos.isStructPos() and
tp = d.getDeclaredType(fieldPos, _)
) and
// check that no explicit type arguments have been supplied for `tp`
not exists(TypeArgumentPosition tapos |
exists(this.getTypeArgument(tapos, _)) and
TTypeParamTypeParameter(tapos.asTypeParam()) = tp
)
)
}
}
private class StructExprAccess extends Access, StructExpr {
override Type getTypeArgument(TypeArgumentPosition apos, TypePath path) {
result = super.getTypeArgument(apos, path)
or
exists(TypePath suffix |
suffix.isCons(TTypeParamTypeParameter(apos.asTypeParam()), path) and
result = CertainTypeInference::inferCertainType(this, suffix)
)
}
override AstNode getNodeAt(AccessPosition apos) {
result = this.getFieldExpr(apos.asFieldPos()).getExpr()
or
result = this and
apos.isStructPos()
}
override Path getStructPath() { result = this.getPath() }
}
/**
* A potential nullary struct/variant construction such as `None`.
*/
private class PathExprAccess extends Access, PathExpr {
PathExprAccess() { not exists(CallExpr ce | this = ce.getFunction()) }
override AstNode getNodeAt(AccessPosition apos) {
result = this and
apos.isStructPos()
}
override Path getStructPath() { result = this.getPath() }
}
predicate accessDeclarationPositionMatch(AccessPosition apos, DeclarationPosition dpos) {
apos = dpos
}
}
private module StructExprMatching = Matching<StructExprMatchingInput>;
pragma[nomagic]
private Type inferStructExprType0(
AstNode n, FunctionPosition pos, boolean hasReceiver, TypePath path
) {
exists(StructExprMatchingInput::Access a, StructExprMatchingInput::AccessPosition apos |
n = a.getNodeAt(apos) and
hasReceiver = false and
if apos.isStructPos() then pos.isReturn() else pos.asPosition() = 0 // the actual position doesn't matter, as long as it is positional
|
result = StructExprMatching::inferAccessType(a, apos, path)
or
a.hasUnknownTypeAt(apos, path) and
result = TUnknownType()
)
}
/**
* Gets the type of `n` at `path`, where `n` is either a struct expression or
* a field expression of a struct expression.
*/
private predicate inferStructExprType =
ContextTyping::CheckContextTyping<inferStructExprType0/4>::check/2;
pragma[nomagic]
private TupleType inferTupleRootType(AstNode n) {
// `typeEquality` handles the non-root cases
@@ -3083,14 +2901,14 @@ private Type inferFunctionCallTypePreCheck(
private predicate inferFunctionCallType =
ContextTyping::CheckContextTyping<inferFunctionCallTypePreCheck/4>::check/2;
abstract private class TupleLikeConstructor extends Addressable {
abstract private class Constructor extends Addressable {
final TypeParameter getTypeParameter(TypeParameterPosition ppos) {
typeParamMatchPosition(this.getTypeItem().getGenericParamList().getATypeParam(), result, ppos)
}
abstract TypeItem getTypeItem();
abstract TupleField getTupleField(int i);
abstract TypeRepr getParameterTypeRepr(int pos);
Type getReturnType(TypePath path) {
result = TDataType(this.getTypeItem()) and
@@ -3105,65 +2923,59 @@ abstract private class TupleLikeConstructor extends Addressable {
or
pos.isReturn() and
result = this.getReturnType(path)
or
pos.isTypeQualifier() and
result = this.getReturnType(path)
}
Type getParameterType(int pos, TypePath path) {
result = this.getTupleField(pos).getTypeRepr().(TypeMention).getTypeAt(path)
result = this.getParameterTypeRepr(pos).(TypeMention).getTypeAt(path)
}
}
private class TupleLikeStruct extends TupleLikeConstructor instanceof Struct {
TupleLikeStruct() { this.isTuple() }
private class StructConstructor extends Constructor instanceof Struct {
override TypeItem getTypeItem() { result = this }
override TupleField getTupleField(int i) { result = Struct.super.getTupleField(i) }
override TypeRepr getParameterTypeRepr(int i) {
result = [super.getTupleField(i).getTypeRepr(), super.getNthStructField(i).getTypeRepr()]
}
}
private class TupleLikeVariant extends TupleLikeConstructor instanceof Variant {
TupleLikeVariant() { this.isTuple() }
private class VariantConstructor extends Constructor instanceof Variant {
override TypeItem getTypeItem() { result = super.getEnum() }
override TupleField getTupleField(int i) { result = Variant.super.getTupleField(i) }
override TypeRepr getParameterTypeRepr(int i) {
result = [super.getTupleField(i).getTypeRepr(), super.getNthStructField(i).getTypeRepr()]
}
}
/**
* A matching configuration for resolving types of tuple-like variants and tuple
* structs such as `Result::Ok(42)`.
* A matching configuration for resolving types of constructions of enums and
* structs, such as `Result::Ok(42)`, `Foo { bar: 1 }` and `None`.
*/
private module TupleLikeConstructionMatchingInput implements MatchingInputSig {
private module ConstructionMatchingInput implements MatchingInputSig {
import FunctionPositionMatchingInput
class Declaration = TupleLikeConstructor;
class Declaration = Constructor;
class Access extends NonAssocCallExpr, ContextTyping::ContextTypedCallCand {
Access() {
this instanceof CallExprImpl::TupleStructExpr or
this instanceof CallExprImpl::TupleVariantExpr
}
abstract class Access extends AstNode {
abstract Type getInferredType(FunctionPosition pos, TypePath path);
override Type getTypeArgument(TypeArgumentPosition apos, TypePath path) {
result = NonAssocCallExpr.super.getTypeArgument(apos, path)
}
abstract Declaration getTarget();
Declaration getTarget() { result = this.resolveCallTargetViaPathResolution() }
abstract AstNode getNodeAt(AccessPosition apos);
abstract Type getTypeArgument(TypeArgumentPosition apos, TypePath path);
/**
* Holds if the return type of this tuple-like construction at `path` may have to be inferred
* from the context, for example in `Result::Ok(42)` the error type has to be inferred from the
* context.
* Holds if the return type of this construction expression at `path` may
* have to be inferred from the context. For example in `Result::Ok(42)` the
* error type has to be inferred from the context.
*/
pragma[nomagic]
predicate hasUnknownTypeAt(FunctionPosition pos, TypePath path) {
exists(TupleLikeConstructor tc, TypeParameter tp |
tc = this.getTarget() and
exists(Declaration d, TypeParameter tp |
d = this.getTarget() and
pos.isReturn() and
tp = tc.getReturnType(path) and
not tp = tc.getParameterType(_, _) and
tp = d.getReturnType(path) and
not exists(FunctionPosition pos2 | not pos2.isReturn() and tp = d.getDeclaredType(pos2, _)) and
// check that no explicit type arguments have been supplied for `tp`
not exists(TypeArgumentPosition tapos |
exists(this.getTypeArgument(tapos, _)) and
@@ -3172,25 +2984,93 @@ private module TupleLikeConstructionMatchingInput implements MatchingInputSig {
)
}
}
private class NonAssocCallAccess extends Access, NonAssocCallExpr,
ContextTyping::ContextTypedCallCand
{
NonAssocCallAccess() {
this instanceof CallExprImpl::TupleStructExpr or
this instanceof CallExprImpl::TupleVariantExpr
}
override Type getTypeArgument(TypeArgumentPosition apos, TypePath path) {
result = NonAssocCallExpr.super.getTypeArgument(apos, path)
}
override AstNode getNodeAt(AccessPosition apos) {
result = NonAssocCallExpr.super.getNodeAt(apos)
}
override Type getInferredType(FunctionPosition pos, TypePath path) {
result = NonAssocCallExpr.super.getInferredType(pos, path)
}
override Declaration getTarget() { result = this.resolveCallTargetViaPathResolution() }
}
abstract private class StructAccess extends Access instanceof PathAstNode {
pragma[nomagic]
override Type getInferredType(AccessPosition apos, TypePath path) {
result = inferType(this.getNodeAt(apos), path)
}
pragma[nomagic]
override Declaration getTarget() { result = resolvePath(super.getPath()) }
pragma[nomagic]
override Type getTypeArgument(TypeArgumentPosition apos, TypePath path) {
// Handle constructions that use `Self {...}` syntax
exists(TypeMention tm, TypePath path0 |
tm = super.getPath() and
result = tm.getTypeAt(path0) and
path0.isCons(TTypeParamTypeParameter(apos.asTypeParam()), path)
)
}
}
private class StructExprAccess extends StructAccess, StructExpr {
override Type getTypeArgument(TypeArgumentPosition apos, TypePath path) {
result = super.getTypeArgument(apos, path)
or
exists(TypePath suffix |
suffix.isCons(TTypeParamTypeParameter(apos.asTypeParam()), path) and
result = CertainTypeInference::inferCertainType(this, suffix)
)
}
override AstNode getNodeAt(AccessPosition apos) {
result =
this.getFieldExpr(this.getNthStructField(apos.asPosition()).getName().getText()).getExpr()
or
result = this and apos.isReturn()
}
}
/** A potential nullary struct/variant construction such as `None`. */
private class PathExprAccess extends StructAccess, PathExpr {
PathExprAccess() { not exists(CallExpr ce | this = ce.getFunction()) }
override AstNode getNodeAt(AccessPosition apos) { result = this and apos.isReturn() }
}
}
private module TupleLikeConstructionMatching = Matching<TupleLikeConstructionMatchingInput>;
private module ConstructionMatching = Matching<ConstructionMatchingInput>;
pragma[nomagic]
private Type inferTupleLikeConstructionTypePreCheck(
private Type inferConstructionTypePreCheck(
AstNode n, FunctionPosition pos, boolean hasReceiver, TypePath path
) {
hasReceiver = false and
exists(TupleLikeConstructionMatchingInput::Access a | n = a.getNodeAt(pos) |
result = TupleLikeConstructionMatching::inferAccessType(a, pos, path)
exists(ConstructionMatchingInput::Access a | n = a.getNodeAt(pos) |
result = ConstructionMatching::inferAccessType(a, pos, path)
or
a.hasUnknownTypeAt(pos, path) and
result = TUnknownType()
)
}
private predicate inferTupleLikeConstructionType =
ContextTyping::CheckContextTyping<inferTupleLikeConstructionTypePreCheck/4>::check/2;
private predicate inferConstructionType =
ContextTyping::CheckContextTyping<inferConstructionTypePreCheck/4>::check/2;
/**
* A matching configuration for resolving types of operations like `a + b`.
@@ -3676,71 +3556,27 @@ private Type inferDereferencedExprPtrType(AstNode n, TypePath path) {
}
/**
* A matching configuration for resolving types of struct patterns
* like `let Foo { bar } = ...`.
* A matching configuration for resolving types of deconstruction patterns like
* `let Foo { bar } = ...` or `let Some(x) = ...`.
*/
private module StructPatMatchingInput implements MatchingInputSig {
class DeclarationPosition = StructExprMatchingInput::DeclarationPosition;
class Declaration = StructExprMatchingInput::Declaration;
class AccessPosition = DeclarationPosition;
class Access extends StructPat {
Type getTypeArgument(TypeArgumentPosition apos, TypePath path) { none() }
AstNode getNodeAt(AccessPosition apos) {
result = this.getPatField(apos.asFieldPos()).getPat()
or
result = this and
apos.isStructPos()
}
Type getInferredType(AccessPosition apos, TypePath path) {
result = inferType(this.getNodeAt(apos), path)
or
// The struct/enum type is supplied explicitly as a type qualifier, e.g.
// `let Foo<Bar>::Variant { ... } = ...`.
apos.isStructPos() and
result = this.getPath().(TypeMention).getTypeAt(path)
}
Declaration getTarget() { result = resolvePath(this.getPath()) }
}
predicate accessDeclarationPositionMatch(AccessPosition apos, DeclarationPosition dpos) {
apos = dpos
}
}
private module StructPatMatching = Matching<StructPatMatchingInput>;
/**
* Gets the type of `n` at `path`, where `n` is either a struct pattern or
* a field pattern of a struct pattern.
*/
pragma[nomagic]
private Type inferStructPatType(AstNode n, TypePath path) {
exists(StructPatMatchingInput::Access a, StructPatMatchingInput::AccessPosition apos |
n = a.getNodeAt(apos) and
result = StructPatMatching::inferAccessType(a, apos, path)
)
}
/**
* A matching configuration for resolving types of tuple struct patterns
* like `let Some(x) = ...`.
*/
private module TupleStructPatMatchingInput implements MatchingInputSig {
private module DeconstructionPatMatchingInput implements MatchingInputSig {
import FunctionPositionMatchingInput
class Declaration = TupleLikeConstructor;
class Declaration = ConstructionMatchingInput::Declaration;
class Access extends Pat instanceof PathAstNode {
Access() { this instanceof TupleStructPat or this instanceof StructPat }
class Access extends TupleStructPat {
Type getTypeArgument(TypeArgumentPosition apos, TypePath path) { none() }
AstNode getNodeAt(AccessPosition apos) {
result = this.getField(apos.asPosition())
this =
any(StructPat sp |
result =
sp.getPatField(sp.getNthStructField(apos.asPosition()).getName().getText()).getPat()
)
or
result = this.(TupleStructPat).getField(apos.asPosition())
or
result = this and
apos.isReturn()
@@ -3750,26 +3586,27 @@ private module TupleStructPatMatchingInput implements MatchingInputSig {
result = inferType(this.getNodeAt(apos), path)
or
// The struct/enum type is supplied explicitly as a type qualifier, e.g.
// `let Foo::<Bar>::Variant { ... } = ...` or
// `let Option::<Foo>::Some(x) = ...`.
apos.isTypeQualifier() and
result = this.getPath().(TypeMention).getTypeAt(path)
apos.isReturn() and
result = super.getPath().(TypeMention).getTypeAt(path)
}
Declaration getTarget() { result = resolvePath(this.getPath()) }
Declaration getTarget() { result = resolvePath(super.getPath()) }
}
}
private module TupleStructPatMatching = Matching<TupleStructPatMatchingInput>;
private module DeconstructionPatMatching = Matching<DeconstructionPatMatchingInput>;
/**
* Gets the type of `n` at `path`, where `n` is either a tuple struct pattern or
* a positional pattern of a tuple struct pattern.
* Gets the type of `n` at `path`, where `n` is a pattern for a constructor,
* either a struct pattern or a tuple-struct pattern.
*/
pragma[nomagic]
private Type inferTupleStructPatType(AstNode n, TypePath path) {
exists(TupleStructPatMatchingInput::Access a, TupleStructPatMatchingInput::AccessPosition apos |
private Type inferDeconstructionPatType(AstNode n, TypePath path) {
exists(DeconstructionPatMatchingInput::Access a, FunctionPosition apos |
n = a.getNodeAt(apos) and
result = TupleStructPatMatching::inferAccessType(a, apos, path)
result = DeconstructionPatMatching::inferAccessType(a, apos, path)
)
}
@@ -4080,11 +3917,9 @@ private module Cached {
or
result = inferTypeEquality(n, path)
or
result = inferStructExprType(n, path)
or
result = inferFunctionCallType(n, path)
or
result = inferTupleLikeConstructionType(n, path)
result = inferConstructionType(n, path)
or
result = inferOperationType(n, path)
or
@@ -4106,9 +3941,7 @@ private module Cached {
or
result = inferClosureExprType(n, path)
or
result = inferStructPatType(n, path)
or
result = inferTupleStructPatType(n, path)
result = inferDeconstructionPatType(n, path)
)
}
}
@@ -4157,9 +3990,9 @@ private module Debug {
t = inferFunctionCallType(n, path)
}
predicate debugInferTupleLikeConstructionType(AstNode n, TypePath path, Type t) {
predicate debugInferConstructionType(AstNode n, TypePath path, Type t) {
n = getRelevantLocatable() and
t = inferTupleLikeConstructionType(n, path)
t = inferConstructionType(n, path)
}
predicate debugTypeMention(TypeMention tm, TypePath path, Type type) {

View File

@@ -0,0 +1,5 @@
---
category: queryMetadata
---
* The `@security-severity` metadata of `rust/log-injection` has been increased from 2.6 (low) to 6.1 (medium).
* The `@security-severity` metadata of `rust/xss` has been increased from 6.1 (medium) to 7.8 (high).

View File

@@ -4,7 +4,7 @@
* allows for a cross-site scripting vulnerability.
* @kind path-problem
* @problem.severity error
* @security-severity 6.1
* @security-severity 7.8
* @precision high
* @id rust/xss
* @tags security

View File

@@ -4,7 +4,7 @@
* insertion of forged log entries by a malicious user.
* @kind path-problem
* @problem.severity error
* @security-severity 2.6
* @security-severity 6.1
* @precision medium
* @id rust/log-injection
* @tags security

View File

@@ -0,0 +1,4 @@
---
category: queryMetadata
---
* The `@security-severity` metadata of `swift/unsafe-webview-fetch` has been increased from 6.1 (medium) to 7.8 (high).

View File

@@ -3,7 +3,7 @@
* @description Fetching data in a WebView without restricting the base URL may allow an attacker to access sensitive local data, or enable cross-site scripting attack.
* @kind path-problem
* @problem.severity warning
* @security-severity 6.1
* @security-severity 7.8
* @precision high
* @id swift/unsafe-webview-fetch
* @tags security