Merge master into next.

Conflict in `cpp/ql/test/library-tests/sideEffects/functions/sideEffects.expected`,
resolved by accepting test output (combining changes).
This commit is contained in:
Aditya Sharad
2018-12-12 17:22:16 +00:00
345 changed files with 9800 additions and 2436 deletions

View File

@@ -109,7 +109,7 @@ class Location extends @location {
exists(@sourceline s | hasLocation(s, this) |
numlines(s, result, _, _)
or
(not numlines(s, _, _, _) and result = 0)
not numlines(s, _, _, _) and result = 0
)
}
@@ -118,7 +118,7 @@ class Location extends @location {
exists(@sourceline s | hasLocation(s, this) |
numlines(s, _, result, _)
or
(not numlines(s, _, _, _) and result = 0)
not numlines(s, _, _, _) and result = 0
)
}
@@ -127,7 +127,7 @@ class Location extends @location {
exists(@sourceline s | hasLocation(s, this) |
numlines(s, _, _, result)
or
(not numlines(s, _, _, _) and result = 0)
not numlines(s, _, _, _) and result = 0
)
}
@@ -169,5 +169,5 @@ cached
private predicate fixedHasLocation(Top l, Location loc, File f) {
hasSourceLocation(l, loc, f)
or
(hasLocation(l, loc) and not hasSourceLocation(l, _, _) and locations_default(loc, f, _, _, _, _))
hasLocation(l, loc) and not hasSourceLocation(l, _, _) and locations_default(loc, f, _, _, _, _)
}

View File

