mirror of
https://github.com/github/codeql.git
synced 2026-02-28 21:03:50 +01:00
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:
@@ -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, _, _, _, _)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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 |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user