Merge branch 'main' into python-db-models

This commit is contained in:
sylwia-budzynska
2022-10-13 16:48:50 +02:00
committed by GitHub
349 changed files with 3168 additions and 1527 deletions

View File

@@ -70,7 +70,6 @@
"python/ql/lib/semmle/python/dataflow/new/internal/tainttracking3/TaintTrackingImpl.qll",
"python/ql/lib/semmle/python/dataflow/new/internal/tainttracking4/TaintTrackingImpl.qll",
"ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
"ruby/ql/lib/codeql/ruby/dataflow/internal/tainttrackingforregexp/TaintTrackingImpl.qll",
"swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTrackingImpl.qll"
],
"DataFlow Java/C++/C#/Python Consistency checks": [

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -137,7 +137,7 @@ private newtype TReturnKind =
exists(IndirectReturnNode return, ReturnIndirectionInstruction returnInd |
returnInd.hasIndex(argumentIndex) and
return.getAddressOperand() = returnInd.getSourceAddressOperand() and
indirectionIndex = return.getIndirectionIndex() - 1 // We subtract one because the return loads the value.
indirectionIndex = return.getIndirectionIndex()
)
}
@@ -197,7 +197,7 @@ class ReturnIndirectionNode extends IndirectReturnNode, ReturnNode {
exists(int argumentIndex, ReturnIndirectionInstruction returnInd |
returnInd.hasIndex(argumentIndex) and
this.getAddressOperand() = returnInd.getSourceAddressOperand() and
result = TIndirectReturnKind(argumentIndex, this.getIndirectionIndex() - 1) and
result = TIndirectReturnKind(argumentIndex, this.getIndirectionIndex()) and
hasNonInitializeParameterDef(returnInd.getIRVariable())
)
or
@@ -365,7 +365,7 @@ predicate jumpStep(Node n1, Node n2) {
predicate storeStep(Node node1, Content c, PostFieldUpdateNode node2) {
exists(int indirectionIndex1, int numberOfLoads, StoreInstruction store |
nodeHasInstruction(node1, store, pragma[only_bind_into](indirectionIndex1)) and
node2.getIndirectionIndex() = 0 and
node2.getIndirectionIndex() = 1 and
numberOfLoadsFromOperand(node2.getFieldAddress(), store.getDestinationAddressOperand(),
numberOfLoads)
|
@@ -465,20 +465,20 @@ predicate clearsContent(Node n, Content c) {
predicate expectsContent(Node n, ContentSet c) { none() }
/** Gets the type of `n` used for type pruning. */
IRType getNodeType(Node n) {
DataFlowType getNodeType(Node n) {
suppressUnusedNode(n) and
result instanceof IRVoidType // stub implementation
result instanceof VoidType // stub implementation
}
/** Gets a string representation of a type returned by `getNodeType`. */
string ppReprType(IRType t) { none() } // stub implementation
string ppReprType(DataFlowType t) { none() } // stub implementation
/**
* Holds if `t1` and `t2` are compatible, that is, whether data can flow from
* a node of type `t1` to a node of type `t2`.
*/
pragma[inline]
predicate compatibleTypes(IRType t1, IRType t2) {
predicate compatibleTypes(DataFlowType t1, DataFlowType t2) {
any() // stub implementation
}
@@ -502,7 +502,7 @@ class DataFlowCallable = Cpp::Declaration;
class DataFlowExpr = Expr;
class DataFlowType = IRType;
class DataFlowType = Type;
/** A function call relevant for data flow. */
class DataFlowCall extends CallInstruction {

View File

@@ -38,13 +38,12 @@ private module Cached {
TVariableNode(Variable var) or
TPostFieldUpdateNode(FieldAddress operand, int indirectionIndex) {
indirectionIndex =
[0 .. Ssa::countIndirectionsForCppType(operand.getObjectAddress().getResultLanguageType()) -
1]
[1 .. Ssa::countIndirectionsForCppType(operand.getObjectAddress().getResultLanguageType())]
} or
TSsaPhiNode(Ssa::PhiNode phi) or
TIndirectArgumentOutNode(ArgumentOperand operand, int indirectionIndex) {
Ssa::isModifiableByCall(operand) and
indirectionIndex = [0 .. Ssa::countIndirectionsForCppType(operand.getLanguageType()) - 1]
indirectionIndex = [1 .. Ssa::countIndirectionsForCppType(operand.getLanguageType())]
} or
TIndirectOperand(Operand op, int indirectionIndex) {
Ssa::hasIndirectOperand(op, indirectionIndex)
@@ -113,7 +112,7 @@ class Node extends TIRDataFlowNode {
Declaration getFunction() { none() } // overridden in subclasses
/** Gets the type of this node. */
IRType getType() { none() } // overridden in subclasses
DataFlowType getType() { none() } // overridden in subclasses
/** Gets the instruction corresponding to this node, if any. */
Instruction asInstruction() { result = this.(InstructionNode).getInstruction() }
@@ -230,7 +229,13 @@ class Node extends TIRDataFlowNode {
Expr asIndirectArgument() { result = this.asIndirectArgument(_) }
/** Gets the positional parameter corresponding to this node, if any. */
Parameter asParameter() { result = asParameter(0) }
Parameter asParameter() { result = this.asParameter(0) }
/**
* Gets the uninitialized local variable corresponding to this node, if
* any.
*/
LocalVariable asUninitialized() { result = this.(UninitializedNode).getLocalVariable() }
/**
* Gets the positional parameter corresponding to the node that represents
@@ -273,7 +278,7 @@ class Node extends TIRDataFlowNode {
/**
* Gets an upper bound on the type of this node.
*/
IRType getTypeBound() { result = this.getType() }
DataFlowType getTypeBound() { result = this.getType() }
/** Gets the location of this element. */
cached
@@ -322,7 +327,7 @@ class InstructionNode extends Node, TInstructionNode {
override Declaration getFunction() { result = instr.getEnclosingFunction() }
override IRType getType() { result = instr.getResultIRType() }
override DataFlowType getType() { result = instr.getResultType() }
final override Location getLocationImpl() { result = instr.getLocation() }
@@ -348,13 +353,32 @@ class OperandNode extends Node, TOperandNode {
override Declaration getFunction() { result = op.getUse().getEnclosingFunction() }
override IRType getType() { result = op.getIRType() }
override DataFlowType getType() { result = op.getType() }
final override Location getLocationImpl() { result = op.getLocation() }
override string toStringImpl() { result = this.getOperand().toString() }
}
/**
* Returns `t`, but stripped of the `n` outermost pointers, references, etc.
*
* For example, `stripPointers(int*&, 2)` is `int` and `stripPointers(int*, 0)` is `int*`.
*/
private Type stripPointers(Type t, int n) {
result = t and n = 0
or
result = stripPointers(t.(PointerType).getBaseType(), n - 1)
or
result = stripPointers(t.(ArrayType).getBaseType(), n - 1)
or
result = stripPointers(t.(ReferenceType).getBaseType(), n - 1)
or
result = stripPointers(t.(PointerToMemberType).getBaseType(), n - 1)
or
result = stripPointers(t.(FunctionPointerIshType).getBaseType(), n - 1)
}
/**
* INTERNAL: do not use.
*
@@ -370,8 +394,6 @@ class PostFieldUpdateNode extends TPostFieldUpdateNode, PartialDefinitionNode {
override Declaration getEnclosingCallable() { result = this.getFunction() }
override IRType getType() { result = fieldAddress.getIRType() }
FieldAddress getFieldAddress() { result = fieldAddress }
Field getUpdatedField() { result = fieldAddress.getField() }
@@ -379,10 +401,8 @@ class PostFieldUpdateNode extends TPostFieldUpdateNode, PartialDefinitionNode {
int getIndirectionIndex() { result = indirectionIndex }
override Node getPreUpdateNode() {
// + 1 because we're storing into an lvalue, and the original node should be the rvalue of
// the same address.
hasOperandAndIndex(result, pragma[only_bind_into](fieldAddress).getObjectAddressOperand(),
indirectionIndex + 1)
indirectionIndex)
}
override Expr getDefinedExpr() {
@@ -411,7 +431,7 @@ class SsaPhiNode extends Node, TSsaPhiNode {
override Declaration getFunction() { result = phi.getBasicBlock().getEnclosingFunction() }
override IRType getType() { result instanceof IRVoidType }
override DataFlowType getType() { result = this.getAnInput().getType() }
final override Location getLocationImpl() { result = phi.getBasicBlock().getLocation() }
@@ -454,8 +474,6 @@ class SideEffectOperandNode extends Node, IndirectOperand {
override Function getFunction() { result = call.getEnclosingFunction() }
override IRType getType() { result instanceof IRVoidType }
Expr getArgument() { result = call.getArgument(argumentIndex).getUnconvertedResultExpression() }
}
@@ -478,8 +496,6 @@ class IndirectParameterNode extends Node, IndirectInstruction {
override Function getFunction() { result = this.getInstruction().getEnclosingFunction() }
override IRType getType() { result instanceof IRVoidType }
override string toStringImpl() {
result = this.getParameter().toString() + " indirection"
or
@@ -504,8 +520,6 @@ class IndirectReturnNode extends IndirectOperand {
Operand getAddressOperand() { result = operand }
override Declaration getEnclosingCallable() { result = this.getFunction() }
override IRType getType() { result instanceof IRVoidType }
}
/**
@@ -536,9 +550,7 @@ class IndirectArgumentOutNode extends Node, TIndirectArgumentOutNode, PostUpdate
override Function getFunction() { result = this.getCallInstruction().getEnclosingFunction() }
override IRType getType() { result instanceof IRVoidType }
override Node getPreUpdateNode() { hasOperandAndIndex(result, operand, indirectionIndex + 1) }
override Node getPreUpdateNode() { hasOperandAndIndex(result, operand, indirectionIndex) }
override string toStringImpl() {
// This string should be unique enough to be helpful but common enough to
@@ -594,6 +606,38 @@ class IndirectReturnOutNode extends Node {
int getIndirectionIndex() { result = indirectionIndex }
}
private PointerType getGLValueType(Type t, int indirectionIndex) {
result.getBaseType() = stripPointers(t, indirectionIndex - 1)
}
bindingset[isGLValue]
private DataFlowType getTypeImpl(Type t, int indirectionIndex, boolean isGLValue) {
if isGLValue = true
then
result = getGLValueType(t, indirectionIndex)
or
// Ideally, the above case would cover all glvalue cases. However, consider the case where
// the database consists only of:
// ```
// void test() {
// int* x;
// x = nullptr;
// }
// ```
// and we want to compute the type of `*x` in the assignment `x = nullptr`. Here, `x` is an lvalue
// of type int* (which morally is an int**). So when we call `getTypeImpl` it will be with the
// parameters:
// - t = int*
// - indirectionIndex = 1 (when we want to model the dataflow node corresponding to *x)
// - isGLValue = true
// In this case, `getTypeImpl(t, indirectionIndex, isGLValue)` should give back `int**`. In this
// case, however, `int**` does not exist in the database. So instead we return int* (which is
// wrong, but at least we have a type).
not exists(getGLValueType(t, indirectionIndex)) and
result = stripPointers(t, indirectionIndex - 1)
else result = stripPointers(t, indirectionIndex)
}
/**
* INTERNAL: Do not use.
*
@@ -615,7 +659,11 @@ class IndirectOperand extends Node, TIndirectOperand {
override Declaration getEnclosingCallable() { result = this.getFunction() }
override IRType getType() { result = this.getOperand().getIRType() }
override DataFlowType getType() {
exists(boolean isGLValue | if operand.isGLValue() then isGLValue = true else isGLValue = false |
result = getTypeImpl(operand.getType().getUnspecifiedType(), indirectionIndex, isGLValue)
)
}
final override Location getLocationImpl() { result = this.getOperand().getLocation() }
@@ -624,6 +672,25 @@ class IndirectOperand extends Node, TIndirectOperand {
}
}
/**
* The value of an uninitialized local variable, viewed as a node in a data
* flow graph.
*/
class UninitializedNode extends Node {
LocalVariable v;
UninitializedNode() {
exists(Ssa::Def def |
def.getDefiningInstruction() instanceof UninitializedInstruction and
Ssa::nodeToDefOrUse(this, def) and
v = def.getSourceVariable().getBaseVariable().(Ssa::BaseIRVariable).getIRVariable().getAst()
)
}
/** Gets the uninitialized local variable corresponding to this node. */
LocalVariable getLocalVariable() { result = v }
}
/**
* INTERNAL: Do not use.
*
@@ -645,7 +712,11 @@ class IndirectInstruction extends Node, TIndirectInstruction {
override Declaration getEnclosingCallable() { result = this.getFunction() }
override IRType getType() { result = this.getInstruction().getResultIRType() }
override DataFlowType getType() {
exists(boolean isGLValue | if instr.isGLValue() then isGLValue = true else isGLValue = false |
result = getTypeImpl(instr.getResultType().getUnspecifiedType(), indirectionIndex, isGLValue)
)
}
final override Location getLocationImpl() { result = this.getInstruction().getLocation() }
@@ -859,6 +930,8 @@ abstract class PostUpdateNode extends Node {
* Gets the node before the state update.
*/
abstract Node getPreUpdateNode();
final override DataFlowType getType() { result = this.getPreUpdateNode().getType() }
}
/**
@@ -922,7 +995,7 @@ class VariableNode extends Node, TVariableNode {
result = v
}
override IRType getType() { result.getCanonicalLanguageType().hasUnspecifiedType(v.getType(), _) }
override DataFlowType getType() { result = v.getType() }
final override Location getLocationImpl() { result = v.getLocation() }
@@ -1075,7 +1148,7 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
store.getDestinationAddressOperand() = address
)
or
Ssa::outNodeHasAddressAndIndex(nodeFrom, address, indirectionIndex - 1)
Ssa::outNodeHasAddressAndIndex(nodeFrom, address, indirectionIndex)
)
}

View File

@@ -41,7 +41,7 @@ Node callOutput(CallInstruction call, FunctionOutput output) {
// The side effect of a call on the value pointed to by an argument or qualifier
exists(int index, int indirectionIndex |
result.(IndirectArgumentOutNode).getArgumentIndex() = index and
result.(IndirectArgumentOutNode).getIndirectionIndex() + 1 = indirectionIndex and
result.(IndirectArgumentOutNode).getIndirectionIndex() = indirectionIndex and
result.(IndirectArgumentOutNode).getCallInstruction() = call and
output.isParameterDerefOrQualifierObject(index, indirectionIndex)
)

View File

@@ -11,7 +11,9 @@ private import DataFlowUtil
* corresponding `(Indirect)OperandNode`.
*/
predicate ignoreOperand(Operand operand) {
operand = any(Instruction instr | ignoreInstruction(instr)).getAnOperand()
operand = any(Instruction instr | ignoreInstruction(instr)).getAnOperand() or
operand = any(Instruction instr | ignoreInstruction(instr)).getAUse() or
operand instanceof MemoryOperand
}
/**

View File

@@ -36,7 +36,7 @@ private module SourceVariables {
override string toString() { result = var.toString() }
override DataFlowType getType() { result = var.getIRType() }
override DataFlowType getType() { result = var.getType() }
}
class BaseCallVariable extends BaseSourceVariable, TBaseCallVariable {
@@ -48,7 +48,7 @@ private module SourceVariables {
override string toString() { result = call.toString() }
override DataFlowType getType() { result = call.getResultIRType() }
override DataFlowType getType() { result = call.getResultType() }
}
private newtype TSourceVariable =

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -0,0 +1,32 @@
/*
* In this example, the developer intended to use a semicolon but accidentally used a comma:
*/
enum privileges entitlements = NONE;
if (is_admin)
entitlements = FULL, // BAD
restrict_privileges(entitlements);
/*
* The use of a comma means that the first example is equivalent to this second example:
*/
enum privileges entitlements = NONE;
if (is_admin) {
entitlements = FULL;
restrict_privileges(entitlements);
}
/*
* The indentation of the first example suggests that the developer probably intended the following code:
*/
enum privileges entitlements = NONE;
if (is_admin)
entitlements = FULL; // GOOD
restrict_privileges(entitlements);

View File

@@ -0,0 +1,39 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>
If the expression after the comma operator starts at an earlier column than the expression before the comma, then
this suspicious indentation possibly indicates a logic error, caused by a typo that may escape visual inspection.
</p>
<warning>
This query has medium precision because CodeQL currently does not distinguish between tabs and spaces in whitespace.
If a file contains mixed tabs and spaces, alerts may highlight code that is correctly indented for one value of tab size but not for other tab sizes.
</warning>
</overview>
<recommendation>
<p>
To ensure that your code is easy to read and review, use standard indentation around the comma operator. Always begin the right-hand-side operand at the same level of
indentation (column number) as the left-hand-side operand. This makes it easier for other developers to see the intended behavior of your code.
</p>
<p>
Use whitespace consistently to communicate your coding intentions. Where possible, avoid mixing tabs and spaces within a file. If you need to mix them, use them consistently.
</p>
</recommendation>
<example>
<p>
This example shows three different ways of writing the same code. The first example contains a comma instead of a semicolon which means that the final line is part of the <code>if</code> statement, even though the indentation suggests that it is intended to be separate. The second example looks different but is functionally the same as the first example. It is more likely that the developer intended to write the third example.
</p>
<sample src="CommaBeforeMisleadingIndentation.cpp" />
</example>
<references>
<li>Wikipedia: <a href="https://en.wikipedia.org/wiki/Comma_operator">Comma operator</a></li>
<li>Wikipedia: <a href="https://en.wikipedia.org/wiki/Indentation_style#Tabs,_spaces,_and_size_of_indentations">Indentation style &mdash; Tabs, spaces, and size of indentations</a></li>
</references>
</qhelp>

View File

@@ -0,0 +1,53 @@
/**
* @name Comma before misleading indentation
* @description If expressions before and after a comma operator use different indentation, it is easy to misread the purpose of the code.
* @kind problem
* @id cpp/comma-before-misleading-indentation
* @problem.severity warning
* @security-severity 7.8
* @precision medium
* @tags maintainability
* readability
* security
* external/cwe/cwe-1078
* external/cwe/cwe-670
*/
import cpp
import semmle.code.cpp.commons.Exclusions
/** Gets the sub-expression of 'e' with the earliest-starting Location */
Expr normalizeExpr(Expr e) {
result =
min(Expr child |
child.getParentWithConversions*() = e.getFullyConverted() and
not child.getParentWithConversions*() = any(Call c).getAnArgument()
|
child order by child.getLocation().getStartColumn(), count(child.getParentWithConversions*())
)
}
predicate isParenthesized(CommaExpr ce) {
ce.getParent*().(Expr).isParenthesised()
or
ce.isUnevaluated() // sizeof(), decltype(), alignof(), noexcept(), typeid()
or
ce.getParent*() = [any(IfStmt i).getCondition(), any(SwitchStmt s).getExpr()]
or
ce.getParent*() = [any(Loop l).getCondition(), any(ForStmt f).getUpdate()]
or
ce.getEnclosingStmt() = any(ForStmt f).getInitialization()
}
from CommaExpr ce, Expr left, Expr right, Location leftLoc, Location rightLoc
where
ce.fromSource() and
not isFromMacroDefinition(ce) and
left = normalizeExpr(ce.getLeftOperand()) and
right = normalizeExpr(ce.getRightOperand()) and
leftLoc = left.getLocation() and
rightLoc = right.getLocation() and
not isParenthesized(ce) and
leftLoc.getEndLine() < rightLoc.getStartLine() and
leftLoc.getStartColumn() > rightLoc.getStartColumn()
select right, "The indentation level may be misleading for some tab sizes."

View File

@@ -11,7 +11,7 @@ caused by an unhandled case.</p>
</overview>
<recommendation>
<p>Check that the unused static variable does not indicate a defect, for example, an unhandled case. If the static variable is genuinuely not needed,
<p>Check that the unused static variable does not indicate a defect, for example, an unhandled case. If the static variable is genuinely not needed,
then removing it will make code more readable. If the static variable is needed then you should update the code to fix the defect.</p>
</recommendation>

View File

@@ -19,7 +19,7 @@ This can occur when an operation performed on the open descriptor fails, and the
<example>
<p>In the example below, the <code>sockfd</code> socket may remain open if an error is triggered.
The code should be updated to ensure that the socket is always closed when when the function ends.
The code should be updated to ensure that the socket is always closed when the function ends.
</p>
<sample src="DescriptorMayNotBeClosed.cpp" />
</example>

View File

@@ -15,7 +15,7 @@ As an exception, because their purpose is usually obvious, it is not necessary t
</overview>
<recommendation>
<p>
Add comments to document the purpose of the function. In particular, ensure that the public API of the function is carefully documented. This reduces the chance that a future change to the function will introduce a defect by changing the API and breaking the expections of the calling functions.
Add comments to document the purpose of the function. In particular, ensure that the public API of the function is carefully documented. This reduces the chance that a future change to the function will introduce a defect by changing the API and breaking the expectations of the calling functions.
</p>
</recommendation>

View File

@@ -6,7 +6,7 @@
<overview>
<p>
This rule finds comparison expressions that use 2 or more comparison operators and are not completely paranthesized.
This rule finds comparison expressions that use 2 or more comparison operators and are not completely parenthesized.
It is best to fully parenthesize complex comparison expressions to explicitly define the order of the comparison operators.
</p>

View File

@@ -6,9 +6,9 @@
<overview>
<p>This rule finds logical-not operator usage as an operator for in a bit-wise operation.</p>
<p>Due to the nature of logical operation result value, only the lowest bit could possibly be set, and it is unlikely to be intent in bitwise opeartions. Violations are often indicative of a typo, using a logical-not (<code>!</code>) opeartor instead of the bit-wise not (<code>~</code>) operator. </p>
<p>Due to the nature of logical operation result value, only the lowest bit could possibly be set, and it is unlikely to be intent in bitwise operations. Violations are often indicative of a typo, using a logical-not (<code>!</code>) operator instead of the bit-wise not (<code>~</code>) operator. </p>
<p>This rule is restricted to analyze bit-wise and (<code>&amp;</code>) and bit-wise or (<code>|</code>) operation in order to provide better precision.</p>
<p>This rule ignores instances where a double negation (<code>!!</code>) is explicitly used as the opeartor of the bitwise operation, as this is a commonly used as a mechanism to normalize an integer value to either 1 or 0.</p>
<p>This rule ignores instances where a double negation (<code>!!</code>) is explicitly used as the operator of the bitwise operation, as this is a commonly used as a mechanism to normalize an integer value to either 1 or 0.</p>
<p>NOTE: It is not recommended to use this rule in kernel code or older C code as it will likely find several false positive instances.</p>
</overview>

View File

@@ -49,7 +49,7 @@ pointer overflow.
<p>
While it's not the subject of this query, the expression <code>ptr + i &lt;
ptr_end</code> is also an invalid range check. It's undefined behavor in
ptr_end</code> is also an invalid range check. It's undefined behavior in
C/C++ to create a pointer that points more than one past the end of an
allocation.
</p>

View File

@@ -12,7 +12,7 @@ the third argument to the entire size of the destination buffer.
Executing a call of this type may cause a buffer overflow unless the buffer is known to be empty.</p>
<p>Similarly, calls of the form <code>strncat(dest, src, sizeof (dest) - strlen (dest))</code> allow one
byte to be written ouside the <code>dest</code> buffer.</p>
byte to be written outside the <code>dest</code> buffer.</p>
<p>Buffer overflows can lead to anything from a segmentation fault to a security vulnerability.</p>

View File

@@ -6,7 +6,7 @@
<p>
This metric provides an indication of the lack of cohesion of a class,
using a method proposed by Chidamber and Kemerer in 1994. The idea
behind measuring a class's cohesion is that most funcions in well-designed
behind measuring a class's cohesion is that most functions in well-designed
classes will access the same fields. Types that exhibit a lack of cohesion
are often trying to take on multiple responsibilities, and should be split
into several smaller classes.

View File

@@ -11,7 +11,7 @@
by changes to other packages. If this metric value is high, a package is easily
influenced. If the values is low, the impact of changes to other packages is likely to be minimal. Instability
is estimated as the number of outgoing dependencies relative to the total
number of depencies.</p>
number of dependencies.</p>
</overview>
<references>

View File

@@ -11,7 +11,7 @@
by changes to other packages. If this metric value is high, a package is easily
influenced. If the values is low, the impact of changes to other packages is likely to be minimal. Instability
is estimated as the number of outgoing dependencies relative to the total
number of depencies.</p>
number of dependencies.</p>
</overview>
<references>

View File

@@ -5,7 +5,7 @@
<overview>
<p>This query indicates that a call is setting the DACL field in a <code>SECURITY_DESCRIPTOR</code> to null.</p>
<p>When using <code>SetSecurityDescriptorDacl</code> to set a discretionary access control (DACL), setting the <code>bDaclPresent</code> argument to <code>TRUE</code> indicates the prescence of a DACL in the security description in the argument <code>pDacl</code>.</p>
<p>When using <code>SetSecurityDescriptorDacl</code> to set a discretionary access control (DACL), setting the <code>bDaclPresent</code> argument to <code>TRUE</code> indicates the presence of a DACL in the security description in the argument <code>pDacl</code>.</p>
<p>When the <code>pDacl</code> parameter does not point to a DACL (i.e. it is <code>NULL</code>) and the <code>bDaclPresent</code> flag is <code>TRUE</code>, a <code>NULL DACL</code> is specified.</p>
<p>A <code>NULL DACL</code> grants full access to any user who requests it; normal security checking is not performed with respect to the object.</p>
</overview>

View File

@@ -0,0 +1,4 @@
---
category: newQuery
---
* Added a new medium-precision query, `cpp/comma-before-misleading-indentation`, which detects instances of whitespace that have readability issues.

View File

@@ -12,7 +12,7 @@ The user should check the return value of `scanf` and related functions and chec
</p>
</recommendation>
<example>
<p>The first first example below is correct, as value of `i` is only read once it is checked that `scanf` has read one item. The second example is incorrect, as the return value of `scanf` is not checked, and as `scanf` might have failed to read any item before returning.</p>
<p>The first example below is correct, as value of `i` is only read once it is checked that `scanf` has read one item. The second example is incorrect, as the return value of `scanf` is not checked, and as `scanf` might have failed to read any item before returning.</p>
<sample src="ImproperCheckReturnValueScanf.cpp" />
</example>

View File

@@ -5,12 +5,12 @@
<overview>
<p>
Some header files, such as those which define structures or classes, cannot be included more than once within a translation unit, as doing so would
cause a redefinition error. Such headers must be guarded to prevent ill-effects from multiple inclusion. Simlarly, if header files include other
cause a redefinition error. Such headers must be guarded to prevent ill-effects from multiple inclusion. Similarly, if header files include other
header files, and this inclusion graph contains a cycle, then at least one file within the cycle must contain header guards in order to break the
cycle. Because of cases like these, all headers should be guarded as a matter of good practice, even if they do not strictly need to be.
</p>
<p>
Furthermore, most modern compilers contain optimisations which are triggered by header guards. If the header guard strictly conforms to the pattern
Furthermore, most modern compilers contain optimizations which are triggered by header guards. If the header guard strictly conforms to the pattern
that compilers expect, then inclusions of that header other than the first have absolutely no effect: the file isn't re-read from disk, nor is it
re-tokenised or re-preprocessed. This can result in a noticeable, albeit minor, improvement to compilation time.
</p>

View File

@@ -0,0 +1,5 @@
| test.cpp:49:2:49:8 | (void)... | The indentation level may be misleading for some tab sizes. |
| test.cpp:52:2:52:15 | (void)... | The indentation level may be misleading for some tab sizes. |
| test.cpp:160:3:160:9 | (void)... | The indentation level may be misleading for some tab sizes. |
| test.cpp:166:5:166:7 | ... ++ | The indentation level may be misleading for some tab sizes. |
| test.cpp:176:6:178:6 | ... ? ... : ... | The indentation level may be misleading for some tab sizes. |

View File

@@ -0,0 +1 @@
Best Practices/Likely Errors/CommaBeforeMisleadingIndentation.ql

View File

@@ -0,0 +1,208 @@
// clang-format off
typedef unsigned size_t;
struct X {
int foo(int y) { return y; }
} x;
#define FOO(x) ( \
(x), \
(x) \
)
#define BAR(x, y) ((x), (y))
#define BAZ //printf
struct Foo {
int i, i_array[3];
int j;
virtual int foo(int) = 0;
virtual int bar(int, int) = 0;
int test(int (*baz)(int));
struct Tata {
struct Titi {
void tutu() {}
long toto() { return 42; }
} titi;
Titi *operator->() { return &titi; }
} *tata;
};
int Foo::test(int (*baz)(int))
{
// Comma in simple if statement (prototypical example):
if (i)
(void)i, // GOOD
j++;
if (i)
this->foo(i), // GOOD
foo(i);
if (i)
(void)i, // BAD
(void)j;
if (1) FOO(i),
(void)x.foo(j); // BAD
// Parenthesized comma (borderline example):
foo(i++), j++; // GOOD
(foo(i++), j++); // GOOD
(foo(i++), // GOOD
j++);
(foo(i++),
foo(i++),
j++, // GOOD (?) -- Currently explicitly excluded
j++);
x.foo(i++), j++; // GOOD
(x.foo(i++), j++); // GOOD
(x.foo(i++), // GOOD
j++);
(x.foo(i++),
x.foo(i++),
j++, // GOOD (?) -- Currently explicitly excluded
j++);
FOO(i++), j++; // GOOD
(FOO(i++), j++); // GOOD
(FOO(i++), // GOOD
j++);
(FOO(i++),
FOO(i++),
j++, // GOOD (?) -- Currently explicitly excluded
j++);
(void)(i++), j++; // GOOD
((void)(i++), j++); // GOOD
((void)(i++), // GOOD
j++);
((void)(i++),
(void)(i++),
j++, // GOOD (?) -- Currently explicitly excluded
j++);
// Comma in argument list doesn't count:
bar(i++, j++); // GOOD
bar(i++,
j++); // GOOD
bar(i++
, j++); // GOOD
bar(i++,
j++); // GOOD: common pattern and unlikely to be misread.
BAR(i++, j++); // GOOD
BAR(i++,
j++); // GOOD
BAR(i++
, j++); // GOOD
BAR(i++,
j++); // GOOD: common pattern and unlikely to be misread.
using T = decltype(x.foo(i++), // GOOD
j++);
(void)sizeof(x.foo(i++), // GOOD
j++);
using U = decltype(x.foo(i++), // GOOD? Unlikely to be misread
j++);
(void)sizeof(x.foo(i++), // GOOD? Unlikely to be misread
j++);
BAZ("%d %d\n", i,
j); // GOOD -- Currently explicitly excluded
// Comma in loops
while (i = foo(j++), // GOOD
i != j && i != 42 &&
!foo(j)) {
i = j = i + j;
}
while (i = foo(j++), // GOOD??? Currently ignoring loop heads
i != j && i != 42 && !foo(j)) {
i = j = i + j;
}
for (i = 0, // GOOD? Currently ignoring loop heads.
j = 1;
i + j < 10;
i++, j++);
for (i = 0,
j = 1; i < 10; i += 2, // GOOD? Currently ignoring loop heads.
j++) {}
// Comma in if-conditions:
if (i = foo(j++),
i == j) // GOOD(?) -- Currently ignoring if-conditions for the same reason as other parenthesized commas.
i = 0;
// Mixed tabs and spaces (ugly case):
for (i = 0, // GOOD if tab >= 4 spaces else BAD -- Currently ignoring loop heads.
j = 0;
i + j < 10;
i++, // GOOD if tab >= 4 spaces else BAD -- Currently ignoring loop heads.
j++);
if (i)
(void)i, // GOOD if tab >= 4 spaces else BAD -- can't exclude w/o source code text :/
(void)j;
// LHS ends on same line RHS begins on:
if (1) foo(
i++
), j++; // GOOD? [FALSE POSITIVE]
if (1) baz(
i++
), j++; // GOOD... when calling a function pointer..!?
// Weird cases:
if (foo(j))
return i++
, i++ // GOOD(?) [FALSE POSITIVE] -- can't exclude w/o source code text :/
? 1
: 2;
int quux =
(tata->titi.tutu(),
foo(tata->titi.toto())); // GOOD
(*tata)->toto(), // GOOD
i_array[i] += (int)(*tata)->toto();
return quux;
}
// Comma in variadic template splice:
namespace std {
template <size_t... Is>
struct index_sequence {};
}
template <size_t I>
struct zip_index {};
template <size_t I>
int& at(zip_index<I>) { throw 1; }
template <class Fn, class At, size_t... Is>
void for_each_input(Fn&& fn, std::index_sequence<Is...>) {
(fn(zip_index<Is>{}, at(zip_index<Is>{})), ...); // GOOD
}
// clang-format on

View File

@@ -20,16 +20,18 @@ class DataFlowNode extends @cil_dataflow_node {
* Holds if this node flows to `sink` in one step.
* `tt` is the tainting that occurs during this step.
*/
predicate getALocalFlowSucc(DataFlowNode sink, TaintType tt) {
deprecated predicate getALocalFlowSucc(DataFlowNode sink, TaintType tt) {
localExactStep(this, sink) and tt = TExactValue()
or
localTaintStep(this, sink) and tt = TTaintedValue()
}
private predicate flowsToStep(DataFlowNode sink) { this.getALocalFlowSucc(sink, TExactValue()) }
deprecated private predicate flowsToStep(DataFlowNode sink) {
this.getALocalFlowSucc(sink, TExactValue())
}
/** Holds if this node flows to `sink` in zero or more steps. */
predicate flowsTo(DataFlowNode sink) { this.flowsToStep*(sink) }
deprecated predicate flowsTo(DataFlowNode sink) { this.flowsToStep*(sink) }
/** Gets the method that contains this dataflow node. */
Method getMethod() { none() }
@@ -38,12 +40,12 @@ class DataFlowNode extends @cil_dataflow_node {
Location getLocation() { none() }
}
private newtype TTaintType =
deprecated private newtype TTaintType =
TExactValue() or
TTaintedValue()
/** Describes how data is tainted. */
class TaintType extends TTaintType {
deprecated class TaintType extends TTaintType {
string toString() {
this = TExactValue() and result = "exact"
or
@@ -52,12 +54,12 @@ class TaintType extends TTaintType {
}
/** A taint type where the data is untainted. */
class Untainted extends TaintType, TExactValue { }
deprecated class Untainted extends TaintType, TExactValue { }
/** A taint type where the data is tainted. */
class Tainted extends TaintType, TTaintedValue { }
deprecated class Tainted extends TaintType, TTaintedValue { }
private predicate localFlowPhiInput(DataFlowNode input, Ssa::PhiNode phi) {
deprecated private predicate localFlowPhiInput(DataFlowNode input, Ssa::PhiNode phi) {
exists(Ssa::Definition def, BasicBlock bb, int i | phi.hasLastInputRef(def, bb, i) |
def.definesAt(_, bb, i) and
input = def.getVariableUpdate().getSource()
@@ -76,7 +78,7 @@ private predicate localFlowPhiInput(DataFlowNode input, Ssa::PhiNode phi) {
)
}
private predicate localExactStep(DataFlowNode src, DataFlowNode sink) {
deprecated private predicate localExactStep(DataFlowNode src, DataFlowNode sink) {
src = sink.(Opcodes::Dup).getAnOperand()
or
exists(Ssa::Definition def, VariableUpdate vu |
@@ -103,7 +105,7 @@ private predicate localExactStep(DataFlowNode src, DataFlowNode sink) {
src = sink.(ConditionalBranch).getAnOperand()
}
private predicate localTaintStep(DataFlowNode src, DataFlowNode sink) {
deprecated private predicate localTaintStep(DataFlowNode src, DataFlowNode sink) {
src = sink.(BinaryArithmeticExpr).getAnOperand() or
src = sink.(Opcodes::Neg).getOperand() or
src = sink.(UnaryBitwiseOperation).getOperand()

View File

@@ -270,7 +270,7 @@ class Setter extends Accessor {
*/
class TrivialSetter extends Method {
TrivialSetter() {
exists(MethodImplementation impl | impl = this.getImplementation() |
exists(MethodImplementation impl | impl = this.getAnImplementation() |
impl.getInstruction(0) instanceof ThisAccess and
impl.getInstruction(1).(ParameterReadAccess).getTarget().getIndex() = 1 and
impl.getInstruction(2) instanceof FieldWriteAccess

View File

@@ -24,10 +24,10 @@ module Ssa {
}
/** Gets a first read of this SSA definition. */
final ReadAccess getAFirstRead() { result = SsaImpl::getAFirstRead(this) }
deprecated final ReadAccess getAFirstRead() { result = SsaImpl::getAFirstRead(this) }
/** Holds if `first` and `second` are adjacent reads of this SSA definition. */
final predicate hasAdjacentReads(ReadAccess first, ReadAccess second) {
deprecated final predicate hasAdjacentReads(ReadAccess first, ReadAccess second) {
SsaImpl::hasAdjacentReads(this, first, second)
}
@@ -58,8 +58,9 @@ module Ssa {
* index `i` in basic block `bb` can reach this phi node without going through
* other references.
*/
final predicate hasLastInputRef(Definition def, BasicBlock bb, int i) {
SsaImpl::hasLastInputRef(this, def, bb, i)
deprecated final predicate hasLastInputRef(Definition def, BasicBlock bb, int i) {
SsaImpl::lastRefRedef(def, bb, i, this) and
def = SsaImpl::getAPhiInput(this)
}
}
}

View File

@@ -29,14 +29,17 @@ private module Cached {
cached
predicate bestImplementation(MethodImplementation mi) {
not assemblyIsStubImpl(mi.getLocation()) and
exists(Assembly asm |
asm = mi.getLocation() and
(assemblyIsStubImpl(asm) implies asm.getFile().extractedQlTest()) and
not exists(MethodImplementation better | mi.getMethod() = better.getMethod() |
mi.getNumberOfInstructions() < better.getNumberOfInstructions()
or
mi.getNumberOfInstructions() = better.getNumberOfInstructions() and
mi.getLocation().getFile().toString() > better.getLocation().getFile().toString()
asm.getFile().toString() > better.getLocation().getFile().toString()
) and
exists(mi.getAnInstruction())
)
}
}

View File

@@ -68,9 +68,8 @@ private module Cached {
Definition getAPhiInput(PhiNode phi) { phiHasInputFromBlock(phi, result, _) }
cached
predicate hasLastInputRef(Definition phi, Definition def, BasicBlock bb, int i) {
lastRefRedef(def, bb, i, phi) and
def = getAPhiInput(phi)
predicate lastRefBeforeRedef(Definition def, BasicBlock bb, int i, Definition next) {
lastRefRedef(def, bb, i, next)
}
}

View File

@@ -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 read of `this.Field` on line 11 is next to the read on line 10.
*/
pragma[nomagic]
AssignableRead getANextRead() {
forex(ControlFlow::Node cfn | cfn = result.getAControlFlowNode() |
cfn = this.getAnAdjacentReadSameVar()
@@ -124,7 +125,7 @@ class AssignableRead extends AssignableAccess {
*
* 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
* `AssignableRead.getANextRead()`.
*/
pragma[nomagic]
AssignableRead getAFirstRead() {
forex(ControlFlow::Node cfn | cfn = result.getAControlFlowNode() |
exists(Ssa::ExplicitDefinition def | result = def.getAFirstReadAtNode(cfn) |
@@ -494,7 +496,7 @@ class AssignableDefinition extends TAssignableDefinition {
*
* 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. */
string toString() { none() }

View File

@@ -11,15 +11,19 @@ private predicate isDisposeMethod(DotNet::Callable method) {
method.getNumberOfParameters() = 0
}
private predicate cilVariableReadFlowsTo(CIL::Variable variable, CIL::DataFlowNode n) {
n = variable.getARead()
private predicate cilVariableReadFlowsToNode(CIL::Variable variable, DataFlow::Node n) {
n.asExpr() = variable.getARead()
or
exists(CIL::DataFlowNode mid |
cilVariableReadFlowsTo(variable, mid) and
mid.getALocalFlowSucc(n, any(CIL::Untainted u))
exists(DataFlow::Node mid |
cilVariableReadFlowsToNode(variable, mid) and
DataFlow::localFlowStep(mid, n)
)
}
private predicate cilVariableReadFlowsTo(CIL::Variable variable, CIL::DataFlowNode n) {
cilVariableReadFlowsToNode(variable, DataFlow::exprNode(n))
}
private predicate disposedCilVariable(CIL::Variable variable) {
// `variable` is the `this` parameter on a dispose method.
isDisposeMethod(variable.(CIL::ThisParameter).getMethod())

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -17,6 +17,7 @@ private import semmle.code.csharp.frameworks.EntityFramework
private import semmle.code.csharp.frameworks.NHibernate
private import semmle.code.csharp.frameworks.system.Collections
private import semmle.code.csharp.frameworks.system.threading.Tasks
private import semmle.code.cil.Ssa::Ssa as CilSsa
/** Gets the callable in which this node occurs. */
DataFlowCallable nodeGetEnclosingCallable(NodeImpl n) { result = n.getEnclosingCallableImpl() }
@@ -177,6 +178,12 @@ predicate hasNodePath(ControlFlowReachabilityConfiguration conf, ExprNode n1, No
)
}
/** Gets the CIL data-flow node for `node`, if any. */
CIL::DataFlowNode asCilDataFlowNode(Node node) {
result = node.asParameter() or
result = node.asExpr()
}
/** Provides predicates related to local data flow. */
module LocalFlow {
private class LocalExprStepConfiguration extends ControlFlowReachabilityConfiguration {
@@ -281,15 +288,6 @@ module LocalFlow {
}
}
private CIL::DataFlowNode asCilDataFlowNode(Node node) {
result = node.asParameter() or
result = node.asExpr()
}
private predicate localFlowStepCil(Node nodeFrom, Node nodeTo) {
asCilDataFlowNode(nodeFrom).getALocalFlowSucc(asCilDataFlowNode(nodeTo), any(CIL::Untainted t))
}
/**
* An uncertain SSA definition. Either an uncertain explicit definition or an
* uncertain qualifier definition.
@@ -341,7 +339,7 @@ module LocalFlow {
/**
* Holds if there is a local flow step from `nodeFrom` to `nodeTo` involving
* SSA definition `def.
* SSA definition `def`.
*/
predicate localSsaFlowStep(Ssa::Definition def, Node nodeFrom, Node nodeTo) {
// Flow from SSA definition/parameter to first read
@@ -386,6 +384,76 @@ module LocalFlow {
)
}
private module CilFlow {
private import semmle.code.cil.internal.SsaImpl as CilSsaImpl
/**
* Holds if `nodeFrom` is a last node referencing SSA definition `def`, which
* can reach `next`.
*/
private predicate localFlowCilSsaInput(
Node nodeFrom, CilSsa::Definition def, CilSsa::Definition next
) {
exists(CIL::BasicBlock bb, int i | CilSsaImpl::lastRefBeforeRedef(def, bb, i, next) |
def.definesAt(_, bb, i) and
def = nodeFrom.(CilSsaDefinitionNode).getDefinition()
or
nodeFrom = TCilExprNode(bb.getNode(i).(CIL::ReadAccess))
)
}
/**
* Holds if there is a local flow step from `nodeFrom` to `nodeTo` involving
* CIL SSA definition `def`.
*/
private predicate localCilSsaFlowStep(CilSsa::Definition def, Node nodeFrom, Node nodeTo) {
// Flow into SSA definition
exists(CIL::VariableUpdate vu |
vu = def.getVariableUpdate() and
vu.getSource() = asCilDataFlowNode(nodeFrom) and
def = nodeTo.(CilSsaDefinitionNode).getDefinition()
)
or
// Flow from SSA definition to first read
def = nodeFrom.(CilSsaDefinitionNode).getDefinition() and
nodeTo = TCilExprNode(CilSsaImpl::getAFirstRead(def))
or
// Flow from read to next read
exists(CIL::ReadAccess readFrom, CIL::ReadAccess readTo |
CilSsaImpl::hasAdjacentReads(def, readFrom, readTo) and
nodeTo = TCilExprNode(readTo) and
nodeFrom = TCilExprNode(readFrom)
)
or
// Flow into phi node
exists(CilSsa::PhiNode phi |
localFlowCilSsaInput(nodeFrom, def, phi) and
phi = nodeTo.(CilSsaDefinitionNode).getDefinition() and
def = CilSsaImpl::getAPhiInput(phi)
)
}
private predicate localExactStep(CIL::DataFlowNode src, CIL::DataFlowNode sink) {
src = sink.(CIL::Opcodes::Dup).getAnOperand()
or
src = sink.(CIL::Conversion).getExpr()
or
src = sink.(CIL::WriteAccess).getExpr()
or
src = sink.(CIL::Method).getAnImplementation().getAnInstruction().(CIL::Return)
or
src = sink.(CIL::Return).getExpr()
or
src = sink.(CIL::ConditionalBranch).getAnOperand()
}
predicate localFlowStepCil(Node nodeFrom, Node nodeTo) {
localExactStep(asCilDataFlowNode(nodeFrom), asCilDataFlowNode(nodeTo))
or
localCilSsaFlowStep(_, nodeFrom, nodeTo)
}
}
predicate localFlowStepCommon(Node nodeFrom, Node nodeTo) {
exists(Ssa::Definition def |
localSsaFlowStep(def, nodeFrom, nodeTo) and
@@ -398,7 +466,7 @@ module LocalFlow {
or
ThisFlow::adjacentThisRefs(nodeFrom.(PostUpdateNode).getPreUpdateNode(), nodeTo)
or
localFlowStepCil(nodeFrom, nodeTo)
CilFlow::localFlowStepCil(nodeFrom, nodeTo)
}
/**
@@ -719,6 +787,7 @@ private module Cached {
cfn.getElement() instanceof Expr
} or
TCilExprNode(CIL::Expr e) { e.getImplementation() instanceof CIL::BestImplementation } or
TCilSsaDefinitionNode(CilSsa::Definition def) or
TSsaDefinitionNode(Ssa::Definition def) {
// Handled by `TExplicitParameterNode` below
not def.(Ssa::ExplicitDefinition).getADefinition() instanceof
@@ -867,6 +936,28 @@ predicate nodeIsHidden(Node n) {
n.asExpr() = any(WithExpr we).getInitializer()
}
/** A CIL SSA definition, viewed as a node in a data flow graph. */
class CilSsaDefinitionNode extends NodeImpl, TCilSsaDefinitionNode {
CilSsa::Definition def;
CilSsaDefinitionNode() { this = TCilSsaDefinitionNode(def) }
/** Gets the underlying SSA definition. */
CilSsa::Definition getDefinition() { result = def }
override DataFlowCallable getEnclosingCallableImpl() {
result.asCallable() = def.getBasicBlock().getFirstNode().getImplementation().getMethod()
}
override CIL::Type getTypeImpl() { result = def.getSourceVariable().getType() }
override ControlFlow::Node getControlFlowNodeImpl() { none() }
override Location getLocationImpl() { result = def.getBasicBlock().getLocation() }
override string toStringImpl() { result = def.toString() }
}
/** An SSA definition, viewed as a node in a data flow graph. */
class SsaDefinitionNode extends NodeImpl, TSsaDefinitionNode {
Ssa::Definition def;

View File

@@ -161,7 +161,7 @@ predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) }
* local (intra-procedural) steps.
*/
pragma[inline]
predicate localExprFlow(Expr e1, Expr e2) { localFlow(exprNode(e1), exprNode(e2)) }
predicate localExprFlow(DotNet::Expr e1, DotNet::Expr e2) { localFlow(exprNode(e1), exprNode(e2)) }
/**
* A data flow node that jumps between callables. This can be extended in

View File

@@ -26,13 +26,14 @@ predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
bindingset[node]
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::Content c) { none() }
private CIL::DataFlowNode asCilDataFlowNode(DataFlow::Node node) {
result = node.asParameter() or
result = node.asExpr()
private predicate localCilTaintStep(CIL::DataFlowNode src, CIL::DataFlowNode sink) {
src = sink.(CIL::BinaryArithmeticExpr).getAnOperand() or
src = sink.(CIL::Opcodes::Neg).getOperand() or
src = sink.(CIL::UnaryBitwiseOperation).getOperand()
}
private predicate localTaintStepCil(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
asCilDataFlowNode(nodeFrom).getALocalFlowSucc(asCilDataFlowNode(nodeTo), any(CIL::Tainted t))
localCilTaintStep(asCilDataFlowNode(nodeFrom), asCilDataFlowNode(nodeTo))
}
private class LocalTaintExprStepConfiguration extends ControlFlowReachabilityConfiguration {

View File

@@ -174,7 +174,9 @@ class VariableAccess extends AssignableAccess, @variable_access_expr {
class VariableRead extends VariableAccess, AssignableRead {
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 {
override LocalScopeVariableRead getANextRead() { result = VariableRead.super.getANextRead() }
override LocalScopeVariableRead getAReachableRead() {
deprecated override LocalScopeVariableRead getAReachableRead() {
result = VariableRead.super.getAReachableRead()
}
}
@@ -242,7 +244,7 @@ class ParameterAccess extends LocalScopeVariableAccess, @parameter_access_expr {
class ParameterRead extends ParameterAccess, LocalScopeVariableRead {
override ParameterRead getANextRead() { result = LocalScopeVariableRead.super.getANextRead() }
override ParameterRead getAReachableRead() {
deprecated override ParameterRead getAReachableRead() {
result = LocalScopeVariableRead.super.getAReachableRead()
}
}
@@ -297,7 +299,7 @@ class LocalVariableAccess extends LocalScopeVariableAccess, @local_variable_acce
class LocalVariableRead extends LocalVariableAccess, LocalScopeVariableRead {
override LocalVariableRead getANextRead() { result = LocalScopeVariableRead.super.getANextRead() }
override LocalVariableRead getAReachableRead() {
deprecated override LocalVariableRead getAReachableRead() {
result = LocalScopeVariableRead.super.getAReachableRead()
}
}
@@ -442,7 +444,9 @@ class PropertyAccess extends AssignableMemberAccess, PropertyAccessExpr {
class PropertyRead extends PropertyAccess, AssignableRead {
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 {
override IndexerRead getANextRead() { result = ElementRead.super.getANextRead() }
override IndexerRead getAReachableRead() { result = ElementRead.super.getAReachableRead() }
deprecated override IndexerRead getAReachableRead() {
result = ElementRead.super.getAReachableRead()
}
}
/**

View File

@@ -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
* format item parameter of `string.Format()`, or a parameter of a method that
@@ -85,15 +99,9 @@ class StringFormatItemParameter extends Parameter {
)
or
// Parameter of a source method that forwards to `string.Format()`
exists(
AssignableDefinitions::ImplicitParameterDefinition def, ParameterRead pr,
StringFormatItemParameter other
|
exists(AssignableDefinitions::ImplicitParameterDefinition def |
def.getParameter() = this and
pr = def.getAReachableRead() and
pr.getAControlFlowNode().postDominates(this.getCallable().getEntryPoint()) and
other.getAnAssignedArgument() = pr and
getParameterType(this) instanceof ObjectType
alwaysPassedToFormatItemParameter(def.getAFirstRead())
)
}
}

View File

@@ -22,12 +22,22 @@ private class DisposeCall extends MethodCall {
DisposeCall() { this.getTarget() instanceof DisposeMethod }
}
private predicate localFlowStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
DataFlow::localFlowStep(nodeFrom, nodeTo) and
not exists(AssignableDefinition def, UsingStmt us |
nodeTo.asExpr() = def.getAReachableRead() and
pragma[nomagic]
private predicate isDisposedAccess(AssignableRead ar) {
exists(AssignableDefinition def, UsingStmt us |
ar = def.getAFirstRead() and
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) {

View File

@@ -18,7 +18,7 @@ more difficult to change which implementation you are using at a later date.</p>
</example>
<references>
<li>C# Corner, <a href="http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_interrfaces03052006095933AM/csharp_interrfaces.aspx">C# Interface Based Development</a>.</li>
<li>C# Corner, <a href="https://www.c-sharpcorner.com/article/C-Sharp-interface-based-development/">C# Interface Based Development</a>.</li>
</references>
</qhelp>

View File

@@ -5,7 +5,7 @@
<overview>
<p>
Comparisons which always yield the same result are unnecessary and may indicate a bug in the
logic. This can can happen when the data type of one of the operands has a limited range of values.
logic. This can happen when the data type of one of the operands has a limited range of values.
For example unsigned integers are always greater than or equal to zero, and <code>byte</code>
values are always less than 256.
</p>

View File

@@ -9,7 +9,7 @@
</p>
</overview>
<recommendation>
<p>Use speific era when creating DateTime and DateTimeOffset structs from previously stored date in Japanese calendar</p>
<p>Use specific era when creating DateTime and DateTimeOffset structs from previously stored date in Japanese calendar</p>
<p>Don't store dates in Japanese format</p>
<p>Don't use hard-coded era start date for date calculations converting dates from Japanese date format</p>
<p>Use <code>JapaneseCalendar</code> class for date formatting only</p>

View File

@@ -6,7 +6,7 @@
<include src="ThreadUnsafeICryptoTransformOverview.inc.qhelp" />
</overview>
<recommendation>
<p>Create new instances of the object that implements or has a field of type <code>System.Security.Cryptography.ICryptoTransform</code> to avoid sharing it accross multiple threads.</p>
<p>Create new instances of the object that implements or has a field of type <code>System.Security.Cryptography.ICryptoTransform</code> to avoid sharing it across multiple threads.</p>
</recommendation>
<example>

View File

@@ -4,7 +4,7 @@
<qhelp>
<overview>
<p>ECB should not be used as a mode for encryption. It has dangerous weaknesses. Data is encrypted the same way every time
meaning the same plaintext input will always produce the same cyphertext. This makes encrypted messages vulnerable
meaning the same plaintext input will always produce the same ciphertext. This makes encrypted messages vulnerable
to replay attacks.</p>
</overview>

View File

@@ -17,8 +17,10 @@ private import semmle.code.csharp.security.dataflow.flowsources.Remote
class TestLibrary extends RefType {
TestLibrary() {
this.getNamespace()
.getName()
.matches(["NUnit.Framework%", "Xunit%", "Microsoft.VisualStudio.TestTools.UnitTesting%"])
.getQualifiedName()
.matches([
"NUnit.Framework%", "Xunit%", "Microsoft.VisualStudio.TestTools.UnitTesting%", "Moq%"
])
}
}
@@ -114,29 +116,39 @@ class ExternalApi extends DotNet::Callable {
int resultLimit() { result = 1000 }
/**
* Holds if the relevant usage count of `api` is `usages`.
* Holds if it is relevant to count usages of `api`.
*/
signature predicate relevantUsagesSig(ExternalApi api, int usages);
signature predicate relevantApi(ExternalApi api);
/**
* Given a predicate to count relevant API usages, this module provides a predicate
* for restricting the number or returned results based on a certain limit.
*/
module Results<relevantUsagesSig/2 getRelevantUsages> {
private int getOrder(ExternalApi api) {
api =
rank[result](ExternalApi a, int usages |
getRelevantUsages(a, usages)
module Results<relevantApi/1 getRelevantUsages> {
private int getUsages(string apiInfo) {
result =
strictcount(DispatchCall c, ExternalApi api |
c = api.getACall() and
apiInfo = api.getInfo() and
getRelevantUsages(api)
)
}
private int getOrder(string apiInfo) {
apiInfo =
rank[result](string info, int usages |
usages = getUsages(info)
|
a order by usages desc, a.getInfo()
info order by usages desc, info
)
}
/**
* Holds if `api` is being used `usages` times and if it is
* in the top results (guarded by resultLimit).
* Holds if there exists an API with `apiInfo` that is being used `usages` times
* and if it is in the top results (guarded by resultLimit).
*/
predicate restrict(ExternalApi api, int usages) {
getRelevantUsages(api, usages) and getOrder(api) <= resultLimit()
predicate restrict(string apiInfo, int usages) {
usages = getUsages(apiInfo) and
getOrder(apiInfo) <= resultLimit()
}
}

View File

@@ -10,12 +10,11 @@ private import csharp
private import semmle.code.csharp.dispatch.Dispatch
private import ExternalApi
private predicate getRelevantUsages(ExternalApi api, int usages) {
private predicate relevant(ExternalApi api) {
not api.isUninteresting() and
api.isSink() and
usages = strictcount(DispatchCall c | c = api.getACall())
api.isSink()
}
from ExternalApi api, int usages
where Results<getRelevantUsages/2>::restrict(api, usages)
select api.getInfo() as info, usages order by usages desc
from string info, int usages
where Results<relevant/1>::restrict(info, usages)
select info, usages order by usages desc

View File

@@ -10,12 +10,11 @@ private import csharp
private import semmle.code.csharp.dispatch.Dispatch
private import ExternalApi
private predicate getRelevantUsages(ExternalApi api, int usages) {
private predicate relevant(ExternalApi api) {
not api.isUninteresting() and
api.isSource() and
usages = strictcount(DispatchCall c | c = api.getACall())
api.isSource()
}
from ExternalApi api, int usages
where Results<getRelevantUsages/2>::restrict(api, usages)
select api.getInfo() as info, usages order by usages desc
from string info, int usages
where Results<relevant/1>::restrict(info, usages)
select info, usages order by usages desc

View File

@@ -10,12 +10,11 @@ private import csharp
private import semmle.code.csharp.dispatch.Dispatch
private import ExternalApi
private predicate getRelevantUsages(ExternalApi api, int usages) {
private predicate relevant(ExternalApi api) {
not api.isUninteresting() and
api.hasSummary() and
usages = strictcount(DispatchCall c | c = api.getACall())
api.hasSummary()
}
from ExternalApi api, int usages
where Results<getRelevantUsages/2>::restrict(api, usages)
select api.getInfo() as info, usages order by usages desc
from string info, int usages
where Results<relevant/1>::restrict(info, usages)
select info, usages order by usages desc

View File

@@ -12,13 +12,12 @@ private import semmle.code.csharp.dataflow.internal.FlowSummaryImpl as FlowSumma
private import semmle.code.csharp.dataflow.internal.NegativeSummary
private import ExternalApi
private predicate getRelevantUsages(ExternalApi api, int usages) {
private predicate relevant(ExternalApi api) {
not api.isUninteresting() and
not api.isSupported() and
not api instanceof FlowSummaryImpl::Public::NegativeSummarizedCallable and
usages = strictcount(DispatchCall c | c = api.getACall())
not api instanceof FlowSummaryImpl::Public::NegativeSummarizedCallable
}
from ExternalApi api, int usages
where Results<getRelevantUsages/2>::restrict(api, usages)
select api.getInfo() as info, usages order by usages desc
from string info, int usages
where Results<relevant/1>::restrict(info, usages)
select info, usages order by usages desc

View File

@@ -6,6 +6,7 @@ import semmle.code.csharp.frameworks.System
* Holds if expression `e`, of type `t`, invokes `ToString()` either explicitly
* or implicitly.
*/
pragma[nomagic]
predicate invokesToString(Expr e, ValueOrRefType t) {
// Explicit invocation
exists(MethodCall mc | mc.getQualifier() = e |
@@ -20,20 +21,24 @@ predicate invokesToString(Expr e, ValueOrRefType t) {
// Implicit invocation via forwarder method
t = e.stripCasts().getType() and
not t instanceof StringType and
exists(Parameter p |
alwaysInvokesToStringOnParameter(p) and
exists(AssignableDefinitions::ImplicitParameterDefinition def, Parameter p |
def.getParameter() = p and
alwaysInvokesToString(def.getAFirstRead()) and
e = p.getAnAssignedArgument()
)
}
pragma[noinline]
private predicate alwaysInvokesToStringOnParameter(Parameter p) {
exists(AssignableDefinitions::ImplicitParameterDefinition def, ParameterRead pr |
def.getParameter() = p and
pr = def.getAReachableRead() and
pr.getAControlFlowNode().postDominates(p.getCallable().getEntryPoint()) and
pragma[nomagic]
private predicate parameterReadPostDominatesEntry(ParameterRead pr) {
pr.getAControlFlowNode().postDominates(pr.getEnclosingCallable().getEntryPoint())
}
pragma[nomagic]
private predicate alwaysInvokesToString(ParameterRead pr) {
parameterReadPostDominatesEntry(pr) and
invokesToString(pr, _)
)
or
alwaysInvokesToString(pr.getANextRead())
}
/**

View File

@@ -21,7 +21,7 @@ You can install the CodeQL extension using any of the normal methods for install
* Go to the `Visual Studio Code Marketplace <https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-codeql>`__ in your browser and click **Install**.
* In the Extensions view (**Ctrl+Shift+X** or **Cmd+Shift+X**), search for ``CodeQL``, then select **Install**.
* Download the `CodeQL VSIX file <https://github.com/github/vscode-codeql/releases>`__. Then, in the Extensions view, click **More actions** > **Install from VSIX**, and select the CodeQL VSIX file.
* Download the `CodeQL VSIX file <https://github.com/github/vscode-codeql/releases>`__. Then, in the Extensions view, click the ellipsis representing the **Views and More Actions...** menu, select **Install from VSIX**, then select the CodeQL VSIX file.
Configuring access to the CodeQL CLI
------------------------------------

View File

@@ -229,6 +229,8 @@ and the CodeQL library pack ``codeql/python-all`` (`changelog <https://github.co
phoenixdb, Database
psycopg2, Database
pyodbc, Database
pymssql, Database
PyMySQL, Database
sqlite3, Database
Flask-SQLAlchemy, Database ORM
peewee, Database ORM

View File

@@ -30,7 +30,7 @@ When the allow list contains only a single host key then the function <code>Fixe
</recommendation>
<example>
<p>The following example shows the use of <code>InsecureIgnoreHostKey</code> and an insecure host key callback implemention commonly used in non-production code.</p>
<p>The following example shows the use of <code>InsecureIgnoreHostKey</code> and an insecure host key callback implementation commonly used in non-production code.</p>
<sample src="InsecureHostKeyCallbackExample.go" />

View File

@@ -18,7 +18,7 @@
<recommendation>
<p>
Generating a cryptograhically secure secret key during application initialization and using this generated key for future JWT signing requests can prevent this vulnerability.
Generating a cryptographically secure secret key during application initialization and using this generated key for future JWT signing requests can prevent this vulnerability.
</p>
</recommendation>

View File

@@ -18,7 +18,7 @@ possibly causing a divide-by-zero panic.
</p>
<sample src="DivideByZeroBad.go" />
<p>
This can be fixed by testing the divisor against against zero:
This can be fixed by testing the divisor against zero:
</p>
<sample src="DivideByZeroGood.go" />
</example>

View File

@@ -14,7 +14,7 @@ server side request forgery attacks, where the attacker controls the request tar
<p>
To guard against server side request forgery, it is advisable to avoid putting user input directly into a
network request. If using user input is necessary, then it must be validated. It is recommended to only allow
user input consisting of alphanumeric characters. Simply URL-encoding other chracters is not always a solution,
user input consisting of alphanumeric characters. Simply URL-encoding other characters is not always a solution,
for example because a downstream entity that is itself vulnerable may decode again before forwarding the request.
</p>
</recommendation>

View File

@@ -120,7 +120,7 @@ func main() {
}
})
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
// OK-ish: the input origin header is validated agains a whitelist.
// OK-ish: the input origin header is validated against a whitelist.
responseHeader := w.Header()
{
origin := req.Header.Get("origin")
@@ -137,7 +137,7 @@ func main() {
})
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
originSuffix := ".example.com"
// OK-ish: the input origin header is validated agains a suffix.
// OK-ish: the input origin header is validated against a suffix.
origin := req.Header.Get("Origin")
if origin != "" && (originSuffix == "" || strings.HasSuffix(origin, originSuffix)) {
w.Header().Set("Access-Control-Allow-Origin", origin)
@@ -152,7 +152,7 @@ func main() {
})
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
originSuffix := ".example.com"
// OK-ish: the input origin header is validated agains a whitelist.
// OK-ish: the input origin header is validated against a whitelist.
origin := req.Header.Get("Origin")
if origin != "" && (originSuffix == "" || AccessControlAllowOrigins[origin]) {
w.Header().Set("Access-Control-Allow-Origin", origin)
@@ -166,7 +166,7 @@ func main() {
}
})
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
// OK-ish: the input origin header is validated agains a whitelist.
// OK-ish: the input origin header is validated against a whitelist.
origin := req.Header.Get("origin")
if origin != "" && origin != "null" {
if len(AccessControlAllowOrigins) == 0 || AccessControlAllowOrigins[origin] {
@@ -178,7 +178,7 @@ func main() {
}
})
// http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
// // OK-ish: the input origin header is validated agains a whitelist.
// // OK-ish: the input origin header is validated against a whitelist.
// origin := req.Header.Get("origin")
// if origin != "" && origin != "null" {
// if _, ok := AccessControlAllowOrigins[origin]; ok {
@@ -190,7 +190,7 @@ func main() {
// }
// })
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
// OK-ish: the input origin header is validated agains a whitelist.
// OK-ish: the input origin header is validated against a whitelist.
if origin := req.Header.Get("Origin"); cors[origin] {
w.Header().Set("Access-Control-Allow-Origin", origin)
} else if len(origin) > 0 && cors["*"] {
@@ -202,7 +202,7 @@ func main() {
w.Header().Set("Access-Control-Allow-Credentials", "true")
})
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
// OK-ish: the input origin header is validated agains a whitelist.
// OK-ish: the input origin header is validated against a whitelist.
origin := req.Header.Get("origin")
for _, v := range GetAllowOrigin() {
if v == origin {

View File

@@ -96,7 +96,7 @@ func test() {
http.HandleFunc("/ex5", func(w http.ResponseWriter, r *http.Request) {
untrustedInput := r.Referer()
// good as input is tested againt regex
// good as input is tested against regex
if m, _ := regexp.MatchString("ws://localhost:12345/*", untrustedInput); m {
nhooyr.Dial(context.TODO(), untrustedInput, nil)
}

View File

@@ -231,7 +231,7 @@ open class KotlinFileExtractor(
// default java visibility (top level)
}
JavaVisibilities.ProtectedAndPackage -> {
// default java visibility (member level)
addModifiers(id, "protected")
}
else -> logger.errorElement("Unexpected delegated visibility: $v", elementForLocation)
}
@@ -1251,6 +1251,10 @@ open class KotlinFileExtractor(
}
extractVisibility(p, id, p.visibility)
if (p.isLateinit) {
addModifiers(id, "lateinit")
}
}
}
}
@@ -1406,6 +1410,9 @@ open class KotlinFileExtractor(
if (!v.isVar) {
addModifiers(varId, "final")
}
if (v.isLateinit) {
addModifiers(varId, "lateinit")
}
}
}

View File

@@ -0,0 +1,6 @@
package extlib;
public class A {
protected void m() {}
}

View File

@@ -0,0 +1,2 @@
| extlib.jar/extlib/A.class:0:0:0:0 | m | protected |
| test.kt:4:12:4:22 | m | override, protected |

View File

@@ -0,0 +1,6 @@
import extlib.A;
class B : A() {
override fun m() { }
}

View File

@@ -0,0 +1,10 @@
from create_database_utils import *
import glob
# Compile Java untraced. Note the Java source is hidden under `javasrc` so the Kotlin compiler
# will certainly reference the jar, not the source or class file for extlib.Lib
os.mkdir('build')
runSuccessfully(["javac"] + glob.glob("libsrc/extlib/*.java") + ["-d", "build"])
runSuccessfully(["jar", "cf", "extlib.jar", "-C", "build", "extlib"])
run_codeql_database_create(["kotlinc test.kt -cp extlib.jar"], lang="java")

View File

@@ -0,0 +1,6 @@
import java
query predicate mods(Method m, string modifiers) {
m.getName() = "m" and
modifiers = concat(string s | m.hasModifier(s) | s, ", ")
}

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Added a new predicate, `hasIncompletePermissions`, in the `AndroidProviderXmlElement` class. This predicate detects if a provider element does not provide both read and write permissions.

View File

@@ -294,6 +294,48 @@ class Callable extends StmtParent, Member, @callable {
constrs(this, _, result, _, _, _) or
methods(this, _, result, _, _, _)
}
/**
* Gets this callable's Kotlin proxy that supplies default parameter values, if one exists.
*
* For example, for the Kotlin declaration `fun f(x: Int, y: Int = 0, z: String = "1")`,
* this will get the synthetic proxy method that fills in the default values for `y` and `z`
* if not supplied, and to which the Kotlin extractor dispatches calls to `f` that are missing
* one or more parameter value. Similarly, constructors with one or more default parameter values
* have a corresponding constructor that fills in default values.
*/
Callable getKotlinParameterDefaultsProxy() {
this.getDeclaringType() = result.getDeclaringType() and
exists(int proxyNParams, int extraLeadingParams, RefType lastParamType |
proxyNParams = result.getNumberOfParameters() and
extraLeadingParams = (proxyNParams - this.getNumberOfParameters()) - 2 and
extraLeadingParams >= 0 and
result.getParameterType(proxyNParams - 1) = lastParamType and
result.getParameterType(proxyNParams - 2).(PrimitiveType).hasName("int") and
(
this instanceof Constructor and
result instanceof Constructor and
extraLeadingParams = 0 and
lastParamType.hasQualifiedName("kotlin.jvm.internal", "DefaultConstructorMarker")
or
this instanceof Method and
result instanceof Method and
this.getName() + "$default" = result.getName() and
extraLeadingParams <= 2 and
lastParamType instanceof TypeObject
)
|
forall(int paramIdx | paramIdx in [extraLeadingParams .. proxyNParams - 3] |
this.getParameterType(paramIdx - extraLeadingParams).getErasure() =
eraseRaw(result.getParameterType(paramIdx))
)
)
}
}
/** Gets the erasure of `t1` if it is a raw type, or `t1` itself otherwise. */
private Type eraseRaw(Type t1) {
if t1 instanceof RawType then result = t1.getErasure() else result = t1
}
/** Holds if method `m1` overrides method `m2`. */

View File

@@ -67,10 +67,10 @@ abstract class Modifiable extends Element {
/** Holds if this element has an `inline` modifier. */
predicate isInline() { this.hasModifier("inline") }
/** Holds if this element has an `noinline` modifier. */
/** Holds if this element has a `noinline` modifier. */
predicate isNoinline() { this.hasModifier("noinline") }
/** Holds if this element has an `crossinline` modifier. */
/** Holds if this element has a `crossinline` modifier. */
predicate isCrossinline() { this.hasModifier("crossinline") }
/** Holds if this element has a `suspend` modifier. */
@@ -93,4 +93,7 @@ abstract class Modifiable extends Element {
/** Holds if this element has a `strictfp` modifier. */
predicate isStrictfp() { this.hasModifier("strictfp") }
/** Holds if this element has a `lateinit` modifier. */
predicate isLateinit() { this.hasModifier("lateinit") }
}

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
* by `revFlow`.
*/
pragma[nomagic]
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
revFlowConsCand(c, conf) and
revFlowStore(c, _, _, conf)
}
pragma[nomagic]
predicate viableReturnPosOutNodeCandFwd1(
additional predicate viableReturnPosOutNodeCandFwd1(
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
) {
fwdFlowReturnPosition(pos, _, config) and
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
}
pragma[nomagic]
predicate viableParamArgNodeCandFwd1(
additional predicate viableParamArgNodeCandFwd1(
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
) {
viableParamArgEx(call, p, arg) and
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
)
}
predicate revFlowState(FlowState state, Configuration config) {
additional predicate revFlowState(FlowState state, Configuration config) {
exists(NodeEx node |
sinkNode(node, state, config) and
revFlow(node, _, pragma[only_bind_into](config)) and
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
* argument.
*/
pragma[nomagic]
predicate fwdFlow(
additional predicate fwdFlow(
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
) {
fwdFlow0(node, state, cc, argAp, ap, config) and
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
* the access path of the returned value.
*/
pragma[nomagic]
predicate revFlow(
additional predicate revFlow(
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
) {
revFlow0(node, state, toReturn, returnAp, ap, config) and
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
revFlow(node, state, _, _, _, config)
}
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
additional predicate revFlowAlias(NodeEx node, Configuration config) {
revFlow(node, _, _, _, _, config)
}
// use an alias as a workaround for bad functionality-induced joins
pragma[nomagic]
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
revFlow(node, state, ap, config)
}
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
revConsCand(tc, ap, config) and
validAp(ap, config)
}
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
)
}
predicate stats(
additional predicate stats(
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
) {
fwd = true and

View File

@@ -304,6 +304,15 @@ class RootdefCallable extends Callable {
this.getAnAnnotation() instanceof OverrideAnnotation
or
this.hasModifier("override")
or
// Exclude generated callables, such as `...$default` ones extracted from Kotlin code.
this.isCompilerGenerated()
or
// Exclude Kotlin serialization constructors.
this.(Constructor)
.getParameterType(this.getNumberOfParameters() - 1)
.(RefType)
.hasQualifiedName("kotlinx.serialization.internal", "SerializationConstructorMarker")
}
}

View File

@@ -59,8 +59,8 @@ predicate matchesEpsilon(RegExpTerm t) {
/**
* A lookahead/lookbehind that matches the empty string.
*/
class EmptyPositiveSubPatttern extends RegExpSubPattern {
EmptyPositiveSubPatttern() {
class EmptyPositiveSubPattern extends RegExpSubPattern {
EmptyPositiveSubPattern() {
(
this instanceof RegExpPositiveLookahead
or
@@ -70,6 +70,9 @@ class EmptyPositiveSubPatttern extends RegExpSubPattern {
}
}
/** DEPRECATED: Use `EmptyPositiveSubPattern` instead. */
deprecated class EmptyPositiveSubPatttern = EmptyPositiveSubPattern;
/**
* A branch in a disjunction that is the root node in a literal, or a literal
* whose root node is not a disjunction.
@@ -133,7 +136,7 @@ private predicate isCanonicalTerm(RelevantRegExpTerm term, string str) {
}
/**
* Gets a string reperesentation of the flags used with the regular expression.
* Gets a string representation of the flags used with the regular expression.
* Only the flags that are relevant for the canonicalization are included.
*/
string getCanonicalizationFlags(RegExpTerm root) {
@@ -334,7 +337,7 @@ private module CharacterClasses {
)
}
private string lowercaseLetter() { result = "abdcefghijklmnopqrstuvwxyz".charAt(_) }
private string lowercaseLetter() { result = "abcdefghijklmnopqrstuvwxyz".charAt(_) }
private string upperCaseLetter() { result = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".charAt(_) }
@@ -697,9 +700,7 @@ predicate delta(State q1, EdgeLabel lbl, State q2) {
lbl = Epsilon() and q2 = Accept(getRoot(dollar))
)
or
exists(EmptyPositiveSubPatttern empty | q1 = before(empty) |
lbl = Epsilon() and q2 = after(empty)
)
exists(EmptyPositiveSubPattern empty | q1 = before(empty) | lbl = Epsilon() and q2 = after(empty))
}
/**
@@ -1028,7 +1029,7 @@ module ReDoSPruning<isCandidateSig/2 isCandidate> {
* as the suffix "X" will cause both the regular expressions to be rejected.
*
* The string `w` is repeated any number of times because it needs to be
* infinitely repeatedable for the attack to work.
* infinitely repeatable for the attack to work.
* For the regular expression `/((ab)+)*abab/` the accepting state is not reachable from the fork
* using epsilon transitions. But any attempt at repeating `w` will end in a state that accepts all suffixes.
*/

View File

@@ -180,6 +180,17 @@ class AndroidProviderXmlElement extends AndroidComponentXmlElement {
attr.getValue() = "true"
)
}
/**
* Holds if the provider element is only protected by either `android:readPermission` or `android:writePermission`.
*/
predicate hasIncompletePermissions() {
(
this.getAnAttribute().(AndroidPermissionXmlAttribute).isWrite() or
this.getAnAttribute().(AndroidPermissionXmlAttribute).isRead()
) and
not this.requiresPermissions()
}
}
/**

View File

@@ -23,6 +23,8 @@ where
m.overrides(overridden) and
not m.hasModifier("override") and
not m.isOverrideAnnotated() and
not exists(FunctionalExpr mref | mref.asMethod() = m)
not exists(FunctionalExpr mref | mref.asMethod() = m) and
// Ignore generated constructs, such as <clinit> functions extracted from Kotlin code:
not m.isCompilerGenerated()
select m, "This method overrides $@; it is advisable to add an Override annotation.", overridden,
overridden.getDeclaringType() + "." + overridden.getName()

View File

@@ -16,7 +16,7 @@ A bean definition is considered to be used if one or more of the following is tr
<li>The bean is injected in to a constructor or method of a live bean due to autowiring. This includes
autowiring by annotation (<code>@Autowired</code> or <code>@Inject</code>), and autowiring configured
by the autowired attribute within bean configuration files.</li>
<li>The bean is explictly loaded from a factory bean. It is not always possible to determine when
<li>The bean is explicitly loaded from a factory bean. It is not always possible to determine when
this occurs, because factory beans are loaded using a <code>String</code> value, which may contain
arbitrary values.</li>
<li>The bean is called reflectively by the Spring framework. For example, if the class is a Spring

View File

@@ -62,7 +62,7 @@ runtime.
<p>
The code above should be rewritten to both use <code>volatile</code> and finish
all initialization before <code>f</code> is updated. Additionally, a local
variable can be used to avoid reading the field more times than neccessary.
variable can be used to avoid reading the field more times than necessary.
</p>
<sample src="DoubleCheckedLockingGood.java"/>

Some files were not shown because too many files have changed in this diff Show More