@@ -112,7 +112,7 @@ class Annotatable extends Element {
*/
predicate suppressesWarningsAbout(string category) {
exists(string withQuotes |
withQuotes = (getAnAnnotation().(SuppressWarningsAnnotation)).getASuppressedWarning()
withQuotes = getAnAnnotation().(SuppressWarningsAnnotation).getASuppressedWarning()
|
category = withQuotes.substring(1, withQuotes.length() - 1)
)

View File

@@ -51,15 +51,11 @@ private predicate hasChildElement(Element parent, Element e) {
or
enclInReftype(e, parent)
or
(
not (enclInReftype(e, _)) and
e.(Class).getCompilationUnit() = parent
)
not enclInReftype(e, _) and
e.(Class).getCompilationUnit() = parent
or
(
not (enclInReftype(e, _)) and
e.(Interface).getCompilationUnit() = parent
)
not enclInReftype(e, _) and
e.(Interface).getCompilationUnit() = parent
or
methods(e, _, _, _, parent, _)
or

View File

@@ -139,10 +139,8 @@ class CompileTimeConstantExpr extends Expr {
// the bitwise and logical operators `&`, `^`, and `|`,
// the conditional-and operator `&&` and the conditional-or operator `||`.
// These are precisely the operators represented by `BinaryExpr`.
(
this.(BinaryExpr).getLeftOperand().isCompileTimeConstant() and
this.(BinaryExpr).getRightOperand().isCompileTimeConstant()
)
this.(BinaryExpr).getLeftOperand().isCompileTimeConstant() and
this.(BinaryExpr).getRightOperand().isCompileTimeConstant()
or
// The ternary conditional operator ` ? : `.
exists(ConditionalExpr e | this = e |
@@ -252,17 +250,13 @@ class CompileTimeConstantExpr extends Expr {
if left != right then result = true else result = false
)
or
(
(b instanceof AndBitwiseExpr or b instanceof AndLogicalExpr) and
result = left.booleanAnd(right)
)
(b instanceof AndBitwiseExpr or b instanceof AndLogicalExpr) and
result = left.booleanAnd(right)
or
(
(b instanceof OrBitwiseExpr or b instanceof OrLogicalExpr) and
result = left.booleanOr(right)
)
(b instanceof OrBitwiseExpr or b instanceof OrLogicalExpr) and
result = left.booleanOr(right)
or
(b instanceof XorBitwiseExpr and result = left.booleanXor(right))
b instanceof XorBitwiseExpr and result = left.booleanXor(right)
)
or
// Handle binary expressions that have `String` operands and a boolean result.
@@ -342,7 +336,7 @@ class CompileTimeConstantExpr extends Expr {
or
result = this.(PlusExpr).getExpr().(CompileTimeConstantExpr).getIntValue()
or
result = -(this.(MinusExpr).getExpr().(CompileTimeConstantExpr).getIntValue())
result = -this.(MinusExpr).getExpr().(CompileTimeConstantExpr).getIntValue()
or
result = this.(BitNotExpr).getExpr().(CompileTimeConstantExpr).getIntValue().bitNot()
or
@@ -1189,12 +1183,7 @@ abstract class InstanceAccess extends Expr {
class ThisAccess extends InstanceAccess, @thisaccess {
/** Gets a printable representation of this expression. */
override string toString() {
if exists(this.getQualifier())
then (
result = this.getQualifier() + ".this"
) else (
result = "this"
)
if exists(this.getQualifier()) then result = this.getQualifier() + ".this" else result = "this"
}
}
@@ -1208,11 +1197,8 @@ class SuperAccess extends InstanceAccess, @superaccess {
/** Gets a printable representation of this expression. */
override string toString() {
if exists(this.getQualifier())
then (
result = this.getQualifier() + ".super"
) else (
result = "super"
)
then result = this.getQualifier() + ".super"
else result = "super"
}
}
@@ -1257,7 +1243,7 @@ class VarAccess extends Expr, @varaccess {
override string toString() {
result = this.getQualifier().toString() + "." + this.getVariable().getName()
or
(not this.hasQualifier() and result = this.getVariable().getName())
not this.hasQualifier() and result = this.getVariable().getName()
}
/**
@@ -1391,7 +1377,7 @@ class TypeAccess extends Expr, Annotatable, @typeaccess {
override string toString() {
result = this.getQualifier().toString() + "." + this.getType().toString()
or
(not this.hasQualifier() and result = this.getType().toString())
not this.hasQualifier() and result = this.getType().toString()
}
}

View File

@@ -56,11 +56,9 @@ class JMXRegistrationCall extends MethodAccess {
*/
class JMXRegistrationMethod extends Method {
JMXRegistrationMethod() {
(
// A direct registration with the `MBeanServer`.
getDeclaringType().hasQualifiedName("javax.management", "MBeanServer") and
getName() = "registerMBean"
)
// A direct registration with the `MBeanServer`.
getDeclaringType().hasQualifiedName("javax.management", "MBeanServer") and
getName() = "registerMBean"
or
// The `MBeanServer` is often wrapped by an application specific management class, so identify
// methods that wrap a call to another `JMXRegistrationMethod`.
@@ -75,12 +73,10 @@ class JMXRegistrationMethod extends Method {
* Gets the position of the parameter through which the "object" to be registered is passed.
*/
int getObjectPosition() {
(
// Passed as the first argument to `registerMBean`.
getDeclaringType().hasQualifiedName("javax.management", "MBeanServer") and
getName() = "registerMBean" and
result = 0
)
// Passed as the first argument to `registerMBean`.
getDeclaringType().hasQualifiedName("javax.management", "MBeanServer") and
getName() = "registerMBean" and
result = 0
or
// Identify the position in this method where the object parameter should be passed.
exists(JMXRegistrationCall c |

View File

@@ -74,7 +74,7 @@ class Callable extends StmtParent, Member, @callable {
}
private string descriptorUpTo(int n) {
(n = 0 and result = "")
n = 0 and result = ""
or
exists(Parameter p | p = this.getParameter(n - 1) |
result = descriptorUpTo(n - 1) + p.getType().getTypeDescriptor()

View File

@@ -129,10 +129,8 @@ private Type parameterForSubTypes(ParameterizedType type) {
// Must not be a catch-all.
not catchallType(arg)
|
(
// Simple case - this type is not a bounded type, so must represent exactly the `arg` class.
not arg instanceof BoundedType and result = arg
)
// Simple case - this type is not a bounded type, so must represent exactly the `arg` class.
not arg instanceof BoundedType and result = arg
or
exists(RefType upperBound |
// Upper bound case
@@ -173,7 +171,7 @@ Type inferClassParameterType(Expr expr) {
// We've been able to identify where this `Class` instance was created, and identified the
// particular class that was loaded.
result = pointsToReflectiveClassIdentifier(expr).getReflectivelyIdentifiedClass()
else (
else
// If we haven't been able to find where the value for this expression was defined, then we
// resort to the type `T` in `Class<T>`.
//
@@ -183,7 +181,6 @@ Type inferClassParameterType(Expr expr) {
// A "catch-all" type is something like `? extends Object` or `? extends Serialization`, which
// would return too many sub-types.
result = parameterForSubTypes(expr.getType())
)
)
}
@@ -290,12 +287,10 @@ class NewInstance extends MethodAccess {
exists(CastExpr cast | cast.getExpr() = this or cast.getExpr().(ParExpr).getExpr() = this |
result = cast.getType()
or
(
// If we cast the result of this method, then this is either the type specified, or a
// sub-type of that type. Make sure we exclude overly generic types such as `Object`.
not overlyGenericType(cast.getType()) and
hasSubtype*(cast.getType(), result)
)
// If we cast the result of this method, then this is either the type specified, or a
// sub-type of that type. Make sure we exclude overly generic types such as `Object`.
not overlyGenericType(cast.getType()) and
hasSubtype*(cast.getType(), result)
)
}
}

View File

@@ -118,7 +118,7 @@ class IfStmt extends ConditionalStmt, @ifstmt {
override string pp() {
result = "if (...) " + this.getThen().pp() + " else " + this.getElse().pp()
or
(not exists(this.getElse()) and result = "if (...) " + this.getThen().pp())
not exists(this.getElse()) and result = "if (...) " + this.getThen().pp()
}
/** This statement's Halstead ID (used to compute Halstead metrics). */
@@ -495,7 +495,7 @@ class ThrowStmt extends Stmt, @throwstmt {
private CatchClause catchClauseForThis(TryStmt try) {
result = try.getACatchClause() and
result.getEnclosingCallable() = this.getEnclosingCallable() and
(getExpr().getType().(RefType)).hasSupertype*(result.getVariable().getType().(RefType)) and
getExpr().getType().(RefType).hasSupertype*(result.getVariable().getType().(RefType)) and
not this.getParent+() = result
}
}
@@ -538,7 +538,7 @@ class JumpStmt extends Stmt {
Stmt getTarget() {
result = getLabelTarget()
or
(not exists(getLabelTarget()) and result = getEnclosingTarget())
not exists(getLabelTarget()) and result = getEnclosingTarget()
}
}

View File

@@ -20,21 +20,21 @@ import JDK
cached
predicate hasSubtype(RefType t, Type sub) {
// Direct subtype.
(extendsReftype(sub, t) and t != sub)
extendsReftype(sub, t) and t != sub
or
implInterface(sub, t)
or
// A parameterized type `T<A>` is a subtype of the corresponding raw type `T<>`.
(parSubtypeRaw(t, sub) and t != sub)
parSubtypeRaw(t, sub) and t != sub
or
// Array subtyping is covariant.
(arraySubtype(t, sub) and t != sub)
arraySubtype(t, sub) and t != sub
or
// Type parameter containment for parameterized types.
(parContainmentSubtype(t, sub) and t != sub)
parContainmentSubtype(t, sub) and t != sub
or
// Type variables are subtypes of their upper bounds.
(typeVarSubtypeBound(t, sub) and t != sub)
typeVarSubtypeBound(t, sub) and t != sub
}
private predicate typeVarSubtypeBound(RefType t, TypeVariable tv) {
@@ -825,21 +825,21 @@ class PrimitiveType extends Type, @primitive {
* Gets the JVM descriptor for this type, as used in bytecode.
*/
override string getTypeDescriptor() {
(this.hasName("float") and result = "F")
this.hasName("float") and result = "F"
or
(this.hasName("double") and result = "D")
this.hasName("double") and result = "D"
or
(this.hasName("int") and result = "I")
this.hasName("int") and result = "I"
or
(this.hasName("boolean") and result = "Z")
this.hasName("boolean") and result = "Z"
or
(this.hasName("short") and result = "S")
this.hasName("short") and result = "S"
or
(this.hasName("byte") and result = "B")
this.hasName("byte") and result = "B"
or
(this.hasName("char") and result = "C")
this.hasName("char") and result = "C"
or
(this.hasName("long") and result = "J")
this.hasName("long") and result = "J"
}
/**
@@ -896,21 +896,21 @@ class BoxedType extends RefType {
/** Gets the primitive type corresponding to this boxed type. */
PrimitiveType getPrimitiveType() {
(this.hasName("Float") and result.hasName("float"))
this.hasName("Float") and result.hasName("float")
or
(this.hasName("Double") and result.hasName("double"))
this.hasName("Double") and result.hasName("double")
or
(this.hasName("Integer") and result.hasName("int"))
this.hasName("Integer") and result.hasName("int")
or
(this.hasName("Boolean") and result.hasName("boolean"))
this.hasName("Boolean") and result.hasName("boolean")
or
(this.hasName("Short") and result.hasName("short"))
this.hasName("Short") and result.hasName("short")
or
(this.hasName("Byte") and result.hasName("byte"))
this.hasName("Byte") and result.hasName("byte")
or
(this.hasName("Character") and result.hasName("char"))
this.hasName("Character") and result.hasName("char")
or
(this.hasName("Long") and result.hasName("long"))
this.hasName("Long") and result.hasName("long")
}
}

View File

@@ -7,46 +7,46 @@ class OrdPrimitiveType extends PrimitiveType {
predicate widerThanOrEqualTo(OrdPrimitiveType that) { getWidthRank() >= that.getWidthRank() }
OrdPrimitiveType maxType(OrdPrimitiveType that) {
(this.widerThan(that) and result = this)
this.widerThan(that) and result = this
or
(not this.widerThan(that) and result = that)
not this.widerThan(that) and result = that
}
int getWidthRank() {
(this.getName() = "byte" and result = 1)
this.getName() = "byte" and result = 1
or
(this.getName() = "short" and result = 2)
this.getName() = "short" and result = 2
or
(this.getName() = "int" and result = 3)
this.getName() = "int" and result = 3
or
(this.getName() = "long" and result = 4)
this.getName() = "long" and result = 4
or
(this.getName() = "float" and result = 5)
this.getName() = "float" and result = 5
or
(this.getName() = "double" and result = 6)
this.getName() = "double" and result = 6
}
float getMaxValue() {
(this.getName() = "byte" and result = 127.0)
this.getName() = "byte" and result = 127.0
or
(this.getName() = "short" and result = 32767.0)
this.getName() = "short" and result = 32767.0
or
(this.getName() = "int" and result = 2147483647.0)
this.getName() = "int" and result = 2147483647.0
or
// Long.MAX_VALUE is 9223372036854775807 but floating point only has 53 bits of precision.
(this.getName() = "long" and result = 9223372036854776000.0)
this.getName() = "long" and result = 9223372036854776000.0
// don't try for floats and doubles
}
float getMinValue() {
(this.getName() = "byte" and result = -128.0)
this.getName() = "byte" and result = -128.0
or
(this.getName() = "short" and result = -32768.0)
this.getName() = "short" and result = -32768.0
or
(this.getName() = "int" and result = -2147483648.0)
this.getName() = "int" and result = -2147483648.0
or
// Long.MIN_VALUE is -9223372036854775808 but floating point only has 53 bits of precision.
(this.getName() = "long" and result = -9223372036854776000.0)
this.getName() = "long" and result = -9223372036854776000.0
// don't try for floats and doubles
}
}
@@ -59,9 +59,9 @@ class NumType extends Type {
/** Gets the width-ordered primitive type corresponding to this type. */
OrdPrimitiveType getOrdPrimitiveType() {
(this instanceof PrimitiveType and result = this)
this instanceof PrimitiveType and result = this
or
(this instanceof BoxedType and result = this.(BoxedType).getPrimitiveType())
this instanceof BoxedType and result = this.(BoxedType).getPrimitiveType()
}
predicate widerThan(NumType that) {

View File

@@ -25,10 +25,8 @@ class ConstantField extends Field {
fa.getEnclosingCallable() instanceof InstanceInitializer
or
// It can be defined in the constructor if there is only one constructor.
(
fa.getEnclosingCallable() instanceof Constructor and
count(getDeclaringType().getAConstructor()) = 1
)
fa.getEnclosingCallable() instanceof Constructor and
count(getDeclaringType().getAConstructor()) = 1
)
)
}
@@ -93,10 +91,8 @@ class ConstantExpr extends Expr {
exists(this.(FieldRead).getField().(ConstantField).getConstantValue())
or
// A binary expression where both sides are constant
(
this.(BinaryExpr).getLeftOperand() instanceof ConstantExpr and
this.(BinaryExpr).getRightOperand() instanceof ConstantExpr
)
this.(BinaryExpr).getLeftOperand() instanceof ConstantExpr and
this.(BinaryExpr).getRightOperand() instanceof ConstantExpr
or
this.(ParExpr).getExpr() instanceof ConstantExpr
)
@@ -179,7 +175,7 @@ class ConstSwitchStmt extends SwitchStmt {
SwitchCase getMatchingCase() {
// Must be a value we can deduce
exists(getExpr().(ConstantExpr).getIntValue()) and
if (exists(getMatchingConstCase()))
if exists(getMatchingConstCase())
then result = getMatchingConstCase()
else result = getDefaultCase()
}
@@ -216,14 +212,12 @@ class UnreachableBasicBlock extends BasicBlock {
or
// This block is not reachable in the CFG, and is not a callable, a body of a callable, an
// expression in an annotation, an expression in an assert statement, or a catch clause.
(
forall(BasicBlock bb | bb = getABBPredecessor() | bb instanceof UnreachableBasicBlock) and
not exists(Callable c | c.getBody() = this) and
not this instanceof Callable and
not exists(Annotation a | a.getAChildExpr*() = this) and
not exists(AssertStmt a | a = this.(Expr).getEnclosingStmt()) and
not this instanceof CatchClause
)
forall(BasicBlock bb | bb = getABBPredecessor() | bb instanceof UnreachableBasicBlock) and
not exists(Callable c | c.getBody() = this) and
not this instanceof Callable and
not exists(Annotation a | a.getAChildExpr*() = this) and
not exists(AssertStmt a | a = this.(Expr).getEnclosingStmt()) and
not this instanceof CatchClause
or
// Switch statements with a constant comparison expression may have unreachable cases.
exists(ConstSwitchStmt constSwitchStmt, BasicBlock failingCaseBlock |

View File

@@ -94,6 +94,34 @@ Expr clearlyNotNullExpr() { result = clearlyNotNullExpr(_) }
/** Holds if `v` is an SSA variable that is provably not `null`. */
predicate clearlyNotNull(SsaVariable v) { clearlyNotNull(v, _) }
/**
* Holds if the evaluation of a call to `m` resulting in the value `branch`
* implies that the argument to the call is guaranteed to be null if `isnull`
* is true, and non-null if `isnull` is false.
*/
predicate nullCheckMethod(Method m, boolean branch, boolean isnull) {
exists(boolean polarity |
m.getDeclaringType().hasQualifiedName("java.util", "Objects") and
(
m.hasName("isNull") and polarity = true
or
m.hasName("nonNull") and polarity = false
) and
(
branch = true and isnull = polarity
or
branch = false and isnull = polarity.booleanNot()
)
)
or
m instanceof EqualsMethod and branch = true and isnull = false
or
m.getDeclaringType().hasQualifiedName("org.apache.commons.lang3", "StringUtils") and
m.hasName("isBlank") and
branch = false and
isnull = false
}
/**
* Gets an expression that directly tests whether a given expression, `e`, is null or not.
*
@@ -114,29 +142,10 @@ Expr basicNullGuard(Expr e, boolean branch, boolean isnull) {
or
result.(InstanceOfExpr).getExpr() = e and branch = true and isnull = false
or
exists(MethodAccess call, Method m, boolean polarity |
call = result and
call.getAnArgument() = e and
call.getMethod() = m and
m.getDeclaringType().hasQualifiedName("java.util", "Objects") and
(
m.hasName("isNull") and polarity = true
or
m.hasName("nonNull") and polarity = false
) and
(
branch = true and isnull = polarity
or
branch = false and isnull = polarity.booleanNot()
)
)
or
exists(MethodAccess call |
call = result and
call.getAnArgument() = e and
call.getMethod() instanceof EqualsMethod and
branch = true and
isnull = false
nullCheckMethod(call.getMethod(), branch, isnull)
)
or
exists(EqualityTest eqtest |

View File

@@ -336,11 +336,11 @@ private predicate nullVarStep(
not exists(boolean branch | nullGuard(midssa, branch, false).hasBranchEdge(mid, bb, branch)) and
not (leavingFinally(mid, bb, true) and midstoredcompletion = true) and
if bb.getFirstNode() = any(TryStmt try | | try.getFinally())
then (
then
if bb.getFirstNode() = mid.getLastNode().getANormalSuccessor()
then storedcompletion = false
else storedcompletion = true
) else
else
if leavingFinally(mid, bb, _)
then storedcompletion = false
else storedcompletion = midstoredcompletion

View File

@@ -232,11 +232,11 @@ private Guard boundFlowCond(SsaVariable v, Expr e, int delta, boolean upper, boo
) and
(
if v.getSourceVariable().getType() instanceof IntegralType
then (
then
upper = true and strengthen = -1
or
upper = false and strengthen = 1
) else strengthen = 0
else strengthen = 0
) and
(
exists(int k | modulusComparison(comp, testIsTrue, k) and d2 = strengthen * k)
@@ -402,17 +402,14 @@ private predicate boundFlowStep(Expr e2, Expr e1, int delta, boolean upper) {
not x instanceof ConstantIntegerExpr and
not e1 instanceof ConstantIntegerExpr and
if strictlyPositive(x)
then (
upper = false and delta = 1
) else
then upper = false and delta = 1
else
if positive(x)
then (
upper = false and delta = 0
) else
then upper = false and delta = 0
else
if strictlyNegative(x)
then (
upper = true and delta = -1
) else if negative(x) then (upper = true and delta = 0) else none()
then upper = true and delta = -1
else if negative(x) then upper = true and delta = 0 else none()
)
or
exists(Expr x |
@@ -431,17 +428,14 @@ private predicate boundFlowStep(Expr e2, Expr e1, int delta, boolean upper) {
// `x instanceof ConstantIntegerExpr` is covered by valueFlowStep
not x instanceof ConstantIntegerExpr and
if strictlyPositive(x)
then (
upper = true and delta = -1
) else
then upper = true and delta = -1
else
if positive(x)
then (
upper = true and delta = 0
) else
then upper = true and delta = 0
else
if strictlyNegative(x)
then (
upper = false and delta = 1
) else if negative(x) then (upper = false and delta = 0) else none()
then upper = false and delta = 1
else if negative(x) then upper = false and delta = 0 else none()
)
or
e2.(RemExpr).getRightOperand() = e1 and positive(e1) and delta = -1 and upper = true

View File

@@ -18,35 +18,29 @@ predicate isLive(Callable c) {
* would imply the liveness of `c`.
*/
Callable possibleLivenessCause(Callable c, string reason) {
(
c.(Method).overridesOrInstantiates(result.(Method)) and
reason = "is overridden or instantiated by"
)
c.(Method).overridesOrInstantiates(result.(Method)) and
reason = "is overridden or instantiated by"
or
(result.calls(c) and reason = "calls")
result.calls(c) and reason = "calls"
or
(result.callsConstructor(c.(Constructor)) and reason = "calls constructor")
result.callsConstructor(c.(Constructor)) and reason = "calls constructor"
or
exists(ClassInstanceExpr e | e.getEnclosingCallable() = result |
e.getConstructor() = c and reason = "constructs"
)
or
(c = result.getSourceDeclaration() and c != result and reason = "instantiates")
c = result.getSourceDeclaration() and c != result and reason = "instantiates"
or
(
c.hasName("<clinit>") and
reason = "class initialization" and
exists(RefType clintedType | c = clintedType.getASupertype*().getACallable() |
result.getDeclaringType() = clintedType or
result.getAnAccessedField().getDeclaringType() = clintedType
)
c.hasName("<clinit>") and
reason = "class initialization" and
exists(RefType clintedType | c = clintedType.getASupertype*().getACallable() |
result.getDeclaringType() = clintedType or
result.getAnAccessedField().getDeclaringType() = clintedType
)
or
(
c.hasName("<obinit>") and
reason = "object initialization" and
result = c.getDeclaringType().getAConstructor()
)
c.hasName("<obinit>") and
reason = "object initialization" and
result = c.getDeclaringType().getAConstructor()
}
Callable possibleLivenessCause(Callable c) { result = possibleLivenessCause(c, _) }
@@ -91,7 +85,7 @@ class SuppressedConstructor extends Constructor {
isPrivate()
or
// A protected, suppressed constructor only makes sense in a non-abstract class.
(isProtected() and not getDeclaringType().isAbstract())
isProtected() and not getDeclaringType().isAbstract()
) and
// Must be no-arg in order to replace the compiler generated default constructor.
getNumberOfParameters() = 0 and
@@ -167,13 +161,11 @@ class LiveClass extends SourceClassOrInterface {
not f instanceof SerialVersionUIDField
)
or
(
// If this is a namespace class, it is live if there is at least one live nested class.
// The definition of `NamespaceClass` is such, that the nested classes must all be static.
// Static methods are handled above.
this instanceof NamespaceClass and
exists(NestedType r | r.getEnclosingType() = this | r instanceof LiveClass)
)
// If this is a namespace class, it is live if there is at least one live nested class.
// The definition of `NamespaceClass` is such, that the nested classes must all be static.
// Static methods are handled above.
this instanceof NamespaceClass and
exists(NestedType r | r.getEnclosingType() = this | r instanceof LiveClass)
or
// An annotation on the class is reflectively accessed.
exists(ReflectiveAnnotationAccess reflectiveAnnotationAccess |
@@ -298,10 +290,8 @@ class RootdefCallable extends Callable {
// Abstract, native and interface methods obviously won't access their own
// parameters, so don't flag unless we can see an overriding method with
// a body that also doesn't.
(
not hasUsefulBody(this) and
not exists(Method m | hasUsefulBody(m) | m.overridesOrInstantiates+(this))
)
not hasUsefulBody(this) and
not exists(Method m | hasUsefulBody(m) | m.overridesOrInstantiates+(this))
}
}

View File

@@ -22,10 +22,8 @@ class Struts1ActionEntryPoint extends EntryPoint, Class {
result.(Method).overrides(methodFromAction)
)
or
(
this.getASupertype*().hasQualifiedName("org.apache.struts.actions", "DispatchAction") and
result.(Method).isPublic()
)
this.getASupertype*().hasQualifiedName("org.apache.struts.actions", "DispatchAction") and
result.(Method).isPublic()
or
result.(Constructor).getNumberOfParameters() = 0
)

View File

@@ -10,11 +10,9 @@ import semmle.code.java.UnitTests
*/
class TestMethodEntry extends CallableEntryPoint {
TestMethodEntry() {
(
this instanceof TestMethod and
// Ignored tests are not run
not this instanceof JUnitIgnoredMethod
)
this instanceof TestMethod and
// Ignored tests are not run
not this instanceof JUnitIgnoredMethod
or
this instanceof JUnit3TestSuite
or

View File

@@ -62,7 +62,7 @@ class JaxbType extends Class {
* Gets the `XmlAccessType` associated with this class.
*/
XmlAccessType getXmlAccessType() {
if (exists(getDeclaredAccessType()))
if exists(getDeclaredAccessType())
then result = getDeclaredAccessType()
else
// Default access type, if not specified.
@@ -136,7 +136,7 @@ class JaxbBoundField extends Field {
type.getXmlAccessType().isField()
or
// Only public fields are automatically bound in this access type.
(type.getXmlAccessType().isPublicMember() and isPublic())
type.getXmlAccessType().isPublicMember() and isPublic()
)
)
}
@@ -192,7 +192,7 @@ class JaxbBoundGetterSetter extends GetterOrSetterMethod {
isProperty() and
(
// In the `PUBLIC_MEMBER` case all public properties are considered bound.
(c.getXmlAccessType().isPublicMember() and isPublic())
c.getXmlAccessType().isPublicMember() and isPublic()
or
// In "property" all properties are considered bound.
c.getXmlAccessType().isProperty()

View File

@@ -15,11 +15,9 @@ class JaxWsEndpoint extends Class {
Callable getARemoteMethod() {
result = this.getACallable() and
(
exists(AnnotationType a | a = result.getAnAnnotation().getType() |
a.hasName("WebMethod") or
a.hasName("WebEndpoint")
)
exists(AnnotationType a | a = result.getAnAnnotation().getType() |
a.hasName("WebMethod") or
a.hasName("WebEndpoint")
)
}
}

View File

@@ -222,24 +222,20 @@ class MockitoInjectedField extends MockitoAnnotatedField {
else
if usingPropertyInjection()
then
(
// We will call the no-arg constructor if the field wasn't initialized.
not exists(getInitializer()) and
result = mockInjectedClass.getNoArgsConstructor()
)
// We will call the no-arg constructor if the field wasn't initialized.
not exists(getInitializer()) and
result = mockInjectedClass.getNoArgsConstructor()
or
(
// Perform property injection into setter fields, but only where there exists a mock
// that can be injected into the method. Otherwise, the setter method is never called.
result = mockInjectedClass.getASetterMethod() and
exists(MockitoMockedField mockedField |
mockedField.getDeclaringType() = this.getDeclaringType() and
mockedField.isValid()
|
// We make a simplifying assumption here - in theory, each mock can only be injected
// once, but we instead assume that there are sufficient mocks to go around.
mockedField.getType().(RefType).getAnAncestor() = result.getParameterType(0)
)
// Perform property injection into setter fields, but only where there exists a mock
// that can be injected into the method. Otherwise, the setter method is never called.
result = mockInjectedClass.getASetterMethod() and
exists(MockitoMockedField mockedField |
mockedField.getDeclaringType() = this.getDeclaringType() and
mockedField.isValid()
|
// We make a simplifying assumption here - in theory, each mock can only be injected
// once, but we instead assume that there are sufficient mocks to go around.
mockedField.getType().(RefType).getAnAncestor() = result.getParameterType(0)
)
else
// There's no instance, and no no-arg constructor we can call, so injection fails.

View File

@@ -30,10 +30,8 @@ class SafeSnakeYamlConstruction extends ClassInstanceExpr {
SafeSnakeYamlConstruction() {
this.getConstructedType() instanceof SnakeYamlSafeConstructor
or
(
this.getConstructedType() instanceof SnakeYamlConstructor and
this.getNumArgument() > 0
)
this.getConstructedType() instanceof SnakeYamlConstructor and
this.getNumArgument() > 0
}
}

View File

@@ -35,10 +35,8 @@ class GwtEntryPointClass extends Class {
// are live.
isGwtXmlIncluded()
implies
(
// The entry point is live if it is specified in a `*.gwt.xml` file.
exists(getAGwtXmlFile())
)
// The entry point is live if it is specified in a `*.gwt.xml` file.
exists(getAGwtXmlFile())
}
}

View File

@@ -39,7 +39,7 @@ class GwtXmlFile extends XMLFile {
* Either the default `client` folder or as specified by `<source>` tags.
*/
string getASourceSubPath() {
(result = "client" and not exists(getAnExplicitSourceSubPath()))
result = "client" and not exists(getAnExplicitSourceSubPath())
or
result = getAnExplicitSourceSubPath()
}

View File

@@ -68,7 +68,7 @@ class SessionEJB extends EJB {
/** Any remote interfaces of this EJB. */
LegacyEjbRemoteInterface getARemoteInterface() {
(result = this.getASupertype() and result instanceof ExtendedRemoteInterface)
result = this.getASupertype() and result instanceof ExtendedRemoteInterface
or
exists(AnnotatedRemoteHomeInterface i | i.getAnEJB() = this |
result = i.getAnAssociatedRemoteInterface()
@@ -79,7 +79,7 @@ class SessionEJB extends EJB {
/** Any remote home interfaces of this EJB. */
LegacyEjbRemoteHomeInterface getARemoteHomeInterface() {
(result = this.getASupertype() and result instanceof ExtendedRemoteHomeInterface)
result = this.getASupertype() and result instanceof ExtendedRemoteHomeInterface
or
result.(AnnotatedRemoteHomeInterface).getAnEJB() = this
or
@@ -88,7 +88,7 @@ class SessionEJB extends EJB {
/** Any local interfaces of this EJB. */
LegacyEjbLocalInterface getALocalInterface() {
(result = this.getASupertype() and result instanceof ExtendedLocalInterface)
result = this.getASupertype() and result instanceof ExtendedLocalInterface
or
exists(AnnotatedLocalHomeInterface i | i.getAnEJB() = this |
result = i.getAnAssociatedLocalInterface()
@@ -99,7 +99,7 @@ class SessionEJB extends EJB {
/** Any local home interfaces of this EJB. */
LegacyEjbLocalHomeInterface getALocalHomeInterface() {
(result = this.getASupertype() and result instanceof ExtendedLocalHomeInterface)
result = this.getASupertype() and result instanceof ExtendedLocalHomeInterface
or
result.(AnnotatedLocalHomeInterface).getAnEJB() = this
or
@@ -898,10 +898,8 @@ TransactionAttributeAnnotation getInnermostTransactionAttributeAnnotation(Method
or
// ...or if the declaring class has such an annotation, the annotation applies to
// any method declared within the class that does not itself have such an annotation.
(
not exists(m.getAnAnnotation().(TransactionAttributeAnnotation)) and
result = m.getDeclaringType().getSourceDeclaration().getAnAnnotation()
)
not exists(m.getAnAnnotation().(TransactionAttributeAnnotation)) and
result = m.getDeclaringType().getSourceDeclaration().getAnAnnotation()
}
/*

View File

@@ -78,30 +78,24 @@ class SpringBeanXMLAutowiredSetterMethod extends Method {
exists(string xmlAutowire |
xmlAutowire = this.getDeclaringType().(SpringBeanRefType).getSpringBean().getAutowire()
|
(
xmlAutowire = "byName" and
// There is a bean whose name is the same as this setter method.
this.getName().toLowerCase() = "set" + result.getBeanIdentifier().toLowerCase()
)
xmlAutowire = "byName" and
// There is a bean whose name is the same as this setter method.
this.getName().toLowerCase() = "set" + result.getBeanIdentifier().toLowerCase()
or
(
(
xmlAutowire = "byType"
or
(
// When it is set to autodetect, we use "byType" if there is a no-arg constructor. This
// approach has been removed in Spring 4.x.
xmlAutowire = "autodetect" and
exists(Constructor c | c = this.getDeclaringType().getAConstructor() |
c.getNumberOfParameters() = 0
)
)
) and
// The resulting bean is of the right type.
result.getClass().getAnAncestor() = getParameter(0).getType() and
getNumberOfParameters() = 1 and
this.getName().matches("set%")
)
xmlAutowire = "byType"
or
// When it is set to autodetect, we use "byType" if there is a no-arg constructor. This
// approach has been removed in Spring 4.x.
xmlAutowire = "autodetect" and
exists(Constructor c | c = this.getDeclaringType().getAConstructor() |
c.getNumberOfParameters() = 0
)
) and
// The resulting bean is of the right type.
result.getClass().getAnAncestor() = getParameter(0).getType() and
getNumberOfParameters() = 1 and
this.getName().matches("set%")
)
}
}
@@ -166,17 +160,17 @@ class SpringBeanAutowiredCallable extends Callable {
result = getQualifier(pos).getSpringBean()
else
if exists(getQualifier()) and getNumberOfParameters() = 1
then (
then
// Resolved by `@Qualifier("qualifier")` on the method
pos = 0 and
result = getQualifier().getSpringBean()
) else
else
if exists(getResource().getNameValue()) and getNumberOfParameters() = 1
then (
then
// Resolved by looking at the name part of `@Resource(name="qualifier")`
pos = 0 and
result = getResource().getSpringBean()
) else
else
// Otherwise no restrictions, just by type
any()
}
@@ -195,17 +189,17 @@ class SpringBeanAutowiredCallable extends Callable {
result = getQualifier(pos).getSpringComponent()
else
if exists(getQualifier()) and getNumberOfParameters() = 1
then (
then
// Resolved by `@Qualifier("qualifier")` on the method
pos = 0 and
result = getQualifier().getSpringComponent()
) else
else
if exists(getResource().getNameValue()) and getNumberOfParameters() = 1
then (
then
// Resolved by looking at the name part of `@Resource(name="qualifier")`
pos = 0 and
result = getResource().getSpringComponent()
) else
else
// Otherwise no restrictions, just by type
any()
}

View File

@@ -279,11 +279,9 @@ class SpringBean extends SpringXMLElement {
/** Any `<property>` elements inherited from parent beans. */
SpringProperty getAnInheritedProperty() {
(
not exists(SpringProperty thisProperty |
thisProperty = this.getADeclaredProperty() and
result.getPropertyName() = thisProperty.getPropertyName()
)
not exists(SpringProperty thisProperty |
thisProperty = this.getADeclaredProperty() and
result.getPropertyName() = thisProperty.getPropertyName()
) and
(
result = this.getBeanParent().getADeclaredProperty() or
@@ -305,11 +303,9 @@ class SpringBean extends SpringXMLElement {
/** Gets a `<constructor-arg>` element inherited from the parent bean. */
SpringConstructorArg getAnInheritedConstructorArg() {
(
not exists(SpringConstructorArg thisArg |
thisArg = this.getADeclaredConstructorArg() and
thisArg.conflictsWithArg(result)
)
not exists(SpringConstructorArg thisArg |
thisArg = this.getADeclaredConstructorArg() and
thisArg.conflictsWithArg(result)
) and
(
result = this.getBeanParent().getADeclaredConstructorArg() or
@@ -331,11 +327,9 @@ class SpringBean extends SpringXMLElement {
/** Gets a `<lookup-method>` element inherited from the parent bean. */
SpringLookupMethod getAnInheritedLookupMethod() {
(
not exists(SpringLookupMethod thisMethod |
thisMethod = this.getADeclaredLookupMethod() and
thisMethod.getMethodName() = result.getMethodName()
)
not exists(SpringLookupMethod thisMethod |
thisMethod = this.getADeclaredLookupMethod() and
thisMethod.getMethodName() = result.getMethodName()
) and
(
result = this.getBeanParent().getADeclaredLookupMethod() or
@@ -357,11 +351,9 @@ class SpringBean extends SpringXMLElement {
/** Gets a `<replaced-method>` element inherited from the parent bean. */
SpringReplacedMethod getAnInheritedReplacedMethod() {
(
not exists(SpringReplacedMethod thisMethod |
thisMethod = this.getADeclaredReplacedMethod() and
thisMethod.getMethodName() = result.getMethodName()
)
not exists(SpringReplacedMethod thisMethod |
thisMethod = this.getADeclaredReplacedMethod() and
thisMethod.getMethodName() = result.getMethodName()
) and
(
result = this.getBeanParent().getADeclaredReplacedMethod() or

View File

@@ -178,15 +178,13 @@ class SpringComponent extends RefType {
// package.
not isSpringXMLEnabled()
or
exists(SpringBasePackage sbp |
this.getPackage().getName().prefix(sbp.length() + 1) = sbp + "." or
this.getPackage().getName() = sbp
) and
(
exists(SpringBasePackage sbp |
this.getPackage().getName().prefix(sbp.length() + 1) = sbp + "." or
this.getPackage().getName() = sbp
) and
(
not exists(getAProfileExpr()) or
getAProfileExpr().(SpringProfileExpr).isActive()
)
not exists(getAProfileExpr()) or
getAProfileExpr().(SpringProfileExpr).isActive()
)
}

View File

@@ -44,13 +44,11 @@ class SpringRemotingDestinationClass extends Class {
this = remotingDestination.getSpringBean().getClass()
)
or
hasAnnotation("org.springframework.flex.remoting", "RemotingDestination") and
// Must either be a live bean, or a live component.
(
hasAnnotation("org.springframework.flex.remoting", "RemotingDestination") and
// Must either be a live bean, or a live component.
(
this.(SpringComponent).isLive() or
this instanceof SpringBeanRefType
)
this.(SpringComponent).isLive() or
this instanceof SpringBeanRefType
)
}

View File

@@ -14,12 +14,10 @@ private string getStrutsMapperClass(RefType refType) {
*/
class Struts2ActionClass extends Class {
Struts2ActionClass() {
(
// If there are no XML files present, then we assume we any class that extends a struts 2
// action must be reflectively constructed, as we have no better indication.
not exists(XMLFile xmlFile) and
this.getAnAncestor().hasQualifiedName("com.opensymphony.xwork2", "Action")
)
// If there are no XML files present, then we assume we any class that extends a struts 2
// action must be reflectively constructed, as we have no better indication.
not exists(XMLFile xmlFile) and
this.getAnAncestor().hasQualifiedName("com.opensymphony.xwork2", "Action")
or
// If there is a struts.xml file, then any class that is specified as an action is considered
// to be reflectively constructed.
@@ -37,7 +35,7 @@ class Struts2ActionClass extends Class {
if
getStrutsMapperClass(this) = "org.apache.struts2.dispatcher.mapper.Restful2ActionMapper" or
getStrutsMapperClass(this) = "org.apache.struts2.dispatcher.mapper.RestfulActionMapper"
then (
then
// The "Restful" action mapper maps rest APIs to specific methods
result.hasName("index") or
result.hasName("create") or
@@ -45,11 +43,11 @@ class Struts2ActionClass extends Class {
result.hasName("view") or
result.hasName("remove") or
result.hasName("update")
) else
else
if
getStrutsMapperClass(this) = "org.apache.struts2.rest.RestActionMapper" or
getStrutsMapperClass(this) = "rest"
then (
then
// The "Rest" action mapper is provided with the rest plugin, and maps rest APIs to specific
// methods based on a "ruby-on-rails" style.
result.hasName("index") or
@@ -59,7 +57,7 @@ class Struts2ActionClass extends Class {
result.hasName("create") or
result.hasName("update") or
result.hasName("destroy")
) else
else
if exists(getStrutsMapperClass(this))
then
// Any method could be live, as this is a custom mapper
@@ -73,14 +71,12 @@ class Struts2ActionClass extends Class {
or
result = this.(Struts2ConventionActionClass).getAnActionMethod()
or
// In the fall-back case, use both the "execute" and any annotated methods
not exists(XMLFile xmlFile) and
(
// In the fall-back case, use both the "execute" and any annotated methods
not exists(XMLFile xmlFile) and
(
result.hasName("executes") or
exists(StrutsActionAnnotation actionAnnotation |
result = actionAnnotation.getActionCallable()
)
result.hasName("executes") or
exists(StrutsActionAnnotation actionAnnotation |
result = actionAnnotation.getActionCallable()
)
)
)

View File

@@ -142,7 +142,7 @@ private string escapeForMatch(string s) { result = s.replaceAll("%", "\\%").repl
*/
bindingset[matches, wildcardstring]
private predicate strutsWildcardMatching(string matches, string wildcardstring) {
if (wildcardstring.matches("%{%}%"))
if wildcardstring.matches("%{%}%")
then matches.matches(escapeForMatch(wildcardstring).regexpReplaceAll("\\{[0-9]\\}", "%"))
else matches = wildcardstring
}
@@ -169,7 +169,7 @@ class StrutsXMLAction extends StrutsXMLElement {
*/
Method getActionMethod() {
getActionClass().inherits(result) and
if (exists(getMethodName()))
if exists(getMethodName())
then strutsWildcardMatching(result.getName(), getMethodName())
else result.hasName("execute")
}

View File

@@ -41,20 +41,16 @@ class MetricElement extends Element {
*/
int getALevel() {
this.fromSource() and
not (this.getADependencySrc+() = this) and
not this.getADependencySrc+() = this and
(
(
not (exists(MetricElement t | t = this.getADependency())) and
result = 0
)
not exists(MetricElement t | t = this.getADependency()) and
result = 0
or
(
not (this.getADependency().fromSource()) and
exists(MetricElement e | this.getADependency() = e) and
result = 1
)
not this.getADependency().fromSource() and
exists(MetricElement e | this.getADependency() = e) and
result = 1
or
(result = this.getADependency().getALevel() + 1)
result = this.getADependency().getALevel() + 1
)
}

View File

@@ -61,8 +61,8 @@ class MetricPackage extends Package, MetricElement {
*/
int getNumberOfPublicCallables() {
result = sum(MetricRefType t, int toSum |
(t.getPackage() = this) and
(toSum = t.getNumberOfPublicCallables())
t.getPackage() = this and
toSum = t.getNumberOfPublicCallables()
|
toSum
)
@@ -138,7 +138,7 @@ class MetricPackage extends Package, MetricElement {
ecoupling = this.getEfferentCoupling() and
sumcoupling = ecoupling + this.getAfferentCoupling() and
sumcoupling > 0 and
result = ecoupling / (sumcoupling.(float))
result = ecoupling / sumcoupling.(float)
)
}
@@ -164,7 +164,7 @@ class MetricPackage extends Package, MetricElement {
exists(int i, int j |
i = count(RefType t | t.getPackage() = this) and
j = count(RefType t | t.getPackage() = this and t.isAbstract()) and
result = j / (i.(float)) and
result = j / i.(float) and
i > 0
)
}
@@ -221,8 +221,8 @@ class MetricPackage extends Package, MetricElement {
float relationalCohesion() {
result = 1 +
avg(RefType t, float toAvg |
(t.getPackage() = this) and
(toAvg = this.countDependencies(t))
t.getPackage() = this and
toAvg = this.countDependencies(t)
|
toAvg
)
@@ -265,8 +265,8 @@ class MetricPackage extends Package, MetricElement {
*/
predicate isRepresentative() {
this.getName() = min(MetricPackage p, string toMin |
(p = this.getACycleMember()) and
(toMin = p.getName())
p = this.getACycleMember() and
toMin = p.getName()
|
toMin
)
@@ -280,7 +280,7 @@ class MetricPackage extends Package, MetricElement {
float getAverageFanIn() {
result = avg(RefType t, MetricCallable c, int toAvg |
(c = t.getACallable() and t.getPackage() = this) and
(toAvg = c.getAfferentCoupling())
toAvg = c.getAfferentCoupling()
|
toAvg
)

View File

@@ -198,18 +198,18 @@ class MetricRefType extends RefType, MetricElement {
// is `C`, is `(C - 1) * C`.
n = (((callables - 1) * callables) - (2 * linked)) / 2.0 and
(
(n < 0 and result = 0)
n < 0 and result = 0
or
(n >= 0 and result = n)
n >= 0 and result = n
)
)
}
/** Gets the length of _some_ path to the root of the hierarchy. */
int getADepth() {
(this.hasQualifiedName("java.lang", "Object") and result = 0)
this.hasQualifiedName("java.lang", "Object") and result = 0
or
(not cyclic() and result = this.getASupertype().(MetricRefType).getADepth() + 1)
not cyclic() and result = this.getASupertype().(MetricRefType).getADepth() + 1
}
/**
@@ -229,9 +229,9 @@ class MetricRefType extends RefType, MetricElement {
/** Gets the length of _some_ path to the specified reference type. */
int getADepth(RefType reference) {
(this = reference and result = 0)
this = reference and result = 0
or
(not cyclic() and result = this.getASupertype().(MetricRefType).getADepth(reference) + 1)
not cyclic() and result = this.getASupertype().(MetricRefType).getADepth(reference) + 1
}
private predicate cyclic() { getASupertype+() = this }
@@ -278,9 +278,9 @@ class MetricRefType extends RefType, MetricElement {
this.getAMethod() = result and
exists(Method c |
result.overrides(c) and
not (c.isAbstract())
not c.isAbstract()
) and
not (this.ignoreOverride(result))
not this.ignoreOverride(result)
}
/** Gets the number of methods that are overridden by this class. */
@@ -297,14 +297,14 @@ class MetricRefType extends RefType, MetricElement {
float getSpecialisationIndex() {
this.getNumberOfCallables() != 0 and
result = (this.getNumberOverridden() * this.getInheritanceDepth()) /
(this.getNumberOfCallables().(float))
this.getNumberOfCallables().(float)
}
/** Gets the Halstead length of a type, estimated as the sum of the Halstead lengths of its callables. */
override int getHalsteadLength() {
result = sum(Callable c, int toSum |
(c = this.getACallable()) and
(toSum = c.getMetrics().getHalsteadLength())
c = this.getACallable() and
toSum = c.getMetrics().getHalsteadLength()
|
toSum
)
@@ -313,8 +313,8 @@ class MetricRefType extends RefType, MetricElement {
/** Gets the Halstead vocabulary of a type, estimated as the sum of the Halstead vocabularies of its callables. */
override int getHalsteadVocabulary() {
result = sum(Callable c, int toSum |
(c = this.getACallable()) and
(toSum = c.getMetrics().getHalsteadVocabulary())
c = this.getACallable() and
toSum = c.getMetrics().getHalsteadVocabulary()
|
toSum
)
@@ -323,8 +323,8 @@ class MetricRefType extends RefType, MetricElement {
/** Gets the cyclomatic complexity of a type, estimated as the sum of the cyclomatic complexities of its callables. */
override int getCyclomaticComplexity() {
result = sum(Callable c, int toSum |
(c = this.getACallable()) and
(toSum = c.getMetrics().getCyclomaticComplexity())
c = this.getACallable() and
toSum = c.getMetrics().getCyclomaticComplexity()
|
toSum
)

View File

@@ -73,17 +73,13 @@ deprecated class FlowSource extends Expr {
not isExcluded(tracked)
|
// Flow within a single method.
(
flowsTo(tracked, fromArg) and
localFlowStep(tracked, sink)
)
flowsTo(tracked, fromArg) and
localFlowStep(tracked, sink)
or
// Flow through a field.
(
flowsTo(tracked, _) and
staticFieldStep(tracked, sink) and
fromArg = false
)
flowsTo(tracked, _) and
staticFieldStep(tracked, sink) and
fromArg = false
or
// Flow through a method that returns one of its arguments.
exists(MethodAccess call, int i |
@@ -104,11 +100,9 @@ deprecated class FlowSource extends Expr {
// Flow out of a method.
// This path is only enabled if the flow did not come from the argument;
// such cases are handled by `methodReturnsArg`.
(
flowsTo(tracked, false) and
methodStep(tracked, sink) and
fromArg = false
)
flowsTo(tracked, false) and
methodStep(tracked, sink) and
fromArg = false
)
}
@@ -170,10 +164,8 @@ deprecated private Callable responderForArg(Call call, int i, FlowExpr tracked)
deprecated private Callable responder(Call call) {
result = exactCallable(call)
or
(
not exists(exactCallable(call)) and
result = call.getCallee()
)
not exists(exactCallable(call)) and
result = call.getCallee()
}
/** Holds if a method can return its argument. This is public for testing. */
@@ -240,7 +232,7 @@ deprecated private predicate localFlowStep(Expr tracked, Expr sink) {
argToMethodStep(tracked, sink)
or
// An unsafe attempt to escape tainted input.
(unsafeEscape(sink) and sink.(MethodAccess).getQualifier() = tracked)
unsafeEscape(sink) and sink.(MethodAccess).getQualifier() = tracked
or
// A logic expression.
sink.(LogicExpr).getAnOperand() = tracked
@@ -349,9 +341,9 @@ deprecated private predicate comparisonStep(Expr tracked, Expr sink) {
exists(MethodAccess m | m.getMethod() instanceof EqualsMethod |
m = sink and
(
(m.getQualifier() = tracked and m.getArgument(0) = other)
m.getQualifier() = tracked and m.getArgument(0) = other
or
(m.getQualifier() = other and m.getArgument(0) = tracked)
m.getQualifier() = other and m.getArgument(0) = tracked
)
)
) and
@@ -605,74 +597,54 @@ deprecated predicate qualifierToMethodStep(Expr tracked, MethodAccess sink) {
*/
deprecated class DataPreservingMethod extends Method {
DataPreservingMethod() {
this.getDeclaringType() instanceof TypeString and
(
this.getDeclaringType() instanceof TypeString and
(
this.getName() = "endsWith" or
this.getName() = "getBytes" or
this.getName() = "split" or
this.getName() = "substring" or
this.getName() = "toCharArray" or
this.getName() = "toLowerCase" or
this.getName() = "toString" or
this.getName() = "toUpperCase" or
this.getName() = "trim"
)
this.getName() = "endsWith" or
this.getName() = "getBytes" or
this.getName() = "split" or
this.getName() = "substring" or
this.getName() = "toCharArray" or
this.getName() = "toLowerCase" or
this.getName() = "toString" or
this.getName() = "toUpperCase" or
this.getName() = "trim"
)
or
exists(Class c | c.getQualifiedName() = "java.lang.Number" |
hasSubtypeStar(c, this.getDeclaringType())
) and
(
exists(Class c | c.getQualifiedName() = "java.lang.Number" |
hasSubtypeStar(c, this.getDeclaringType())
) and
(
this.getName().matches("to%String") or
this.getName() = "toByteArray" or
this.getName().matches("%Value")
)
this.getName().matches("to%String") or
this.getName() = "toByteArray" or
this.getName().matches("%Value")
)
or
(
this.getDeclaringType().getQualifiedName().matches("%Reader") and
this.getName().matches("read%")
)
this.getDeclaringType().getQualifiedName().matches("%Reader") and
this.getName().matches("read%")
or
this.getDeclaringType().getQualifiedName().matches("%StringWriter") and
this.getName() = "toString"
or
this.getDeclaringType().hasQualifiedName("java.util", "StringTokenizer") and
this.getName().matches("next%")
or
this.getDeclaringType().hasQualifiedName("java.io", "ByteArrayOutputStream") and
(this.getName() = "toByteArray" or this.getName() = "toString")
or
this.getDeclaringType().hasQualifiedName("java.io", "ObjectInputStream") and
this.getName().matches("read%")
or
(
this.getDeclaringType().getQualifiedName().matches("%StringWriter") and
this.getName() = "toString"
)
this.getDeclaringType().hasQualifiedName("java.lang", "StringBuilder") or
this.getDeclaringType().hasQualifiedName("java.lang", "StringBuffer")
) and
(this.getName() = "toString" or this.getName() = "append")
or
(
this.getDeclaringType().hasQualifiedName("java.util", "StringTokenizer") and
this.getName().matches("next%")
)
this.getDeclaringType().hasQualifiedName("javax.xml.transform.sax", "SAXSource") and
this.hasName("getInputSource")
or
(
this.getDeclaringType().hasQualifiedName("java.io", "ByteArrayOutputStream") and
(this.getName() = "toByteArray" or this.getName() = "toString")
)
or
(
this.getDeclaringType().hasQualifiedName("java.io", "ObjectInputStream") and
this.getName().matches("read%")
)
or
(
(
this.getDeclaringType().hasQualifiedName("java.lang", "StringBuilder") or
this.getDeclaringType().hasQualifiedName("java.lang", "StringBuffer")
) and
(this.getName() = "toString" or this.getName() = "append")
)
or
(
this.getDeclaringType().hasQualifiedName("javax.xml.transform.sax", "SAXSource") and
this.hasName("getInputSource")
)
or
(
this.getDeclaringType().hasQualifiedName("javax.xml.transform.stream", "StreamSource") and
this.hasName("getInputStream")
)
this.getDeclaringType().hasQualifiedName("javax.xml.transform.stream", "StreamSource") and
this.hasName("getInputStream")
}
}
@@ -681,89 +653,75 @@ deprecated class DataPreservingMethod extends Method {
* is tainted.
*/
deprecated predicate dataPreservingArgument(Method method, int arg) {
method instanceof StringReplaceMethod and
arg = 1
or
exists(Class c | c.getQualifiedName() = "java.lang.Number" |
hasSubtypeStar(c, method.getDeclaringType())
) and
(
method instanceof StringReplaceMethod and
arg = 1
method.getName().matches("parse%") and arg = 0
or
method.getName().matches("valueOf%") and arg = 0
or
method.getName().matches("to%String") and arg = 0
)
or
(
exists(Class c | c.getQualifiedName() = "java.lang.Number" |
hasSubtypeStar(c, method.getDeclaringType())
) and
(
(method.getName().matches("parse%") and arg = 0)
or
(method.getName().matches("valueOf%") and arg = 0)
or
(method.getName().matches("to%String") and arg = 0)
)
method.getDeclaringType().hasQualifiedName("java.lang", "StringBuilder") or
method.getDeclaringType().hasQualifiedName("java.lang", "StringBuffer")
) and
(
method.getName() = "append" and arg = 0
or
method.getName() = "insert" and arg = 1
or
method.getName() = "replace" and arg = 2
)
or
(
(
method.getDeclaringType().hasQualifiedName("java.lang", "StringBuilder") or
method.getDeclaringType().hasQualifiedName("java.lang", "StringBuffer")
) and
(
method.getName() = "append" and arg = 0
or
method.getName() = "insert" and arg = 1
or
method.getName() = "replace" and arg = 2
)
method.getDeclaringType().hasQualifiedName("java.util", "Base64$Encoder") or
method.getDeclaringType().hasQualifiedName("java.util", "Base64$Decoder")
) and
(
method.getName() = "encode" and arg = 0 and method.getNumberOfParameters() = 1
or
method.getName() = "decode" and arg = 0 and method.getNumberOfParameters() = 1
or
method.getName() = "encodeToString" and arg = 0
or
method.getName() = "wrap" and arg = 0
)
or
method.getDeclaringType().hasQualifiedName("org.apache.commons.io", "IOUtils") and
(
(
method.getDeclaringType().hasQualifiedName("java.util", "Base64$Encoder") or
method.getDeclaringType().hasQualifiedName("java.util", "Base64$Decoder")
) and
(
method.getName() = "encode" and arg = 0 and method.getNumberOfParameters() = 1
or
method.getName() = "decode" and arg = 0 and method.getNumberOfParameters() = 1
or
method.getName() = "encodeToString" and arg = 0
or
method.getName() = "wrap" and arg = 0
)
method.getName() = "buffer" and arg = 0
or
method.getName() = "readLines" and arg = 0
or
method.getName() = "readFully" and arg = 0 and method.getParameterType(1).hasName("int")
or
method.getName() = "toBufferedInputStream" and arg = 0
or
method.getName() = "toBufferedReader" and arg = 0
or
method.getName() = "toByteArray" and arg = 0
or
method.getName() = "toCharArray" and arg = 0
or
method.getName() = "toInputStream" and arg = 0
or
method.getName() = "toString" and arg = 0
)
or
(
(method.getDeclaringType().hasQualifiedName("org.apache.commons.io", "IOUtils")) and
(
method.getName() = "buffer" and arg = 0
or
method.getName() = "readLines" and arg = 0
or
method.getName() = "readFully" and arg = 0 and method.getParameterType(1).hasName("int")
or
method.getName() = "toBufferedInputStream" and arg = 0
or
method.getName() = "toBufferedReader" and arg = 0
or
method.getName() = "toByteArray" and arg = 0
or
method.getName() = "toCharArray" and arg = 0
or
method.getName() = "toInputStream" and arg = 0
or
method.getName() = "toString" and arg = 0
)
)
//A URI created from a tainted string is still tainted.
method.getDeclaringType().hasQualifiedName("java.net", "URI") and
method.hasName("create") and
arg = 0
or
(
//A URI created from a tainted string is still tainted.
method.getDeclaringType().hasQualifiedName("java.net", "URI") and
method.hasName("create") and
arg = 0
)
or
(
method.getDeclaringType().hasQualifiedName("javax.xml.transform.sax", "SAXSource") and
method.hasName("sourceToInputSource") and
arg = 0
)
method.getDeclaringType().hasQualifiedName("javax.xml.transform.sax", "SAXSource") and
method.hasName("sourceToInputSource") and
arg = 0
}
deprecated class StringReplaceMethod extends Method {

View File

@@ -44,17 +44,13 @@ private EnumConstant getAContainedEnumConstant(Expr enumSetRef) {
exists(MethodAccess addToSet |
addToSet.getQualifier() = enumSetAccess.getVariable().getAnAccess()
|
(
// Call to `add(..)` on the enum set variable.
addToSet.getMethod().hasName("add") and
result = addToSet.getArgument(0).(VarAccess).getVariable()
)
// Call to `add(..)` on the enum set variable.
addToSet.getMethod().hasName("add") and
result = addToSet.getArgument(0).(VarAccess).getVariable()
or
(
// Call to `addAll(..)` on the enum set variable.
addToSet.getMethod().hasName("addAll") and
result = getAContainedEnumConstant(addToSet.getArgument(0))
)
// Call to `addAll(..)` on the enum set variable.
addToSet.getMethod().hasName("addAll") and
result = getAContainedEnumConstant(addToSet.getArgument(0))
)
)
)

View File

@@ -148,11 +148,9 @@ abstract class ReturnsPredictableExpr extends Method { }
class ReturnsSystemTime extends ReturnsPredictableExpr {
ReturnsSystemTime() {
(
this.getDeclaringType().hasQualifiedName("java.lang", "System") and
this.hasName("currentTimeMillis")
)
this.getDeclaringType().hasQualifiedName("java.lang", "System") and
this.hasName("currentTimeMillis")
or
(this.getDeclaringType().hasQualifiedName("java.lang", "System") and this.hasName("nanoTime"))
this.getDeclaringType().hasQualifiedName("java.lang", "System") and this.hasName("nanoTime")
}
}

View File

@@ -59,7 +59,7 @@ class Pom extends ProtoPom {
override Group getGroup() {
// For a project element, the group may be defined in the parent tags instead
if not (exists(super.getGroup()))
if not exists(super.getGroup())
then exists(Parent p | p = this.getAChild() and result = p.getAChild())
else result = super.getGroup()
}
@@ -94,10 +94,8 @@ class Pom extends ProtoPom {
PomProperty getAProperty() {
result = getALocalProperty()
or
(
result = getParentPom().getAProperty() and
not getALocalProperty().getName() = result.getName()
)
result = getParentPom().getAProperty() and
not getALocalProperty().getName() = result.getName()
}
/**
@@ -116,11 +114,9 @@ class Pom extends ProtoPom {
// It must either be a child of the pom, or a child of the parent node of the pom
result = getAChild()
or
(
result = getParentPom().getAChild() and
// The parent project property is not shadowed by a local project property
not exists(PomElement p | p = getAChild() and p.getName() = result.getName())
)
result = getParentPom().getAChild() and
// The parent project property is not shadowed by a local project property
not exists(PomElement p | p = getAChild() and p.getName() = result.getName())
) and
// Can't be a property if it has children of its own
not exists(result.getAChild())

View File

@@ -142,15 +142,11 @@ class XMLDTD extends @xmldtd {
/** Gets a printable representation of this DTD. */
string toString() {
(
this.isPublic() and
result = this.getRoot() + " PUBLIC '" + this.getPublicId() + "' '" + this.getSystemId() + "'"
)
this.isPublic() and
result = this.getRoot() + " PUBLIC '" + this.getPublicId() + "' '" + this.getSystemId() + "'"
or
(
not this.isPublic() and
result = this.getRoot() + " SYSTEM '" + this.getSystemId() + "'"
)
not this.isPublic() and
result = this.getRoot() + " SYSTEM '" + this.getSystemId() + "'"
}
}
@@ -233,9 +229,9 @@ class XMLNamespace extends @xmlnamespace {
/** Gets a printable representation of this XML namespace. */
string toString() {
(this.isDefault() and result = this.getURI())
this.isDefault() and result = this.getURI()
or
(not this.isDefault() and result = this.getPrefix() + ":" + this.getURI())
not this.isDefault() and result = this.getPrefix() + ":" + this.getURI()
}
}