mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Merge branch 'main' into emptyRedos
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
lgtm,codescanning
|
||||
* The `StackVariableReachability` library now ignores some paths that contain an infeasible combination
|
||||
of conditionals. These improvements primarily affect the queries `cpp/uninitialized-local` and
|
||||
`cpp/use-after-free`.
|
||||
@@ -0,0 +1,2 @@
|
||||
lgtm,codescanning
|
||||
* The 'Wrong type of arguments to formatting function' (cpp/wrong-type-format-argument) query is now more accepting of the string and character formatting differences between Microsoft and non-Microsoft platforms. There are now fewer false positive results.
|
||||
@@ -19,28 +19,32 @@ import cpp
|
||||
* Holds if the argument corresponding to the `pos` conversion specifier
|
||||
* of `ffc` is expected to have type `expected`.
|
||||
*/
|
||||
pragma[noopt]
|
||||
private predicate formattingFunctionCallExpectedType(
|
||||
FormattingFunctionCall ffc, int pos, Type expected
|
||||
) {
|
||||
exists(FormattingFunction f, int i, FormatLiteral fl |
|
||||
ffc instanceof FormattingFunctionCall and
|
||||
ffc.getTarget() = f and
|
||||
f.getFormatParameterIndex() = i and
|
||||
ffc.getArgument(i) = fl and
|
||||
fl.getConversionType(pos) = expected
|
||||
)
|
||||
ffc.getFormat().(FormatLiteral).getConversionType(pos) = expected
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the argument corresponding to the `pos` conversion specifier
|
||||
* of `ffc` is expected to have type `expected` and the corresponding
|
||||
* argument `arg` has type `actual`.
|
||||
* of `ffc` could alternatively have type `expected`, for example on a different
|
||||
* platform.
|
||||
*/
|
||||
private predicate formattingFunctionCallAlternateType(
|
||||
FormattingFunctionCall ffc, int pos, Type expected
|
||||
) {
|
||||
ffc.getFormat().(FormatLiteral).getConversionTypeAlternate(pos) = expected
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the argument corresponding to the `pos` conversion specifier
|
||||
* of `ffc` is `arg` and has type `actual`.
|
||||
*/
|
||||
pragma[noopt]
|
||||
predicate formatArgType(FormattingFunctionCall ffc, int pos, Type expected, Expr arg, Type actual) {
|
||||
predicate formattingFunctionCallActualType(
|
||||
FormattingFunctionCall ffc, int pos, Expr arg, Type actual
|
||||
) {
|
||||
exists(Expr argConverted |
|
||||
formattingFunctionCallExpectedType(ffc, pos, expected) and
|
||||
ffc.getConversionArgument(pos) = arg and
|
||||
argConverted = arg.getFullyConverted() and
|
||||
actual = argConverted.getType()
|
||||
@@ -72,7 +76,8 @@ class ExpectedType extends Type {
|
||||
ExpectedType() {
|
||||
exists(Type t |
|
||||
(
|
||||
formatArgType(_, _, t, _, _) or
|
||||
formattingFunctionCallExpectedType(_, _, t) or
|
||||
formattingFunctionCallAlternateType(_, _, t) or
|
||||
formatOtherArgType(_, _, t, _, _)
|
||||
) and
|
||||
this = t.getUnspecifiedType()
|
||||
@@ -91,7 +96,11 @@ class ExpectedType extends Type {
|
||||
*/
|
||||
predicate trivialConversion(ExpectedType expected, Type actual) {
|
||||
exists(Type exp, Type act |
|
||||
formatArgType(_, _, exp, _, act) and
|
||||
(
|
||||
formattingFunctionCallExpectedType(_, _, exp) or
|
||||
formattingFunctionCallAlternateType(_, _, exp)
|
||||
) and
|
||||
formattingFunctionCallActualType(_, _, _, act) and
|
||||
expected = exp.getUnspecifiedType() and
|
||||
actual = act.getUnspecifiedType()
|
||||
) and
|
||||
@@ -146,9 +155,13 @@ int sizeof_IntType() { exists(IntType it | result = it.getSize()) }
|
||||
from FormattingFunctionCall ffc, int n, Expr arg, Type expected, Type actual
|
||||
where
|
||||
(
|
||||
formatArgType(ffc, n, expected, arg, actual) and
|
||||
formattingFunctionCallExpectedType(ffc, n, expected) and
|
||||
formattingFunctionCallActualType(ffc, n, arg, actual) and
|
||||
not exists(Type anyExpected |
|
||||
formatArgType(ffc, n, anyExpected, arg, actual) and
|
||||
(
|
||||
formattingFunctionCallExpectedType(ffc, n, anyExpected) or
|
||||
formattingFunctionCallAlternateType(ffc, n, anyExpected)
|
||||
) and
|
||||
trivialConversion(anyExpected.getUnspecifiedType(), actual.getUnspecifiedType())
|
||||
)
|
||||
or
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
intA = ++intA + 1; // BAD: undefined behavior when changing variable `intA`
|
||||
...
|
||||
intA++;
|
||||
intA = intA + 1; // GOOD: correct design
|
||||
...
|
||||
char * buff;
|
||||
...
|
||||
if(funcAdd(buff)+fucDel(buff)>0) return 1; // BAD: undefined behavior when calling functions to change the `buff` variable
|
||||
...
|
||||
intA = funcAdd(buff);
|
||||
intB = funcDel(buff);
|
||||
if(intA+intB>0) return 1; // GOOD: correct design
|
||||
@@ -0,0 +1,28 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>In some situations, the code constructs used may be executed in the wrong order in which the developer designed them. For example, if you call multiple functions as part of a single expression, and the functions have the ability to modify a shared resource, then the sequence in which the resource is changed can be unpredictable. These code snippets look suspicious and require the developer's attention.</p>
|
||||
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>We recommend that you use more guaranteed, in terms of sequence of execution, coding techniques.</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
<p>The following example demonstrates sections of code with insufficient execution sequence definition.</p>
|
||||
<sample src="UndefinedOrImplementationDefinedBehavior.c" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
<li>
|
||||
CWE Common Weakness Enumeration:
|
||||
<a href="https://wiki.sei.cmu.edu/confluence/display/c/EXP10-C.+Do+not+depend+on+the+order+of+evaluation+of+subexpressions+or+the+order+in+which+side+effects+take+place"> EXP10-C. Do not depend on the order of evaluation of subexpressions or the order in which side effects take place</a>.
|
||||
</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,166 @@
|
||||
/**
|
||||
* @name Errors Of Undefined Program Behavior
|
||||
* @description --In some situations, the code constructs used may be executed in the wrong order in which the developer designed them.
|
||||
* --For example, if you call multiple functions as part of a single expression, and the functions have the ability to modify a shared resource, then the sequence in which the resource is changed can be unpredictable.
|
||||
* --These code snippets look suspicious and require the developer's attention.
|
||||
* @kind problem
|
||||
* @id cpp/errors-of-undefined-program-behavior
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
* @tags security
|
||||
* external/cwe/cwe-758
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.valuenumbering.HashCons
|
||||
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
||||
|
||||
/**
|
||||
* Threatening expressions of undefined behavior.
|
||||
*/
|
||||
class ExpressionsOfTheSameLevel extends Expr {
|
||||
Expr exp2;
|
||||
|
||||
ExpressionsOfTheSameLevel() {
|
||||
this != exp2 and
|
||||
this.getParent() = exp2.getParent()
|
||||
}
|
||||
|
||||
/** Holds if the underlying expression is a function call. */
|
||||
predicate expressionCall() {
|
||||
this instanceof FunctionCall and
|
||||
exp2.getAChild*() instanceof FunctionCall and
|
||||
not this.getParent() instanceof Operator and
|
||||
not this.(FunctionCall).hasQualifier()
|
||||
}
|
||||
|
||||
/** Holds if the underlying expression is a call to a function to free resources. */
|
||||
predicate existsCloseOrFreeCall() {
|
||||
(
|
||||
globalValueNumber(this.(FunctionCall).getAnArgument()) =
|
||||
globalValueNumber(exp2.getAChild*().(FunctionCall).getAnArgument()) or
|
||||
hashCons(this.(FunctionCall).getAnArgument()) =
|
||||
hashCons(exp2.getAChild*().(FunctionCall).getAnArgument())
|
||||
) and
|
||||
(
|
||||
this.(FunctionCall).getTarget().hasGlobalOrStdName("close") or
|
||||
this.(FunctionCall).getTarget().hasGlobalOrStdName("free") or
|
||||
this.(FunctionCall).getTarget().hasGlobalOrStdName("fclose")
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if the arguments in the function can be changed. */
|
||||
predicate generalArgumentDerivedType() {
|
||||
exists(Parameter prt1, Parameter prt2, AssignExpr aet1, AssignExpr aet2, int i, int j |
|
||||
not this.(FunctionCall).getArgument(i).isConstant() and
|
||||
hashCons(this.(FunctionCall).getArgument(i)) =
|
||||
hashCons(exp2.getAChild*().(FunctionCall).getArgument(j)) and
|
||||
prt1 = this.(FunctionCall).getTarget().getParameter(i) and
|
||||
prt2 = exp2.getAChild*().(FunctionCall).getTarget().getParameter(j) and
|
||||
prt1.getType() instanceof DerivedType and
|
||||
(
|
||||
aet1 = this.(FunctionCall).getTarget().getEntryPoint().getASuccessor*() and
|
||||
(
|
||||
aet1.getLValue().(ArrayExpr).getArrayBase().(VariableAccess).getTarget() =
|
||||
prt1.getAnAccess().getTarget() or
|
||||
aet1.getLValue().(VariableAccess).getTarget() = prt1.getAnAccess().getTarget()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc1 |
|
||||
fc1.getTarget().hasGlobalName("memcpy") and
|
||||
fc1.getArgument(0).(VariableAccess).getTarget() = prt1.getAnAccess().getTarget() and
|
||||
fc1 = this.(FunctionCall).getTarget().getEntryPoint().getASuccessor*()
|
||||
)
|
||||
) and
|
||||
(
|
||||
aet2 = exp2.getAChild*().(FunctionCall).getTarget().getEntryPoint().getASuccessor*() and
|
||||
(
|
||||
aet2.getLValue().(ArrayExpr).getArrayBase().(VariableAccess).getTarget() =
|
||||
prt2.getAnAccess().getTarget() or
|
||||
aet2.getLValue().(VariableAccess).getTarget() = prt2.getAnAccess().getTarget()
|
||||
)
|
||||
or
|
||||
exists(FunctionCall fc1 |
|
||||
fc1.getTarget().hasGlobalName("memcpy") and
|
||||
fc1.getArgument(0).(VariableAccess).getTarget() = prt2.getAnAccess().getTarget() and
|
||||
fc1 = exp2.(FunctionCall).getTarget().getEntryPoint().getASuccessor*()
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if functions have a common global argument. */
|
||||
predicate generalGlobalArgument() {
|
||||
exists(Declaration dl, AssignExpr aet1, AssignExpr aet2 |
|
||||
dl instanceof GlobalVariable and
|
||||
(
|
||||
(
|
||||
aet1.getLValue().(Access).getTarget() = dl or
|
||||
aet1.getLValue().(ArrayExpr).getArrayBase().(VariableAccess).getTarget() = dl
|
||||
) and
|
||||
aet1 = this.(FunctionCall).getTarget().getEntryPoint().getASuccessor*() and
|
||||
not aet1.getRValue().isConstant()
|
||||
or
|
||||
exists(FunctionCall fc1 |
|
||||
fc1.getTarget().hasGlobalName("memcpy") and
|
||||
fc1.getArgument(0).(VariableAccess).getTarget() = dl and
|
||||
fc1 = this.(FunctionCall).getTarget().getEntryPoint().getASuccessor*()
|
||||
)
|
||||
) and
|
||||
(
|
||||
(
|
||||
aet2.getLValue().(Access).getTarget() = dl or
|
||||
aet2.getLValue().(ArrayExpr).getArrayBase().(VariableAccess).getTarget() = dl
|
||||
) and
|
||||
aet2 = exp2.(FunctionCall).getTarget().getEntryPoint().getASuccessor*()
|
||||
or
|
||||
exists(FunctionCall fc1 |
|
||||
fc1.getTarget().hasGlobalName("memcpy") and
|
||||
fc1.getArgument(0).(VariableAccess).getTarget() = dl and
|
||||
fc1 = exp2.(FunctionCall).getTarget().getEntryPoint().getASuccessor*()
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if sequence point is not present in expression. */
|
||||
predicate orderOfActionExpressions() {
|
||||
not this.getParent() instanceof BinaryLogicalOperation and
|
||||
not this.getParent() instanceof ConditionalExpr and
|
||||
not this.getParent() instanceof Loop and
|
||||
not this.getParent() instanceof CommaExpr
|
||||
}
|
||||
|
||||
/** Holds if expression is crement. */
|
||||
predicate dangerousCrementChanges() {
|
||||
hashCons(this.(CrementOperation).getOperand()) = hashCons(exp2.(CrementOperation).getOperand())
|
||||
or
|
||||
hashCons(this.(CrementOperation).getOperand()) = hashCons(exp2)
|
||||
or
|
||||
hashCons(this.(CrementOperation).getOperand()) = hashCons(exp2.(ArrayExpr).getArrayOffset())
|
||||
or
|
||||
hashCons(this.(Assignment).getLValue()) = hashCons(exp2.(Assignment).getLValue())
|
||||
or
|
||||
not this.getAChild*() instanceof Call and
|
||||
(
|
||||
hashCons(this.getAChild*().(CrementOperation).getOperand()) = hashCons(exp2) or
|
||||
hashCons(this.getAChild*().(CrementOperation).getOperand()) =
|
||||
hashCons(exp2.(Assignment).getLValue())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from ExpressionsOfTheSameLevel eots
|
||||
where
|
||||
eots.orderOfActionExpressions() and
|
||||
(
|
||||
eots.expressionCall() and
|
||||
(
|
||||
eots.generalArgumentDerivedType() or
|
||||
eots.generalGlobalArgument() or
|
||||
eots.existsCloseOrFreeCall()
|
||||
)
|
||||
or
|
||||
eots.dangerousCrementChanges()
|
||||
)
|
||||
select eots, "This expression may have undefined behavior."
|
||||
@@ -272,20 +272,16 @@ class File extends Container, @file {
|
||||
* are compiled by a Microsoft compiler are detected by this predicate.
|
||||
*/
|
||||
predicate compiledAsMicrosoft() {
|
||||
exists(Compilation c |
|
||||
c.getAFileCompiled() = this and
|
||||
exists(File f, Compilation c |
|
||||
c.getAFileCompiled() = f and
|
||||
(
|
||||
c.getAnArgument() = "--microsoft" or
|
||||
c.getAnArgument()
|
||||
.toLowerCase()
|
||||
.replaceAll("\\", "/")
|
||||
.matches(["%/cl.exe", "%/clang-cl.exe"])
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(File parent |
|
||||
parent.compiledAsMicrosoft() and
|
||||
parent.getAnIncludedFile() = this
|
||||
) and
|
||||
f.getAnIncludedFile*() = this
|
||||
)
|
||||
}
|
||||
|
||||
@@ -358,6 +354,11 @@ class File extends Container, @file {
|
||||
string getShortName() { files(underlyingElement(this), _, result, _, _) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if any file was compiled by a Microsoft compiler.
|
||||
*/
|
||||
predicate anyFileCompiledAsMicrosoft() { any(File f).compiledAsMicrosoft() }
|
||||
|
||||
/**
|
||||
* A C/C++ header file, as determined (mainly) by file extension.
|
||||
*
|
||||
|
||||
@@ -306,7 +306,7 @@ class FormatLiteral extends Literal {
|
||||
* Holds if this `FormatLiteral` is in a context that supports
|
||||
* Microsoft rules and extensions.
|
||||
*/
|
||||
predicate isMicrosoft() { any(File f).compiledAsMicrosoft() }
|
||||
predicate isMicrosoft() { anyFileCompiledAsMicrosoft() }
|
||||
|
||||
/**
|
||||
* Gets the format string, with '%%' and '%@' replaced by '_' (to avoid processing
|
||||
@@ -869,6 +869,33 @@ class FormatLiteral extends Literal {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an alternate argument type that would be required by the nth
|
||||
* conversion specifier on a Microsoft or non-Microsoft platform, opposite
|
||||
* to that of the snapshot. This may be useful for answering 'what might
|
||||
* happen' questions.
|
||||
*/
|
||||
Type getConversionTypeAlternate(int n) {
|
||||
exists(string len, string conv |
|
||||
this.parseConvSpec(n, _, _, _, _, _, len, conv) and
|
||||
(len != "l" and len != "w" and len != "h") and
|
||||
getUse().getTarget().(FormattingFunction).getFormatCharType().getSize() > 1 and // wide function
|
||||
(
|
||||
conv = "c" and
|
||||
result = getNonDefaultCharType()
|
||||
or
|
||||
conv = "C" and
|
||||
result = getDefaultCharType()
|
||||
or
|
||||
conv = "s" and
|
||||
result.(PointerType).getBaseType() = getNonDefaultCharType()
|
||||
or
|
||||
conv = "S" and
|
||||
result.(PointerType).getBaseType() = getDefaultCharType()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the nth conversion specifier of this format string (if `mode = 2`), it's
|
||||
* minimum field width (if `mode = 0`) or it's precision (if `mode = 1`) requires a
|
||||
|
||||
@@ -208,7 +208,7 @@ private predicate bbSuccessorEntryReachesDefOrUse(
|
||||
boolean skipsFirstLoopAlwaysTrueUponEntry
|
||||
) {
|
||||
exists(BasicBlock succ, boolean succSkipsFirstLoopAlwaysTrueUponEntry |
|
||||
bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
|
||||
bbSuccessorEntryReachesLoopInvariant0(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
|
|
||||
bbEntryReachesDefOrUseLocally(succ, v, defOrUse) and
|
||||
|
||||
@@ -3,7 +3,250 @@
|
||||
* reachability involving stack variables.
|
||||
*/
|
||||
|
||||
import cpp
|
||||
private import semmle.code.cpp.controlflow.Guards
|
||||
private import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
||||
|
||||
/** A `GuardCondition` which appear in a control-flow path to a sink. */
|
||||
abstract private class LogicalGuardCondition extends GuardCondition {
|
||||
LogicalGuardCondition() {
|
||||
// Either the `GuardCondition` is part of the path from a source to a sink
|
||||
revBbSuccessorEntryReaches0(_, this.getBasicBlock(), _, _, _)
|
||||
or
|
||||
// or it controls the basic block that contains the source node.
|
||||
this.controls(any(BasicBlock bb | fwdBbEntryReachesLocally(bb, _, _, _)), _)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the truth of this logical expression having value `wholeIsTrue`
|
||||
* implies that the truth of the child expression `part` has truth value `partIsTrue`.
|
||||
*/
|
||||
abstract predicate impliesCondition(
|
||||
LogicalGuardCondition e, boolean testIsTrue, boolean condIsTrue
|
||||
);
|
||||
}
|
||||
|
||||
private class BinaryLogicalGuardCondition extends LogicalGuardCondition, BinaryLogicalOperation {
|
||||
override predicate impliesCondition(
|
||||
LogicalGuardCondition e, boolean testIsTrue, boolean condIsTrue
|
||||
) {
|
||||
this.impliesValue(e, testIsTrue, condIsTrue)
|
||||
}
|
||||
}
|
||||
|
||||
private class VariableGuardCondition extends LogicalGuardCondition, VariableAccess {
|
||||
override predicate impliesCondition(
|
||||
LogicalGuardCondition e, boolean testIsTrue, boolean condIsTrue
|
||||
) {
|
||||
this = e and
|
||||
(
|
||||
testIsTrue = true and condIsTrue = true
|
||||
or
|
||||
testIsTrue = false and condIsTrue = false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class NotGuardCondition extends LogicalGuardCondition, NotExpr {
|
||||
override predicate impliesCondition(
|
||||
LogicalGuardCondition e, boolean testIsTrue, boolean condIsTrue
|
||||
) {
|
||||
e = this.getOperand() and
|
||||
(
|
||||
testIsTrue = true and
|
||||
condIsTrue = false
|
||||
or
|
||||
testIsTrue = false and
|
||||
condIsTrue = true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private newtype TCondition =
|
||||
MkCondition(LogicalGuardCondition guard, boolean testIsTrue) { testIsTrue = [false, true] }
|
||||
|
||||
private class Condition extends MkCondition {
|
||||
boolean testIsTrue;
|
||||
LogicalGuardCondition guard;
|
||||
|
||||
Condition() { this = MkCondition(guard, testIsTrue) }
|
||||
|
||||
/**
|
||||
* Holds if this condition having the value `this.getTruthValue()` implies that `cond` has truth
|
||||
* value `cond.getTruthValue()`.
|
||||
*/
|
||||
string toString() { result = guard.toString() + " == " + testIsTrue.toString() }
|
||||
|
||||
/** Gets the value of this `Condition`. */
|
||||
boolean getTruthValue() { result = testIsTrue }
|
||||
|
||||
LogicalGuardCondition getCondition() { result = guard }
|
||||
|
||||
pragma[nomagic]
|
||||
predicate impliesCondition(Condition cond) {
|
||||
exists(LogicalGuardCondition other |
|
||||
other = cond.getCondition() and
|
||||
this.getCondition()
|
||||
.impliesCondition(globalValueNumber(other).getAnExpr(),
|
||||
pragma[only_bind_into](pragma[only_bind_out](testIsTrue)),
|
||||
pragma[only_bind_into](pragma[only_bind_out](cond.getTruthValue())))
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the negated expression represented by this `Condition`, if any. */
|
||||
private Condition negate() {
|
||||
result.getCondition() = guard and
|
||||
result.getTruthValue() = testIsTrue.booleanNot()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this condition having the value `this.getTruthValue()` implies that `cond` cannot have
|
||||
* the truth value `cond.getTruthValue()`.
|
||||
*/
|
||||
final predicate refutesCondition(Condition cond) { this.impliesCondition(cond.negate()) }
|
||||
|
||||
/** Gets the `Location` of the expression that generated this `Condition`. */
|
||||
Location getLocation() { result = guard.getLocation() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a `Condition` that controls `b`. That is, to enter `b` the condition must hold.
|
||||
*/
|
||||
private Condition getADirectCondition(BasicBlock b) {
|
||||
result.getCondition().controls(b, result.getTruthValue())
|
||||
}
|
||||
|
||||
/**
|
||||
* Like the shared dataflow library, the reachability analysis is split into two stages:
|
||||
* In the first stage, we compute an overapproximation of the possible control-flow paths where we don't
|
||||
* reason about path conditions. This stage is split into phases: A forward phase (computed by the
|
||||
* predicates prefixes with `fwd`), and a reverse phase (computed by the predicates prefixed with `rev`).
|
||||
*
|
||||
* The forward phease computes the set of control-flow nodes reachable from a given `source` and `v` such
|
||||
* that `config.isSource(source, v)` holds.
|
||||
*
|
||||
* See the QLDoc on `revBbSuccessorEntryReaches0` for a description of what the reverse phase computes.
|
||||
*/
|
||||
private predicate fwdBbSuccessorEntryReaches0(
|
||||
ControlFlowNode source, BasicBlock bb, SemanticStackVariable v,
|
||||
boolean skipsFirstLoopAlwaysTrueUponEntry, StackVariableReachability config
|
||||
) {
|
||||
fwdBbEntryReachesLocally(bb, v, source, config) and
|
||||
skipsFirstLoopAlwaysTrueUponEntry = false
|
||||
or
|
||||
exists(BasicBlock pred, boolean predSkipsFirstLoopAlwaysTrueUponEntry |
|
||||
bbSuccessorEntryReachesLoopInvariant0(pred, bb, predSkipsFirstLoopAlwaysTrueUponEntry,
|
||||
skipsFirstLoopAlwaysTrueUponEntry)
|
||||
|
|
||||
// Note we cannot filter out barriers at this point.
|
||||
// See the comment in `revBbSuccessorEntryReaches0` for an explanation why,
|
||||
fwdBbSuccessorEntryReaches0(source, pred, v, predSkipsFirstLoopAlwaysTrueUponEntry, config)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* The second phase of the first stages computes, for each `source` and `v` pair such
|
||||
* that `config.isSource(source, v)`, which sinks are reachable from that `(source, v)` pair.
|
||||
*/
|
||||
private predicate revBbSuccessorEntryReaches0(
|
||||
ControlFlowNode source, BasicBlock bb, SemanticStackVariable v,
|
||||
boolean skipsFirstLoopAlwaysTrueUponEntry, StackVariableReachability config
|
||||
) {
|
||||
exists(BasicBlock succ, boolean succSkipsFirstLoopAlwaysTrueUponEntry |
|
||||
fwdBbSuccessorEntryReaches0(source, bb, v, skipsFirstLoopAlwaysTrueUponEntry, config) and
|
||||
bbSuccessorEntryReachesLoopInvariant0(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
|
|
||||
revBbEntryReachesLocally(succ, v, _, config) and
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry = false
|
||||
or
|
||||
// Note: We cannot rule out a successor block that contain a barrier here (like we do later in
|
||||
// `bbSuccessorEntryReaches`) as we might later discover that the only way to get through a piece of
|
||||
// code is through that barrier, and we want to discover this in
|
||||
// `bbSuccessorEntryReachesLoopInvariant`. As an example, consider this piece of code:
|
||||
// ```
|
||||
// if(b) { (1) source(); }
|
||||
// (2) if(b) { (3) barrier(); }
|
||||
// (4) sink();
|
||||
// ```
|
||||
// here, we want the successor relation to contain:
|
||||
// 1 -> {2}, 2 -> {3, 4}
|
||||
// since the second stage will deduce that the edge (2) -> (3) is unconditional (as b is always true
|
||||
// if we start at `source()`), and so there is actually no path from (1) to (4) without going through
|
||||
// a barrier.
|
||||
revBbSuccessorEntryReaches0(source, succ, v, succSkipsFirstLoopAlwaysTrueUponEntry, config)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate successorExitsLoop(BasicBlock pred, BasicBlock succ, Loop loop) {
|
||||
pred.getASuccessor() = succ and
|
||||
bbDominates(loop.getStmt(), pred) and
|
||||
not bbDominates(loop.getStmt(), succ)
|
||||
}
|
||||
|
||||
private predicate successorExitsFirstDisjunct(BasicBlock pred, BasicBlock succ) {
|
||||
exists(LogicalOrExpr orExpr | orExpr instanceof GuardCondition |
|
||||
pred.getAFalseSuccessor() = succ and
|
||||
pred.contains(orExpr.getLeftOperand())
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* When we exit a loop, we filter out the conditions that arise from the loop's guard.
|
||||
* To see why this is necessary, consider this example:
|
||||
* ```
|
||||
* (1) source();
|
||||
* while (b) { (2) ... }
|
||||
* (3) sink();
|
||||
* ```
|
||||
* If we keep all the conditions when we transition from (2) to (3) we learn that `b` is true at
|
||||
* (3), but since we exited the loop we also learn that `b` is false at 3.
|
||||
* Thus, when we transition from (2) to (3) we discard all those conditions that are true at (2),
|
||||
* but NOT true at (3).
|
||||
*/
|
||||
private predicate isLoopCondition(LogicalGuardCondition cond, BasicBlock pred, BasicBlock bb) {
|
||||
exists(Loop loop, boolean testIsTrue | successorExitsLoop(pred, bb, loop) |
|
||||
// the resulting `Condition` holds inside the loop
|
||||
cond.controls(pred, testIsTrue) and
|
||||
// but not prior to the loop.
|
||||
not cond.controls(loop.getBasicBlock(), testIsTrue)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* When we leave the first disjunct we throw away the condition that says the the first disjunct is
|
||||
* false. To see why this is necessary, consider this example:
|
||||
* ```
|
||||
* if((1) b1 || (2) b2) { (3) ... }
|
||||
* ```
|
||||
* it holds that `b1 == false` controls (2), and since (2) steps to (3) we learn that `b1 == false `
|
||||
* holds at (3). So we filter out the conditions that we learn from leaving taking the false
|
||||
* branch in a disjunction.
|
||||
*/
|
||||
private predicate isDisjunctionCondition(LogicalGuardCondition cond, BasicBlock pred, BasicBlock bb) {
|
||||
exists(boolean testIsTrue | successorExitsFirstDisjunct(pred, bb) |
|
||||
// the resulting `Condition` holds after evaluating the left-hand side
|
||||
cond.controls(bb, testIsTrue) and
|
||||
// but not before evaluating the left-hand side.
|
||||
not cond.controls(pred, testIsTrue)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isLoopVariantCondition(LogicalGuardCondition cond, BasicBlock pred, BasicBlock bb) {
|
||||
exists(Loop loop |
|
||||
bb.getEnd() = loop.getCondition() and
|
||||
pred.getASuccessor() = bb and
|
||||
bbDominates(bb, pred) and
|
||||
loopVariant(cond.getAChild*(), loop)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate loopVariant(VariableAccess e, Loop loop) {
|
||||
exists(SsaDefinition d | d.getAUse(e.getTarget()) = e |
|
||||
d.getAnUltimateDefiningValue(e.getTarget()) = loop.getCondition().getAChild*() or
|
||||
d.getAnUltimateDefiningValue(e.getTarget()).getEnclosingStmt().getParent*() = loop.getStmt() or
|
||||
d.getAnUltimateDefiningValue(e.getTarget()) = loop.(ForStmt).getUpdate().getAChild*()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A reachability analysis for control-flow nodes involving stack variables.
|
||||
@@ -60,7 +303,8 @@ abstract class StackVariableReachability extends string {
|
||||
* ```
|
||||
*
|
||||
* In addition to using a better performing implementation, this analysis
|
||||
* accounts for loops where the condition is provably true upon entry.
|
||||
* accounts for loops where the condition is provably true upon entry, and discards paths that require
|
||||
* an infeasible combination of guard conditions (for example, `if(b) { ... }` and `if(!b) { ... }`).
|
||||
*/
|
||||
predicate reaches(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) {
|
||||
/*
|
||||
@@ -80,46 +324,184 @@ abstract class StackVariableReachability extends string {
|
||||
j > i and
|
||||
sink = bb.getNode(j) and
|
||||
isSink(sink, v) and
|
||||
not exists(int k | isBarrier(bb.getNode(k), v) | k in [i + 1 .. j - 1])
|
||||
not isBarrier(bb.getNode(pragma[only_bind_into]([i + 1 .. j - 1])), v)
|
||||
)
|
||||
or
|
||||
not exists(int k | isBarrier(bb.getNode(k), v) | k > i) and
|
||||
bbSuccessorEntryReaches(bb, v, sink, _)
|
||||
bbSuccessorEntryReaches(source, bb, v, sink, _)
|
||||
)
|
||||
}
|
||||
|
||||
private Condition getASinkCondition(SemanticStackVariable v) {
|
||||
exists(BasicBlock bb |
|
||||
revBbEntryReachesLocally(bb, v, _, this) and
|
||||
result.getCondition().controls(bb, result.getTruthValue())
|
||||
)
|
||||
}
|
||||
|
||||
private Condition getABarrierCondition(SemanticStackVariable v) {
|
||||
exists(BasicBlock bb |
|
||||
isBarrier(bb.getANode(), v) and
|
||||
result.getCondition().controls(bb, result.getTruthValue())
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a condition with a known truth value in `bb` when the control-flow starts at the source
|
||||
* node `source` and we're tracking reachability using variable `v` (that is,
|
||||
* `this.isSource(source, v)` holds).
|
||||
*
|
||||
* This predicate is `pragma[noopt]` as it seems difficult to get the correct join order for the
|
||||
* recursive case otherwise:
|
||||
* revBbSuccessorEntryReaches0(bb) -> getASuccessor -> prev_delta ->
|
||||
* revBbSuccessorEntryReaches0(pred) -> {isLoopCondition, isDisjunctionCondition, isLoopVariantCondition}
|
||||
*/
|
||||
pragma[noopt]
|
||||
private Condition getACondition(ControlFlowNode source, SemanticStackVariable v, BasicBlock bb) {
|
||||
revBbSuccessorEntryReaches0(source, bb, v, _, this) and
|
||||
(
|
||||
result = getADirectCondition(bb) and
|
||||
(
|
||||
exists(Condition c |
|
||||
c = getASinkCondition(v) and
|
||||
result.refutesCondition(c)
|
||||
)
|
||||
or
|
||||
exists(Condition c |
|
||||
c = getABarrierCondition(v) and
|
||||
result.impliesCondition(c)
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(BasicBlock pred |
|
||||
pred.getASuccessor() = bb and
|
||||
result = getACondition(source, v, pred) and
|
||||
revBbSuccessorEntryReaches0(source, pred, v, _, this) and
|
||||
exists(LogicalGuardCondition c | c = result.getCondition() |
|
||||
not isLoopCondition(c, pred, bb) and
|
||||
not isDisjunctionCondition(c, pred, bb) and
|
||||
not isLoopVariantCondition(c, pred, bb)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate bbSuccessorEntryReachesLoopInvariantSucc(
|
||||
ControlFlowNode source, BasicBlock pred, SemanticStackVariable v, BasicBlock succ,
|
||||
boolean predSkipsFirstLoopAlwaysTrueUponEntry
|
||||
) {
|
||||
revBbSuccessorEntryReaches0(source, pragma[only_bind_into](pred), v,
|
||||
predSkipsFirstLoopAlwaysTrueUponEntry, this) and
|
||||
pred.getASuccessor() = succ
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate bbSuccessorEntryReachesLoopInvariantCand(
|
||||
ControlFlowNode source, BasicBlock pred, SemanticStackVariable v, BasicBlock succ,
|
||||
boolean predSkipsFirstLoopAlwaysTrueUponEntry, boolean succSkipsFirstLoopAlwaysTrueUponEntry
|
||||
) {
|
||||
bbSuccessorEntryReachesLoopInvariantSucc(source, pragma[only_bind_into](pred), v, succ,
|
||||
predSkipsFirstLoopAlwaysTrueUponEntry) and
|
||||
bbSuccessorEntryReachesLoopInvariant0(pred, succ, predSkipsFirstLoopAlwaysTrueUponEntry,
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `pred`, `succ`, `predSkipsFirstLoopAlwaysTrueUponEntry` and
|
||||
* `succSkipsFirstLoopAlwaysTrueUponEntry` satisfy the loop invariants specified in the QLDoc
|
||||
* for `bbSuccessorEntryReachesLoopInvariant0`.
|
||||
*
|
||||
* In addition, this predicate:
|
||||
* 1. Rules out successor blocks that are unreachable due to contradictory path conditions.
|
||||
* 2. Refines the successor relation when the edge `pred -> succ` is a conditional edge whose truth
|
||||
* value is known.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate bbSuccessorEntryReachesLoopInvariant(
|
||||
ControlFlowNode source, BasicBlock pred, SemanticStackVariable v, BasicBlock succ,
|
||||
boolean predSkipsFirstLoopAlwaysTrueUponEntry, boolean succSkipsFirstLoopAlwaysTrueUponEntry
|
||||
) {
|
||||
bbSuccessorEntryReachesLoopInvariantCand(source, pred, v, succ,
|
||||
predSkipsFirstLoopAlwaysTrueUponEntry, succSkipsFirstLoopAlwaysTrueUponEntry) and
|
||||
not exists(Condition cond, Condition direct |
|
||||
cond = getACondition(source, v, pred) and
|
||||
direct = pragma[only_bind_out](getADirectCondition(succ)) and
|
||||
cond.refutesCondition(direct)
|
||||
) and
|
||||
(
|
||||
// If we picked the successor edge corresponding to a condition being true, there must not be
|
||||
// another path condition that refutes that the condition is true.
|
||||
not exists(Condition cond | cond = getACondition(source, v, pred) |
|
||||
succ = pred.getATrueSuccessor() and
|
||||
cond.refutesCondition(pragma[only_bind_out](MkCondition(pred.getEnd(), true)))
|
||||
) and
|
||||
// If we picked the successor edge corresponding to a condition being false, there must not be
|
||||
// another path condition that refutes that the condition is false.
|
||||
not exists(Condition cond | cond = getACondition(source, v, pred) |
|
||||
succ = pred.getAFalseSuccessor() and
|
||||
cond.refutesCondition(pragma[only_bind_out](MkCondition(pred.getEnd(), false)))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate bbSuccessorEntryReaches(
|
||||
BasicBlock bb, SemanticStackVariable v, ControlFlowNode node,
|
||||
ControlFlowNode source, BasicBlock bb, SemanticStackVariable v, ControlFlowNode node,
|
||||
boolean skipsFirstLoopAlwaysTrueUponEntry
|
||||
) {
|
||||
exists(BasicBlock succ, boolean succSkipsFirstLoopAlwaysTrueUponEntry |
|
||||
bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
|
||||
bbSuccessorEntryReachesLoopInvariant(source, bb, v, succ, skipsFirstLoopAlwaysTrueUponEntry,
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
|
|
||||
bbEntryReachesLocally(succ, v, node) and
|
||||
revBbEntryReachesLocally(succ, v, node, this) and
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry = false
|
||||
or
|
||||
not isBarrier(succ.getNode(_), v) and
|
||||
bbSuccessorEntryReaches(succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
bbSuccessorEntryReachesLoopInvariant(source, bb, v, succ, skipsFirstLoopAlwaysTrueUponEntry,
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry) and
|
||||
not isBarrier(pragma[only_bind_out](succ.getANode()), v) and
|
||||
pragma[only_bind_into](this)
|
||||
.bbSuccessorEntryReaches(source, succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private predicate bbEntryReachesLocally(
|
||||
BasicBlock bb, SemanticStackVariable v, ControlFlowNode node
|
||||
) {
|
||||
exists(int n |
|
||||
node = bb.getNode(n) and
|
||||
isSink(node, v)
|
||||
|
|
||||
not exists(this.firstBarrierIndexIn(bb, v))
|
||||
private predicate fwdBbEntryReachesLocally(
|
||||
BasicBlock bb, SemanticStackVariable v, ControlFlowNode node, StackVariableReachability config
|
||||
) {
|
||||
exists(int n |
|
||||
node = bb.getNode(n) and
|
||||
config.isSource(node, v) and
|
||||
(
|
||||
not exists(lastBarrierIndexIn(bb, v, config))
|
||||
or
|
||||
n <= this.firstBarrierIndexIn(bb, v)
|
||||
lastBarrierIndexIn(bb, v, config) <= n
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private int firstBarrierIndexIn(BasicBlock bb, SemanticStackVariable v) {
|
||||
result = min(int m | isBarrier(bb.getNode(m), v))
|
||||
}
|
||||
private predicate revBbEntryReachesLocally(
|
||||
BasicBlock bb, SemanticStackVariable v, ControlFlowNode node, StackVariableReachability config
|
||||
) {
|
||||
exists(int n |
|
||||
node = bb.getNode(n) and
|
||||
config.isSink(node, v)
|
||||
|
|
||||
not exists(firstBarrierIndexIn(bb, v, config))
|
||||
or
|
||||
n <= firstBarrierIndexIn(bb, v, config)
|
||||
)
|
||||
}
|
||||
|
||||
private int firstBarrierIndexIn(
|
||||
BasicBlock bb, SemanticStackVariable v, StackVariableReachability config
|
||||
) {
|
||||
result = min(int m | config.isBarrier(bb.getNode(m), v))
|
||||
}
|
||||
|
||||
private int lastBarrierIndexIn(
|
||||
BasicBlock bb, SemanticStackVariable v, StackVariableReachability config
|
||||
) {
|
||||
result = max(int m | config.isBarrier(bb.getNode(m), v))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,7 +564,7 @@ private predicate bbLoopConditionAlwaysTrueUponEntrySuccessor(
|
||||
* is provably true upon entry, then `succ` is not allowed to skip
|
||||
* that loop (`succSkipsFirstLoopAlwaysTrueUponEntry = false`).
|
||||
*/
|
||||
predicate bbSuccessorEntryReachesLoopInvariant(
|
||||
predicate bbSuccessorEntryReachesLoopInvariant0(
|
||||
BasicBlock pred, BasicBlock succ, boolean predSkipsFirstLoopAlwaysTrueUponEntry,
|
||||
boolean succSkipsFirstLoopAlwaysTrueUponEntry
|
||||
) {
|
||||
@@ -296,10 +678,52 @@ abstract class StackVariableReachabilityWithReassignment extends StackVariableRe
|
||||
)
|
||||
}
|
||||
|
||||
private predicate bbSuccessorEntryReaches(
|
||||
BasicBlock bb, SemanticStackVariable v, ControlFlowNode node,
|
||||
boolean skipsFirstLoopAlwaysTrueUponEntry
|
||||
) {
|
||||
exists(BasicBlock succ, boolean succSkipsFirstLoopAlwaysTrueUponEntry |
|
||||
bbSuccessorEntryReachesLoopInvariant0(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
|
|
||||
revBbEntryReachesLocally(succ, v, node, this) and
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry = false
|
||||
or
|
||||
not isBarrier(succ.getNode(_), v) and
|
||||
bbSuccessorEntryReaches(succ, v, node, succSkipsFirstLoopAlwaysTrueUponEntry)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate reaches0(ControlFlowNode source, SemanticStackVariable v, ControlFlowNode sink) {
|
||||
/*
|
||||
* Implementation detail: the predicates in this class are a generalization of
|
||||
* those in DefinitionsAndUses.qll, and should be kept in sync.
|
||||
*
|
||||
* Unfortunately, caching of abstract predicates does not work well, so the
|
||||
* predicates in DefinitionsAndUses.qll cannot use this library.
|
||||
*/
|
||||
|
||||
exists(BasicBlock bb, int i |
|
||||
isSource(source, v) and
|
||||
bb.getNode(i) = source and
|
||||
not bb.isUnreachable()
|
||||
|
|
||||
exists(int j |
|
||||
j > i and
|
||||
sink = bb.getNode(j) and
|
||||
isSink(sink, v) and
|
||||
not isBarrier(bb.getNode(pragma[only_bind_into]([i + 1 .. j - 1])), v)
|
||||
)
|
||||
or
|
||||
not exists(int k | isBarrier(bb.getNode(k), v) | k > i) and
|
||||
bbSuccessorEntryReaches(bb, v, sink, _)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate reassignment(
|
||||
ControlFlowNode source, SemanticStackVariable v, ControlFlowNode def, SemanticStackVariable v0
|
||||
) {
|
||||
StackVariableReachability.super.reaches(source, v, def) and
|
||||
reaches0(source, v, def) and
|
||||
exprDefinition(v0, def, v.getAnAccess())
|
||||
}
|
||||
|
||||
@@ -365,11 +789,11 @@ abstract class StackVariableReachabilityExt extends string {
|
||||
boolean skipsFirstLoopAlwaysTrueUponEntry
|
||||
) {
|
||||
exists(BasicBlock succ, boolean succSkipsFirstLoopAlwaysTrueUponEntry |
|
||||
bbSuccessorEntryReachesLoopInvariant(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
|
||||
bbSuccessorEntryReachesLoopInvariant0(bb, succ, skipsFirstLoopAlwaysTrueUponEntry,
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry) and
|
||||
not isBarrier(source, bb.getEnd(), succ.getStart(), v)
|
||||
|
|
||||
bbEntryReachesLocally(source, succ, v, node) and
|
||||
this.bbEntryReachesLocally(source, succ, v, node) and
|
||||
succSkipsFirstLoopAlwaysTrueUponEntry = false
|
||||
or
|
||||
not exists(int k | isBarrier(source, succ.getNode(k), succ.getNode(k + 1), v)) and
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -1117,6 +1117,44 @@ ReturnPosition getReturnPosition(ReturnNodeExt ret) {
|
||||
result = getReturnPosition0(ret, ret.getKind())
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether `inner` can return to `call` in the call context `innercc`.
|
||||
* Assumes a context of `inner = viableCallableExt(call)`.
|
||||
*/
|
||||
bindingset[innercc, inner, call]
|
||||
predicate checkCallContextReturn(CallContext innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
innercc instanceof CallContextAny
|
||||
or
|
||||
exists(DataFlowCallable c0, DataFlowCall call0 |
|
||||
callEnclosingCallable(call0, inner) and
|
||||
innercc = TReturn(c0, call0) and
|
||||
c0 = prunedViableImplInCallContextReverse(call0, call)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether `call` can resolve to `calltarget` in the call context `cc`.
|
||||
* Assumes a context of `calltarget = viableCallableExt(call)`.
|
||||
*/
|
||||
bindingset[cc, call, calltarget]
|
||||
predicate checkCallContextCall(CallContext cc, DataFlowCall call, DataFlowCallable calltarget) {
|
||||
exists(DataFlowCall ctx | cc = TSpecificCall(ctx) |
|
||||
if reducedViableImplInCallContext(call, _, ctx)
|
||||
then calltarget = prunedViableImplInCallContext(call, ctx)
|
||||
else any()
|
||||
)
|
||||
or
|
||||
cc instanceof CallContextSomeCall
|
||||
or
|
||||
cc instanceof CallContextAny
|
||||
or
|
||||
cc instanceof CallContextReturn
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a return from `callable` in `cc` to `call`. This is equivalent to
|
||||
* `callable = viableCallableExt(call) and checkCallContextReturn(cc, callable, call)`.
|
||||
*/
|
||||
bindingset[cc, callable]
|
||||
predicate resolveReturn(CallContext cc, DataFlowCallable callable, DataFlowCall call) {
|
||||
cc instanceof CallContextAny and callable = viableCallableExt(call)
|
||||
@@ -1128,6 +1166,10 @@ predicate resolveReturn(CallContext cc, DataFlowCallable callable, DataFlowCall
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a call from `call` in `cc` to `result`. This is equivalent to
|
||||
* `result = viableCallableExt(call) and checkCallContextCall(cc, call, result)`.
|
||||
*/
|
||||
bindingset[call, cc]
|
||||
DataFlowCallable resolveCall(DataFlowCall call, CallContext cc) {
|
||||
exists(DataFlowCall ctx | cc = TSpecificCall(ctx) |
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -1117,6 +1117,44 @@ ReturnPosition getReturnPosition(ReturnNodeExt ret) {
|
||||
result = getReturnPosition0(ret, ret.getKind())
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether `inner` can return to `call` in the call context `innercc`.
|
||||
* Assumes a context of `inner = viableCallableExt(call)`.
|
||||
*/
|
||||
bindingset[innercc, inner, call]
|
||||
predicate checkCallContextReturn(CallContext innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
innercc instanceof CallContextAny
|
||||
or
|
||||
exists(DataFlowCallable c0, DataFlowCall call0 |
|
||||
callEnclosingCallable(call0, inner) and
|
||||
innercc = TReturn(c0, call0) and
|
||||
c0 = prunedViableImplInCallContextReverse(call0, call)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether `call` can resolve to `calltarget` in the call context `cc`.
|
||||
* Assumes a context of `calltarget = viableCallableExt(call)`.
|
||||
*/
|
||||
bindingset[cc, call, calltarget]
|
||||
predicate checkCallContextCall(CallContext cc, DataFlowCall call, DataFlowCallable calltarget) {
|
||||
exists(DataFlowCall ctx | cc = TSpecificCall(ctx) |
|
||||
if reducedViableImplInCallContext(call, _, ctx)
|
||||
then calltarget = prunedViableImplInCallContext(call, ctx)
|
||||
else any()
|
||||
)
|
||||
or
|
||||
cc instanceof CallContextSomeCall
|
||||
or
|
||||
cc instanceof CallContextAny
|
||||
or
|
||||
cc instanceof CallContextReturn
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a return from `callable` in `cc` to `call`. This is equivalent to
|
||||
* `callable = viableCallableExt(call) and checkCallContextReturn(cc, callable, call)`.
|
||||
*/
|
||||
bindingset[cc, callable]
|
||||
predicate resolveReturn(CallContext cc, DataFlowCallable callable, DataFlowCall call) {
|
||||
cc instanceof CallContextAny and callable = viableCallableExt(call)
|
||||
@@ -1128,6 +1166,10 @@ predicate resolveReturn(CallContext cc, DataFlowCallable callable, DataFlowCall
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a call from `call` in `cc` to `result`. This is equivalent to
|
||||
* `result = viableCallableExt(call) and checkCallContextCall(cc, call, result)`.
|
||||
*/
|
||||
bindingset[call, cc]
|
||||
DataFlowCallable resolveCall(DataFlowCall call, CallContext cc) {
|
||||
exists(DataFlowCall ctx | cc = TSpecificCall(ctx) |
|
||||
|
||||
@@ -50,7 +50,7 @@ abstract class FormattingFunction extends ArrayFunction, TaintFunction {
|
||||
* Holds if this `FormattingFunction` is in a context that supports
|
||||
* Microsoft rules and extensions.
|
||||
*/
|
||||
predicate isMicrosoft() { any(File f).compiledAsMicrosoft() }
|
||||
predicate isMicrosoft() { anyFileCompiledAsMicrosoft() }
|
||||
|
||||
/**
|
||||
* Holds if the default meaning of `%s` is a `wchar_t *`, rather than
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
| test.c:13:10:13:21 | call to tmpFunction1 | This expression may have undefined behavior. |
|
||||
| test.c:13:30:13:41 | call to tmpFunction2 | This expression may have undefined behavior. |
|
||||
| test.c:16:15:16:20 | ... ++ | This expression may have undefined behavior. |
|
||||
@@ -0,0 +1 @@
|
||||
experimental/Security/CWE/CWE-758/UndefinedOrImplementationDefinedBehavior.ql
|
||||
@@ -0,0 +1,19 @@
|
||||
char tmpFunction1(char * buf)
|
||||
{
|
||||
buf[1]=buf[1] + buf[2] + buf[3];
|
||||
return buf[1];
|
||||
}
|
||||
char tmpFunction2(char * buf)
|
||||
{
|
||||
buf[2]=buf[1] + buf[2] + buf[3];
|
||||
return buf[2];
|
||||
}
|
||||
void workFunction_0(char *s, char * buf) {
|
||||
int intA;
|
||||
intA = tmpFunction1(buf) + tmpFunction2(buf); // BAD
|
||||
intA = tmpFunction1(buf); //GOOD
|
||||
intA += tmpFunction2(buf); // GOOD
|
||||
buf[intA] = intA++; // BAD
|
||||
intA++;
|
||||
buf[intA] = intA; // GOOD
|
||||
}
|
||||
@@ -1,13 +1,21 @@
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:4:9:4:12 | name | public | CharPointerType | char |
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:4:9:4:12 | name | public | PointerDumpType | char |
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:5:8:5:8 | t | public | Enum | |
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:5:8:5:8 | t | public | UserDumpType | |
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:6:9:6:9 | s | public | CharPointerType | char |
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:6:9:6:9 | s | public | PointerDumpType | char |
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:7:7:7:7 | i | public | IntType | |
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:7:7:7:7 | i | public | IntegralDumpType | |
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:7:7:7:7 | i | public | MicrosoftInt32Type | |
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:9:7:9:14 | internal | private | IntType | |
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:9:7:9:14 | internal | private | IntegralDumpType | |
|
||||
| fields.cpp:3:8:3:12 | Entry | fields.cpp:9:7:9:14 | internal | private | MicrosoftInt32Type | |
|
||||
| fields.cpp:12:7:12:10 | Name | fields.cpp:13:15:13:15 | s | private | PointerType | const char |
|
||||
| fields.cpp:16:7:16:11 | Table | fields.cpp:17:9:17:9 | p | private | PointerType | Name |
|
||||
| fields.cpp:12:7:12:10 | Name | fields.cpp:13:15:13:15 | s | private | PointerDumpType | const char |
|
||||
| fields.cpp:16:7:16:11 | Table | fields.cpp:17:9:17:9 | p | private | PointerDumpType | Name |
|
||||
| fields.cpp:16:7:16:11 | Table | fields.cpp:18:7:18:8 | sz | private | IntType | |
|
||||
| fields.cpp:16:7:16:11 | Table | fields.cpp:18:7:18:8 | sz | private | IntegralDumpType | |
|
||||
| fields.cpp:16:7:16:11 | Table | fields.cpp:18:7:18:8 | sz | private | MicrosoftInt32Type | |
|
||||
| fields.cpp:26:7:26:10 | Date | fields.cpp:28:16:28:26 | cache_valid | private | BoolType | |
|
||||
| fields.cpp:26:7:26:10 | Date | fields.cpp:28:16:28:26 | cache_valid | private | IntegralDumpType | |
|
||||
| fields.cpp:26:7:26:10 | Date | fields.cpp:30:17:30:21 | cache | public | CharPointerType | char |
|
||||
| fields.cpp:26:7:26:10 | Date | fields.cpp:30:17:30:21 | cache | public | PointerDumpType | char |
|
||||
|
||||
@@ -1 +1 @@
|
||||
| routinetype.cpp:2:7:2:19 | myRoutineType | file://:0:0:0:0 | ..()(..) | RoutineType |
|
||||
| routinetype.cpp:2:7:2:19 | myRoutineType | file://:0:0:0:0 | ..()(..) | PrintableElement, RoutineDumpType |
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
| typedefs.cpp:6:6:6:7 | f1 | typedefs.cpp:8:15:8:18 | TYPE | CTypedefType, LocalTypedefType |
|
||||
| typedefs.cpp:6:6:6:7 | f1 | typedefs.cpp:9:9:9:9 | D | DirectAccessHolder, LocalClass, MetricClass, StructLikeClass |
|
||||
| typedefs.cpp:6:6:6:7 | f1 | typedefs.cpp:8:15:8:18 | TYPE | CTypedefType, LocalTypedefType, PrintableElement, UserDumpType |
|
||||
| typedefs.cpp:6:6:6:7 | f1 | typedefs.cpp:9:9:9:9 | D | DirectAccessHolder, LocalClass, MetricClass, PrintableElement, StructLikeClass, UserDumpType |
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
| file://:0:0:0:0 | __wchar_t * | PointerType | Wchar_t, WideCharType |
|
||||
| file://:0:0:0:0 | const __wchar_t | SpecifiedType | Wchar_t, WideCharType |
|
||||
| file://:0:0:0:0 | wchar_t | Wchar_t, WideCharType | |
|
||||
| file://:0:0:0:0 | __wchar_t * | PointerDumpType, PrintableElement | IntegralDumpType, PrintableElement, Wchar_t, WideCharType |
|
||||
| file://:0:0:0:0 | const __wchar_t | PrintableElement, SpecifiedDumpType | IntegralDumpType, PrintableElement, Wchar_t, WideCharType |
|
||||
| file://:0:0:0:0 | wchar_t | IntegralDumpType, PrintableElement, Wchar_t, WideCharType | |
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
| cstd_types.cpp:47:13:47:15 | if8 | CTypedefType, FastestMinimumWidthIntegralType, Int_fast8_t |
|
||||
| cstd_types.cpp:48:14:48:17 | if16 | CTypedefType, FastestMinimumWidthIntegralType, Int_fast16_t |
|
||||
| cstd_types.cpp:49:14:49:17 | if32 | CTypedefType, FastestMinimumWidthIntegralType, Int_fast32_t |
|
||||
| cstd_types.cpp:50:14:50:17 | if64 | CTypedefType, FastestMinimumWidthIntegralType, Int_fast64_t |
|
||||
| cstd_types.cpp:51:14:51:16 | uf8 | CTypedefType, FastestMinimumWidthIntegralType, UInt_fast8_t |
|
||||
| cstd_types.cpp:52:15:52:18 | uf16 | CTypedefType, FastestMinimumWidthIntegralType, UInt_fast16_t |
|
||||
| cstd_types.cpp:53:15:53:18 | uf32 | CTypedefType, FastestMinimumWidthIntegralType, UInt_fast32_t |
|
||||
| cstd_types.cpp:54:15:54:18 | uf64 | CTypedefType, FastestMinimumWidthIntegralType, UInt_fast64_t |
|
||||
| cstd_types.cpp:47:13:47:15 | if8 | CTypedefType, FastestMinimumWidthIntegralType, Int_fast8_t, PrintableElement, UserDumpType |
|
||||
| cstd_types.cpp:48:14:48:17 | if16 | CTypedefType, FastestMinimumWidthIntegralType, Int_fast16_t, PrintableElement, UserDumpType |
|
||||
| cstd_types.cpp:49:14:49:17 | if32 | CTypedefType, FastestMinimumWidthIntegralType, Int_fast32_t, PrintableElement, UserDumpType |
|
||||
| cstd_types.cpp:50:14:50:17 | if64 | CTypedefType, FastestMinimumWidthIntegralType, Int_fast64_t, PrintableElement, UserDumpType |
|
||||
| cstd_types.cpp:51:14:51:16 | uf8 | CTypedefType, FastestMinimumWidthIntegralType, PrintableElement, UInt_fast8_t, UserDumpType |
|
||||
| cstd_types.cpp:52:15:52:18 | uf16 | CTypedefType, FastestMinimumWidthIntegralType, PrintableElement, UInt_fast16_t, UserDumpType |
|
||||
| cstd_types.cpp:53:15:53:18 | uf32 | CTypedefType, FastestMinimumWidthIntegralType, PrintableElement, UInt_fast32_t, UserDumpType |
|
||||
| cstd_types.cpp:54:15:54:18 | uf64 | CTypedefType, FastestMinimumWidthIntegralType, PrintableElement, UInt_fast64_t, UserDumpType |
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
| cstd_types.cpp:31:8:31:9 | i8 | CTypedefType, FixedWidthIntegralType, Int8_t |
|
||||
| cstd_types.cpp:32:9:32:11 | i16 | CTypedefType, FixedWidthIntegralType, Int16_t |
|
||||
| cstd_types.cpp:33:9:33:11 | i32 | CTypedefType, FixedWidthIntegralType, Int32_t |
|
||||
| cstd_types.cpp:34:9:34:11 | i64 | CTypedefType, FixedWidthIntegralType, Int64_t |
|
||||
| cstd_types.cpp:35:9:35:11 | ui8 | CTypedefType, FixedWidthIntegralType, UInt8_t |
|
||||
| cstd_types.cpp:36:10:36:13 | ui16 | CTypedefType, FixedWidthIntegralType, UInt16_t |
|
||||
| cstd_types.cpp:37:10:37:13 | ui32 | CTypedefType, FixedWidthIntegralType, UInt32_t |
|
||||
| cstd_types.cpp:38:10:38:13 | ui64 | CTypedefType, FixedWidthIntegralType, UInt64_t |
|
||||
| cstd_types.cpp:31:8:31:9 | i8 | CTypedefType, FixedWidthIntegralType, Int8_t, PrintableElement, UserDumpType |
|
||||
| cstd_types.cpp:32:9:32:11 | i16 | CTypedefType, FixedWidthIntegralType, Int16_t, PrintableElement, UserDumpType |
|
||||
| cstd_types.cpp:33:9:33:11 | i32 | CTypedefType, FixedWidthIntegralType, Int32_t, PrintableElement, UserDumpType |
|
||||
| cstd_types.cpp:34:9:34:11 | i64 | CTypedefType, FixedWidthIntegralType, Int64_t, PrintableElement, UserDumpType |
|
||||
| cstd_types.cpp:35:9:35:11 | ui8 | CTypedefType, FixedWidthIntegralType, PrintableElement, UInt8_t, UserDumpType |
|
||||
| cstd_types.cpp:36:10:36:13 | ui16 | CTypedefType, FixedWidthIntegralType, PrintableElement, UInt16_t, UserDumpType |
|
||||
| cstd_types.cpp:37:10:37:13 | ui32 | CTypedefType, FixedWidthIntegralType, PrintableElement, UInt32_t, UserDumpType |
|
||||
| cstd_types.cpp:38:10:38:13 | ui64 | CTypedefType, FixedWidthIntegralType, PrintableElement, UInt64_t, UserDumpType |
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
| cstd_types.cpp:74:4:74:6 | _e0 | Enum, FixedWidthEnumType |
|
||||
| cstd_types.cpp:75:4:75:6 | _e1 | FixedWidthEnumType, ScopedEnum |
|
||||
| cstd_types.cpp:74:4:74:6 | _e0 | Enum, FixedWidthEnumType, PrintableElement, UserDumpType |
|
||||
| cstd_types.cpp:75:4:75:6 | _e1 | FixedWidthEnumType, PrintableElement, ScopedEnum, UserDumpType |
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
| cstd_types.cpp:55:10:55:11 | im | CTypedefType, Intmax_t, MaximumWidthIntegralType |
|
||||
| cstd_types.cpp:56:11:56:13 | uim | CTypedefType, MaximumWidthIntegralType, Uintmax_t |
|
||||
| cstd_types.cpp:55:10:55:11 | im | CTypedefType, Intmax_t, MaximumWidthIntegralType, PrintableElement, UserDumpType |
|
||||
| cstd_types.cpp:56:11:56:13 | uim | CTypedefType, MaximumWidthIntegralType, PrintableElement, Uintmax_t, UserDumpType |
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
| cstd_types.cpp:39:15:39:16 | l8 | CTypedefType, Int_least8_t, MinimumWidthIntegralType |
|
||||
| cstd_types.cpp:40:15:40:17 | l16 | CTypedefType, Int_least16_t, MinimumWidthIntegralType |
|
||||
| cstd_types.cpp:41:15:41:17 | l32 | CTypedefType, Int_least32_t, MinimumWidthIntegralType |
|
||||
| cstd_types.cpp:42:15:42:17 | l64 | CTypedefType, Int_least64_t, MinimumWidthIntegralType |
|
||||
| cstd_types.cpp:43:15:43:17 | ul8 | CTypedefType, MinimumWidthIntegralType, UInt_least8_t |
|
||||
| cstd_types.cpp:44:16:44:19 | ul16 | CTypedefType, MinimumWidthIntegralType, UInt_least16_t |
|
||||
| cstd_types.cpp:45:16:45:19 | ul32 | CTypedefType, MinimumWidthIntegralType, UInt_least32_t |
|
||||
| cstd_types.cpp:46:16:46:19 | ul64 | CTypedefType, MinimumWidthIntegralType, UInt_least64_t |
|
||||
| cstd_types.cpp:39:15:39:16 | l8 | CTypedefType, Int_least8_t, MinimumWidthIntegralType, PrintableElement, UserDumpType |
|
||||
| cstd_types.cpp:40:15:40:17 | l16 | CTypedefType, Int_least16_t, MinimumWidthIntegralType, PrintableElement, UserDumpType |
|
||||
| cstd_types.cpp:41:15:41:17 | l32 | CTypedefType, Int_least32_t, MinimumWidthIntegralType, PrintableElement, UserDumpType |
|
||||
| cstd_types.cpp:42:15:42:17 | l64 | CTypedefType, Int_least64_t, MinimumWidthIntegralType, PrintableElement, UserDumpType |
|
||||
| cstd_types.cpp:43:15:43:17 | ul8 | CTypedefType, MinimumWidthIntegralType, PrintableElement, UInt_least8_t, UserDumpType |
|
||||
| cstd_types.cpp:44:16:44:19 | ul16 | CTypedefType, MinimumWidthIntegralType, PrintableElement, UInt_least16_t, UserDumpType |
|
||||
| cstd_types.cpp:45:16:45:19 | ul32 | CTypedefType, MinimumWidthIntegralType, PrintableElement, UInt_least32_t, UserDumpType |
|
||||
| cstd_types.cpp:46:16:46:19 | ul64 | CTypedefType, MinimumWidthIntegralType, PrintableElement, UInt_least64_t, UserDumpType |
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
| integral_types.cpp:2:8:2:9 | i8 | file://:0:0:0:0 | char | MicrosoftInt8Type, PlainCharType |
|
||||
| integral_types.cpp:3:9:3:11 | i16 | file://:0:0:0:0 | short | MicrosoftInt16Type, ShortType |
|
||||
| integral_types.cpp:4:9:4:11 | i32 | file://:0:0:0:0 | int | IntType, MicrosoftInt32Type |
|
||||
| integral_types.cpp:5:9:5:11 | i64 | file://:0:0:0:0 | long long | LongLongType, MicrosoftInt64Type |
|
||||
| integral_types.cpp:2:8:2:9 | i8 | file://:0:0:0:0 | char | IntegralDumpType, MicrosoftInt8Type, PlainCharType, PrintableElement |
|
||||
| integral_types.cpp:3:9:3:11 | i16 | file://:0:0:0:0 | short | IntegralDumpType, MicrosoftInt16Type, PrintableElement, ShortType |
|
||||
| integral_types.cpp:4:9:4:11 | i32 | file://:0:0:0:0 | int | IntType, IntegralDumpType, MicrosoftInt32Type, PrintableElement |
|
||||
| integral_types.cpp:5:9:5:11 | i64 | file://:0:0:0:0 | long long | IntegralDumpType, LongLongType, MicrosoftInt64Type, PrintableElement |
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
| file://:0:0:0:0 | wchar_t | Wchar_t, WideCharType | |
|
||||
| file://:0:0:0:0 | wchar_t * | PointerType | CTypedefType, Wchar_t |
|
||||
| ms.c:2:24:2:30 | wchar_t | CTypedefType, Wchar_t | |
|
||||
| file://:0:0:0:0 | wchar_t | IntegralDumpType, PrintableElement, Wchar_t, WideCharType | |
|
||||
| file://:0:0:0:0 | wchar_t * | PointerDumpType, PrintableElement | CTypedefType, PrintableElement, UserDumpType, Wchar_t |
|
||||
| ms.c:2:24:2:30 | wchar_t | CTypedefType, PrintableElement, UserDumpType, Wchar_t | |
|
||||
|
||||
@@ -1,94 +1,94 @@
|
||||
| ..()(..) | RoutineType | | | | |
|
||||
| ..(*)(..) | FunctionPointerType | | ..()(..) | | |
|
||||
| _Complex __float128 | BinaryFloatingPointType, ComplexNumberType | | | | |
|
||||
| _Complex double | BinaryFloatingPointType, ComplexNumberType | | | | |
|
||||
| _Complex float | BinaryFloatingPointType, ComplexNumberType | | | | |
|
||||
| _Complex long double | BinaryFloatingPointType, ComplexNumberType | | | | |
|
||||
| _Decimal32 | Decimal32Type | | | | |
|
||||
| _Decimal64 | Decimal64Type | | | | |
|
||||
| _Decimal128 | Decimal128Type | | | | |
|
||||
| _Float32 | BinaryFloatingPointType, RealNumberType | | | | |
|
||||
| _Float32x | BinaryFloatingPointType, RealNumberType | | | | |
|
||||
| _Float64 | BinaryFloatingPointType, RealNumberType | | | | |
|
||||
| _Float64x | BinaryFloatingPointType, RealNumberType | | | | |
|
||||
| _Float128 | BinaryFloatingPointType, RealNumberType | | | | |
|
||||
| _Float128x | BinaryFloatingPointType, RealNumberType | | | | |
|
||||
| _Imaginary double | BinaryFloatingPointType, ImaginaryNumberType | | | | |
|
||||
| _Imaginary float | BinaryFloatingPointType, ImaginaryNumberType | | | | |
|
||||
| _Imaginary long double | BinaryFloatingPointType, ImaginaryNumberType | | | | |
|
||||
| __float128 | Float128Type | | | | |
|
||||
| __int128 | Int128Type | | | | |
|
||||
| __va_list_tag | DirectAccessHolder, MetricClass, Struct, StructLikeClass | | | | |
|
||||
| __va_list_tag & | LValueReferenceType | | __va_list_tag | | |
|
||||
| __va_list_tag && | RValueReferenceType | | __va_list_tag | | |
|
||||
| address | DirectAccessHolder, MetricClass, Struct, StructLikeClass | | | | |
|
||||
| address & | LValueReferenceType | | address | | |
|
||||
| address && | RValueReferenceType | | address | | |
|
||||
| auto | AutoType | | | | |
|
||||
| bool | BoolType | | | | |
|
||||
| char | MicrosoftInt8Type, PlainCharType | | | | |
|
||||
| char8_t | Char8Type | | | | |
|
||||
| char16_t | Char16Type | | | | |
|
||||
| char32_t | Char32Type | | | | |
|
||||
| char * | CharPointerType | | char | | |
|
||||
| char *[3] | ArrayType | char * | char * | | |
|
||||
| char *[32] | ArrayType | char * | char * | | |
|
||||
| char *[] | ArrayType | char * | char * | | |
|
||||
| char[2] | ArrayType | char | char | | |
|
||||
| char[3] | ArrayType | char | char | | |
|
||||
| char[5] | ArrayType | char | char | | |
|
||||
| char[6] | ArrayType | char | char | | |
|
||||
| char[8] | ArrayType | char | char | | |
|
||||
| char[9] | ArrayType | char | char | | |
|
||||
| char[10] | ArrayType | char | char | | |
|
||||
| char[53] | ArrayType | char | char | | |
|
||||
| char[] | ArrayType | char | char | | |
|
||||
| const __va_list_tag | SpecifiedType | | __va_list_tag | | |
|
||||
| const __va_list_tag & | LValueReferenceType | | const __va_list_tag | | |
|
||||
| const address | SpecifiedType | | address | | |
|
||||
| const address & | LValueReferenceType | | const address | | |
|
||||
| const char | SpecifiedType | | char | | |
|
||||
| const char * | PointerType | | const char | | |
|
||||
| const char *[3] | ArrayType | const char * | const char * | | |
|
||||
| const char *[] | ArrayType | const char * | const char * | | |
|
||||
| const char[5] | ArrayType | const char | const char | | |
|
||||
| const char[6] | ArrayType | const char | const char | | |
|
||||
| const char[8] | ArrayType | const char | const char | | |
|
||||
| const char[9] | ArrayType | const char | const char | | |
|
||||
| const char[10] | ArrayType | const char | const char | | |
|
||||
| const char[53] | ArrayType | const char | const char | | |
|
||||
| const double | SpecifiedType | | double | | |
|
||||
| const int | SpecifiedType | | int | | |
|
||||
| decltype(nullptr) | NullPointerType | | | | |
|
||||
| double | DoubleType | | | | |
|
||||
| error | ErroneousType | | | | |
|
||||
| float | FloatType | | | | |
|
||||
| float[3] | ArrayType | float | float | | |
|
||||
| int | IntType, MicrosoftInt32Type | | | | |
|
||||
| int * | IntPointerType | | int | | |
|
||||
| int[4] | ArrayType | int | int | | |
|
||||
| int[8] | ArrayType | int | int | | |
|
||||
| int[10] | ArrayType | int | int | | |
|
||||
| int[10][20] | ArrayType | int[20] | int[20] | | |
|
||||
| int[20] | ArrayType | int | int | | |
|
||||
| int[] | ArrayType | int | int | | |
|
||||
| long | LongType | | | | |
|
||||
| long double | LongDoubleType | | | | |
|
||||
| long long | LongLongType, MicrosoftInt64Type | | | | |
|
||||
| short | MicrosoftInt16Type, ShortType | | | | |
|
||||
| signed __int128 | Int128Type | | | | |
|
||||
| signed char | SignedCharType | | | | |
|
||||
| signed int | IntType | | | | |
|
||||
| signed long | LongType | | | | |
|
||||
| signed long long | LongLongType | | | | |
|
||||
| signed short | ShortType | | | | |
|
||||
| unknown | UnknownType | | | | |
|
||||
| unsigned __int128 | Int128Type | | | | unsigned integral |
|
||||
| unsigned char | UnsignedCharType | | | | unsigned integral |
|
||||
| unsigned int | IntType | | | unsigned int | unsigned integral |
|
||||
| unsigned long | LongType | | | | unsigned integral |
|
||||
| unsigned long long | LongLongType | | | | unsigned integral |
|
||||
| unsigned short | ShortType | | | | unsigned integral |
|
||||
| void | VoidType | | | | |
|
||||
| void * | VoidPointerType | | void | | |
|
||||
| wchar_t | Wchar_t, WideCharType | | | | |
|
||||
| ..()(..) | PrintableElement, RoutineDumpType | | | | |
|
||||
| ..(*)(..) | FunctionPointerDumpType, PrintableElement | | ..()(..) | | |
|
||||
| _Complex __float128 | BinaryFloatingPointType, BuiltInDumpType, ComplexNumberType, PrintableElement | | | | |
|
||||
| _Complex double | BinaryFloatingPointType, BuiltInDumpType, ComplexNumberType, PrintableElement | | | | |
|
||||
| _Complex float | BinaryFloatingPointType, BuiltInDumpType, ComplexNumberType, PrintableElement | | | | |
|
||||
| _Complex long double | BinaryFloatingPointType, BuiltInDumpType, ComplexNumberType, PrintableElement | | | | |
|
||||
| _Decimal32 | BuiltInDumpType, Decimal32Type, PrintableElement | | | | |
|
||||
| _Decimal64 | BuiltInDumpType, Decimal64Type, PrintableElement | | | | |
|
||||
| _Decimal128 | BuiltInDumpType, Decimal128Type, PrintableElement | | | | |
|
||||
| _Float32 | BinaryFloatingPointType, BuiltInDumpType, PrintableElement, RealNumberType | | | | |
|
||||
| _Float32x | BinaryFloatingPointType, BuiltInDumpType, PrintableElement, RealNumberType | | | | |
|
||||
| _Float64 | BinaryFloatingPointType, BuiltInDumpType, PrintableElement, RealNumberType | | | | |
|
||||
| _Float64x | BinaryFloatingPointType, BuiltInDumpType, PrintableElement, RealNumberType | | | | |
|
||||
| _Float128 | BinaryFloatingPointType, BuiltInDumpType, PrintableElement, RealNumberType | | | | |
|
||||
| _Float128x | BinaryFloatingPointType, BuiltInDumpType, PrintableElement, RealNumberType | | | | |
|
||||
| _Imaginary double | BinaryFloatingPointType, BuiltInDumpType, ImaginaryNumberType, PrintableElement | | | | |
|
||||
| _Imaginary float | BinaryFloatingPointType, BuiltInDumpType, ImaginaryNumberType, PrintableElement | | | | |
|
||||
| _Imaginary long double | BinaryFloatingPointType, BuiltInDumpType, ImaginaryNumberType, PrintableElement | | | | |
|
||||
| __float128 | BuiltInDumpType, Float128Type, PrintableElement | | | | |
|
||||
| __int128 | Int128Type, IntegralDumpType, PrintableElement | | | | |
|
||||
| __va_list_tag | DirectAccessHolder, MetricClass, PrintableElement, Struct, StructLikeClass, UserDumpType | | | | |
|
||||
| __va_list_tag & | LValueReferenceDumpType, PrintableElement | | __va_list_tag | | |
|
||||
| __va_list_tag && | PrintableElement, RValueReferenceDumpType | | __va_list_tag | | |
|
||||
| address | DirectAccessHolder, MetricClass, PrintableElement, Struct, StructLikeClass, UserDumpType | | | | |
|
||||
| address & | LValueReferenceDumpType, PrintableElement | | address | | |
|
||||
| address && | PrintableElement, RValueReferenceDumpType | | address | | |
|
||||
| auto | AutoType, PrintableElement, UserDumpType | | | | |
|
||||
| bool | BoolType, IntegralDumpType, PrintableElement | | | | |
|
||||
| char | IntegralDumpType, MicrosoftInt8Type, PlainCharType, PrintableElement | | | | |
|
||||
| char8_t | Char8Type, IntegralDumpType, PrintableElement | | | | |
|
||||
| char16_t | Char16Type, IntegralDumpType, PrintableElement | | | | |
|
||||
| char32_t | Char32Type, IntegralDumpType, PrintableElement | | | | |
|
||||
| char * | CharPointerType, PointerDumpType, PrintableElement | | char | | |
|
||||
| char *[3] | ArrayDumpType, PrintableElement | char * | char * | | |
|
||||
| char *[32] | ArrayDumpType, PrintableElement | char * | char * | | |
|
||||
| char *[] | ArrayDumpType, PrintableElement | char * | char * | | |
|
||||
| char[2] | ArrayDumpType, PrintableElement | char | char | | |
|
||||
| char[3] | ArrayDumpType, PrintableElement | char | char | | |
|
||||
| char[5] | ArrayDumpType, PrintableElement | char | char | | |
|
||||
| char[6] | ArrayDumpType, PrintableElement | char | char | | |
|
||||
| char[8] | ArrayDumpType, PrintableElement | char | char | | |
|
||||
| char[9] | ArrayDumpType, PrintableElement | char | char | | |
|
||||
| char[10] | ArrayDumpType, PrintableElement | char | char | | |
|
||||
| char[53] | ArrayDumpType, PrintableElement | char | char | | |
|
||||
| char[] | ArrayDumpType, PrintableElement | char | char | | |
|
||||
| const __va_list_tag | PrintableElement, SpecifiedDumpType | | __va_list_tag | | |
|
||||
| const __va_list_tag & | LValueReferenceDumpType, PrintableElement | | const __va_list_tag | | |
|
||||
| const address | PrintableElement, SpecifiedDumpType | | address | | |
|
||||
| const address & | LValueReferenceDumpType, PrintableElement | | const address | | |
|
||||
| const char | PrintableElement, SpecifiedDumpType | | char | | |
|
||||
| const char * | PointerDumpType, PrintableElement | | const char | | |
|
||||
| const char *[3] | ArrayDumpType, PrintableElement | const char * | const char * | | |
|
||||
| const char *[] | ArrayDumpType, PrintableElement | const char * | const char * | | |
|
||||
| const char[5] | ArrayDumpType, PrintableElement | const char | const char | | |
|
||||
| const char[6] | ArrayDumpType, PrintableElement | const char | const char | | |
|
||||
| const char[8] | ArrayDumpType, PrintableElement | const char | const char | | |
|
||||
| const char[9] | ArrayDumpType, PrintableElement | const char | const char | | |
|
||||
| const char[10] | ArrayDumpType, PrintableElement | const char | const char | | |
|
||||
| const char[53] | ArrayDumpType, PrintableElement | const char | const char | | |
|
||||
| const double | PrintableElement, SpecifiedDumpType | | double | | |
|
||||
| const int | PrintableElement, SpecifiedDumpType | | int | | |
|
||||
| decltype(nullptr) | BuiltInDumpType, NullPointerType, PrintableElement | | | | |
|
||||
| double | BuiltInDumpType, DoubleType, PrintableElement | | | | |
|
||||
| error | BuiltInDumpType, ErroneousType, PrintableElement | | | | |
|
||||
| float | BuiltInDumpType, FloatType, PrintableElement | | | | |
|
||||
| float[3] | ArrayDumpType, PrintableElement | float | float | | |
|
||||
| int | IntType, IntegralDumpType, MicrosoftInt32Type, PrintableElement | | | | |
|
||||
| int * | IntPointerType, PointerDumpType, PrintableElement | | int | | |
|
||||
| int[4] | ArrayDumpType, PrintableElement | int | int | | |
|
||||
| int[8] | ArrayDumpType, PrintableElement | int | int | | |
|
||||
| int[10] | ArrayDumpType, PrintableElement | int | int | | |
|
||||
| int[10][20] | ArrayDumpType, PrintableElement | int[20] | int[20] | | |
|
||||
| int[20] | ArrayDumpType, PrintableElement | int | int | | |
|
||||
| int[] | ArrayDumpType, PrintableElement | int | int | | |
|
||||
| long | IntegralDumpType, LongType, PrintableElement | | | | |
|
||||
| long double | BuiltInDumpType, LongDoubleType, PrintableElement | | | | |
|
||||
| long long | IntegralDumpType, LongLongType, MicrosoftInt64Type, PrintableElement | | | | |
|
||||
| short | IntegralDumpType, MicrosoftInt16Type, PrintableElement, ShortType | | | | |
|
||||
| signed __int128 | Int128Type, IntegralDumpType, PrintableElement | | | | |
|
||||
| signed char | IntegralDumpType, PrintableElement, SignedCharType | | | | |
|
||||
| signed int | IntType, IntegralDumpType, PrintableElement | | | | |
|
||||
| signed long | IntegralDumpType, LongType, PrintableElement | | | | |
|
||||
| signed long long | IntegralDumpType, LongLongType, PrintableElement | | | | |
|
||||
| signed short | IntegralDumpType, PrintableElement, ShortType | | | | |
|
||||
| unknown | BuiltInDumpType, PrintableElement, UnknownType | | | | |
|
||||
| unsigned __int128 | Int128Type, IntegralDumpType, PrintableElement | | | | unsigned integral |
|
||||
| unsigned char | IntegralDumpType, PrintableElement, UnsignedCharType | | | | unsigned integral |
|
||||
| unsigned int | IntType, IntegralDumpType, PrintableElement | | | unsigned int | unsigned integral |
|
||||
| unsigned long | IntegralDumpType, LongType, PrintableElement | | | | unsigned integral |
|
||||
| unsigned long long | IntegralDumpType, LongLongType, PrintableElement | | | | unsigned integral |
|
||||
| unsigned short | IntegralDumpType, PrintableElement, ShortType | | | | unsigned integral |
|
||||
| void | BuiltInDumpType, PrintableElement, VoidType | | | | |
|
||||
| void * | PointerDumpType, PrintableElement, VoidPointerType | | void | | |
|
||||
| wchar_t | IntegralDumpType, PrintableElement, Wchar_t, WideCharType | | | | |
|
||||
|
||||
@@ -1,70 +1,111 @@
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | __va_list_tag && | DumpVariable | | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | __va_list_tag && | SemanticStackVariable | | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | address && | DumpVariable | | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | address && | SemanticStackVariable | | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | const __va_list_tag & | DumpVariable | | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | const __va_list_tag & | SemanticStackVariable | | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | const address & | DumpVariable | | |
|
||||
| file://:0:0:0:0 | (unnamed parameter 0) | file://:0:0:0:0 | const address & | SemanticStackVariable | | |
|
||||
| file://:0:0:0:0 | fp_offset | file://:0:0:0:0 | unsigned int | DumpVariable | | |
|
||||
| file://:0:0:0:0 | fp_offset | file://:0:0:0:0 | unsigned int | Field | | |
|
||||
| file://:0:0:0:0 | gp_offset | file://:0:0:0:0 | unsigned int | DumpVariable | | |
|
||||
| file://:0:0:0:0 | gp_offset | file://:0:0:0:0 | unsigned int | Field | | |
|
||||
| file://:0:0:0:0 | overflow_arg_area | file://:0:0:0:0 | void * | DumpVariable | | |
|
||||
| file://:0:0:0:0 | overflow_arg_area | file://:0:0:0:0 | void * | Field | | |
|
||||
| file://:0:0:0:0 | reg_save_area | file://:0:0:0:0 | void * | DumpVariable | | |
|
||||
| file://:0:0:0:0 | reg_save_area | file://:0:0:0:0 | void * | Field | | |
|
||||
| variables.cpp:1:12:1:12 | i | file://:0:0:0:0 | int | DumpVariable | | |
|
||||
| variables.cpp:1:12:1:12 | i | file://:0:0:0:0 | int | GlobalVariable | | |
|
||||
| variables.cpp:1:12:1:12 | i | file://:0:0:0:0 | int | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:2:12:2:12 | i | file://:0:0:0:0 | int | DumpVariable | | |
|
||||
| variables.cpp:2:12:2:12 | i | file://:0:0:0:0 | int | GlobalVariable | | |
|
||||
| variables.cpp:2:12:2:12 | i | file://:0:0:0:0 | int | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:3:12:3:12 | i | file://:0:0:0:0 | int | DumpVariable | | |
|
||||
| variables.cpp:3:12:3:12 | i | file://:0:0:0:0 | int | GlobalVariable | | |
|
||||
| variables.cpp:3:12:3:12 | i | file://:0:0:0:0 | int | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:5:11:5:11 | c | file://:0:0:0:0 | const int | DumpVariable | const | static |
|
||||
| variables.cpp:5:11:5:11 | c | file://:0:0:0:0 | const int | GlobalVariable | const | static |
|
||||
| variables.cpp:5:11:5:11 | c | file://:0:0:0:0 | const int | StaticStorageDurationVariable | const | static |
|
||||
| variables.cpp:6:14:6:15 | pi | file://:0:0:0:0 | const double | DumpVariable | const | static |
|
||||
| variables.cpp:6:14:6:15 | pi | file://:0:0:0:0 | const double | GlobalVariable | const | static |
|
||||
| variables.cpp:6:14:6:15 | pi | file://:0:0:0:0 | const double | StaticStorageDurationVariable | const | static |
|
||||
| variables.cpp:8:10:8:10 | a | file://:0:0:0:0 | unsigned int | DumpVariable | | |
|
||||
| variables.cpp:8:10:8:10 | a | file://:0:0:0:0 | unsigned int | GlobalVariable | | |
|
||||
| variables.cpp:8:10:8:10 | a | file://:0:0:0:0 | unsigned int | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:10:14:10:14 | b | file://:0:0:0:0 | unsigned int | DumpVariable | | |
|
||||
| variables.cpp:10:14:10:14 | b | file://:0:0:0:0 | unsigned int | GlobalVariable | | |
|
||||
| variables.cpp:10:14:10:14 | b | file://:0:0:0:0 | unsigned int | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:12:13:12:17 | kings | file://:0:0:0:0 | const char *[] | DumpVariable | | |
|
||||
| variables.cpp:12:13:12:17 | kings | file://:0:0:0:0 | const char *[] | GlobalVariable | | |
|
||||
| variables.cpp:12:13:12:17 | kings | file://:0:0:0:0 | const char *[] | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:14:6:14:6 | p | file://:0:0:0:0 | int * | DumpVariable | | |
|
||||
| variables.cpp:14:6:14:6 | p | file://:0:0:0:0 | int * | GlobalVariable | | |
|
||||
| variables.cpp:14:6:14:6 | p | file://:0:0:0:0 | int * | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:14:9:14:9 | q | file://:0:0:0:0 | int | DumpVariable | | |
|
||||
| variables.cpp:14:9:14:9 | q | file://:0:0:0:0 | int | GlobalVariable | | |
|
||||
| variables.cpp:14:9:14:9 | q | file://:0:0:0:0 | int | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:15:12:15:13 | v1 | file://:0:0:0:0 | int[10] | DumpVariable | | static |
|
||||
| variables.cpp:15:12:15:13 | v1 | file://:0:0:0:0 | int[10] | GlobalVariable | | static |
|
||||
| variables.cpp:15:12:15:13 | v1 | file://:0:0:0:0 | int[10] | StaticStorageDurationVariable | | static |
|
||||
| variables.cpp:15:21:15:22 | pv | file://:0:0:0:0 | int * | DumpVariable | | static |
|
||||
| variables.cpp:15:21:15:22 | pv | file://:0:0:0:0 | int * | GlobalVariable | | static |
|
||||
| variables.cpp:15:21:15:22 | pv | file://:0:0:0:0 | int * | StaticStorageDurationVariable | | static |
|
||||
| variables.cpp:17:7:17:8 | fp | file://:0:0:0:0 | ..(*)(..) | DumpVariable | | |
|
||||
| variables.cpp:17:7:17:8 | fp | file://:0:0:0:0 | ..(*)(..) | FunctionPointerVariable | | |
|
||||
| variables.cpp:17:7:17:8 | fp | file://:0:0:0:0 | ..(*)(..) | GlobalVariable | | |
|
||||
| variables.cpp:17:7:17:8 | fp | file://:0:0:0:0 | ..(*)(..) | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:19:7:19:8 | v2 | file://:0:0:0:0 | float[3] | DumpVariable | | |
|
||||
| variables.cpp:19:7:19:8 | v2 | file://:0:0:0:0 | float[3] | GlobalVariable | | |
|
||||
| variables.cpp:19:7:19:8 | v2 | file://:0:0:0:0 | float[3] | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:20:7:20:8 | v3 | file://:0:0:0:0 | char *[32] | DumpVariable | | |
|
||||
| variables.cpp:20:7:20:8 | v3 | file://:0:0:0:0 | char *[32] | GlobalVariable | | |
|
||||
| variables.cpp:20:7:20:8 | v3 | file://:0:0:0:0 | char *[32] | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:22:5:22:6 | d2 | file://:0:0:0:0 | int[10][20] | DumpVariable | | |
|
||||
| variables.cpp:22:5:22:6 | d2 | file://:0:0:0:0 | int[10][20] | GlobalVariable | | |
|
||||
| variables.cpp:22:5:22:6 | d2 | file://:0:0:0:0 | int[10][20] | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:24:6:24:7 | v4 | file://:0:0:0:0 | char[3] | DumpVariable | | |
|
||||
| variables.cpp:24:6:24:7 | v4 | file://:0:0:0:0 | char[3] | GlobalVariable | | |
|
||||
| variables.cpp:24:6:24:7 | v4 | file://:0:0:0:0 | char[3] | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:26:5:26:6 | v5 | file://:0:0:0:0 | int[8] | DumpVariable | | |
|
||||
| variables.cpp:26:5:26:6 | v5 | file://:0:0:0:0 | int[8] | GlobalVariable | | |
|
||||
| variables.cpp:26:5:26:6 | v5 | file://:0:0:0:0 | int[8] | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:28:7:28:8 | p2 | file://:0:0:0:0 | char * | DumpVariable | | |
|
||||
| variables.cpp:28:7:28:8 | p2 | file://:0:0:0:0 | char * | GlobalVariable | | |
|
||||
| variables.cpp:28:7:28:8 | p2 | file://:0:0:0:0 | char * | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:29:6:29:7 | p3 | file://:0:0:0:0 | char[] | DumpVariable | | |
|
||||
| variables.cpp:29:6:29:7 | p3 | file://:0:0:0:0 | char[] | GlobalVariable | | |
|
||||
| variables.cpp:29:6:29:7 | p3 | file://:0:0:0:0 | char[] | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:31:6:31:10 | alpha | file://:0:0:0:0 | char[] | DumpVariable | | |
|
||||
| variables.cpp:31:6:31:10 | alpha | file://:0:0:0:0 | char[] | GlobalVariable | | |
|
||||
| variables.cpp:31:6:31:10 | alpha | file://:0:0:0:0 | char[] | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:34:5:34:6 | av | file://:0:0:0:0 | int[] | DumpVariable | | |
|
||||
| variables.cpp:34:5:34:6 | av | file://:0:0:0:0 | int[] | GlobalVariable | | |
|
||||
| variables.cpp:34:5:34:6 | av | file://:0:0:0:0 | int[] | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:35:6:35:8 | ap1 | file://:0:0:0:0 | int * | DumpVariable | | |
|
||||
| variables.cpp:35:6:35:8 | ap1 | file://:0:0:0:0 | int * | GlobalVariable | | |
|
||||
| variables.cpp:35:6:35:8 | ap1 | file://:0:0:0:0 | int * | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:36:6:36:8 | ap2 | file://:0:0:0:0 | int * | DumpVariable | | |
|
||||
| variables.cpp:36:6:36:8 | ap2 | file://:0:0:0:0 | int * | GlobalVariable | | |
|
||||
| variables.cpp:36:6:36:8 | ap2 | file://:0:0:0:0 | int * | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:37:6:37:8 | ap3 | file://:0:0:0:0 | int * | DumpVariable | | |
|
||||
| variables.cpp:37:6:37:8 | ap3 | file://:0:0:0:0 | int * | GlobalVariable | | |
|
||||
| variables.cpp:37:6:37:8 | ap3 | file://:0:0:0:0 | int * | StaticStorageDurationVariable | | |
|
||||
| variables.cpp:41:7:41:11 | local | file://:0:0:0:0 | char[] | DumpVariable | | |
|
||||
| variables.cpp:41:7:41:11 | local | file://:0:0:0:0 | char[] | LocalVariable | | |
|
||||
| variables.cpp:41:7:41:11 | local | file://:0:0:0:0 | char[] | SemanticStackVariable | | |
|
||||
| variables.cpp:43:14:43:18 | local | file://:0:0:0:0 | int | DumpVariable | | static |
|
||||
| variables.cpp:43:14:43:18 | local | file://:0:0:0:0 | int | StaticLocalVariable | | static |
|
||||
| variables.cpp:48:9:48:12 | name | file://:0:0:0:0 | char * | DumpVariable | | |
|
||||
| variables.cpp:48:9:48:12 | name | file://:0:0:0:0 | char * | Field | | |
|
||||
| variables.cpp:49:12:49:17 | number | file://:0:0:0:0 | long | DumpVariable | | |
|
||||
| variables.cpp:49:12:49:17 | number | file://:0:0:0:0 | long | Field | | |
|
||||
| variables.cpp:50:9:50:14 | street | file://:0:0:0:0 | char * | DumpVariable | | |
|
||||
| variables.cpp:50:9:50:14 | street | file://:0:0:0:0 | char * | Field | | |
|
||||
| variables.cpp:51:9:51:12 | town | file://:0:0:0:0 | char * | DumpVariable | | |
|
||||
| variables.cpp:51:9:51:12 | town | file://:0:0:0:0 | char * | Field | | |
|
||||
| variables.cpp:52:16:52:22 | country | file://:0:0:0:0 | char * | DumpVariable | | static |
|
||||
| variables.cpp:52:16:52:22 | country | file://:0:0:0:0 | char * | MemberVariable | | static |
|
||||
| variables.cpp:52:16:52:22 | country | file://:0:0:0:0 | char * | StaticStorageDurationVariable | | static |
|
||||
| variables.cpp:56:14:56:29 | externInFunction | file://:0:0:0:0 | int | DumpVariable | | |
|
||||
| variables.cpp:56:14:56:29 | externInFunction | file://:0:0:0:0 | int | GlobalVariable | | |
|
||||
| variables.cpp:56:14:56:29 | externInFunction | file://:0:0:0:0 | int | StaticStorageDurationVariable | | |
|
||||
|
||||
@@ -3,12 +3,8 @@
|
||||
| tests.cpp:21:15:21:21 | Hello | This argument should be of type 'char16_t *' but is of type 'char *' |
|
||||
| tests.cpp:21:15:21:21 | Hello | This argument should be of type 'wchar_t *' but is of type 'char *' |
|
||||
| tests.cpp:26:17:26:24 | Hello | This argument should be of type 'char *' but is of type 'char16_t *' |
|
||||
| tests.cpp:27:17:27:24 | Hello | This argument should be of type 'char *' but is of type 'wchar_t *' |
|
||||
| tests.cpp:29:17:29:23 | Hello | This argument should be of type 'wchar_t *' but is of type 'char *' |
|
||||
| tests.cpp:30:17:30:24 | Hello | This argument should be of type 'wchar_t *' but is of type 'char16_t *' |
|
||||
| tests.cpp:34:36:34:43 | Hello | This argument should be of type 'char *' but is of type 'char16_t *' |
|
||||
| tests.cpp:35:36:35:43 | Hello | This argument should be of type 'char *' but is of type 'wchar_t *' |
|
||||
| tests.cpp:37:36:37:42 | Hello | This argument should be of type 'char16_t *' but is of type 'char *' |
|
||||
| tests.cpp:39:36:39:43 | Hello | This argument should be of type 'char16_t *' but is of type 'wchar_t *' |
|
||||
| tests.cpp:42:37:42:44 | Hello | This argument should be of type 'char *' but is of type 'char16_t *' |
|
||||
| tests.cpp:43:37:43:44 | Hello | This argument should be of type 'char *' but is of type 'wchar_t *' |
|
||||
|
||||
@@ -24,17 +24,17 @@ void tests() {
|
||||
|
||||
wprintf(L"%s", "Hello"); // GOOD
|
||||
wprintf(L"%s", u"Hello"); // BAD: expecting char
|
||||
wprintf(L"%s", L"Hello"); // BAD: expecting char
|
||||
wprintf(L"%s", L"Hello"); // BAD: expecting char [NOT DETECTED; correct on Microsoft platforms]
|
||||
|
||||
wprintf(L"%S", "Hello"); // BAD: expecting wchar_t
|
||||
wprintf(L"%S", "Hello"); // BAD: expecting wchar_t [NOT DETECTED; correct on Microsoft platforms]
|
||||
wprintf(L"%S", u"Hello"); // BAD: expecting wchar_t
|
||||
wprintf(L"%S", L"Hello"); // GOOD
|
||||
|
||||
swprintf(buffer, BUF_SIZE, u"%s", "Hello"); // GOOD
|
||||
swprintf(buffer, BUF_SIZE, u"%s", u"Hello"); // BAD: expecting char
|
||||
swprintf(buffer, BUF_SIZE, u"%s", u"Hello"); // BAD: expecting char [NOT DETECTED; correct on Microsoft platforms]
|
||||
swprintf(buffer, BUF_SIZE, u"%s", L"Hello"); // BAD: expecting char
|
||||
|
||||
swprintf(buffer, BUF_SIZE, u"%S", "Hello"); // BAD: expecting char16_t
|
||||
swprintf(buffer, BUF_SIZE, u"%S", "Hello"); // BAD: expecting char16_t [NOT DETECTED; correct on Microsoft platforms]
|
||||
swprintf(buffer, BUF_SIZE, u"%S", u"Hello"); // GOOD
|
||||
swprintf(buffer, BUF_SIZE, u"%S", L"Hello"); // BAD: expecting char16_t
|
||||
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
| printf.cpp:31:31:31:37 | test | This argument should be of type 'char *' but is of type 'char16_t *' |
|
||||
| printf.cpp:43:29:43:35 | test | This argument should be of type 'char *' but is of type 'char16_t *' |
|
||||
| printf.cpp:50:29:50:35 | test | This argument should be of type 'char16_t *' but is of type 'wchar_t *' |
|
||||
|
||||
@@ -28,7 +28,7 @@ int sprintf(char *dest, char *format, ...);
|
||||
void test1() {
|
||||
WCHAR string[20];
|
||||
|
||||
swprintf(string, u"test %s", u"test"); // BAD: `char16_t` string parameter read as `char` string
|
||||
swprintf(string, u"test %s", u"test"); // BAD: `char16_t` string parameter read as `char` string [NOT DETECTED; correct on Microsoft platforms]
|
||||
}
|
||||
|
||||
void test2() {
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
| printf1.h:45:18:45:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long' |
|
||||
| printf1.h:46:18:46:20 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long' |
|
||||
| printf1.h:130:18:130:18 | 0 | This argument should be of type 'void *' but is of type 'int' |
|
||||
| printf1.h:154:18:154:19 | wc | This argument should be of type 'char *' but is of type 'wchar_t *' |
|
||||
| printf1.h:155:18:155:18 | c | This argument should be of type 'wchar_t *' but is of type 'char *' |
|
||||
| printf1.h:168:19:168:19 | i | This argument should be of type 'long long' but is of type 'int' |
|
||||
| printf1.h:169:19:169:20 | ui | This argument should be of type 'unsigned long long' but is of type 'unsigned int' |
|
||||
| real_world.h:61:21:61:22 | & ... | This argument should be of type 'int *' but is of type 'short *' |
|
||||
|
||||
@@ -151,8 +151,8 @@ void test_chars(char c, wchar_t wc, wint_t wt)
|
||||
void test_ws(char *c, wchar_t *wc)
|
||||
{
|
||||
wprintf(L"%s", c); // GOOD
|
||||
wprintf(L"%s", wc); // BAD
|
||||
wprintf(L"%S", c); // BAD
|
||||
wprintf(L"%s", wc); // BAD [NOT DETECTED; correct on Microsoft platforms]
|
||||
wprintf(L"%S", c); // BAD [NOT DETECTED; correct on Microsoft platforms]
|
||||
wprintf(L"%S", wc); // GOOD
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
| printf1.h:116:16:116:24 | myString3 | This argument should be of type '__wchar_t *' but is of type 'int *' |
|
||||
| printf1.h:117:16:117:24 | myString4 | This argument should be of type '__wchar_t *' but is of type 'int *' |
|
||||
| printf1.h:130:18:130:18 | 0 | This argument should be of type 'void *' but is of type 'int' |
|
||||
| printf1.h:153:18:153:18 | c | This argument should be of type '__wchar_t *' but is of type 'char *' |
|
||||
| printf1.h:156:18:156:19 | wc | This argument should be of type 'char *' but is of type '__wchar_t *' |
|
||||
| printf1.h:181:21:181:22 | ll | This argument should be of type 'int' but is of type 'long long' |
|
||||
| printf1.h:182:21:182:23 | ull | This argument should be of type 'unsigned int' but is of type 'unsigned long long' |
|
||||
| printf1.h:185:21:185:23 | i64 | This argument should be of type 'int' but is of type 'long long' |
|
||||
|
||||
@@ -150,10 +150,10 @@ void test_chars(char c, wchar_t wc, wint_t wt)
|
||||
|
||||
void test_ws(char *c, wchar_t *wc, wint_t *wt)
|
||||
{
|
||||
wprintf(L"%s", c); // BAD
|
||||
wprintf(L"%s", c); // BAD [NOT DETECTED; correct on non-Microsoft platforms]
|
||||
wprintf(L"%s", wc); // GOOD
|
||||
wprintf(L"%S", c); // GOOD
|
||||
wprintf(L"%S", wc); // BAD
|
||||
wprintf(L"%S", wc); // BAD [NOT DETECTED; correct on non-Microsoft platforms]
|
||||
}
|
||||
|
||||
void fun4()
|
||||
|
||||
@@ -7,3 +7,4 @@
|
||||
| test.cpp:170:6:170:9 | data | Memory pointed to by 'data' may have been previously freed $@ | test.cpp:165:2:165:5 | call to free | here |
|
||||
| test.cpp:193:6:193:9 | data | Memory pointed to by 'data' may have been previously freed $@ | test.cpp:191:3:191:6 | call to free | here |
|
||||
| test.cpp:201:6:201:6 | x | Memory pointed to by 'x' may have been previously freed $@ | test.cpp:200:2:200:9 | delete | here |
|
||||
| test.cpp:242:14:242:17 | data | Memory pointed to by 'data' may have been previously freed $@ | test.cpp:243:11:243:14 | call to free | here |
|
||||
|
||||
@@ -213,3 +213,42 @@ void regression_test_for_static_var_handling()
|
||||
data = (char *)malloc(100*sizeof(char));
|
||||
use(data); // GOOD
|
||||
}
|
||||
|
||||
void test16(int n, bool b) {
|
||||
char* data = NULL;
|
||||
for(int i = 0; i < n; ++i) {
|
||||
if(b) data = (char*)malloc(10 * sizeof(char));
|
||||
if(!b || data == NULL) return;
|
||||
use(data); // GOOD
|
||||
free(data); // GOOD
|
||||
}
|
||||
}
|
||||
|
||||
void test17(int n, bool b) {
|
||||
char* data = (char*)malloc(10);
|
||||
if(b) {
|
||||
free(data);
|
||||
}
|
||||
|
||||
if(!b) {
|
||||
use(data); // GOOD
|
||||
}
|
||||
}
|
||||
|
||||
void test18(int* array) {
|
||||
char* data = (char*)malloc(10 * sizeof(char));
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
int b = array[i];
|
||||
if(b) use(data); // BAD
|
||||
if(!b) free(data);
|
||||
}
|
||||
}
|
||||
|
||||
void test19(int* array) {
|
||||
char* data = (char*)malloc(10 * sizeof(char));
|
||||
int b = array[0];
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if(b) use(data); // GOOD
|
||||
if(!b) free(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
| test.cpp:132:9:132:9 | j | The variable $@ may not be initialized here. | test.cpp:126:6:126:6 | j | j |
|
||||
| test.cpp:219:3:219:3 | x | The variable $@ may not be initialized here. | test.cpp:218:7:218:7 | x | x |
|
||||
| test.cpp:243:13:243:13 | i | The variable $@ may not be initialized here. | test.cpp:241:6:241:6 | i | i |
|
||||
| test.cpp:329:9:329:11 | val | The variable $@ may not be initialized here. | test.cpp:321:6:321:8 | val | val |
|
||||
| test.cpp:336:10:336:10 | a | The variable $@ may not be initialized here. | test.cpp:333:7:333:7 | a | a |
|
||||
| test.cpp:369:10:369:10 | a | The variable $@ may not be initialized here. | test.cpp:358:7:358:7 | a | a |
|
||||
| test.cpp:378:9:378:11 | val | The variable $@ may not be initialized here. | test.cpp:359:6:359:8 | val | val |
|
||||
|
||||
@@ -326,7 +326,7 @@ int test28() {
|
||||
a = false;
|
||||
c = false;
|
||||
}
|
||||
return val; // GOOD [FALSE POSITIVE]
|
||||
return val; // GOOD
|
||||
}
|
||||
|
||||
int test29() {
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
<overview>
|
||||
<p>Relying on <code>HttpRequest</code> to provide access to a particular client variable is not
|
||||
safe. The <code>HttpRequest</code> class implements an indexer to provide a simplified, combined
|
||||
access to its <code>QueryString</code>, <code>Form</code>, <code>Cookies</code>, or <code>
|
||||
ServerVariables</code> collections, in that particular order. When searching for a variable, the
|
||||
access to its <code>QueryString</code>, <code>Form</code>, <code>Cookies</code>, or
|
||||
<code>ServerVariables</code> collections, in that particular order. When searching for a variable, the
|
||||
first match is returned: <code>QueryString</code> parameters hence supersede values from forms,
|
||||
cookies and server variables, and so on. This is a serious attack vector since an attacker could
|
||||
inject a value in the query string that you do not expect, and which supersedes the value of a more
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -1117,6 +1117,44 @@ ReturnPosition getReturnPosition(ReturnNodeExt ret) {
|
||||
result = getReturnPosition0(ret, ret.getKind())
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether `inner` can return to `call` in the call context `innercc`.
|
||||
* Assumes a context of `inner = viableCallableExt(call)`.
|
||||
*/
|
||||
bindingset[innercc, inner, call]
|
||||
predicate checkCallContextReturn(CallContext innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
innercc instanceof CallContextAny
|
||||
or
|
||||
exists(DataFlowCallable c0, DataFlowCall call0 |
|
||||
callEnclosingCallable(call0, inner) and
|
||||
innercc = TReturn(c0, call0) and
|
||||
c0 = prunedViableImplInCallContextReverse(call0, call)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether `call` can resolve to `calltarget` in the call context `cc`.
|
||||
* Assumes a context of `calltarget = viableCallableExt(call)`.
|
||||
*/
|
||||
bindingset[cc, call, calltarget]
|
||||
predicate checkCallContextCall(CallContext cc, DataFlowCall call, DataFlowCallable calltarget) {
|
||||
exists(DataFlowCall ctx | cc = TSpecificCall(ctx) |
|
||||
if reducedViableImplInCallContext(call, _, ctx)
|
||||
then calltarget = prunedViableImplInCallContext(call, ctx)
|
||||
else any()
|
||||
)
|
||||
or
|
||||
cc instanceof CallContextSomeCall
|
||||
or
|
||||
cc instanceof CallContextAny
|
||||
or
|
||||
cc instanceof CallContextReturn
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a return from `callable` in `cc` to `call`. This is equivalent to
|
||||
* `callable = viableCallableExt(call) and checkCallContextReturn(cc, callable, call)`.
|
||||
*/
|
||||
bindingset[cc, callable]
|
||||
predicate resolveReturn(CallContext cc, DataFlowCallable callable, DataFlowCall call) {
|
||||
cc instanceof CallContextAny and callable = viableCallableExt(call)
|
||||
@@ -1128,6 +1166,10 @@ predicate resolveReturn(CallContext cc, DataFlowCallable callable, DataFlowCall
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a call from `call` in `cc` to `result`. This is equivalent to
|
||||
* `result = viableCallableExt(call) and checkCallContextCall(cc, call, result)`.
|
||||
*/
|
||||
bindingset[call, cc]
|
||||
DataFlowCallable resolveCall(DataFlowCall call, CallContext cc) {
|
||||
exists(DataFlowCall ctx | cc = TSpecificCall(ctx) |
|
||||
|
||||
2
java/change-notes/2021-07-14-spring-jdbc.md
Normal file
2
java/change-notes/2021-07-14-spring-jdbc.md
Normal file
@@ -0,0 +1,2 @@
|
||||
lgtm,codescanning
|
||||
* SQL-injection vulnerabilities relating to the `org.springframework.jdbc.object` are now recognised.
|
||||
@@ -1,6 +1,6 @@
|
||||
package,sink,source,summary,sink:bean-validation,sink:create-file,sink:header-splitting,sink:information-leak,sink:jexl,sink:ldap,sink:open-url,sink:set-hostname-verifier,sink:sql,sink:url-open-stream,sink:url-redirect,sink:xpath,sink:xss,source:remote,summary:taint,summary:value
|
||||
android.content,8,,,,,,,,,,,8,,,,,,,
|
||||
android.database,59,,,,,,,,,,,59,,,,,,,
|
||||
android.content,8,,4,,,,,,,,,8,,,,,,4,
|
||||
android.database,59,,30,,,,,,,,,59,,,,,,30,
|
||||
android.util,,16,,,,,,,,,,,,,,,16,,
|
||||
android.webkit,3,2,,,,,,,,,,,,,,3,2,,
|
||||
com.esotericsoftware.kryo.io,,,1,,,,,,,,,,,,,,,1,
|
||||
@@ -27,7 +27,7 @@ javax.ws.rs.core,3,,143,,,1,,,,,,,,2,,,,88,55
|
||||
javax.xml.transform.sax,,,4,,,,,,,,,,,,,,,4,
|
||||
javax.xml.transform.stream,,,2,,,,,,,,,,,,,,,2,
|
||||
javax.xml.xpath,3,,,,,,,,,,,,,,3,,,,
|
||||
org.apache.commons.codec,,,2,,,,,,,,,,,,,,,2,
|
||||
org.apache.commons.codec,,,6,,,,,,,,,,,,,,,6,
|
||||
org.apache.commons.collections,,,99,,,,,,,,,,,,,,,4,95
|
||||
org.apache.commons.collections4,,,99,,,,,,,,,,,,,,,4,95
|
||||
org.apache.commons.io,,,22,,,,,,,,,,,,,,,22,
|
||||
@@ -46,15 +46,17 @@ org.dom4j,20,,,,,,,,,,,,,,20,,,,
|
||||
org.hibernate,7,,,,,,,,,,,7,,,,,,,
|
||||
org.jooq,1,,,,,,,,,,,1,,,,,,,
|
||||
org.springframework.beans,,,26,,,,,,,,,,,,,,,,26
|
||||
org.springframework.cache,,,13,,,,,,,,,,,,,,,,13
|
||||
org.springframework.http,14,,,,,,,,,14,,,,,,,,,
|
||||
org.springframework.jdbc.core,10,,,,,,,,,,,10,,,,,,,
|
||||
org.springframework.ldap.core,14,,,,,,,,14,,,,,,,,,,
|
||||
org.springframework.security.web.savedrequest,,6,,,,,,,,,,,,,,,6,,
|
||||
org.springframework.ui,,,32,,,,,,,,,,,,,,,,32
|
||||
org.springframework.util,,,139,,,,,,,,,,,,,,,87,52
|
||||
org.springframework.validation,,,13,,,,,,,,,,,,,,,13,
|
||||
org.springframework.web.client,13,3,,,,,,,,13,,,,,,,3,,
|
||||
org.springframework.web.context.request,,8,,,,,,,,,,,,,,,8,,
|
||||
org.springframework.web.multipart,,12,,,,,,,,,,,,,,,12,,
|
||||
org.springframework.web.multipart,,12,13,,,,,,,,,,,,,,12,13,
|
||||
org.springframework.web.reactive.function.client,2,,,,,,,,,2,,,,,,,,,
|
||||
org.xml.sax,,,1,,,,,,,,,,,,,,,1,
|
||||
org.xmlpull.v1,,3,,,,,,,,,,,,,,,3,,
|
||||
|
||||
|
@@ -7,7 +7,7 @@ Java framework & library support
|
||||
:widths: auto
|
||||
|
||||
Framework / library,Package,Flow sources,Taint & value steps,Sinks (total),`CWE‑022` :sub:`Path injection`,`CWE‑036` :sub:`Path traversal`,`CWE‑079` :sub:`Cross-site scripting`,`CWE‑089` :sub:`SQL injection`,`CWE‑090` :sub:`LDAP injection`,`CWE‑094` :sub:`Code injection`,`CWE‑319` :sub:`Cleartext transmission`
|
||||
Android,``android.*``,18,,70,,,3,67,,,
|
||||
Android,``android.*``,18,34,70,,,3,67,,,
|
||||
`Apache Commons Collections <https://commons.apache.org/proper/commons-collections/>`_,"``org.apache.commons.collections``, ``org.apache.commons.collections4``",,198,,,,,,,,
|
||||
`Apache Commons IO <https://commons.apache.org/proper/commons-io/>`_,``org.apache.commons.io``,,22,,,,,,,,
|
||||
`Apache Commons Lang <https://commons.apache.org/proper/commons-lang/>`_,``org.apache.commons.lang3``,,420,,,,,,,,
|
||||
@@ -16,7 +16,7 @@ Java framework & library support
|
||||
`Google Guava <https://guava.dev/>`_,``com.google.common.*``,,158,6,,6,,,,,
|
||||
Java Standard Library,``java.*``,3,327,30,13,,,7,,,10
|
||||
Java extensions,"``javax.*``, ``jakarta.*``",22,294,18,,,,,1,1,2
|
||||
`Spring <https://spring.io/>`_,``org.springframework.*``,29,178,53,,,,10,14,,29
|
||||
Others,"``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.databind``, ``com.unboundid.ldap.sdk``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.dom4j``, ``org.hibernate``, ``org.jooq``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``",7,8,82,,,,14,18,,
|
||||
Totals,,84,2013,287,13,6,6,98,33,1,66
|
||||
`Spring <https://spring.io/>`_,``org.springframework.*``,29,236,53,,,,10,14,,29
|
||||
Others,"``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.databind``, ``com.unboundid.ldap.sdk``, ``org.apache.commons.codec``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.directory.ldap.client.api``, ``org.apache.ibatis.jdbc``, ``org.dom4j``, ``org.hibernate``, ``org.jooq``, ``org.xml.sax``, ``org.xmlpull.v1``, ``play.mvc``",7,12,82,,,,14,18,,
|
||||
Totals,,84,2109,287,13,6,6,98,33,1,66
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
* @description Sensitive cookies without the 'HttpOnly' flag set leaves session cookies vulnerable to
|
||||
* an XSS attack.
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @precision medium
|
||||
* @id java/sensitive-cookie-not-httponly
|
||||
* @tags security
|
||||
* external/cwe/cwe-1004
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
* @name Cleartext Credentials in Properties File
|
||||
* @description Finds cleartext credentials in Java properties files.
|
||||
* @kind problem
|
||||
* @problem.severity warning
|
||||
* @precision high
|
||||
* @id java/credentials-in-properties
|
||||
* @tags security
|
||||
* external/cwe/cwe-555
|
||||
|
||||
@@ -652,6 +652,48 @@ Element interpretElement(
|
||||
)
|
||||
}
|
||||
|
||||
private predicate parseField(string c, FieldContent f) {
|
||||
specSplit(_, c, _) and
|
||||
exists(string fieldRegex, string package, string className, string fieldName |
|
||||
fieldRegex = "^Field\\[(.*)\\.([^.]+)\\.([^.]+)\\]$" and
|
||||
package = c.regexpCapture(fieldRegex, 1) and
|
||||
className = c.regexpCapture(fieldRegex, 2) and
|
||||
fieldName = c.regexpCapture(fieldRegex, 3) and
|
||||
f.getField().hasQualifiedName(package, className, fieldName)
|
||||
)
|
||||
}
|
||||
|
||||
/** A string representing a synthetic instance field. */
|
||||
class SyntheticField extends string {
|
||||
SyntheticField() { parseSynthField(_, this) }
|
||||
|
||||
/**
|
||||
* Gets the type of this field. The default type is `Object`, but this can be
|
||||
* overridden.
|
||||
*/
|
||||
Type getType() { result instanceof TypeObject }
|
||||
}
|
||||
|
||||
private predicate parseSynthField(string c, string f) {
|
||||
specSplit(_, c, _) and
|
||||
c.regexpCapture("SyntheticField\\[([.a-zA-Z0-9]+)\\]", 1) = f
|
||||
}
|
||||
|
||||
/** Holds if the specification component parses as a `Content`. */
|
||||
predicate parseContent(string component, Content content) {
|
||||
parseField(component, content)
|
||||
or
|
||||
parseSynthField(component, content.(SyntheticFieldContent).getField())
|
||||
or
|
||||
component = "ArrayElement" and content instanceof ArrayContent
|
||||
or
|
||||
component = "Element" and content instanceof CollectionContent
|
||||
or
|
||||
component = "MapKey" and content instanceof MapKeyContent
|
||||
or
|
||||
component = "MapValue" and content instanceof MapValueContent
|
||||
}
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
/**
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -943,13 +943,8 @@ private module Stage2 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1122,8 +1117,7 @@ private module Stage2 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -1615,13 +1609,8 @@ private module Stage3 {
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) { any() }
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) { any() }
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
any()
|
||||
}
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) { any() }
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) { any() }
|
||||
@@ -1816,8 +1805,7 @@ private module Stage3 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
@@ -2364,20 +2352,16 @@ private module Stage4 {
|
||||
|
||||
bindingset[call, c, outercc]
|
||||
private CcCall getCallContextCall(DataFlowCall call, DataFlowCallable c, Cc outercc) {
|
||||
c = resolveCall(call, outercc) and
|
||||
checkCallContextCall(outercc, call, c) and
|
||||
if recordDataFlowCallSite(call, c) then result = TSpecificCall(call) else result = TSomeCall()
|
||||
}
|
||||
|
||||
bindingset[call, c]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call) {
|
||||
bindingset[call, c, innercc]
|
||||
private CcNoCall getCallContextReturn(DataFlowCallable c, DataFlowCall call, Cc innercc) {
|
||||
checkCallContextReturn(innercc, c, call) and
|
||||
if reducedViableImplInReturn(c, call) then result = TReturn(c, call) else result = ccNone()
|
||||
}
|
||||
|
||||
bindingset[innercc, inner, call]
|
||||
private predicate checkCallContextReturn(Cc innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
resolveReturn(innercc, inner, call)
|
||||
}
|
||||
|
||||
bindingset[node, cc, config]
|
||||
private LocalCc getLocalCc(NodeEx node, Cc cc, Configuration config) {
|
||||
localFlowEntry(node, config) and
|
||||
@@ -2579,8 +2563,7 @@ private module Stage4 {
|
||||
fwdFlow(ret, innercc, argAp, ap, config) and
|
||||
flowOutOfCall(call, ret, out, allowsFieldFlow, config) and
|
||||
inner = ret.getEnclosingCallable() and
|
||||
checkCallContextReturn(innercc, inner, call) and
|
||||
ccOut = getCallContextReturn(inner, call)
|
||||
ccOut = getCallContextReturn(inner, call, innercc)
|
||||
|
|
||||
ap instanceof ApNil or allowsFieldFlow = true
|
||||
)
|
||||
|
||||
@@ -1117,6 +1117,44 @@ ReturnPosition getReturnPosition(ReturnNodeExt ret) {
|
||||
result = getReturnPosition0(ret, ret.getKind())
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether `inner` can return to `call` in the call context `innercc`.
|
||||
* Assumes a context of `inner = viableCallableExt(call)`.
|
||||
*/
|
||||
bindingset[innercc, inner, call]
|
||||
predicate checkCallContextReturn(CallContext innercc, DataFlowCallable inner, DataFlowCall call) {
|
||||
innercc instanceof CallContextAny
|
||||
or
|
||||
exists(DataFlowCallable c0, DataFlowCall call0 |
|
||||
callEnclosingCallable(call0, inner) and
|
||||
innercc = TReturn(c0, call0) and
|
||||
c0 = prunedViableImplInCallContextReverse(call0, call)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether `call` can resolve to `calltarget` in the call context `cc`.
|
||||
* Assumes a context of `calltarget = viableCallableExt(call)`.
|
||||
*/
|
||||
bindingset[cc, call, calltarget]
|
||||
predicate checkCallContextCall(CallContext cc, DataFlowCall call, DataFlowCallable calltarget) {
|
||||
exists(DataFlowCall ctx | cc = TSpecificCall(ctx) |
|
||||
if reducedViableImplInCallContext(call, _, ctx)
|
||||
then calltarget = prunedViableImplInCallContext(call, ctx)
|
||||
else any()
|
||||
)
|
||||
or
|
||||
cc instanceof CallContextSomeCall
|
||||
or
|
||||
cc instanceof CallContextAny
|
||||
or
|
||||
cc instanceof CallContextReturn
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a return from `callable` in `cc` to `call`. This is equivalent to
|
||||
* `callable = viableCallableExt(call) and checkCallContextReturn(cc, callable, call)`.
|
||||
*/
|
||||
bindingset[cc, callable]
|
||||
predicate resolveReturn(CallContext cc, DataFlowCallable callable, DataFlowCall call) {
|
||||
cc instanceof CallContextAny and callable = viableCallableExt(call)
|
||||
@@ -1128,6 +1166,10 @@ predicate resolveReturn(CallContext cc, DataFlowCallable callable, DataFlowCall
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a call from `call` in `cc` to `result`. This is equivalent to
|
||||
* `result = viableCallableExt(call) and checkCallContextCall(cc, call, result)`.
|
||||
*/
|
||||
bindingset[call, cc]
|
||||
DataFlowCallable resolveCall(DataFlowCall call, CallContext cc) {
|
||||
exists(DataFlowCall ctx | cc = TSpecificCall(ctx) |
|
||||
|
||||
@@ -162,7 +162,8 @@ private newtype TContent =
|
||||
TArrayContent() or
|
||||
TCollectionContent() or
|
||||
TMapKeyContent() or
|
||||
TMapValueContent()
|
||||
TMapValueContent() or
|
||||
TSyntheticFieldContent(SyntheticField s)
|
||||
|
||||
/**
|
||||
* A description of the way data may be stored inside an object. Examples
|
||||
@@ -170,6 +171,9 @@ private newtype TContent =
|
||||
* of an array.
|
||||
*/
|
||||
class Content extends TContent {
|
||||
/** Gets the type of the contained data for the purpose of type pruning. */
|
||||
abstract DataFlowType getType();
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
abstract string toString();
|
||||
|
||||
@@ -193,6 +197,8 @@ class FieldContent extends Content, TFieldContent {
|
||||
|
||||
InstanceField getField() { result = f }
|
||||
|
||||
override DataFlowType getType() { result = getErasedRepr(f.getType()) }
|
||||
|
||||
override string toString() { result = f.toString() }
|
||||
|
||||
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
|
||||
@@ -202,24 +208,45 @@ class FieldContent extends Content, TFieldContent {
|
||||
|
||||
/** A reference through an array. */
|
||||
class ArrayContent extends Content, TArrayContent {
|
||||
override DataFlowType getType() { result instanceof TypeObject }
|
||||
|
||||
override string toString() { result = "[]" }
|
||||
}
|
||||
|
||||
/** A reference through the contents of some collection-like container. */
|
||||
class CollectionContent extends Content, TCollectionContent {
|
||||
override DataFlowType getType() { result instanceof TypeObject }
|
||||
|
||||
override string toString() { result = "<element>" }
|
||||
}
|
||||
|
||||
/** A reference through a map key. */
|
||||
class MapKeyContent extends Content, TMapKeyContent {
|
||||
override DataFlowType getType() { result instanceof TypeObject }
|
||||
|
||||
override string toString() { result = "<map.key>" }
|
||||
}
|
||||
|
||||
/** A reference through a map value. */
|
||||
class MapValueContent extends Content, TMapValueContent {
|
||||
override DataFlowType getType() { result instanceof TypeObject }
|
||||
|
||||
override string toString() { result = "<map.value>" }
|
||||
}
|
||||
|
||||
/** A reference through a synthetic instance field. */
|
||||
class SyntheticFieldContent extends Content, TSyntheticFieldContent {
|
||||
SyntheticField s;
|
||||
|
||||
SyntheticFieldContent() { this = TSyntheticFieldContent(s) }
|
||||
|
||||
SyntheticField getField() { result = s }
|
||||
|
||||
override DataFlowType getType() { result = getErasedRepr(s.getType()) }
|
||||
|
||||
override string toString() { result = s.toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A guard that validates some expression.
|
||||
*
|
||||
|
||||
@@ -23,21 +23,7 @@ Node summaryNode(SummarizedCallable c, SummaryNodeState state) { result = getSum
|
||||
DataFlowCall summaryDataFlowCall(Node receiver) { none() }
|
||||
|
||||
/** Gets the type of content `c`. */
|
||||
DataFlowType getContentType(Content c) {
|
||||
result = getErasedRepr(c.(FieldContent).getField().getType())
|
||||
or
|
||||
c instanceof CollectionContent and
|
||||
result instanceof TypeObject
|
||||
or
|
||||
c instanceof ArrayContent and
|
||||
result instanceof TypeObject
|
||||
or
|
||||
c instanceof MapKeyContent and
|
||||
result instanceof TypeObject
|
||||
or
|
||||
c instanceof MapValueContent and
|
||||
result instanceof TypeObject
|
||||
}
|
||||
DataFlowType getContentType(Content c) { result = c.getType() }
|
||||
|
||||
/** Gets the return type of kind `rk` for callable `c`. */
|
||||
DataFlowType getReturnType(SummarizedCallable c, ReturnKind rk) {
|
||||
@@ -70,29 +56,10 @@ predicate summaryElement(DataFlowCallable c, string input, string output, string
|
||||
)
|
||||
}
|
||||
|
||||
private FieldContent parseField(string c) {
|
||||
External::specSplit(_, c, _) and
|
||||
exists(string fieldRegex, string package, string className, string fieldName |
|
||||
fieldRegex = "^Field\\[(.*)\\.([^.]+)\\.([^.]+)\\]$" and
|
||||
package = c.regexpCapture(fieldRegex, 1) and
|
||||
className = c.regexpCapture(fieldRegex, 2) and
|
||||
fieldName = c.regexpCapture(fieldRegex, 3) and
|
||||
result.getField().hasQualifiedName(package, className, fieldName)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the summary component for specification component `c`, if any. */
|
||||
bindingset[c]
|
||||
SummaryComponent interpretComponentSpecific(string c) {
|
||||
result = SummaryComponent::content(parseField(c))
|
||||
or
|
||||
c = "ArrayElement" and result = SummaryComponent::content(any(ArrayContent c0))
|
||||
or
|
||||
c = "Element" and result = SummaryComponent::content(any(CollectionContent c0))
|
||||
or
|
||||
c = "MapKey" and result = SummaryComponent::content(any(MapKeyContent c0))
|
||||
or
|
||||
c = "MapValue" and result = SummaryComponent::content(any(MapValueContent c0))
|
||||
exists(Content content | parseContent(c, content) and result = SummaryComponent::content(content))
|
||||
}
|
||||
|
||||
class SourceOrSinkElement = Top;
|
||||
|
||||
@@ -24,7 +24,16 @@ private class SqlSinkCsv extends SinkModelCsv {
|
||||
"org.springframework.jdbc.core;JdbcTemplate;false;queryForMap;;;Argument[0];sql",
|
||||
"org.springframework.jdbc.core;JdbcTemplate;false;queryForObject;;;Argument[0];sql",
|
||||
"org.springframework.jdbc.core;JdbcTemplate;false;queryForRowSet;;;Argument[0];sql",
|
||||
"org.springframework.jdbc.core;JdbcTemplate;false;queryForStream;;;Argument[0];sql"
|
||||
"org.springframework.jdbc.core;JdbcTemplate;false;queryForStream;;;Argument[0];sql",
|
||||
"org.springframework.jdbc.object;BatchSqlUpdate;false;BatchSqlUpdate;;;Argument[1];sql",
|
||||
"org.springframework.jdbc.object;MappingSqlQuery;false;BatchSqlUpdate;;;Argument[1];sql",
|
||||
"org.springframework.jdbc.object;MappingSqlQueryWithParameters;false;BatchSqlUpdate;;;Argument[1];sql",
|
||||
"org.springframework.jdbc.object;RdbmsOperation;true;setSql;;;Argument[0];sql",
|
||||
"org.springframework.jdbc.object;SqlCall;false;SqlCall;;;Argument[1];sql",
|
||||
"org.springframework.jdbc.object;SqlFunction;false;SqlFunction;;;Argument[1];sql",
|
||||
"org.springframework.jdbc.object;SqlQuery;false;SqlQuery;;;Argument[1];sql",
|
||||
"org.springframework.jdbc.object;SqlUpdate;false;SqlUpdate;;;Argument[1];sql",
|
||||
"org.springframework.jdbc.object;UpdatableSqlQuery;false;UpdatableSqlQuery;;;Argument[1];sql"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Map;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.object.BatchSqlUpdate;
|
||||
import org.springframework.jdbc.object.MappingSqlQueryWithParameters;
|
||||
import org.springframework.jdbc.object.SqlFunction;
|
||||
import org.springframework.jdbc.object.SqlUpdate;
|
||||
import org.springframework.jdbc.object.UpdatableSqlQuery;
|
||||
|
||||
public class SpringJdbc {
|
||||
|
||||
public static String source() { return null; }
|
||||
|
||||
private static class MyUpdatableSqlQuery extends UpdatableSqlQuery<String> {
|
||||
public MyUpdatableSqlQuery() {
|
||||
super(null, source()); // $ sqlInjection
|
||||
}
|
||||
|
||||
protected String updateRow(ResultSet rs, int rowNum, Map<?,?> context) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void test(JdbcTemplate template) {
|
||||
new BatchSqlUpdate(null, source()); // $ sqlInjection
|
||||
new SqlFunction(null, source()); // $ sqlInjection
|
||||
new SqlUpdate(null, source()); // $ sqlInjection
|
||||
|
||||
(new BatchSqlUpdate()).setSql(source()); // $ sqlInjection
|
||||
|
||||
template.batchUpdate(source()); // $ sqlInjection
|
||||
template.batchUpdate(source(), null, 0, null); // $ sqlInjection
|
||||
template.execute(source()); // $ sqlInjection
|
||||
template.update(source()); // $ sqlInjection
|
||||
template.query(source(), (RowMapper)null); // $ sqlInjection
|
||||
template.queryForList(source()); // $ sqlInjection
|
||||
template.queryForMap(source()); // $ sqlInjection
|
||||
template.queryForObject(source(), (Class)null); // $ sqlInjection
|
||||
template.queryForRowSet(source()); // $ sqlInjection
|
||||
template.queryForStream(source(), (RowMapper)null); // $ sqlInjection
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/mongodbClient
|
||||
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../../stubs/mongodbClient:${testdir}/../../../../../stubs/springframework-5.3.8
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.security.QueryInjection
|
||||
import TestUtilities.InlineExpectationsTest
|
||||
|
||||
private class QueryInjectionFlowConfig extends TaintTracking::Configuration {
|
||||
QueryInjectionFlowConfig() { this = "SqlInjectionLib::QueryInjectionFlowConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node src) {
|
||||
src.asExpr() = any(MethodAccess ma | ma.getMethod().hasName("source"))
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) { sink instanceof QueryInjectionSink }
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
node.getType() instanceof PrimitiveType or
|
||||
node.getType() instanceof BoxedType or
|
||||
node.getType() instanceof NumberType
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) {
|
||||
any(AdditionalQueryInjectionTaintStep s).step(node1, node2)
|
||||
}
|
||||
}
|
||||
|
||||
class HasFlowTest extends InlineExpectationsTest {
|
||||
HasFlowTest() { this = "HasFlowTest" }
|
||||
|
||||
override string getARelevantTag() { result = "sqlInjection" }
|
||||
|
||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||
tag = "sqlInjection" and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink, QueryInjectionFlowConfig conf |
|
||||
conf.hasFlow(src, sink)
|
||||
|
|
||||
sink.getLocation() = location and
|
||||
element = sink.toString() and
|
||||
value = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Generated automatically from org.springframework.core.NestedRuntimeException for testing purposes
|
||||
|
||||
package org.springframework.core;
|
||||
|
||||
|
||||
abstract public class NestedRuntimeException extends RuntimeException
|
||||
{
|
||||
protected NestedRuntimeException() {}
|
||||
public NestedRuntimeException(String p0){}
|
||||
public NestedRuntimeException(String p0, Throwable p1){}
|
||||
public String getMessage(){ return null; }
|
||||
public Throwable getMostSpecificCause(){ return null; }
|
||||
public Throwable getRootCause(){ return null; }
|
||||
public boolean contains(Class<? extends Object> p0){ return false; }
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// Generated automatically from org.springframework.dao.DataAccessException for testing purposes
|
||||
|
||||
package org.springframework.dao;
|
||||
|
||||
import org.springframework.core.NestedRuntimeException;
|
||||
|
||||
abstract public class DataAccessException extends NestedRuntimeException
|
||||
{
|
||||
protected DataAccessException() {}
|
||||
public DataAccessException(String p0){}
|
||||
public DataAccessException(String p0, Throwable p1){}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Generated automatically from org.springframework.jdbc.core.BatchPreparedStatementSetter for testing purposes
|
||||
|
||||
package org.springframework.jdbc.core;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
|
||||
public interface BatchPreparedStatementSetter
|
||||
{
|
||||
int getBatchSize();
|
||||
void setValues(PreparedStatement p0, int p1);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Generated automatically from org.springframework.jdbc.core.CallableStatementCallback for testing purposes
|
||||
|
||||
package org.springframework.jdbc.core;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
|
||||
public interface CallableStatementCallback<T>
|
||||
{
|
||||
T doInCallableStatement(CallableStatement p0);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Generated automatically from org.springframework.jdbc.core.CallableStatementCreator for testing purposes
|
||||
|
||||
package org.springframework.jdbc.core;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.Connection;
|
||||
|
||||
public interface CallableStatementCreator
|
||||
{
|
||||
CallableStatement createCallableStatement(Connection p0);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Generated automatically from org.springframework.jdbc.core.ConnectionCallback for testing purposes
|
||||
|
||||
package org.springframework.jdbc.core;
|
||||
|
||||
import java.sql.Connection;
|
||||
|
||||
public interface ConnectionCallback<T>
|
||||
{
|
||||
T doInConnection(Connection p0);
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
// Generated automatically from org.springframework.jdbc.core.JdbcOperations for testing purposes
|
||||
|
||||
package org.springframework.jdbc.core;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
|
||||
import org.springframework.jdbc.core.CallableStatementCallback;
|
||||
import org.springframework.jdbc.core.CallableStatementCreator;
|
||||
import org.springframework.jdbc.core.ConnectionCallback;
|
||||
import org.springframework.jdbc.core.ParameterizedPreparedStatementSetter;
|
||||
import org.springframework.jdbc.core.PreparedStatementCallback;
|
||||
import org.springframework.jdbc.core.PreparedStatementCreator;
|
||||
import org.springframework.jdbc.core.PreparedStatementSetter;
|
||||
import org.springframework.jdbc.core.ResultSetExtractor;
|
||||
import org.springframework.jdbc.core.RowCallbackHandler;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.SqlParameter;
|
||||
import org.springframework.jdbc.core.StatementCallback;
|
||||
import org.springframework.jdbc.support.KeyHolder;
|
||||
import org.springframework.jdbc.support.rowset.SqlRowSet;
|
||||
|
||||
public interface JdbcOperations
|
||||
{
|
||||
<T> List<T> query(PreparedStatementCreator p0, RowMapper<T> p1);
|
||||
<T> List<T> query(String p0, Object[] p1, RowMapper<T> p2);
|
||||
<T> List<T> query(String p0, Object[] p1, int[] p2, RowMapper<T> p3);
|
||||
<T> List<T> query(String p0, PreparedStatementSetter p1, RowMapper<T> p2);
|
||||
<T> List<T> query(String p0, RowMapper<T> p1);
|
||||
<T> List<T> query(String p0, RowMapper<T> p1, Object... p2);
|
||||
<T> List<T> queryForList(String p0, Class<T> p1);
|
||||
<T> List<T> queryForList(String p0, Class<T> p1, Object... p2);
|
||||
<T> List<T> queryForList(String p0, Object[] p1, Class<T> p2);
|
||||
<T> List<T> queryForList(String p0, Object[] p1, int[] p2, Class<T> p3);
|
||||
<T> Stream<T> queryForStream(PreparedStatementCreator p0, RowMapper<T> p1);
|
||||
<T> Stream<T> queryForStream(String p0, PreparedStatementSetter p1, RowMapper<T> p2);
|
||||
<T> Stream<T> queryForStream(String p0, RowMapper<T> p1);
|
||||
<T> Stream<T> queryForStream(String p0, RowMapper<T> p1, Object... p2);
|
||||
<T> T execute(CallableStatementCreator p0, CallableStatementCallback<T> p1);
|
||||
<T> T execute(ConnectionCallback<T> p0);
|
||||
<T> T execute(PreparedStatementCreator p0, PreparedStatementCallback<T> p1);
|
||||
<T> T execute(StatementCallback<T> p0);
|
||||
<T> T execute(String p0, CallableStatementCallback<T> p1);
|
||||
<T> T execute(String p0, PreparedStatementCallback<T> p1);
|
||||
<T> T query(PreparedStatementCreator p0, ResultSetExtractor<T> p1);
|
||||
<T> T query(String p0, Object[] p1, ResultSetExtractor<T> p2);
|
||||
<T> T query(String p0, Object[] p1, int[] p2, ResultSetExtractor<T> p3);
|
||||
<T> T query(String p0, PreparedStatementSetter p1, ResultSetExtractor<T> p2);
|
||||
<T> T query(String p0, ResultSetExtractor<T> p1);
|
||||
<T> T query(String p0, ResultSetExtractor<T> p1, Object... p2);
|
||||
<T> T queryForObject(String p0, Class<T> p1);
|
||||
<T> T queryForObject(String p0, Class<T> p1, Object... p2);
|
||||
<T> T queryForObject(String p0, Object[] p1, Class<T> p2);
|
||||
<T> T queryForObject(String p0, Object[] p1, RowMapper<T> p2);
|
||||
<T> T queryForObject(String p0, Object[] p1, int[] p2, Class<T> p3);
|
||||
<T> T queryForObject(String p0, Object[] p1, int[] p2, RowMapper<T> p3);
|
||||
<T> T queryForObject(String p0, RowMapper<T> p1);
|
||||
<T> T queryForObject(String p0, RowMapper<T> p1, Object... p2);
|
||||
<T> int[] batchUpdate(String p0, Collection<T> p1, int p2, ParameterizedPreparedStatementSetter<T> p3);
|
||||
List<Map<String, Object>> queryForList(String p0);
|
||||
List<Map<String, Object>> queryForList(String p0, Object... p1);
|
||||
List<Map<String, Object>> queryForList(String p0, Object[] p1, int[] p2);
|
||||
Map<String, Object> call(CallableStatementCreator p0, List<SqlParameter> p1);
|
||||
Map<String, Object> queryForMap(String p0);
|
||||
Map<String, Object> queryForMap(String p0, Object... p1);
|
||||
Map<String, Object> queryForMap(String p0, Object[] p1, int[] p2);
|
||||
SqlRowSet queryForRowSet(String p0);
|
||||
SqlRowSet queryForRowSet(String p0, Object... p1);
|
||||
SqlRowSet queryForRowSet(String p0, Object[] p1, int[] p2);
|
||||
int update(PreparedStatementCreator p0);
|
||||
int update(PreparedStatementCreator p0, KeyHolder p1);
|
||||
int update(String p0);
|
||||
int update(String p0, Object... p1);
|
||||
int update(String p0, Object[] p1, int[] p2);
|
||||
int update(String p0, PreparedStatementSetter p1);
|
||||
int[] batchUpdate(String p0, BatchPreparedStatementSetter p1);
|
||||
int[] batchUpdate(String p0, List<Object[]> p1);
|
||||
int[] batchUpdate(String p0, List<Object[]> p1, int[] p2);
|
||||
int[] batchUpdate(String... p0);
|
||||
void execute(String p0);
|
||||
void query(PreparedStatementCreator p0, RowCallbackHandler p1);
|
||||
void query(String p0, Object[] p1, RowCallbackHandler p2);
|
||||
void query(String p0, Object[] p1, int[] p2, RowCallbackHandler p3);
|
||||
void query(String p0, PreparedStatementSetter p1, RowCallbackHandler p2);
|
||||
void query(String p0, RowCallbackHandler p1);
|
||||
void query(String p0, RowCallbackHandler p1, Object... p2);
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
// Generated automatically from org.springframework.jdbc.core.JdbcTemplate for testing purposes
|
||||
|
||||
package org.springframework.jdbc.core;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.SQLWarning;
|
||||
import java.sql.Statement;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
import javax.sql.DataSource;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
|
||||
import org.springframework.jdbc.core.CallableStatementCallback;
|
||||
import org.springframework.jdbc.core.CallableStatementCreator;
|
||||
import org.springframework.jdbc.core.ConnectionCallback;
|
||||
import org.springframework.jdbc.core.JdbcOperations;
|
||||
import org.springframework.jdbc.core.ParameterizedPreparedStatementSetter;
|
||||
import org.springframework.jdbc.core.PreparedStatementCallback;
|
||||
import org.springframework.jdbc.core.PreparedStatementCreator;
|
||||
import org.springframework.jdbc.core.PreparedStatementSetter;
|
||||
import org.springframework.jdbc.core.ResultSetExtractor;
|
||||
import org.springframework.jdbc.core.ResultSetSupportingSqlParameter;
|
||||
import org.springframework.jdbc.core.RowCallbackHandler;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.SqlParameter;
|
||||
import org.springframework.jdbc.core.StatementCallback;
|
||||
import org.springframework.jdbc.support.JdbcAccessor;
|
||||
import org.springframework.jdbc.support.KeyHolder;
|
||||
import org.springframework.jdbc.support.rowset.SqlRowSet;
|
||||
|
||||
public class JdbcTemplate extends JdbcAccessor implements JdbcOperations
|
||||
{
|
||||
protected <T> RowMapper<T> getSingleColumnRowMapper(Class<T> p0){ return null; }
|
||||
protected Connection createConnectionProxy(Connection p0){ return null; }
|
||||
protected DataAccessException translateException(String p0, String p1, SQLException p2){ return null; }
|
||||
protected Map<String, Object> createResultsMap(){ return null; }
|
||||
protected Map<String, Object> extractOutputParameters(CallableStatement p0, List<SqlParameter> p1){ return null; }
|
||||
protected Map<String, Object> extractReturnedResults(CallableStatement p0, List<SqlParameter> p1, List<SqlParameter> p2, int p3){ return null; }
|
||||
protected Map<String, Object> processResultSet(ResultSet p0, ResultSetSupportingSqlParameter p1){ return null; }
|
||||
protected PreparedStatementSetter newArgPreparedStatementSetter(Object[] p0){ return null; }
|
||||
protected PreparedStatementSetter newArgTypePreparedStatementSetter(Object[] p0, int[] p1){ return null; }
|
||||
protected RowMapper<Map<String, Object>> getColumnMapRowMapper(){ return null; }
|
||||
protected int update(PreparedStatementCreator p0, PreparedStatementSetter p1){ return 0; }
|
||||
protected void applyStatementSettings(Statement p0){}
|
||||
protected void handleWarnings(SQLWarning p0){}
|
||||
protected void handleWarnings(Statement p0){}
|
||||
public <T> List<T> query(PreparedStatementCreator p0, RowMapper<T> p1){ return null; }
|
||||
public <T> List<T> query(String p0, Object[] p1, RowMapper<T> p2){ return null; }
|
||||
public <T> List<T> query(String p0, Object[] p1, int[] p2, RowMapper<T> p3){ return null; }
|
||||
public <T> List<T> query(String p0, PreparedStatementSetter p1, RowMapper<T> p2){ return null; }
|
||||
public <T> List<T> query(String p0, RowMapper<T> p1){ return null; }
|
||||
public <T> List<T> query(String p0, RowMapper<T> p1, Object... p2){ return null; }
|
||||
public <T> List<T> queryForList(String p0, Class<T> p1){ return null; }
|
||||
public <T> List<T> queryForList(String p0, Class<T> p1, Object... p2){ return null; }
|
||||
public <T> List<T> queryForList(String p0, Object[] p1, Class<T> p2){ return null; }
|
||||
public <T> List<T> queryForList(String p0, Object[] p1, int[] p2, Class<T> p3){ return null; }
|
||||
public <T> Stream<T> queryForStream(PreparedStatementCreator p0, PreparedStatementSetter p1, RowMapper<T> p2){ return null; }
|
||||
public <T> Stream<T> queryForStream(PreparedStatementCreator p0, RowMapper<T> p1){ return null; }
|
||||
public <T> Stream<T> queryForStream(String p0, PreparedStatementSetter p1, RowMapper<T> p2){ return null; }
|
||||
public <T> Stream<T> queryForStream(String p0, RowMapper<T> p1){ return null; }
|
||||
public <T> Stream<T> queryForStream(String p0, RowMapper<T> p1, Object... p2){ return null; }
|
||||
public <T> T execute(CallableStatementCreator p0, CallableStatementCallback<T> p1){ return null; }
|
||||
public <T> T execute(ConnectionCallback<T> p0){ return null; }
|
||||
public <T> T execute(PreparedStatementCreator p0, PreparedStatementCallback<T> p1){ return null; }
|
||||
public <T> T execute(StatementCallback<T> p0){ return null; }
|
||||
public <T> T execute(String p0, CallableStatementCallback<T> p1){ return null; }
|
||||
public <T> T execute(String p0, PreparedStatementCallback<T> p1){ return null; }
|
||||
public <T> T query(PreparedStatementCreator p0, PreparedStatementSetter p1, ResultSetExtractor<T> p2){ return null; }
|
||||
public <T> T query(PreparedStatementCreator p0, ResultSetExtractor<T> p1){ return null; }
|
||||
public <T> T query(String p0, Object[] p1, ResultSetExtractor<T> p2){ return null; }
|
||||
public <T> T query(String p0, Object[] p1, int[] p2, ResultSetExtractor<T> p3){ return null; }
|
||||
public <T> T query(String p0, PreparedStatementSetter p1, ResultSetExtractor<T> p2){ return null; }
|
||||
public <T> T query(String p0, ResultSetExtractor<T> p1){ return null; }
|
||||
public <T> T query(String p0, ResultSetExtractor<T> p1, Object... p2){ return null; }
|
||||
public <T> T queryForObject(String p0, Class<T> p1){ return null; }
|
||||
public <T> T queryForObject(String p0, Class<T> p1, Object... p2){ return null; }
|
||||
public <T> T queryForObject(String p0, Object[] p1, Class<T> p2){ return null; }
|
||||
public <T> T queryForObject(String p0, Object[] p1, RowMapper<T> p2){ return null; }
|
||||
public <T> T queryForObject(String p0, Object[] p1, int[] p2, Class<T> p3){ return null; }
|
||||
public <T> T queryForObject(String p0, Object[] p1, int[] p2, RowMapper<T> p3){ return null; }
|
||||
public <T> T queryForObject(String p0, RowMapper<T> p1){ return null; }
|
||||
public <T> T queryForObject(String p0, RowMapper<T> p1, Object... p2){ return null; }
|
||||
public <T> int[] batchUpdate(String p0, Collection<T> p1, int p2, ParameterizedPreparedStatementSetter<T> p3){ return null; }
|
||||
public JdbcTemplate(){}
|
||||
public JdbcTemplate(DataSource p0){}
|
||||
public JdbcTemplate(DataSource p0, boolean p1){}
|
||||
public List<Map<String, Object>> queryForList(String p0){ return null; }
|
||||
public List<Map<String, Object>> queryForList(String p0, Object... p1){ return null; }
|
||||
public List<Map<String, Object>> queryForList(String p0, Object[] p1, int[] p2){ return null; }
|
||||
public Map<String, Object> call(CallableStatementCreator p0, List<SqlParameter> p1){ return null; }
|
||||
public Map<String, Object> queryForMap(String p0){ return null; }
|
||||
public Map<String, Object> queryForMap(String p0, Object... p1){ return null; }
|
||||
public Map<String, Object> queryForMap(String p0, Object[] p1, int[] p2){ return null; }
|
||||
public SqlRowSet queryForRowSet(String p0){ return null; }
|
||||
public SqlRowSet queryForRowSet(String p0, Object... p1){ return null; }
|
||||
public SqlRowSet queryForRowSet(String p0, Object[] p1, int[] p2){ return null; }
|
||||
public boolean isIgnoreWarnings(){ return false; }
|
||||
public boolean isResultsMapCaseInsensitive(){ return false; }
|
||||
public boolean isSkipResultsProcessing(){ return false; }
|
||||
public boolean isSkipUndeclaredResults(){ return false; }
|
||||
public int getFetchSize(){ return 0; }
|
||||
public int getMaxRows(){ return 0; }
|
||||
public int getQueryTimeout(){ return 0; }
|
||||
public int update(PreparedStatementCreator p0){ return 0; }
|
||||
public int update(PreparedStatementCreator p0, KeyHolder p1){ return 0; }
|
||||
public int update(String p0){ return 0; }
|
||||
public int update(String p0, Object... p1){ return 0; }
|
||||
public int update(String p0, Object[] p1, int[] p2){ return 0; }
|
||||
public int update(String p0, PreparedStatementSetter p1){ return 0; }
|
||||
public int[] batchUpdate(String p0, BatchPreparedStatementSetter p1){ return null; }
|
||||
public int[] batchUpdate(String p0, List<Object[]> p1){ return null; }
|
||||
public int[] batchUpdate(String p0, List<Object[]> p1, int[] p2){ return null; }
|
||||
public int[] batchUpdate(String... p0){ return null; }
|
||||
public void execute(String p0){}
|
||||
public void query(PreparedStatementCreator p0, RowCallbackHandler p1){}
|
||||
public void query(String p0, Object[] p1, RowCallbackHandler p2){}
|
||||
public void query(String p0, Object[] p1, int[] p2, RowCallbackHandler p3){}
|
||||
public void query(String p0, PreparedStatementSetter p1, RowCallbackHandler p2){}
|
||||
public void query(String p0, RowCallbackHandler p1){}
|
||||
public void query(String p0, RowCallbackHandler p1, Object... p2){}
|
||||
public void setFetchSize(int p0){}
|
||||
public void setIgnoreWarnings(boolean p0){}
|
||||
public void setMaxRows(int p0){}
|
||||
public void setQueryTimeout(int p0){}
|
||||
public void setResultsMapCaseInsensitive(boolean p0){}
|
||||
public void setSkipResultsProcessing(boolean p0){}
|
||||
public void setSkipUndeclaredResults(boolean p0){}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Generated automatically from org.springframework.jdbc.core.ParameterizedPreparedStatementSetter for testing purposes
|
||||
|
||||
package org.springframework.jdbc.core;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
|
||||
public interface ParameterizedPreparedStatementSetter<T>
|
||||
{
|
||||
void setValues(PreparedStatement p0, T p1);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Generated automatically from org.springframework.jdbc.core.PreparedStatementCallback for testing purposes
|
||||
|
||||
package org.springframework.jdbc.core;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
|
||||
public interface PreparedStatementCallback<T>
|
||||
{
|
||||
T doInPreparedStatement(PreparedStatement p0);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Generated automatically from org.springframework.jdbc.core.PreparedStatementCreator for testing purposes
|
||||
|
||||
package org.springframework.jdbc.core;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
|
||||
public interface PreparedStatementCreator
|
||||
{
|
||||
PreparedStatement createPreparedStatement(Connection p0);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Generated automatically from org.springframework.jdbc.core.PreparedStatementSetter for testing purposes
|
||||
|
||||
package org.springframework.jdbc.core;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
|
||||
public interface PreparedStatementSetter
|
||||
{
|
||||
void setValues(PreparedStatement p0);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Generated automatically from org.springframework.jdbc.core.ResultSetExtractor for testing purposes
|
||||
|
||||
package org.springframework.jdbc.core;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
|
||||
public interface ResultSetExtractor<T>
|
||||
{
|
||||
T extractData(ResultSet p0);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// Generated automatically from org.springframework.jdbc.core.ResultSetSupportingSqlParameter for testing purposes
|
||||
|
||||
package org.springframework.jdbc.core;
|
||||
|
||||
import org.springframework.jdbc.core.ResultSetExtractor;
|
||||
import org.springframework.jdbc.core.RowCallbackHandler;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.SqlParameter;
|
||||
|
||||
public class ResultSetSupportingSqlParameter extends SqlParameter
|
||||
{
|
||||
protected ResultSetSupportingSqlParameter() {}
|
||||
public ResultSetExtractor<? extends Object> getResultSetExtractor(){ return null; }
|
||||
public ResultSetSupportingSqlParameter(String p0, int p1){}
|
||||
public ResultSetSupportingSqlParameter(String p0, int p1, ResultSetExtractor<? extends Object> p2){}
|
||||
public ResultSetSupportingSqlParameter(String p0, int p1, RowCallbackHandler p2){}
|
||||
public ResultSetSupportingSqlParameter(String p0, int p1, RowMapper<? extends Object> p2){}
|
||||
public ResultSetSupportingSqlParameter(String p0, int p1, String p2){}
|
||||
public ResultSetSupportingSqlParameter(String p0, int p1, int p2){}
|
||||
public RowCallbackHandler getRowCallbackHandler(){ return null; }
|
||||
public RowMapper<? extends Object> getRowMapper(){ return null; }
|
||||
public boolean isInputValueProvided(){ return false; }
|
||||
public boolean isResultSetSupported(){ return false; }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Generated automatically from org.springframework.jdbc.core.RowCallbackHandler for testing purposes
|
||||
|
||||
package org.springframework.jdbc.core;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
|
||||
public interface RowCallbackHandler
|
||||
{
|
||||
void processRow(ResultSet p0);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Generated automatically from org.springframework.jdbc.core.RowMapper for testing purposes
|
||||
|
||||
package org.springframework.jdbc.core;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
|
||||
public interface RowMapper<T>
|
||||
{
|
||||
T mapRow(ResultSet p0, int p1);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// Generated automatically from org.springframework.jdbc.core.SqlParameter for testing purposes
|
||||
|
||||
package org.springframework.jdbc.core;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SqlParameter
|
||||
{
|
||||
protected SqlParameter() {}
|
||||
public Integer getScale(){ return null; }
|
||||
public SqlParameter(SqlParameter p0){}
|
||||
public SqlParameter(String p0, int p1){}
|
||||
public SqlParameter(String p0, int p1, String p2){}
|
||||
public SqlParameter(String p0, int p1, int p2){}
|
||||
public SqlParameter(int p0){}
|
||||
public SqlParameter(int p0, String p1){}
|
||||
public SqlParameter(int p0, int p1){}
|
||||
public String getName(){ return null; }
|
||||
public String getTypeName(){ return null; }
|
||||
public boolean isInputValueProvided(){ return false; }
|
||||
public boolean isResultsParameter(){ return false; }
|
||||
public int getSqlType(){ return 0; }
|
||||
public static List<SqlParameter> sqlTypesToAnonymousParameterList(int... p0){ return null; }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Generated automatically from org.springframework.jdbc.core.StatementCallback for testing purposes
|
||||
|
||||
package org.springframework.jdbc.core;
|
||||
|
||||
import java.sql.Statement;
|
||||
|
||||
public interface StatementCallback<T>
|
||||
{
|
||||
T doInStatement(Statement p0);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// Generated automatically from org.springframework.jdbc.core.namedparam.ParsedSql for testing purposes
|
||||
|
||||
package org.springframework.jdbc.core.namedparam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ParsedSql
|
||||
{
|
||||
protected ParsedSql() {}
|
||||
List<String> getParameterNames(){ return null; }
|
||||
ParsedSql(String p0){}
|
||||
String getOriginalSql(){ return null; }
|
||||
int getNamedParameterCount(){ return 0; }
|
||||
int getTotalParameterCount(){ return 0; }
|
||||
int getUnnamedParameterCount(){ return 0; }
|
||||
int[] getParameterIndexes(int p0){ return null; }
|
||||
public String toString(){ return null; }
|
||||
void addNamedParameter(String p0, int p1, int p2){}
|
||||
void setNamedParameterCount(int p0){}
|
||||
void setTotalParameterCount(int p0){}
|
||||
void setUnnamedParameterCount(int p0){}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// Generated automatically from org.springframework.jdbc.object.BatchSqlUpdate for testing purposes
|
||||
|
||||
package org.springframework.jdbc.object;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import org.springframework.jdbc.object.SqlUpdate;
|
||||
|
||||
public class BatchSqlUpdate extends SqlUpdate
|
||||
{
|
||||
protected boolean supportsLobParameters(){ return false; }
|
||||
public BatchSqlUpdate(){}
|
||||
public BatchSqlUpdate(DataSource p0, String p1){}
|
||||
public BatchSqlUpdate(DataSource p0, String p1, int[] p2){}
|
||||
public BatchSqlUpdate(DataSource p0, String p1, int[] p2, int p3){}
|
||||
public int getExecutionCount(){ return 0; }
|
||||
public int getQueueCount(){ return 0; }
|
||||
public int update(Object... p0){ return 0; }
|
||||
public int[] flush(){ return null; }
|
||||
public int[] getRowsAffected(){ return null; }
|
||||
public static int DEFAULT_BATCH_SIZE = 0;
|
||||
public void reset(){}
|
||||
public void setBatchSize(int p0){}
|
||||
public void setTrackRowsAffected(boolean p0){}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Generated automatically from org.springframework.jdbc.object.MappingSqlQuery for testing purposes
|
||||
|
||||
package org.springframework.jdbc.object;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Map;
|
||||
import javax.sql.DataSource;
|
||||
import org.springframework.jdbc.object.MappingSqlQueryWithParameters;
|
||||
|
||||
abstract public class MappingSqlQuery<T> extends MappingSqlQueryWithParameters<T>
|
||||
{
|
||||
protected abstract T mapRow(ResultSet p0, int p1);
|
||||
protected final T mapRow(ResultSet p0, int p1, Object[] p2, Map<? extends Object, ? extends Object> p3){ return null; }
|
||||
public MappingSqlQuery(){}
|
||||
public MappingSqlQuery(DataSource p0, String p1){}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Generated automatically from org.springframework.jdbc.object.MappingSqlQueryWithParameters for testing purposes
|
||||
|
||||
package org.springframework.jdbc.object;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.util.Map;
|
||||
import javax.sql.DataSource;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.object.SqlQuery;
|
||||
|
||||
abstract public class MappingSqlQueryWithParameters<T> extends SqlQuery<T>
|
||||
{
|
||||
protected RowMapper<T> newRowMapper(Object[] p0, Map<? extends Object, ? extends Object> p1){ return null; }
|
||||
protected abstract T mapRow(ResultSet p0, int p1, Object[] p2, Map<? extends Object, ? extends Object> p3);
|
||||
public MappingSqlQueryWithParameters(){}
|
||||
public MappingSqlQueryWithParameters(DataSource p0, String p1){}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// Generated automatically from org.springframework.jdbc.object.RdbmsOperation for testing purposes
|
||||
|
||||
package org.springframework.jdbc.object;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.sql.DataSource;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.SqlParameter;
|
||||
|
||||
abstract public class RdbmsOperation implements InitializingBean
|
||||
{
|
||||
protected List<SqlParameter> getDeclaredParameters(){ return null; }
|
||||
protected String resolveSql(){ return null; }
|
||||
protected abstract void compileInternal();
|
||||
protected boolean allowsUnusedParameters(){ return false; }
|
||||
protected boolean supportsLobParameters(){ return false; }
|
||||
protected void checkCompiled(){}
|
||||
protected void validateNamedParameters(Map<String, ? extends Object> p0){}
|
||||
protected void validateParameters(Object[] p0){}
|
||||
public JdbcTemplate getJdbcTemplate(){ return null; }
|
||||
public RdbmsOperation(){}
|
||||
public String getSql(){ return null; }
|
||||
public String[] getGeneratedKeysColumnNames(){ return null; }
|
||||
public boolean isCompiled(){ return false; }
|
||||
public boolean isReturnGeneratedKeys(){ return false; }
|
||||
public boolean isUpdatableResults(){ return false; }
|
||||
public final void compile(){}
|
||||
public int getResultSetType(){ return 0; }
|
||||
public void afterPropertiesSet(){}
|
||||
public void declareParameter(SqlParameter p0){}
|
||||
public void setDataSource(DataSource p0){}
|
||||
public void setFetchSize(int p0){}
|
||||
public void setGeneratedKeysColumnNames(String... p0){}
|
||||
public void setJdbcTemplate(JdbcTemplate p0){}
|
||||
public void setMaxRows(int p0){}
|
||||
public void setParameters(SqlParameter... p0){}
|
||||
public void setQueryTimeout(int p0){}
|
||||
public void setResultSetType(int p0){}
|
||||
public void setReturnGeneratedKeys(boolean p0){}
|
||||
public void setSql(String p0){}
|
||||
public void setTypes(int[] p0){}
|
||||
public void setUpdatableResults(boolean p0){}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user