Skip to content

Commit bf46fa2

Browse files
author
Dave Bartolomeo
committed
Merge remote-tracking branch 'origin/main' into dbartol/rc3.13-mergeback
2 parents 311ba8e + aeb667c commit bf46fa2

File tree

18 files changed

+300
-63
lines changed

18 files changed

+300
-63
lines changed

cpp/ql/lib/semmle/code/cpp/controlflow/IRGuards.qll

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,9 @@ class GuardCondition extends Expr {
138138
cached
139139
predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) { none() }
140140

141-
/** Holds if (determined by this guard) `e == k` evaluates to `areEqual` if this expression evaluates to `testIsTrue`. */
141+
/** Holds if (determined by this guard) `e == k` evaluates to `areEqual` if this expression evaluates to `value`. */
142142
cached
143-
predicate comparesEq(Expr e, int k, boolean areEqual, boolean testIsTrue) { none() }
143+
predicate comparesEq(Expr e, int k, boolean areEqual, AbstractValue value) { none() }
144144

145145
/**
146146
* Holds if (determined by this guard) `e == k` must be `areEqual` in `block`.
@@ -196,17 +196,18 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardCondition {
196196
)
197197
}
198198

199-
override predicate comparesEq(Expr e, int k, boolean areEqual, boolean testIsTrue) {
200-
exists(boolean partIsTrue, GuardCondition part |
201-
this.(BinaryLogicalOperation).impliesValue(part, partIsTrue, testIsTrue)
199+
override predicate comparesEq(Expr e, int k, boolean areEqual, AbstractValue value) {
200+
exists(BooleanValue partValue, GuardCondition part |
201+
this.(BinaryLogicalOperation)
202+
.impliesValue(part, partValue.getValue(), value.(BooleanValue).getValue())
202203
|
203-
part.comparesEq(e, k, areEqual, partIsTrue)
204+
part.comparesEq(e, k, areEqual, partValue)
204205
)
205206
}
206207

207208
override predicate ensuresEq(Expr e, int k, BasicBlock block, boolean areEqual) {
208-
exists(boolean testIsTrue |
209-
this.comparesEq(e, k, areEqual, testIsTrue) and this.controls(block, testIsTrue)
209+
exists(AbstractValue value |
210+
this.comparesEq(e, k, areEqual, value) and this.valueControls(block, value)
210211
)
211212
}
212213
}
@@ -270,18 +271,18 @@ private class GuardConditionFromIR extends GuardCondition {
270271
)
271272
}
272273

273-
override predicate comparesEq(Expr e, int k, boolean areEqual, boolean testIsTrue) {
274+
override predicate comparesEq(Expr e, int k, boolean areEqual, AbstractValue value) {
274275
exists(Instruction i |
275276
i.getUnconvertedResultExpression() = e and
276-
ir.comparesEq(i.getAUse(), k, areEqual, testIsTrue)
277+
ir.comparesEq(i.getAUse(), k, areEqual, value)
277278
)
278279
}
279280

280281
override predicate ensuresEq(Expr e, int k, BasicBlock block, boolean areEqual) {
281-
exists(Instruction i, boolean testIsTrue |
282+
exists(Instruction i, AbstractValue value |
282283
i.getUnconvertedResultExpression() = e and
283-
ir.comparesEq(i.getAUse(), k, areEqual, testIsTrue) and
284-
this.controls(block, testIsTrue)
284+
ir.comparesEq(i.getAUse(), k, areEqual, value) and
285+
this.valueControls(block, value)
285286
)
286287
}
287288

@@ -492,19 +493,10 @@ class IRGuardCondition extends Instruction {
492493
)
493494
}
494495

495-
/** Holds if (determined by this guard) `op == k` evaluates to `areEqual` if this expression evaluates to `testIsTrue`. */
496+
/** Holds if (determined by this guard) `op == k` evaluates to `areEqual` if this expression evaluates to `value`. */
496497
cached
497-
predicate comparesEq(Operand op, int k, boolean areEqual, boolean testIsTrue) {
498-
exists(MatchValue mv |
499-
compares_eq(this, op, k, areEqual, mv) and
500-
// A match value cannot be dualized, so `testIsTrue` is always true
501-
testIsTrue = true
502-
)
503-
or
504-
exists(BooleanValue bv |
505-
compares_eq(this, op, k, areEqual, bv) and
506-
bv.getValue() = testIsTrue
507-
)
498+
predicate comparesEq(Operand op, int k, boolean areEqual, AbstractValue value) {
499+
compares_eq(this, op, k, areEqual, value)
508500
}
509501

510502
/**

cpp/ql/test/library-tests/controlflow/guards-ir/tests.ql

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import semmle.code.cpp.controlflow.IRGuards
44
query predicate astGuards(GuardCondition guard) { any() }
55

66
query predicate astGuardsCompare(int startLine, string msg) {
7-
exists(GuardCondition guard, Expr left, int k, string which, string op |
8-
exists(boolean sense |
7+
exists(GuardCondition guard, Expr left, int k, string op |
8+
exists(boolean sense, string which |
99
sense = true and which = "true"
1010
or
1111
sense = false and which = "false"
@@ -21,14 +21,16 @@ query predicate astGuardsCompare(int startLine, string msg) {
2121
|
2222
msg = left + op + right + "+" + k + " when " + guard + " is " + which
2323
)
24+
)
25+
or
26+
exists(AbstractValue value |
27+
guard.comparesEq(left, k, true, value) and op = " == "
2428
or
25-
(
26-
guard.comparesEq(left, k, true, sense) and op = " == "
27-
or
28-
guard.comparesEq(left, k, false, sense) and op = " != "
29-
) and
30-
msg = left + op + k + " when " + guard + " is " + which
31-
) and
29+
guard.comparesEq(left, k, false, value) and op = " != "
30+
|
31+
msg = left + op + k + " when " + guard + " is " + value
32+
)
33+
|
3234
startLine = guard.getLocation().getStartLine()
3335
)
3436
}
@@ -71,8 +73,8 @@ query predicate astGuardsEnsure_const(
7173
query predicate irGuards(IRGuardCondition guard) { any() }
7274

7375
query predicate irGuardsCompare(int startLine, string msg) {
74-
exists(IRGuardCondition guard, Operand left, int k, string which, string op |
75-
exists(boolean sense |
76+
exists(IRGuardCondition guard, Operand left, int k, string op |
77+
exists(boolean sense, string which |
7678
sense = true and which = "true"
7779
or
7880
sense = false and which = "false"
@@ -91,16 +93,18 @@ query predicate irGuardsCompare(int startLine, string msg) {
9193
right.getAnyDef().getUnconvertedResultExpression() + "+" + k + " when " + guard + " is "
9294
+ which
9395
)
96+
)
97+
or
98+
exists(AbstractValue value |
99+
guard.comparesEq(left, k, true, value) and op = " == "
94100
or
95-
(
96-
guard.comparesEq(left, k, true, sense) and op = " == "
97-
or
98-
guard.comparesEq(left, k, false, sense) and op = " != "
99-
) and
101+
guard.comparesEq(left, k, false, value) and op = " != "
102+
|
100103
msg =
101104
left.getAnyDef().getUnconvertedResultExpression() + op + k + " when " + guard + " is " +
102-
which
103-
) and
105+
value
106+
)
107+
|
104108
startLine = guard.getLocation().getStartLine()
105109
)
106110
}

cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.expected

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@
5555
| 58 | y < 0+0 when ... < ... is true |
5656
| 58 | y >= 0+0 when ... < ... is false |
5757
| 58 | y >= 0+0 when ... \|\| ... is false |
58-
| 61 | i == 0 when i is true |
59-
| 61 | i == 1 when i is true |
60-
| 61 | i == 2 when i is true |
58+
| 61 | i == 0 when i is Case[0] |
59+
| 61 | i == 1 when i is Case[1] |
60+
| 61 | i == 2 when i is Case[2] |
6161
| 75 | 0 != x+0 when ... == ... is false |
6262
| 75 | 0 == x+0 when ... == ... is true |
6363
| 75 | x != 0 when ... == ... is false |

cpp/ql/test/library-tests/controlflow/guards/GuardsCompare.ql

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
import cpp
88
import semmle.code.cpp.controlflow.Guards
99

10-
from GuardCondition guard, Expr left, int k, string which, string op, string msg
10+
from GuardCondition guard, Expr left, int k, string op, string msg
1111
where
12-
exists(boolean sense |
12+
exists(boolean sense, string which |
1313
sense = true and which = "true"
1414
or
1515
sense = false and which = "false"
@@ -25,12 +25,13 @@ where
2525
|
2626
msg = left + op + right + "+" + k + " when " + guard + " is " + which
2727
)
28+
)
29+
or
30+
exists(AbstractValue value |
31+
guard.comparesEq(left, k, true, value) and op = " == "
2832
or
29-
(
30-
guard.comparesEq(left, k, true, sense) and op = " == "
31-
or
32-
guard.comparesEq(left, k, false, sense) and op = " != "
33-
) and
34-
msg = left + op + k + " when " + guard + " is " + which
33+
guard.comparesEq(left, k, false, value) and op = " != "
34+
|
35+
msg = left + op + k + " when " + guard + " is " + value
3536
)
3637
select guard.getLocation().getStartLine(), msg

cpp/ql/test/library-tests/ir/ir/PrintAST.expected

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,6 +1781,12 @@ destructors_for_temps.cpp:
17811781
# 15| getQualifier(): [ConstructorCall] call to ClassWithDestructor2
17821782
# 15| Type = [VoidType] void
17831783
# 15| ValueCategory = prvalue
1784+
# 15| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor2
1785+
# 15| Type = [VoidType] void
1786+
# 15| ValueCategory = prvalue
1787+
# 15| getQualifier(): [ReuseExpr] reuse of temporary object
1788+
# 15| Type = [Class] ClassWithDestructor2
1789+
# 15| ValueCategory = xvalue
17841790
# 15| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object
17851791
# 15| Type = [Class] ClassWithDestructor2
17861792
# 15| ValueCategory = prvalue(load)
@@ -1804,6 +1810,12 @@ destructors_for_temps.cpp:
18041810
# 16| getQualifier().getFullyConverted(): [TemporaryObjectExpr] temporary object
18051811
# 16| Type = [Class] ClassWithDestructor2
18061812
# 16| ValueCategory = prvalue(load)
1813+
# 16| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor2
1814+
# 16| Type = [VoidType] void
1815+
# 16| ValueCategory = prvalue
1816+
# 16| getQualifier(): [ReuseExpr] reuse of temporary object
1817+
# 16| Type = [Class] ClassWithDestructor2
1818+
# 16| ValueCategory = xvalue
18071819
# 17| getStmt(2): [ReturnStmt] return ...
18081820
# 17| getExpr(): [FunctionCall] call to get_x
18091821
# 17| Type = [PlainCharType] char
@@ -18145,6 +18157,12 @@ ir.cpp:
1814518157
# 2293| getArgument(0).getFullyConverted(): [ArrayToPointerConversion] array to pointer conversion
1814618158
# 2293| Type = [PointerType] const char *
1814718159
# 2293| ValueCategory = prvalue
18160+
# 2293| getImplicitDestructorCall(0): [DestructorCall] call to ~String
18161+
# 2293| Type = [VoidType] void
18162+
# 2293| ValueCategory = prvalue
18163+
# 2293| getQualifier(): [ReuseExpr] reuse of temporary object
18164+
# 2293| Type = [Struct] String
18165+
# 2293| ValueCategory = xvalue
1814818166
# 2293| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object
1814918167
# 2293| Type = [Struct] String
1815018168
# 2293| ValueCategory = lvalue

java/ql/lib/ext/java.io.model.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,13 @@ extensions:
7878
- ["java.io", "File", True, "getCanonicalFile", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
7979
- ["java.io", "File", True, "getCanonicalPath", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
8080
- ["java.io", "File", True, "getName", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
81+
- ["java.io", "File", True, "getParent", "()", "", "Argument[this]", "ReturnValue", "taint", "df-manual"]
8182
- ["java.io", "File", True, "getParentFile", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
8283
- ["java.io", "File", True, "getPath", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
8384
- ["java.io", "File", True, "toPath", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
8485
- ["java.io", "File", True, "toString", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
8586
- ["java.io", "File", True, "toURI", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
87+
- ["java.io", "File", True, "toURL", "()", "", "Argument[this]", "ReturnValue", "taint", "df-manual"]
8688
- ["java.io", "FilterOutputStream", True, "FilterOutputStream", "(OutputStream)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
8789
- ["java.io", "InputStream", True, "read", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"]
8890
- ["java.io", "InputStream", True, "read", "(byte[])", "", "Argument[this]", "Argument[0]", "taint", "manual"]
@@ -118,6 +120,7 @@ extensions:
118120
- ["java.io", "File", "listFiles", "", "summary", "df-manual"]
119121
- ["java.io", "File", "mkdirs", "()", "summary", "manual"]
120122
- ["java.io", "FileInputStream", "FileInputStream", "(File)", "summary", "manual"]
123+
- ["java.io", "FileInputStream", "FileInputStream", "(FileDescriptor)", "summary", "df-manual"]
121124
- ["java.io", "FileInputStream", "FileInputStream", "(String)", "summary", "df-manual"]
122125
- ["java.io", "InputStream", "close", "()", "summary", "manual"]
123126
- ["java.io", "ObjectInput", "readObject", "()", "summary", "df-manual"] # this is a deserialization sink modeled in regular CodeQL

java/ql/lib/ext/java.lang.model.yml

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ extensions:
114114
- ["java.lang", "String", False, "indent", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
115115
- ["java.lang", "String", False, "intern", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
116116
- ["java.lang", "String", False, "join", "", "", "Argument[0..1]", "ReturnValue", "taint", "manual"]
117+
- ["java.lang", "String", False, "lines", "()", "", "Argument[this]", "ReturnValue.Element", "taint", "df-manual"]
117118
- ["java.lang", "String", False, "repeat", "(int)", "", "Argument[this]", "ReturnValue", "taint", "manual"]
118119
- ["java.lang", "String", False, "replace", "", "", "Argument[this]", "ReturnValue", "taint", "manual"]
119120
- ["java.lang", "String", False, "replace", "", "", "Argument[1]", "ReturnValue", "taint", "manual"]
@@ -185,8 +186,19 @@ extensions:
185186
- ["java.lang", "Class", "isAssignableFrom", "(Class)", "summary", "manual"]
186187
- ["java.lang", "Class", "isInstance", "(Object)", "summary", "manual"]
187188
- ["java.lang", "Class", "toString", "()", "summary", "manual"]
189+
- ["java.lang", "ClassLoader", "findResource", "(String)", "summary", "df-manual"]
190+
- ["java.lang", "ClassLoader", "getDefinedPackage", "(String)", "summary", "df-manual"]
191+
- ["java.lang", "ClassLoader", "getDefinedPackage", "(String)", "summary", "df-manual"]
192+
- ["java.lang", "ClassLoader", "getName", "()", "summary", "df-manual"]
193+
- ["java.lang", "ClassLoader", "getParent", "()", "summary", "df-manual"]
188194
- ["java.lang", "ClassLoader", "getResource", "(String)", "summary", "manual"]
189195
- ["java.lang", "ClassLoader", "getResourceAsStream", "(String)", "summary", "manual"]
196+
- ["java.lang", "ClassLoader", "getSystemResource", "(String)", "summary", "df-manual"]
197+
- ["java.lang", "ClassLoader", "getUnnamedModule", "()", "summary", "df-manual"]
198+
- ["java.lang", "ClassLoader", "loadClass", "(String)", "summary", "df-manual"]
199+
- ["java.lang", "ClassLoader", "loadClass", "(String,boolean)", "summary", "df-manual"]
200+
- ["java.lang", "ClassLoader", "setClassAssertionStatus", "(String,boolean)", "summary", "df-manual"]
201+
- ["java.lang", "ClassLoader", "setPackageAssertionStatus", "(String,boolean)", "summary", "df-manual"]
190202
- ["java.lang", "Enum", "Enum", "(String,int)", "summary", "manual"]
191203
- ["java.lang", "Enum", "equals", "(Object)", "summary", "manual"]
192204
- ["java.lang", "Enum", "hashCode", "()", "summary", "manual"]
@@ -228,14 +240,14 @@ extensions:
228240
- ["java.lang", "Thread", "interrupt", "()", "summary", "manual"]
229241
- ["java.lang", "Thread", "sleep", "(long)", "summary", "manual"]
230242
- ["java.lang", "Thread", "start", "()", "summary", "manual"]
231-
- ["java.lang", "Throwable", "addSuppressed", "(Throwable)", "summary", "manual"]
232-
- ["java.lang", "Throwable", "fillInStackTrace", "()", "summary", "manual"]
233-
- ["java.lang", "Throwable", "getStackTrace", "()", "summary", "manual"]
234-
- ["java.lang", "Throwable", "getSuppressed", "()", "summary", "manual"]
235-
- ["java.lang", "Throwable", "printStackTrace", "()", "summary", "manual"]
236-
- ["java.lang", "Throwable", "printStackTrace", "(PrintStream)", "summary", "manual"]
237-
- ["java.lang", "Throwable", "printStackTrace", "(PrintWriter)", "summary", "manual"]
238-
- ["java.lang", "Throwable", "setStackTrace", "(StackTraceElement[])", "summary", "manual"]
243+
- ["java.lang", "Throwable", "addSuppressed", "(Throwable)", "summary", "df-manual"]
244+
- ["java.lang", "Throwable", "fillInStackTrace", "()", "summary", "df-manual"]
245+
- ["java.lang", "Throwable", "getStackTrace", "()", "summary", "df-manual"]
246+
- ["java.lang", "Throwable", "getSuppressed", "()", "summary", "df-manual"]
247+
- ["java.lang", "Throwable", "printStackTrace", "()", "summary", "df-manual"]
248+
- ["java.lang", "Throwable", "printStackTrace", "(PrintStream)", "summary", "df-manual"]
249+
- ["java.lang", "Throwable", "printStackTrace", "(PrintWriter)", "summary", "df-manual"]
250+
- ["java.lang", "Throwable", "setStackTrace", "(StackTraceElement[])", "summary", "df-manual"]
239251
# The below APIs have numeric flow and are currently being stored as neutral models.
240252
# These may be changed to summary models with kinds "value-numeric" and "taint-numeric" (or similar) in the future.
241253
- ["java.lang", "Double", "doubleToLongBits", "(double)", "summary", "manual"] # taint-numeric

java/ql/lib/ext/java.net.model.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,5 @@ extensions:
6767
data:
6868
# summary neutrals
6969
- ["java.net", "Socket", "getOutputStream", "()", "summary", "df-manual"]
70+
- ["java.net", "Socket", "connect", "(SocketAddress)", "summary", "df-manual"]
7071
- ["java.net", "Socket", "connect", "(SocketAddress,int)", "summary", "df-manual"]

java/ql/lib/ext/java.nio.file.model.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ extensions:
9191
data:
9292
# summary neutrals
9393
- ["java.nio.file", "Files", "exists", "(Path,LinkOption[])", "summary", "manual"]
94-
- ["java.nio.file", "Files", "newInputStream", "(Path,LinkOption[])", "summary", "df-manual"]
94+
- ["java.nio.file", "Files", "newInputStream", "(Path,OpenOption[])", "summary", "df-manual"]
9595
# sink neutrals
9696
- ["java.nio.file", "Files", "getLastModifiedTime", "", "sink", "hq-manual"]
9797
- ["java.nio.file", "Files", "getOwner", "", "sink", "hq-manual"]

0 commit comments

Comments
 (0)