mirror of
https://github.com/github/codeql.git
synced 2026-04-24 08:15:14 +02:00
Merge pull request #15406 from hvitved/csharp/no-stats-experiment
C#: Remove all DB stats
This commit is contained in:
@@ -159,6 +159,11 @@ private module Annotations {
|
||||
getNoFlagsNullability(result) = getChildNullability(annotations.getNullability(), i)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private Nullability getChildNullability0(Nullability n, int i) {
|
||||
nullability_parent(getNullability(result), i, getNullability(n))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `i`th child of nullability `n`.
|
||||
* Returns `n` if the nullability is not explicitly
|
||||
@@ -167,9 +172,10 @@ private module Annotations {
|
||||
*/
|
||||
bindingset[i]
|
||||
Nullability getChildNullability(Nullability n, int i) {
|
||||
if nullability_parent(_, i, getNullability(n))
|
||||
then nullability_parent(getNullability(result), i, getNullability(n))
|
||||
else result = n
|
||||
result = getChildNullability0(n, i)
|
||||
or
|
||||
not exists(getChildNullability0(n, i)) and
|
||||
result = n
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -276,6 +282,11 @@ private Annotations::Nullability getElementNullability(@has_type_annotation elem
|
||||
else result instanceof Annotations::NoNullability
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate isNoFlagsNoNullability(Annotations::TypeAnnotations annotations) {
|
||||
Annotations::getNoFlagsNullability(annotations) instanceof Annotations::NoNullability
|
||||
}
|
||||
|
||||
private newtype TAnnotatedType =
|
||||
TAnnotatedTypeNullability(Type type, Annotations::TypeAnnotations annotations) {
|
||||
Annotations::elementTypeAnnotations(_, type, annotations)
|
||||
@@ -288,7 +299,7 @@ private newtype TAnnotatedType =
|
||||
Annotations::getNoFlagsNullability(annotations) = getTypeParameterNullability(_, type)
|
||||
or
|
||||
// All types have at least one annotated type
|
||||
Annotations::getNoFlagsNullability(annotations) instanceof Annotations::NoNullability
|
||||
isNoFlagsNoNullability(annotations) and exists(type)
|
||||
or
|
||||
exists(AnnotatedArrayType at |
|
||||
type = at.getType().(ArrayType).getElementType() and
|
||||
|
||||
@@ -95,10 +95,16 @@ private string getTypeArgumentsToString(ConstructedGeneric cg) {
|
||||
strictconcat(Type t, int i | t = cg.getTypeArgument(i) | t.toStringWithTypes(), ", " order by i)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private string getTypeArgumentName(ConstructedGeneric cg, int i) {
|
||||
result = cg.getTypeArgument(i).getName()
|
||||
}
|
||||
|
||||
/** Gets the concatenation of the `getName()` of type arguments. */
|
||||
language[monotonicAggregates]
|
||||
private string getTypeArgumentsNames(ConstructedGeneric cg) {
|
||||
result = strictconcat(Type t, int i | t = cg.getTypeArgument(i) | t.getName(), "," order by i)
|
||||
result =
|
||||
strictconcat(int i | exists(cg.getTypeArgument(i)) | getTypeArgumentName(cg, i), "," order by i)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -197,9 +203,9 @@ class TypeParameter extends DotNet::TypeParameter, Type, @type_parameter {
|
||||
// A<int>.B<T2> is a partially constructed UnboundGenericClass and
|
||||
// A<int>.B<int> is a ConstructedGenericClass.
|
||||
exists(ConstructedGeneric c, UnboundGeneric u, int tpi |
|
||||
this = u.getTypeParameter(tpi) and
|
||||
this = u.getTypeParameter(pragma[only_bind_into](tpi)) and
|
||||
(u = c.getUnboundGeneric() or u = c.getUnboundDeclaration()) and
|
||||
result = c.getTypeArgument(tpi)
|
||||
result = c.getTypeArgument(pragma[only_bind_into](tpi))
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -108,28 +108,29 @@ private predicate hasMemberCompatibleWithInterfaceMember(ValueOrRefType t, Virtu
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private Virtualizable getACompatibleInterfaceMember(Virtualizable m) {
|
||||
result = getACompatibleInterfaceMemberAux(m) and
|
||||
(
|
||||
exists(ValueOrRefType declType | result = getACompatibleInterfaceMemberAux(m, declType) |
|
||||
// If there is both an implicit and an explicit compatible member
|
||||
// in the same type, then the explicit implementation must be used
|
||||
not result = getACompatibleExplicitInterfaceMember(_, m.getDeclaringType())
|
||||
not result = getACompatibleExplicitInterfaceMember(_, declType)
|
||||
or
|
||||
result = getACompatibleExplicitInterfaceMember(m, m.getDeclaringType())
|
||||
result = getACompatibleExplicitInterfaceMember(m, declType)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private Virtualizable getACompatibleExplicitInterfaceMember(Virtualizable m, ValueOrRefType declType) {
|
||||
result = getACompatibleInterfaceMemberAux(m) and
|
||||
declType = m.getDeclaringType() and
|
||||
result = getACompatibleInterfaceMemberAux(m, declType) and
|
||||
m.implementsExplicitInterface()
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private Virtualizable getACompatibleInterfaceMemberAux(Virtualizable m) {
|
||||
result = getACompatibleInterfaceAccessor(m) or
|
||||
result = getACompatibleInterfaceIndexer(m) or
|
||||
result = getACompatibleRelevantInterfaceMember(m)
|
||||
private Virtualizable getACompatibleInterfaceMemberAux(Virtualizable m, ValueOrRefType declType) {
|
||||
(
|
||||
result = getACompatibleInterfaceAccessor(m) or
|
||||
result = getACompatibleInterfaceIndexer(m) or
|
||||
result = getACompatibleRelevantInterfaceMember(m)
|
||||
) and
|
||||
declType = m.getDeclaringType()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,13 +183,16 @@ ValueOrRefType getAPossibleImplementor(Interface i) {
|
||||
not result instanceof Interface
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private Type getParameterType(Parameterizable p, int i) { result = p.getParameter(i).getType() }
|
||||
|
||||
private Indexer getACompatibleInterfaceIndexer0(Indexer i, int j) {
|
||||
result = getACompatibleInterfaceIndexerCandidate(i) and
|
||||
convIdentity(i.getType(), result.getType()) and
|
||||
j = -1
|
||||
or
|
||||
result = getACompatibleInterfaceIndexer0(i, j - 1) and
|
||||
convIdentity(i.getParameter(j).getType(), result.getParameter(j).getType())
|
||||
convIdentity(getParameterType(i, j), getParameterType(result, j))
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -49,11 +49,20 @@ module QualifiedName<QualifiedNameInputSig Input> {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private string getTypeArgumentsQualifiedName(ConstructedGeneric cg, int i) {
|
||||
result = getFullName(cg.getTypeArgument(i))
|
||||
}
|
||||
|
||||
/** Gets the concatenation of the `getFullName` of type arguments. */
|
||||
language[monotonicAggregates]
|
||||
private string getTypeArgumentsQualifiedNames(ConstructedGeneric cg) {
|
||||
result =
|
||||
strictconcat(Type t, int i | t = cg.getTypeArgument(i) | getFullName(t), "," order by i)
|
||||
strictconcat(int i |
|
||||
exists(cg.getTypeArgument(i))
|
||||
|
|
||||
getTypeArgumentsQualifiedName(cg, i), "," order by i
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if declaration `d` has the qualified name `qualifier`.`name`. */
|
||||
|
||||
@@ -195,8 +195,6 @@ predicate toGvn = toGvnCached/1;
|
||||
/**
|
||||
* Holds if the control flow elements `x` and `y` are structurally equal.
|
||||
*/
|
||||
pragma[inline]
|
||||
predicate sameGvn(ControlFlowElement x, ControlFlowElement y) {
|
||||
pragma[only_bind_into](toGvn(pragma[only_bind_out](x))) =
|
||||
pragma[only_bind_into](toGvn(pragma[only_bind_out](y)))
|
||||
}
|
||||
bindingset[x, y]
|
||||
pragma[inline_late]
|
||||
predicate sameGvn(ControlFlowElement x, ControlFlowElement y) { toGvn(x) = toGvn(y) }
|
||||
|
||||
@@ -1013,12 +1013,18 @@ module Internal {
|
||||
* Holds if pre-basic-block `bb` only is reached when guard `g` has abstract value `v`,
|
||||
* not taking implications into account.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate preControlsDirect(Guard g, PreBasicBlocks::PreBasicBlock bb, AbstractValue v) {
|
||||
exists(PreBasicBlocks::ConditionBlock cb, ConditionalSuccessor s | cb.controls(bb, s) |
|
||||
v.branch(cb.getLastElement(), s, g)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate preControlsDefDirect(Guard g, PreSsa::Definition def, AbstractValue v) {
|
||||
preControlsDirect(g, def.getBasicBlock(), v)
|
||||
}
|
||||
|
||||
/** Holds if pre-basic-block `bb` only is reached when guard `g` has abstract value `v`. */
|
||||
predicate preControls(Guard g, PreBasicBlocks::PreBasicBlock bb, AbstractValue v) {
|
||||
preControlsDirect(g, bb, v)
|
||||
@@ -1111,36 +1117,47 @@ module Internal {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
pragma[nomagic]
|
||||
private predicate conditionalAssign0(
|
||||
Guard guard, AbstractValue vGuard, PreSsa::PhiNode phi, Expr e, PreSsa::Definition upd,
|
||||
PreBasicBlocks::PreBasicBlock bbGuard
|
||||
PreBasicBlocks::PreBasicBlock bbGuard, PreBasicBlocks::PreBasicBlock bbPhi
|
||||
) {
|
||||
e = upd.getDefinition().getSource() and
|
||||
upd = phi.getAnInput() and
|
||||
preControlsDirect(guard, upd.getBasicBlock(), vGuard) and
|
||||
preControlsDefDirect(guard, upd, vGuard) and
|
||||
bbGuard.getAnElement() = guard and
|
||||
bbGuard.strictlyDominates(phi.getBasicBlock()) and
|
||||
not preControlsDirect(guard, phi.getBasicBlock(), vGuard)
|
||||
bbPhi = phi.getBasicBlock()
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate conditionalAssign1(
|
||||
Guard guard, AbstractValue vGuard, PreSsa::PhiNode phi, Expr e, PreSsa::Definition upd,
|
||||
PreBasicBlocks::PreBasicBlock bbGuard
|
||||
) {
|
||||
exists(PreBasicBlocks::PreBasicBlock bbPhi |
|
||||
conditionalAssign0(guard, vGuard, phi, e, upd, bbGuard, bbPhi) and
|
||||
bbGuard.strictlyDominates(bbPhi) and
|
||||
not preControlsDefDirect(guard, phi, vGuard)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate conditionalAssign2(
|
||||
Guard guard, AbstractValue vGuard, PreSsa::PhiNode phi, Expr e, PreSsa::Definition upd,
|
||||
PreBasicBlocks::PreBasicBlock bbGuard, PreSsa::Definition other
|
||||
) {
|
||||
conditionalAssign0(guard, vGuard, phi, e, upd, bbGuard) and
|
||||
conditionalAssign1(guard, vGuard, phi, e, upd, bbGuard) and
|
||||
other != upd and
|
||||
other = phi.getAnInput()
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate conditionalAssign2(
|
||||
private predicate conditionalAssign3(
|
||||
Guard guard, AbstractValue vGuard, PreSsa::Definition def, Expr e, PreSsa::Definition upd,
|
||||
PreBasicBlocks::PreBasicBlock bbGuard, PreSsa::Definition other
|
||||
) {
|
||||
conditionalAssign1(guard, vGuard, def, e, upd, bbGuard, other) and
|
||||
preControlsDirect(guard, other.getBasicBlock(), vGuard.getDualValue())
|
||||
conditionalAssign2(guard, vGuard, def, e, upd, bbGuard, other) and
|
||||
preControlsDefDirect(guard, other, vGuard.getDualValue())
|
||||
}
|
||||
|
||||
/** Gets the successor block that is reached when guard `g` has abstract value `v`. */
|
||||
@@ -1153,11 +1170,11 @@ module Internal {
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate conditionalAssign3(
|
||||
private predicate conditionalAssign4(
|
||||
Guard guard, AbstractValue vGuard, PreSsa::Definition def, Expr e, PreSsa::Definition upd,
|
||||
PreBasicBlocks::PreBasicBlock bbGuard, PreSsa::Definition other
|
||||
) {
|
||||
conditionalAssign1(guard, vGuard, def, e, upd, bbGuard, other) and
|
||||
conditionalAssign2(guard, vGuard, def, e, upd, bbGuard, other) and
|
||||
other.getBasicBlock().dominates(bbGuard) and
|
||||
not other.isLiveAtEndOfBlock(getConditionalSuccessor(guard, vGuard))
|
||||
}
|
||||
@@ -1184,10 +1201,10 @@ module Internal {
|
||||
)
|
||||
or
|
||||
exists(PreSsa::Definition upd, PreBasicBlocks::PreBasicBlock bbGuard |
|
||||
conditionalAssign0(guard, vGuard, def, e, upd, bbGuard)
|
||||
conditionalAssign1(guard, vGuard, def, e, upd, bbGuard)
|
||||
|
|
||||
forall(PreSsa::Definition other |
|
||||
conditionalAssign1(guard, vGuard, def, e, upd, bbGuard, other)
|
||||
conditionalAssign2(guard, vGuard, def, e, upd, bbGuard, other)
|
||||
|
|
||||
// For example:
|
||||
// if (guard)
|
||||
@@ -1195,14 +1212,14 @@ module Internal {
|
||||
// else
|
||||
// other = b;
|
||||
// def = phi(upd, other)
|
||||
conditionalAssign2(guard, vGuard, def, e, upd, bbGuard, other)
|
||||
conditionalAssign3(guard, vGuard, def, e, upd, bbGuard, other)
|
||||
or
|
||||
// For example:
|
||||
// other = a;
|
||||
// if (guard)
|
||||
// upd = b;
|
||||
// def = phi(other, upd)
|
||||
conditionalAssign3(guard, vGuard, def, e, upd, bbGuard, other)
|
||||
conditionalAssign4(guard, vGuard, def, e, upd, bbGuard, other)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -49,7 +49,10 @@ private newtype TCompletion =
|
||||
nestedFinallyCompletion(outer, nestLevel)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
pragma[nomagic]
|
||||
private int getAFinallyNestLevel() { result = any(Statements::TryStmtTree t).nestLevel() }
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate nestedFinallyCompletion(Completion outer, int nestLevel) {
|
||||
(
|
||||
outer = TReturnCompletion()
|
||||
@@ -64,7 +67,7 @@ private predicate nestedFinallyCompletion(Completion outer, int nestLevel) {
|
||||
or
|
||||
outer = TExitCompletion()
|
||||
) and
|
||||
nestLevel = any(Statements::TryStmtTree t).nestLevel()
|
||||
nestLevel = getAFinallyNestLevel()
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
|
||||
@@ -75,8 +75,10 @@ class PreBasicBlock extends ControlFlowElement {
|
||||
|
||||
predicate immediatelyDominates(PreBasicBlock bb) { bbIDominates(this, bb) }
|
||||
|
||||
pragma[inline]
|
||||
predicate strictlyDominates(PreBasicBlock bb) { this.immediatelyDominates+(bb) }
|
||||
|
||||
pragma[inline]
|
||||
predicate dominates(PreBasicBlock bb) {
|
||||
bb = this
|
||||
or
|
||||
@@ -97,6 +99,7 @@ class ConditionBlock extends PreBasicBlock {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate immediatelyControls(PreBasicBlock succ, ConditionalCompletion cc) {
|
||||
exists(ControlFlowElement last, Completion c |
|
||||
last = this.getLastElement() and
|
||||
|
||||
@@ -121,12 +121,19 @@ class OverridableCallable extends Callable, Overridable {
|
||||
result = c.getDeclaringType()
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate isDeclaringSubType(ValueOrRefType t) {
|
||||
t = this.getDeclaringType()
|
||||
or
|
||||
exists(ValueOrRefType mid | this.isDeclaringSubType(mid) | t = mid.getASubType())
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate isDeclaringSubType(ValueOrRefType t, ValueOrRefType sub) {
|
||||
this.isDeclaringSubType(t) and
|
||||
t = sub.getABaseType()
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private Callable getAnOverrider0(ValueOrRefType t) {
|
||||
// A (transitive) overrider
|
||||
@@ -155,10 +162,7 @@ class OverridableCallable extends Callable, Overridable {
|
||||
Callable getAnOverrider(ValueOrRefType t) {
|
||||
result = this.getAnOverrider0(t)
|
||||
or
|
||||
exists(ValueOrRefType mid | result = this.getAnOverrider(mid) |
|
||||
t = mid.getABaseType() and
|
||||
this.isDeclaringSubType(t)
|
||||
)
|
||||
exists(ValueOrRefType mid | result = this.getAnOverrider(mid) | this.isDeclaringSubType(t, mid))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,6 +15,12 @@ import csharp
|
||||
import semmle.code.csharp.security.dataflow.UnsafeDeserializationQuery
|
||||
import Flow::PathGraph
|
||||
|
||||
bindingset[e1, e2]
|
||||
pragma[inline_late]
|
||||
private predicate sameParent(DataFlow::Node e1, DataFlow::Node e2) {
|
||||
e1.asExpr().getParent() = e2.asExpr().getParent()
|
||||
}
|
||||
|
||||
module Flow =
|
||||
DataFlow::MergePathGraph3<TaintToObjectMethodTracking::PathNode,
|
||||
TaintToConstructorOrStaticMethodTracking::PathNode, JsonConvertTracking::PathNode,
|
||||
@@ -48,7 +54,7 @@ where
|
||||
exists(DataFlow::Node settingsCallArg |
|
||||
JsonConvertTracking::flowPath(userInput.asPathNode3(), deserializeCallArg.asPathNode3()) and
|
||||
TypeNameTracking::flow(_, settingsCallArg) and
|
||||
deserializeCallArg.getNode().asExpr().getParent() = settingsCallArg.asExpr().getParent()
|
||||
sameParent(deserializeCallArg.getNode(), settingsCallArg)
|
||||
)
|
||||
select deserializeCallArg, userInput, deserializeCallArg, "$@ flows to unsafe deserializer.",
|
||||
userInput, "User-provided data"
|
||||
|
||||
Reference in New Issue
Block a user