mirror of
https://github.com/github/codeql.git
synced 2026-04-23 15:55:18 +02:00
Merge pull request #15961 from igfoo/igfoo/MissingEnumInSwitch
Java: Limit the amount of results that MissingEnumInSwitch produces per switch
This commit is contained in:
@@ -13,10 +13,51 @@
|
||||
|
||||
import java
|
||||
|
||||
from SwitchStmt switch, EnumType enum, EnumConstant missing
|
||||
where
|
||||
switch.getExpr().getType() = enum and
|
||||
missing.getDeclaringType() = enum and
|
||||
EnumConstant nthMissing(SwitchStmt switch, int index) {
|
||||
not exists(switch.getDefaultCase()) and
|
||||
not switch.getAConstCase().getValue() = missing.getAnAccess()
|
||||
select switch, "Switch statement does not have a case for $@.", missing, missing.getName()
|
||||
exists(EnumType enum |
|
||||
switch.getExpr().getType() = enum and
|
||||
result =
|
||||
rank[index](EnumConstant ec |
|
||||
ec.getDeclaringType() = enum and
|
||||
not switch.getAConstCase().getValue() = ec.getAnAccess()
|
||||
|
|
||||
ec order by ec.getName()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
predicate first3(string msg, SwitchStmt switch, EnumConstant e1, EnumConstant e2, EnumConstant e3) {
|
||||
exists(int n | n = strictcount(nthMissing(switch, _)) |
|
||||
if n > 3
|
||||
then msg = "Switch statement does not have a case for $@, $@, $@, or " + (n - 3) + " more."
|
||||
else msg = "Switch statement does not have a case for $@, $@, or $@."
|
||||
) and
|
||||
e1 = nthMissing(switch, 1) and
|
||||
e2 = nthMissing(switch, 2) and
|
||||
e3 = nthMissing(switch, 3)
|
||||
}
|
||||
|
||||
predicate only2(string msg, SwitchStmt switch, EnumConstant e1, EnumConstant e2) {
|
||||
msg = "Switch statement does not have a case for $@ or $@." and
|
||||
e1 = nthMissing(switch, 1) and
|
||||
e2 = nthMissing(switch, 2)
|
||||
}
|
||||
|
||||
predicate only1(string msg, SwitchStmt switch, EnumConstant e) {
|
||||
msg = "Switch statement does not have a case for $@." and
|
||||
e = nthMissing(switch, 1)
|
||||
}
|
||||
|
||||
from string msg, SwitchStmt switch, EnumConstant e1, EnumConstant e2, EnumConstant e3
|
||||
where
|
||||
if first3(_, switch, _, _, _)
|
||||
then first3(msg, switch, e1, e2, e3)
|
||||
else
|
||||
if only2(_, switch, _, _)
|
||||
then (
|
||||
only2(msg, switch, e1, e2) and e1 = e3
|
||||
) else (
|
||||
only1(msg, switch, e1) and e1 = e2 and e1 = e3
|
||||
)
|
||||
select switch, msg, e1, e1.getName(), e2, e2.getName(), e3, e3.getName()
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: majorAnalysis
|
||||
---
|
||||
* The `java/missing-case-in-switch` query now gives only a single alert for each switch statement, giving some examples of the missing cases as well as a count of how many are missing.
|
||||
@@ -0,0 +1,10 @@
|
||||
| Test.java:8:5:8:13 | switch (...) | Switch statement does not have a case for $@, $@, $@, or 22 more. | Test.java:4:27:4:27 | B | B | Test.java:4:25:4:25 | C | C | Test.java:4:45:4:45 | D | D |
|
||||
| Test.java:11:5:11:13 | switch (...) | Switch statement does not have a case for $@, $@, $@, or 21 more. | Test.java:4:25:4:25 | C | C | Test.java:4:45:4:45 | D | D | Test.java:4:15:4:15 | E | E |
|
||||
| Test.java:15:5:15:13 | switch (...) | Switch statement does not have a case for $@, $@, $@, or 20 more. | Test.java:4:45:4:45 | D | D | Test.java:4:15:4:15 | E | E | Test.java:4:43:4:43 | F | F |
|
||||
| Test.java:20:5:20:13 | switch (...) | Switch statement does not have a case for $@, $@, $@, or 19 more. | Test.java:4:15:4:15 | E | E | Test.java:4:43:4:43 | F | F | Test.java:4:49:4:49 | G | G |
|
||||
| Test.java:26:5:26:13 | switch (...) | Switch statement does not have a case for $@, $@, $@, or 18 more. | Test.java:4:43:4:43 | F | F | Test.java:4:49:4:49 | G | G | Test.java:4:35:4:35 | H | H |
|
||||
| Test.java:33:5:33:13 | switch (...) | Switch statement does not have a case for $@, $@, $@, or 2 more. | Test.java:4:21:4:21 | V | V | Test.java:4:13:4:13 | W | W | Test.java:4:23:4:23 | X | X |
|
||||
| Test.java:56:5:56:13 | switch (...) | Switch statement does not have a case for $@, $@, $@, or 1 more. | Test.java:4:13:4:13 | W | W | Test.java:4:23:4:23 | X | X | Test.java:4:11:4:11 | Y | Y |
|
||||
| Test.java:80:5:80:13 | switch (...) | Switch statement does not have a case for $@, $@, or $@. | Test.java:4:23:4:23 | X | X | Test.java:4:11:4:11 | Y | Y | Test.java:4:33:4:33 | Z | Z |
|
||||
| Test.java:105:5:105:13 | switch (...) | Switch statement does not have a case for $@ or $@. | Test.java:4:11:4:11 | Y | Y | Test.java:4:33:4:33 | Z | Z | Test.java:4:11:4:11 | Y | Y |
|
||||
| Test.java:131:5:131:13 | switch (...) | Switch statement does not have a case for $@. | Test.java:4:33:4:33 | Z | Z | Test.java:4:33:4:33 | Z | Z | Test.java:4:33:4:33 | Z | Z |
|
||||
@@ -0,0 +1 @@
|
||||
Likely Bugs/Statements/MissingEnumInSwitch.ql
|
||||
@@ -0,0 +1,187 @@
|
||||
public class Test {
|
||||
private enum MyEnum {
|
||||
// A..Z in random order
|
||||
N,R,S,Y,W,E,K,I,V,X,C,B,O,J,Z,H,T,P,A,F,D,M,G,U,L,Q
|
||||
}
|
||||
|
||||
public void use(MyEnum e) {
|
||||
switch(e) {
|
||||
case A: break;
|
||||
}
|
||||
switch(e) {
|
||||
case A: break;
|
||||
case B: break;
|
||||
}
|
||||
switch(e) {
|
||||
case A: break;
|
||||
case B: break;
|
||||
case C: break;
|
||||
}
|
||||
switch(e) {
|
||||
case A: break;
|
||||
case B: break;
|
||||
case C: break;
|
||||
case D: break;
|
||||
}
|
||||
switch(e) {
|
||||
case A: break;
|
||||
case B: break;
|
||||
case C: break;
|
||||
case D: break;
|
||||
case E: break;
|
||||
}
|
||||
switch(e) {
|
||||
case A: break;
|
||||
case B: break;
|
||||
case C: break;
|
||||
case D: break;
|
||||
case E: break;
|
||||
case F: break;
|
||||
case G: break;
|
||||
case H: break;
|
||||
case I: break;
|
||||
case J: break;
|
||||
case K: break;
|
||||
case L: break;
|
||||
case M: break;
|
||||
case N: break;
|
||||
case O: break;
|
||||
case P: break;
|
||||
case Q: break;
|
||||
case R: break;
|
||||
case S: break;
|
||||
case T: break;
|
||||
case U: break;
|
||||
}
|
||||
switch(e) {
|
||||
case A: break;
|
||||
case B: break;
|
||||
case C: break;
|
||||
case D: break;
|
||||
case E: break;
|
||||
case F: break;
|
||||
case G: break;
|
||||
case H: break;
|
||||
case I: break;
|
||||
case J: break;
|
||||
case K: break;
|
||||
case L: break;
|
||||
case M: break;
|
||||
case N: break;
|
||||
case O: break;
|
||||
case P: break;
|
||||
case Q: break;
|
||||
case R: break;
|
||||
case S: break;
|
||||
case T: break;
|
||||
case U: break;
|
||||
case V: break;
|
||||
}
|
||||
switch(e) {
|
||||
case A: break;
|
||||
case B: break;
|
||||
case C: break;
|
||||
case D: break;
|
||||
case E: break;
|
||||
case F: break;
|
||||
case G: break;
|
||||
case H: break;
|
||||
case I: break;
|
||||
case J: break;
|
||||
case K: break;
|
||||
case L: break;
|
||||
case M: break;
|
||||
case N: break;
|
||||
case O: break;
|
||||
case P: break;
|
||||
case Q: break;
|
||||
case R: break;
|
||||
case S: break;
|
||||
case T: break;
|
||||
case U: break;
|
||||
case V: break;
|
||||
case W: break;
|
||||
}
|
||||
switch(e) {
|
||||
case A: break;
|
||||
case B: break;
|
||||
case C: break;
|
||||
case D: break;
|
||||
case E: break;
|
||||
case F: break;
|
||||
case G: break;
|
||||
case H: break;
|
||||
case I: break;
|
||||
case J: break;
|
||||
case K: break;
|
||||
case L: break;
|
||||
case M: break;
|
||||
case N: break;
|
||||
case O: break;
|
||||
case P: break;
|
||||
case Q: break;
|
||||
case R: break;
|
||||
case S: break;
|
||||
case T: break;
|
||||
case U: break;
|
||||
case V: break;
|
||||
case W: break;
|
||||
case X: break;
|
||||
}
|
||||
switch(e) {
|
||||
case A: break;
|
||||
case B: break;
|
||||
case C: break;
|
||||
case D: break;
|
||||
case E: break;
|
||||
case F: break;
|
||||
case G: break;
|
||||
case H: break;
|
||||
case I: break;
|
||||
case J: break;
|
||||
case K: break;
|
||||
case L: break;
|
||||
case M: break;
|
||||
case N: break;
|
||||
case O: break;
|
||||
case P: break;
|
||||
case Q: break;
|
||||
case R: break;
|
||||
case S: break;
|
||||
case T: break;
|
||||
case U: break;
|
||||
case V: break;
|
||||
case W: break;
|
||||
case X: break;
|
||||
case Y: break;
|
||||
}
|
||||
switch(e) {
|
||||
case A: break;
|
||||
case B: break;
|
||||
case C: break;
|
||||
case D: break;
|
||||
case E: break;
|
||||
case F: break;
|
||||
case G: break;
|
||||
case H: break;
|
||||
case I: break;
|
||||
case J: break;
|
||||
case K: break;
|
||||
case L: break;
|
||||
case M: break;
|
||||
case N: break;
|
||||
case O: break;
|
||||
case P: break;
|
||||
case Q: break;
|
||||
case R: break;
|
||||
case S: break;
|
||||
case T: break;
|
||||
case U: break;
|
||||
case V: break;
|
||||
case W: break;
|
||||
case X: break;
|
||||
case Y: break;
|
||||
case Z: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user