Use EqualityTest for either value or ref comparions, and ReferenceEqualityTest for strictly ref comparison.

This commit is contained in:
Chris Smowton
2022-02-07 16:56:45 +00:00
committed by Ian Lynagh
parent f95effcf82
commit 7dec3f4835
26 changed files with 47 additions and 47 deletions

View File

@@ -9,6 +9,6 @@
import java
from AnyEqualityTest eq
from EqualityTest eq
where eq.getAnOperand() instanceof BooleanLiteral
select eq

View File

@@ -1099,8 +1099,8 @@ class GreaterThanComparison extends ComparisonExpr {
*
* This could be a reference- or a value-in/equality test.
*/
class AnyEqualityTest extends BinaryExpr {
AnyEqualityTest() {
class EqualityTest extends BinaryExpr {
EqualityTest() {
this instanceof EQExpr or
this instanceof NEExpr or
this instanceof ValueEQExpr or
@@ -1121,12 +1121,12 @@ class AnyEqualityTest extends BinaryExpr {
/**
* An equality test is a binary expression using
* Java's `==` or `!=` operator.
* Java's `==` or `!=` operators or Kotlin's `===` or `!==` operators.
*
* If either operand is a reference type, this is a reference-in/equality test.
*/
class EqualityTest extends AnyEqualityTest {
EqualityTest() {
class ReferenceEqualityTest extends EqualityTest {
ReferenceEqualityTest() {
this instanceof EQExpr or
this instanceof NEExpr
}

View File

@@ -242,7 +242,7 @@ private predicate guardControls_v3(Guard guard, BasicBlock controlled, boolean b
}
private predicate equalityGuard(Guard g, Expr e1, Expr e2, boolean polarity) {
exists(AnyEqualityTest eqtest |
exists(EqualityTest eqtest |
eqtest = g and
polarity = eqtest.polarity() and
eqtest.hasOperands(e1, e2)

View File

@@ -35,7 +35,7 @@ predicate implies_v1(Guard g1, boolean b1, Guard g2, boolean b2) {
b1 = b2.booleanNot() and
b1 = [true, false]
or
exists(AnyEqualityTest eqtest, boolean polarity, BooleanLiteral boollit |
exists(EqualityTest eqtest, boolean polarity, BooleanLiteral boollit |
eqtest = g1 and
eqtest.hasOperands(g2, boollit) and
eqtest.polarity() = polarity and

View File

@@ -42,7 +42,7 @@ class IntComparableExpr extends Expr {
*/
pragma[nomagic]
Expr integerGuard(IntComparableExpr e, boolean branch, int k, boolean is_k) {
exists(AnyEqualityTest eqtest, boolean polarity |
exists(EqualityTest eqtest, boolean polarity |
eqtest = result and
eqtest.hasOperands(e, any(ConstantIntegerExpr c | c.getIntValue() = k)) and
polarity = eqtest.polarity() and
@@ -53,7 +53,7 @@ Expr integerGuard(IntComparableExpr e, boolean branch, int k, boolean is_k) {
)
)
or
exists(AnyEqualityTest eqtest, int val, Expr c, boolean upper |
exists(EqualityTest eqtest, int val, Expr c, boolean upper |
k = e.relevantInt() and
eqtest = result and
eqtest.hasOperands(e, c) and

View File

@@ -17,7 +17,7 @@ Expr alwaysNullExpr() {
/** Gets an equality test between an expression `e` and an enum constant `c`. */
Expr enumConstEquality(Expr e, boolean polarity, EnumConstant c) {
exists(AnyEqualityTest eqtest |
exists(EqualityTest eqtest |
eqtest = result and
eqtest.hasOperands(e, c.getAnAccess()) and
polarity = eqtest.polarity()
@@ -36,7 +36,7 @@ InstanceOfExpr instanceofExpr(SsaVariable v, RefType type) {
*
* Note this includes Kotlin's `==` and `!=` operators, which are value-equality tests.
*/
AnyEqualityTest varEqualityTestExpr(SsaVariable v1, SsaVariable v2, boolean isEqualExpr) {
EqualityTest varEqualityTestExpr(SsaVariable v1, SsaVariable v2, boolean isEqualExpr) {
result.hasOperands(v1.getAUse(), v2.getAUse()) and
isEqualExpr = result.polarity()
}
@@ -174,7 +174,7 @@ predicate nullCheckMethod(Method m, boolean branch, boolean isnull) {
* is true, and non-null if `isnull` is false.
*/
Expr basicNullGuard(Expr e, boolean branch, boolean isnull) {
exists(AnyEqualityTest eqtest, boolean polarity |
exists(EqualityTest eqtest, boolean polarity |
eqtest = result and
eqtest.hasOperands(e, any(NullLiteral n)) and
polarity = eqtest.polarity() and
@@ -193,7 +193,7 @@ Expr basicNullGuard(Expr e, boolean branch, boolean isnull) {
nullCheckMethod(call.getMethod(), branch, isnull)
)
or
exists(AnyEqualityTest eqtest |
exists(EqualityTest eqtest |
eqtest = result and
eqtest.hasOperands(e, clearlyNotNullExpr()) and
isnull = false and

View File

@@ -70,13 +70,13 @@ private predicate unboxed(Expr e) {
or
exists(AssignOp assign | assign.getSource() = e and assign.getType() instanceof PrimitiveType)
or
exists(AnyEqualityTest eq |
exists(EqualityTest eq |
eq.getAnOperand() = e and eq.getAnOperand().getType() instanceof PrimitiveType
)
or
exists(BinaryExpr bin |
bin.getAnOperand() = e and
not bin instanceof AnyEqualityTest and
not bin instanceof EqualityTest and
bin.getType() instanceof PrimitiveType
)
or
@@ -653,7 +653,7 @@ private Expr trackingVarGuard(
)
)
or
exists(AnyEqualityTest eqtest, boolean branch0, boolean polarity, BooleanLiteral boollit |
exists(EqualityTest eqtest, boolean branch0, boolean polarity, BooleanLiteral boollit |
eqtest = result and
eqtest.hasOperands(trackingVarGuard(trackssa, trackvar, kind, branch0, isA), boollit) and
eqtest.polarity() = polarity and

View File

@@ -387,7 +387,7 @@ private predicate taintPreservingArgumentToQualifier(Method method, int arg) {
/** A comparison or equality test with a constant. */
private predicate comparisonStep(Expr tracked, Expr sink) {
exists(Expr other |
exists(BinaryExpr e | e instanceof ComparisonExpr or e instanceof AnyEqualityTest |
exists(BinaryExpr e | e instanceof ComparisonExpr or e instanceof EqualityTest |
e = sink and
e.hasOperands(tracked, other)
)

View File

@@ -116,7 +116,7 @@ private predicate intentFlagsOrDataChecked(Guard g, Expr intent, boolean branch)
bitwiseLocalTaintStep*(DataFlow::exprNode(ma), DataFlow::exprNode(checkedValue))
|
bitwiseCheck(g, branch) and
checkedValue = g.(AnyEqualityTest).getAnOperand().(AndBitwiseExpr)
checkedValue = g.(EqualityTest).getAnOperand().(AndBitwiseExpr)
or
g.(MethodAccess).getMethod() instanceof EqualsMethod and
branch = true and
@@ -129,10 +129,10 @@ private predicate intentFlagsOrDataChecked(Guard g, Expr intent, boolean branch)
* and `false` otherwise.
*/
private predicate bitwiseCheck(Guard g, boolean branch) {
exists(CompileTimeConstantExpr operand | operand = g.(AnyEqualityTest).getAnOperand() |
exists(CompileTimeConstantExpr operand | operand = g.(EqualityTest).getAnOperand() |
if operand.getIntValue() = 0
then g.(AnyEqualityTest).polarity() = branch
else g.(AnyEqualityTest).polarity().booleanNot() = branch
then g.(EqualityTest).polarity() = branch
else g.(EqualityTest).polarity().booleanNot() = branch
)
}

View File

@@ -45,7 +45,7 @@ class ShiftExpr extends BinaryExpr {
*/
class RelationExpr extends BinaryExpr {
RelationExpr() {
this instanceof AnyEqualityTest or
this instanceof EqualityTest or
this instanceof ComparisonExpr
}
}
@@ -79,7 +79,7 @@ class AssocNestedExpr extends BinaryExpr {
parent.getKind() = this.getKind()
or
// Equality tests are associate over each other.
this instanceof AnyEqualityTest and parent instanceof AnyEqualityTest
this instanceof EqualityTest and parent instanceof EqualityTest
or
// (x*y)/z = x*(y/z)
this instanceof MulExpr and parent instanceof DivExpr and idx = 0

View File

@@ -14,7 +14,7 @@
import java
predicate comparison(BinaryExpr binop, Expr left, Expr right) {
(binop instanceof ComparisonExpr or binop instanceof AnyEqualityTest) and
(binop instanceof ComparisonExpr or binop instanceof EqualityTest) and
binop.getLeftOperand() = left and
binop.getRightOperand() = right
}
@@ -64,7 +64,7 @@ predicate equal(Expr left, Expr right) {
)
}
predicate specialCase(AnyEqualityTest comparison, string msg) {
predicate specialCase(EqualityTest comparison, string msg) {
exists(FloatingPointType fptp, string neg, string boxedName |
fptp = comparison.getAnOperand().getType() and
// Name of boxed type corresponding to `fptp`.

View File

@@ -25,7 +25,7 @@ class BooleanExpr extends Expr {
private predicate assignAndCheck(AssignExpr e) {
exists(BinaryExpr c | e = c.getAChildExpr() |
c instanceof ComparisonExpr or
c instanceof AnyEqualityTest
c instanceof EqualityTest
)
}

View File

@@ -46,7 +46,7 @@ predicate comparisonMethod(Method m) { m.getName() = "compareTo" }
// Check for equalities of the form `a.x == b.x` or `a.x == x`, where `x` is assigned to `a.x`,
// which are less interesting but occur often.
predicate similarVarComparison(AnyEqualityTest e) {
predicate similarVarComparison(EqualityTest e) {
exists(Field f |
e.getLeftOperand() = f.getAnAccess() and
e.getRightOperand() = f.getAnAccess()
@@ -59,7 +59,7 @@ predicate similarVarComparison(AnyEqualityTest e) {
)
}
from AnyEqualityTest ee
from EqualityTest ee
where
ee.getAnOperand().getType() instanceof Floating and
not ee.getAnOperand() instanceof NullLiteral and

View File

@@ -19,7 +19,7 @@ class FinalFieldAccess extends VarAccess {
FinalFieldAccess() { this.getVariable().(Field).isFinal() }
}
class ReferenceEqualityTestOnObject extends EqualityTest {
class ReferenceEqualityTestOnObject extends ReferenceEqualityTest {
ReferenceEqualityTestOnObject() {
this.getLeftOperand().getType() instanceof TypeObject and
this.getRightOperand().getType() instanceof TypeObject and

View File

@@ -13,7 +13,7 @@
import java
from EqualityTest c
from ReferenceEqualityTest c
where
c.getLeftOperand().getType() instanceof BoxedType and
c.getRightOperand().getType() instanceof BoxedType and

View File

@@ -57,7 +57,7 @@ predicate variableValuesInterned(Variable v) {
forall(StringValue sv | sv = v.getAnAssignedValue() | sv.isInterned())
}
from EqualityTest e, StringValue lhs, StringValue rhs
from ReferenceEqualityTest e, StringValue lhs, StringValue rhs
where
e.getLeftOperand() = lhs and
e.getRightOperand() = rhs and

View File

@@ -44,7 +44,7 @@ predicate constCond(BinaryExpr cond, boolean isTrue, Reason reason) {
isTrue = false and not comp.isStrict() and d1 > d2
)
or
exists(AnyEqualityTest eq, Expr lhs, Expr rhs |
exists(EqualityTest eq, Expr lhs, Expr rhs |
eq = cond and
lhs = eq.getLeftOperand() and
rhs = eq.getRightOperand()
@@ -192,7 +192,7 @@ predicate concurrentModificationTest(BinaryExpr test) {
* Holds if `test` and `guard` are equality tests of the same integral variable v with constants `c1` and `c2`.
*/
pragma[nomagic]
predicate guardedTest(AnyEqualityTest test, Guard guard, boolean isEq, int i1, int i2) {
predicate guardedTest(EqualityTest test, Guard guard, boolean isEq, int i1, int i2) {
exists(SsaVariable v, CompileTimeConstantExpr c1, CompileTimeConstantExpr c2 |
guard.isEquality(v.getAUse(), c1, isEq) and
test.hasOperands(v.getAUse(), c2) and
@@ -205,7 +205,7 @@ predicate guardedTest(AnyEqualityTest test, Guard guard, boolean isEq, int i1, i
/**
* Holds if `guard` implies that `test` always has the value `testIsTrue`.
*/
predicate uselessEqTest(AnyEqualityTest test, boolean testIsTrue, Guard guard) {
predicate uselessEqTest(EqualityTest test, boolean testIsTrue, Guard guard) {
exists(boolean guardIsTrue, boolean guardpolarity, int i |
guardedTest(test, guard, guardpolarity, i, i) and
guard.controls(test.getBasicBlock(), guardIsTrue) and
@@ -218,7 +218,7 @@ where
(
if uselessEqTest(test, _, _)
then
exists(AnyEqualityTest r |
exists(EqualityTest r |
uselessEqTest(test, testIsTrue, r) and reason = ", because of $@" and reasonElem = r
)
else

View File

@@ -42,7 +42,7 @@ predicate uselessTest(ConditionNode s1, BinaryExpr test, boolean testIsTrue) {
exists(BoundKind boundKind, int bound |
// Simple range analysis. We infer a bound based on `cond` being
// either true (`condIsTrue = true`) or false (`condIsTrue = false`).
exists(AnyEqualityTest condeq | cond = condeq and bound = k1 |
exists(EqualityTest condeq | cond = condeq and bound = k1 |
condIsTrue = condeq.polarity() and boundKind.isEqual()
or
condIsTrue = condeq.polarity().booleanNot() and boundKind.isNotEqual()
@@ -74,7 +74,7 @@ predicate uselessTest(ConditionNode s1, BinaryExpr test, boolean testIsTrue) {
|
// Given the bound we check if the `test` is either
// always true (`testIsTrue = true`) or always false (`testIsTrue = false`).
exists(AnyEqualityTest testeq, boolean pol | testeq = test and pol = testeq.polarity() |
exists(EqualityTest testeq, boolean pol | testeq = test and pol = testeq.polarity() |
(
boundKind.providesLowerBound() and k2 < bound
or

View File

@@ -16,7 +16,7 @@ predicate nanField(Field f) {
f.hasName("NaN")
}
from AnyEqualityTest eq, Field f, string classname
from EqualityTest eq, Field f, string classname
where
eq.getAnOperand() = f.getAnAccess() and nanField(f) and f.getDeclaringType().hasName(classname)
select eq,

View File

@@ -21,7 +21,7 @@ private Expr getAFieldRead(Field f) {
* `f` or indirectly through a local variable `(x = f) == null`.
*/
private Expr getANullCheck(Field f) {
exists(AnyEqualityTest eq | eq.polarity() = true |
exists(EqualityTest eq | eq.polarity() = true |
eq.hasOperands(any(NullLiteral nl), getAFieldRead(f)) and
result = eq
)

View File

@@ -17,7 +17,7 @@ import java
class ComparisonOrEqTestExpr extends Expr {
ComparisonOrEqTestExpr() {
this instanceof ComparisonExpr or
this instanceof EqualityTest
this instanceof ReferenceEqualityTest
}
}

View File

@@ -16,7 +16,7 @@ private predicate inWeakCheck(Expr e) {
)
or
// Checking against `null` has no bearing on path traversal.
exists(AnyEqualityTest b | b.getAnOperand() = e | b.getAnOperand() instanceof NullLiteral)
exists(EqualityTest b | b.getAnOperand() = e | b.getAnOperand() instanceof NullLiteral)
}
// Ignore cases where the variable has been checked somehow,

View File

@@ -46,7 +46,7 @@ predicate boundedRead(RValue read) {
}
predicate castCheck(RValue read) {
exists(AnyEqualityTest eq, CastExpr cast |
exists(EqualityTest eq, CastExpr cast |
cast.getExpr() = read and
eq.hasOperands(cast, read.getVariable().getAnAccess())
)

View File

@@ -10,7 +10,7 @@
import java
class BoolCompare extends AnyEqualityTest {
class BoolCompare extends EqualityTest {
BoolCompare() { this.getAnOperand() instanceof BooleanLiteral }
predicate simplify(string pattern, string rewrite) {
@@ -61,7 +61,7 @@ predicate conditionalWithBool(ConditionalExpr c, string pattern, string rewrite)
}
class ComparisonOrEquality extends BinaryExpr {
ComparisonOrEquality() { this instanceof ComparisonExpr or this instanceof AnyEqualityTest }
ComparisonOrEquality() { this instanceof ComparisonExpr or this instanceof EqualityTest }
predicate negate(string pattern, string rewrite) {
this instanceof EQExpr and pattern = "!(A == B)" and rewrite = "A != B"

View File

@@ -36,7 +36,7 @@ Variable flowTarget(Expr arg) {
*/
predicate unboxed(BoxedExpr e) {
exists(BinaryExpr bin | e = bin.getAnOperand() |
if bin instanceof AnyEqualityTest or bin instanceof ComparisonExpr
if bin instanceof EqualityTest or bin instanceof ComparisonExpr
then bin.getAnOperand() instanceof PrimitiveExpr
else bin instanceof PrimitiveExpr
)

View File

@@ -266,7 +266,7 @@ private predicate isNonConstantTimeComparisonCall(Expr firstInput, Expr secondIn
*/
private predicate existsFailFastCheck(Expr firstArray, Expr secondArray) {
exists(
Guard guard, AnyEqualityTest eqTest, boolean branch, Stmt fastFailingStmt,
Guard guard, EqualityTest eqTest, boolean branch, Stmt fastFailingStmt,
ArrayAccess firstArrayAccess, ArrayAccess secondArrayAccess
|
guard = eqTest and