Files
codeql/java/ql/test/query-tests/Nullness/B.java
2025-09-12 15:41:16 +02:00

561 lines
12 KiB
Java

public class B {
private boolean maybe;
public final boolean flag;
public B(boolean b, boolean f) {
this.maybe = b;
this.flag = f;
}
public void caller() {
callee1(new Object());
callee1(null);
callee2(new Object());
}
public void callee1(Object param) {
param.toString(); // NPE
}
public void callee2(Object param) {
if (param != null) {
param.toString(); // OK
}
param.toString(); // NPE
}
private static boolean customIsNull(Object x) {
if (x instanceof String) return false;
if (x == null) return true;
return x == null;
}
public void nullGuards() {
Object o1 = maybe ? null : new Object();
if (o1 != null) o1.hashCode(); // OK
Object o2 = maybe ? null : "";
if (o2 instanceof String) o2.hashCode(); // OK
Object o3 = null;
if ((o3 = maybe ? null : "") != null) o3.hashCode(); // OK
Object o4 = maybe ? null : "";
if ((2 > 1 && o4 != null) != false) o4.hashCode(); // OK
Object o5 = (o4 != null) ? "" : null;
if (o5 != null) o4.hashCode(); // OK
if (o4 != null) o5.hashCode(); // OK
Object o6 = maybe ? null : "";
if (!customIsNull(o6)) o6.hashCode(); // OK
Object o7 = maybe ? null : "";
boolean ok = o7 != null && 2 > 1;
if (ok)
o7.hashCode(); // OK
else
o7.hashCode(); // NPE
Object o8 = maybe ? null : "";
int track = o8 == null ? 42 : 1+1;
if (track == 2) o8.hashCode(); // OK
if (track != 42) o8.hashCode(); // OK
if (track < 42) o8.hashCode(); // OK
if (track <= 41) o8.hashCode(); // OK
}
public void deref() {
int[] xs = maybe ? null : new int[2];
if (2 > 1) xs[0] = 5; // NPE
if (2 > 1) maybe = xs[1] > 5; // NPE
if (2 > 1) {
int l = xs.length; // NPE
}
if (2 > 1) {
for (int i : xs) { } // NPE
}
if (2 > 1) {
synchronized(xs) { // NPE
xs.hashCode(); // Not reported - same basic block
}
}
if (4 > 3) {
assert xs != null;
xs[0] = xs[1]; // OK
}
}
public void f(boolean b) {
String x = b ? null : "abc";
x = x == null ? "" : x;
if (x == null)
x.hashCode(); // OK - dead
else
x.hashCode(); // OK
}
public void lengthGuard(int[] a, int[] b) {
int alen = a == null ? 0 : a.length; // OK
int blen = b == null ? 0 : b.length; // OK
int sum = 0;
if (alen == blen) {
for(int i = 0; i < alen; i++) {
sum += a[i]; // OK
sum += b[i]; // OK
}
}
int alen2;
if (a != null)
alen2 = a.length; // OK
else
alen2 = 0;
for(int i = 1; i <= alen2; ++i) {
sum += a[i-1]; // OK
}
}
public void missedGuard(Object obj) {
obj.hashCode(); // NPE
int x = obj != null ? 1 : 0;
}
private Object mkMaybe() {
if (maybe) throw new RuntimeException();
return new Object();
}
public void exceptions() {
Object obj = null;
try {
obj = mkMaybe();
} catch(Exception e) {
}
obj.hashCode(); // NPE
Object obj2 = null;
try {
obj2 = mkMaybe();
} catch(Exception e) {
assert false;
}
obj2.hashCode(); // OK
Object obj3 = null;
try {
obj3 = mkMaybe();
} finally {
//cleanup
}
obj3.hashCode(); // OK
}
public void clearNotNull() {
Object o = new Object();
if (o == null) o.hashCode(); // OK
o.hashCode(); // OK
try {
mkMaybe();
} catch(Exception e) {
if (e == null) e.hashCode(); // OK
e.hashCode(); // OK
}
Object n = null;
Object o2 = n == null ? new Object() : n;
o2.hashCode(); // OK
Object o3 = "abc";
if (o3 == null) o3.hashCode(); // OK
o3.hashCode(); // OK
Object o4 = "" + null;
if (o4 == null) o4.hashCode(); // OK
o4.hashCode(); // OK
}
public void correlatedConditions(boolean cond, int num) {
Object o = null;
if (cond) o = new Object();
if (cond) o.hashCode(); // OK
o = null;
if (flag) o = "";
if (flag) o.hashCode(); // OK
o = null;
Object other = maybe ? null : "";
if (other == null) o = "";
if (other != null)
o.hashCode(); // NPE
else
o.hashCode(); // OK
Object o2 = (num < 0) ? null : "";
if (num < 0)
o2 = "";
else
o2.hashCode(); // OK
}
public void trackingVariable(int[] a) {
Object o = null;
Object other = null;
if (maybe) {
o = "abc";
other = "def";
}
if (other instanceof String) o.hashCode(); // OK
o = null;
int count = 0;
boolean found = false;
for (int i = 0; i < a.length; i++) {
if (a[i] == 42) {
o = ((Integer)a[i]).toString();
count++;
if (2 > 1) { }
found = true;
}
if (a[i] > 10000) {
o = null;
count = 0;
if (2 > 1) { }
found = false;
}
}
if (count > 3) o.hashCode(); // OK
if (found) o.hashCode(); // OK
Object prev = null;
for (int i = 0; i < a.length; ++i) {
if (i != 0) prev.hashCode(); // OK
prev = a[i];
}
String s = null;
if (2 > 1) {
boolean s_null = true;
for (int i : a) {
s_null = false;
s = "" + a;
}
if (!s_null) s.hashCode(); // OK
}
Object r = null;
MyStatus stat = MyStatus.INIT;
while (stat == MyStatus.INIT && stat != MyStatus.READY) {
r = mkMaybe();
if (2 > 1)
stat = MyStatus.READY;
}
r.hashCode(); // OK
}
public enum MyStatus {
READY,
INIT
}
public void g(Object obj) {
String msg = null;
if(obj == null)
msg = "foo";
else if(obj.hashCode() > 7) { // OK
msg = "bar";
}
if(msg != null) {
msg += "foobar";
throw new RuntimeException(msg);
}
obj.hashCode(); // OK
}
public void loopCorr(int iters) {
int[] a = null;
if (iters > 0) a = new int[iters];
for (int i = 0; i < iters; ++i)
a[i] = 0; // OK
if (iters > 0) {
String last = null;
for (int i = 0; i < iters; i++) last = "abc";
last.hashCode(); // OK
}
int[] b = maybe ? null : new int[iters];
if (iters > 0 && (b == null || b.length < iters)) {
throw new RuntimeException();
}
for (int i = 0; i < iters; ++i) {
b[i] = 0; // OK
}
}
void test(Exception e, boolean b) {
Exception ioe = null;
if (b) {
ioe = new Exception("");
}
if (ioe != null) {
ioe = e;
} else {
ioe.getMessage(); // NPE; always
}
}
public void lengthGuard2(int[] a, int[] b) {
int alen = a == null ? 0 : a.length; // OK
int sum = 0;
int i;
for(i = 0; i < alen; i++) {
sum += a[i]; // OK
}
int blen = b == null ? 0 : b.length; // OK
for(i = 0; i < blen; i++) {
sum += b[i]; // OK
}
i = -3;
}
public void corrConds2(Object x, Object y) {
if ((x != null && y == null) || (x == null && y != null)) return;
if (x != null) y.hashCode(); // OK
if (y != null) x.hashCode(); // OK
}
public void corrConds3(Object y) {
Object x = null;
if(y instanceof String) {
x = new Object();
}
if(y instanceof String) {
x.hashCode(); // Spurious NPE - false positive
}
}
public void corrConds4(Object y) {
Object x = null;
if(!(y instanceof String)) {
x = new Object();
}
if(!(y instanceof String)) {
x.hashCode(); // Spurious NPE - false positive
}
}
public void corrConds5(Object y, Object z) {
Object x = null;
if(y == z) {
x = new Object();
}
if(y == z) {
x.hashCode(); // Spurious NPE - false positive
}
Object x2 = null;
if(y != z) {
x2 = new Object();
}
if(y != z) {
x2.hashCode(); // Spurious NPE - false positive
}
Object x3 = null;
if(y != z) {
x3 = new Object();
}
if(!(y == z)) {
x3.hashCode(); // Spurious NPE - false positive
}
}
public void bitwise(Object x, boolean b) {
boolean notnull = x != null;
boolean g1 = notnull;
g1 &= b;
if (g1) {
x.hashCode(); // OK
}
boolean g2 = b;
g2 &= notnull;
if (g2) {
x.hashCode(); // OK
}
boolean g3 = !notnull;
g3 |= b;
if (!g3) {
x.hashCode(); // OK
}
boolean g4 = b;
g4 |= !notnull;
if (!g4) {
x.hashCode(); // OK
}
boolean g5 = g1 = b & notnull;
if (g5) {
x.hashCode(); // OK
}
g5 |= b;
if (g5) {
x.hashCode(); // NPE
}
}
public void corrCondLoop1(boolean a[]) {
Object x = new Object();
for (int i = 0; i < a.length; i++) {
boolean b = a[i];
if (b) {
x = null;
}
if (!b) {
x.hashCode(); // NPE
}
// flow can loop around from one iteration to the next
}
}
public void corrCondLoop2(boolean a[]) {
for (int i = 0; i < a.length; i++) {
// x is local to the loop iteration and thus cannot loop around and reach the sink
Object x = new Object();
boolean b = a[i];
if (b) {
x = null;
}
if (!b) {
x.hashCode(); // OK
}
}
}
public void loopCorrTest1(int[] a) {
boolean ready = a.length > 7;
Object x = new Object();
for (int i = 0; i < a.length; i++) {
// condition correlates with itself through iterations when ready isn't updated
if (!ready) {
x = null;
} else {
x.hashCode(); // OK
}
if ((a[i] & 1) != 0) {
ready = (a[i] & 2) != 0;
x = new Object();
}
}
}
public void loopCorrTest2(boolean[] a) {
Object x = new Object();
boolean cur = a[0];
for (int i = 1; i < a.length; i++) {
boolean prev = cur;
cur = a[i];
if (!prev) {
// correctly guarded by !cur from the _previous_ iteration
x.hashCode(); // Spurious NPE - false positive
} else {
x = new Object();
}
if (cur) {
x = null;
}
}
}
public void loopCorrTest3(String[] ss) {
Object x = null;
Object t = null;
for (String s : ss) {
if (t == null) {
t = s;
} else {
if (t instanceof String) {
x = new Object();
t = new Object();
}
// correctly guarded by t: null -> String -> Object
x.hashCode(); // Spurious NPE - false positive
}
}
}
public void initCorr(boolean b) {
Object o2 = b ? null : "";
if (b)
o2 = "";
else
o2.hashCode(); // OK
}
public void complexLoopTest(int[] xs, int[] ys) {
int len = ys != null ? ys.length : 0;
for (int i = 0, j = 0; i < xs.length; i++) {
if (j < len && ys[j] == 42) { // OK
j++;
} else if (j > 0) {
ys[0]++; // OK
}
}
}
public void trackTest(Object o, int n) {
boolean isnull = o == null;
int c = -1;
if (maybe) { }
if (c == 100) { return; }
o.hashCode(); // NPE
}
public void testFinally(int[] xs, int[] ys) {
if (xs.length == 0) return;
if (ys.length == 0) return;
String s1 = null;
String s2 = null;
for (int x : xs) {
try {
if (x == 0) { break; }
s1 = "1";
for (int y : ys) {
if (y == 0) { break; }
s2 = "2";
}
} finally {
}
s1.hashCode(); // OK
s2.hashCode(); // NPE
}
s1.hashCode(); // NPE - false negative, Java CFG lacks proper edge label
}
public void lenCheck(int[] xs, int n, int t) {
if (n > 42) return;
if (maybe) {}
if (n > 0 && (xs == null || xs.length < n)) {
return;
}
if (maybe) {}
if (n > 21) return;
if (maybe) {}
for (int i = 0; i < n; ++i) {
xs[i]++; // OK
}
}
public void rangetest(int n) {
String s = null;
if (n < 0 || n > 10) s = "A";
if (n > 100) s.hashCode(); // OK
if (n == 42) s.hashCode(); // OK
}
}