mirror of
https://github.com/github/codeql.git
synced 2025-12-17 01:03:14 +01:00
C#: Deprecate Assignable(Read)::getAReachableRead
This commit is contained in:
@@ -111,6 +111,7 @@ class AssignableRead extends AssignableAccess {
|
|||||||
* - The reads of `i` on lines 7 and 8 are next to the read on line 6.
|
* - The reads of `i` on lines 7 and 8 are next to the read on line 6.
|
||||||
* - The read of `this.Field` on line 11 is next to the read on line 10.
|
* - The read of `this.Field` on line 11 is next to the read on line 10.
|
||||||
*/
|
*/
|
||||||
|
pragma[nomagic]
|
||||||
AssignableRead getANextRead() {
|
AssignableRead getANextRead() {
|
||||||
forex(ControlFlow::Node cfn | cfn = result.getAControlFlowNode() |
|
forex(ControlFlow::Node cfn | cfn = result.getAControlFlowNode() |
|
||||||
cfn = this.getAnAdjacentReadSameVar()
|
cfn = this.getAnAdjacentReadSameVar()
|
||||||
@@ -124,7 +125,7 @@ class AssignableRead extends AssignableAccess {
|
|||||||
*
|
*
|
||||||
* This is the transitive closure of `getANextRead()`.
|
* This is the transitive closure of `getANextRead()`.
|
||||||
*/
|
*/
|
||||||
AssignableRead getAReachableRead() { result = this.getANextRead+() }
|
deprecated AssignableRead getAReachableRead() { result = this.getANextRead+() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -479,6 +480,7 @@ class AssignableDefinition extends TAssignableDefinition {
|
|||||||
* Subsequent reads can be found by following the steps defined by
|
* Subsequent reads can be found by following the steps defined by
|
||||||
* `AssignableRead.getANextRead()`.
|
* `AssignableRead.getANextRead()`.
|
||||||
*/
|
*/
|
||||||
|
pragma[nomagic]
|
||||||
AssignableRead getAFirstRead() {
|
AssignableRead getAFirstRead() {
|
||||||
forex(ControlFlow::Node cfn | cfn = result.getAControlFlowNode() |
|
forex(ControlFlow::Node cfn | cfn = result.getAControlFlowNode() |
|
||||||
exists(Ssa::ExplicitDefinition def | result = def.getAFirstReadAtNode(cfn) |
|
exists(Ssa::ExplicitDefinition def | result = def.getAFirstReadAtNode(cfn) |
|
||||||
@@ -494,7 +496,7 @@ class AssignableDefinition extends TAssignableDefinition {
|
|||||||
*
|
*
|
||||||
* This is the equivalent with `getAFirstRead().getANextRead*()`.
|
* This is the equivalent with `getAFirstRead().getANextRead*()`.
|
||||||
*/
|
*/
|
||||||
AssignableRead getAReachableRead() { result = this.getAFirstRead().getANextRead*() }
|
deprecated AssignableRead getAReachableRead() { result = this.getAFirstRead().getANextRead*() }
|
||||||
|
|
||||||
/** Gets a textual representation of this assignable definition. */
|
/** Gets a textual representation of this assignable definition. */
|
||||||
string toString() { none() }
|
string toString() { none() }
|
||||||
|
|||||||
@@ -174,7 +174,9 @@ class VariableAccess extends AssignableAccess, @variable_access_expr {
|
|||||||
class VariableRead extends VariableAccess, AssignableRead {
|
class VariableRead extends VariableAccess, AssignableRead {
|
||||||
override VariableRead getANextRead() { result = AssignableRead.super.getANextRead() }
|
override VariableRead getANextRead() { result = AssignableRead.super.getANextRead() }
|
||||||
|
|
||||||
override VariableRead getAReachableRead() { result = AssignableRead.super.getAReachableRead() }
|
deprecated override VariableRead getAReachableRead() {
|
||||||
|
result = AssignableRead.super.getAReachableRead()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -200,7 +202,7 @@ class LocalScopeVariableAccess extends VariableAccess, @local_scope_variable_acc
|
|||||||
class LocalScopeVariableRead extends LocalScopeVariableAccess, VariableRead {
|
class LocalScopeVariableRead extends LocalScopeVariableAccess, VariableRead {
|
||||||
override LocalScopeVariableRead getANextRead() { result = VariableRead.super.getANextRead() }
|
override LocalScopeVariableRead getANextRead() { result = VariableRead.super.getANextRead() }
|
||||||
|
|
||||||
override LocalScopeVariableRead getAReachableRead() {
|
deprecated override LocalScopeVariableRead getAReachableRead() {
|
||||||
result = VariableRead.super.getAReachableRead()
|
result = VariableRead.super.getAReachableRead()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -242,7 +244,7 @@ class ParameterAccess extends LocalScopeVariableAccess, @parameter_access_expr {
|
|||||||
class ParameterRead extends ParameterAccess, LocalScopeVariableRead {
|
class ParameterRead extends ParameterAccess, LocalScopeVariableRead {
|
||||||
override ParameterRead getANextRead() { result = LocalScopeVariableRead.super.getANextRead() }
|
override ParameterRead getANextRead() { result = LocalScopeVariableRead.super.getANextRead() }
|
||||||
|
|
||||||
override ParameterRead getAReachableRead() {
|
deprecated override ParameterRead getAReachableRead() {
|
||||||
result = LocalScopeVariableRead.super.getAReachableRead()
|
result = LocalScopeVariableRead.super.getAReachableRead()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -297,7 +299,7 @@ class LocalVariableAccess extends LocalScopeVariableAccess, @local_variable_acce
|
|||||||
class LocalVariableRead extends LocalVariableAccess, LocalScopeVariableRead {
|
class LocalVariableRead extends LocalVariableAccess, LocalScopeVariableRead {
|
||||||
override LocalVariableRead getANextRead() { result = LocalScopeVariableRead.super.getANextRead() }
|
override LocalVariableRead getANextRead() { result = LocalScopeVariableRead.super.getANextRead() }
|
||||||
|
|
||||||
override LocalVariableRead getAReachableRead() {
|
deprecated override LocalVariableRead getAReachableRead() {
|
||||||
result = LocalScopeVariableRead.super.getAReachableRead()
|
result = LocalScopeVariableRead.super.getAReachableRead()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -442,7 +444,9 @@ class PropertyAccess extends AssignableMemberAccess, PropertyAccessExpr {
|
|||||||
class PropertyRead extends PropertyAccess, AssignableRead {
|
class PropertyRead extends PropertyAccess, AssignableRead {
|
||||||
override PropertyRead getANextRead() { result = AssignableRead.super.getANextRead() }
|
override PropertyRead getANextRead() { result = AssignableRead.super.getANextRead() }
|
||||||
|
|
||||||
override PropertyRead getAReachableRead() { result = AssignableRead.super.getAReachableRead() }
|
deprecated override PropertyRead getAReachableRead() {
|
||||||
|
result = AssignableRead.super.getAReachableRead()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -581,7 +585,9 @@ class IndexerAccess extends AssignableMemberAccess, ElementAccess, IndexerAccess
|
|||||||
class IndexerRead extends IndexerAccess, ElementRead {
|
class IndexerRead extends IndexerAccess, ElementRead {
|
||||||
override IndexerRead getANextRead() { result = ElementRead.super.getANextRead() }
|
override IndexerRead getANextRead() { result = ElementRead.super.getANextRead() }
|
||||||
|
|
||||||
override IndexerRead getAReachableRead() { result = ElementRead.super.getAReachableRead() }
|
deprecated override IndexerRead getAReachableRead() {
|
||||||
|
result = ElementRead.super.getAReachableRead()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -71,6 +71,20 @@ class FormatMethod extends Method {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pragma[nomagic]
|
||||||
|
private predicate parameterReadPostDominatesEntry(ParameterRead pr) {
|
||||||
|
pr.getAControlFlowNode().postDominates(pr.getEnclosingCallable().getEntryPoint()) and
|
||||||
|
getParameterType(pr.getTarget()) instanceof ObjectType
|
||||||
|
}
|
||||||
|
|
||||||
|
pragma[nomagic]
|
||||||
|
private predicate alwaysPassedToFormatItemParameter(ParameterRead pr) {
|
||||||
|
pr = any(StringFormatItemParameter other).getAnAssignedArgument() and
|
||||||
|
parameterReadPostDominatesEntry(pr)
|
||||||
|
or
|
||||||
|
alwaysPassedToFormatItemParameter(pr.getANextRead())
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A parameter that is used as a format item for `string.Format()`. Either a
|
* A parameter that is used as a format item for `string.Format()`. Either a
|
||||||
* format item parameter of `string.Format()`, or a parameter of a method that
|
* format item parameter of `string.Format()`, or a parameter of a method that
|
||||||
@@ -85,15 +99,9 @@ class StringFormatItemParameter extends Parameter {
|
|||||||
)
|
)
|
||||||
or
|
or
|
||||||
// Parameter of a source method that forwards to `string.Format()`
|
// Parameter of a source method that forwards to `string.Format()`
|
||||||
exists(
|
exists(AssignableDefinitions::ImplicitParameterDefinition def |
|
||||||
AssignableDefinitions::ImplicitParameterDefinition def, ParameterRead pr,
|
|
||||||
StringFormatItemParameter other
|
|
||||||
|
|
|
||||||
def.getParameter() = this and
|
def.getParameter() = this and
|
||||||
pr = def.getAReachableRead() and
|
alwaysPassedToFormatItemParameter(def.getAFirstRead())
|
||||||
pr.getAControlFlowNode().postDominates(this.getCallable().getEntryPoint()) and
|
|
||||||
other.getAnAssignedArgument() = pr and
|
|
||||||
getParameterType(this) instanceof ObjectType
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,12 +22,22 @@ private class DisposeCall extends MethodCall {
|
|||||||
DisposeCall() { this.getTarget() instanceof DisposeMethod }
|
DisposeCall() { this.getTarget() instanceof DisposeMethod }
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate localFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
pragma[nomagic]
|
||||||
DataFlow::localFlowStep(nodeFrom, nodeTo) and
|
private predicate isDisposedAccess(AssignableRead ar) {
|
||||||
not exists(AssignableDefinition def, UsingStmt us |
|
exists(AssignableDefinition def, UsingStmt us |
|
||||||
nodeTo.asExpr() = def.getAReachableRead() and
|
ar = def.getAFirstRead() and
|
||||||
def.getTargetAccess() = us.getAVariableDeclExpr().getAccess()
|
def.getTargetAccess() = us.getAVariableDeclExpr().getAccess()
|
||||||
)
|
)
|
||||||
|
or
|
||||||
|
exists(AssignableRead mid |
|
||||||
|
isDisposedAccess(mid) and
|
||||||
|
ar = mid.getANextRead()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private predicate localFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||||
|
DataFlow::localFlowStep(nodeFrom, nodeTo) and
|
||||||
|
not isDisposedAccess(nodeTo.asExpr())
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate reachesDisposeCall(DisposeCall disposeCall, DataFlow::Node node) {
|
private predicate reachesDisposeCall(DisposeCall disposeCall, DataFlow::Node node) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import semmle.code.csharp.frameworks.System
|
|||||||
* Holds if expression `e`, of type `t`, invokes `ToString()` either explicitly
|
* Holds if expression `e`, of type `t`, invokes `ToString()` either explicitly
|
||||||
* or implicitly.
|
* or implicitly.
|
||||||
*/
|
*/
|
||||||
|
pragma[nomagic]
|
||||||
predicate invokesToString(Expr e, ValueOrRefType t) {
|
predicate invokesToString(Expr e, ValueOrRefType t) {
|
||||||
// Explicit invocation
|
// Explicit invocation
|
||||||
exists(MethodCall mc | mc.getQualifier() = e |
|
exists(MethodCall mc | mc.getQualifier() = e |
|
||||||
@@ -20,20 +21,24 @@ predicate invokesToString(Expr e, ValueOrRefType t) {
|
|||||||
// Implicit invocation via forwarder method
|
// Implicit invocation via forwarder method
|
||||||
t = e.stripCasts().getType() and
|
t = e.stripCasts().getType() and
|
||||||
not t instanceof StringType and
|
not t instanceof StringType and
|
||||||
exists(Parameter p |
|
exists(AssignableDefinitions::ImplicitParameterDefinition def, Parameter p |
|
||||||
alwaysInvokesToStringOnParameter(p) and
|
def.getParameter() = p and
|
||||||
|
alwaysInvokesToString(def.getAFirstRead()) and
|
||||||
e = p.getAnAssignedArgument()
|
e = p.getAnAssignedArgument()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pragma[noinline]
|
pragma[nomagic]
|
||||||
private predicate alwaysInvokesToStringOnParameter(Parameter p) {
|
private predicate parameterReadPostDominatesEntry(ParameterRead pr) {
|
||||||
exists(AssignableDefinitions::ImplicitParameterDefinition def, ParameterRead pr |
|
pr.getAControlFlowNode().postDominates(pr.getEnclosingCallable().getEntryPoint())
|
||||||
def.getParameter() = p and
|
}
|
||||||
pr = def.getAReachableRead() and
|
|
||||||
pr.getAControlFlowNode().postDominates(p.getCallable().getEntryPoint()) and
|
pragma[nomagic]
|
||||||
invokesToString(pr, _)
|
private predicate alwaysInvokesToString(ParameterRead pr) {
|
||||||
)
|
parameterReadPostDominatesEntry(pr) and
|
||||||
|
invokesToString(pr, _)
|
||||||
|
or
|
||||||
|
alwaysInvokesToString(pr.getANextRead())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user