mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
Kotlin: Add dataflow tests for stdlib calls
This commit is contained in:
@@ -6,4 +6,5 @@ import java
|
||||
|
||||
private module GeneratedFrameworks {
|
||||
private import apache.IOGenerated
|
||||
private import kotlin.StdLibGenerated
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* THIS FILE IS AN AUTO-GENERATED MODELS AS DATA FILE. DO NOT EDIT.
|
||||
* Definitions of taint steps in the StdLibGenerated framework.
|
||||
*/
|
||||
|
||||
import java
|
||||
private import semmle.code.java.dataflow.ExternalFlow
|
||||
@@ -4,17 +4,17 @@ class ListFlowTest {
|
||||
|
||||
fun test(l: MutableList<String>) {
|
||||
l[0] = taint("a")
|
||||
sink(l)
|
||||
sink(l[0])
|
||||
sink(l) // $ hasTaintFlow=a
|
||||
sink(l[0]) // $ hasValueFlow=a
|
||||
for (s in l) {
|
||||
sink(s)
|
||||
sink(s) // $ hasValueFlow=a
|
||||
}
|
||||
|
||||
val a = arrayOf(taint("a"), "b")
|
||||
sink(a)
|
||||
sink(a[0])
|
||||
val a = arrayOf(taint("b"), "c")
|
||||
sink(a) // $ hasTaintFlow=b
|
||||
sink(a[0]) // $ hasValueFlow=b
|
||||
for (s in a) {
|
||||
sink(s)
|
||||
sink(s) // $ hasValueFlow=b
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,26 @@
|
||||
| list.kt:6:23:6:23 | a | list.kt:7:14:7:14 | l |
|
||||
| list.kt:6:23:6:23 | a | list.kt:8:14:8:17 | get(...) |
|
||||
| list.kt:6:23:6:23 | a | list.kt:10:18:10:18 | s |
|
||||
| list.kt:13:32:13:32 | a | list.kt:14:14:14:14 | a |
|
||||
| list.kt:13:32:13:32 | a | list.kt:15:14:15:17 | ...[...] |
|
||||
| list.kt:13:32:13:32 | a | list.kt:17:18:17:18 | s |
|
||||
| test.kt:16:53:16:69 | // $ hasTaintFlow | Missing result:hasTaintFlow= |
|
||||
| test.kt:17:53:17:69 | // $ hasTaintFlow | Missing result:hasTaintFlow= |
|
||||
| test.kt:20:53:20:69 | // $ hasTaintFlow | Missing result:hasTaintFlow= |
|
||||
| test.kt:21:53:21:69 | // $ hasTaintFlow | Missing result:hasTaintFlow= |
|
||||
| test.kt:23:53:23:69 | // $ hasTaintFlow | Missing result:hasTaintFlow= |
|
||||
| test.kt:26:53:26:71 | // $ hasTaintFlow=a | Missing result:hasTaintFlow=a |
|
||||
| test.kt:27:53:27:71 | // $ hasTaintFlow=a | Missing result:hasTaintFlow=a |
|
||||
| test.kt:30:57:30:75 | // $ hasTaintFlow=b | Missing result:hasTaintFlow=b |
|
||||
| test.kt:31:57:31:75 | // $ hasTaintFlow=c | Missing result:hasTaintFlow=c |
|
||||
| test.kt:34:53:34:71 | // $ hasTaintFlow=d | Missing result:hasTaintFlow=d |
|
||||
| test.kt:36:53:36:71 | // $ hasTaintFlow=d | Missing result:hasTaintFlow=d |
|
||||
| test.kt:39:53:39:71 | // $ hasTaintFlow=e | Missing result:hasTaintFlow=e |
|
||||
| test.kt:40:53:40:71 | // $ hasTaintFlow=e | Missing result:hasTaintFlow=e |
|
||||
| test.kt:44:53:44:71 | // $ hasTaintFlow=a | Missing result:hasTaintFlow=a |
|
||||
| test.kt:45:53:45:71 | // $ hasTaintFlow=a | Missing result:hasTaintFlow=a |
|
||||
| test.kt:47:53:47:71 | // $ hasTaintFlow=a | Missing result:hasTaintFlow=a |
|
||||
| test.kt:51:53:51:71 | // $ hasTaintFlow=f | Missing result:hasTaintFlow=f |
|
||||
| test.kt:52:53:52:71 | // $ hasTaintFlow=f | Missing result:hasTaintFlow=f |
|
||||
| test.kt:56:53:56:71 | // $ hasTaintFlow=g | Missing result:hasTaintFlow=g |
|
||||
| test.kt:57:53:57:71 | // $ hasTaintFlow=g | Missing result:hasTaintFlow=g |
|
||||
| test.kt:61:53:61:71 | // $ hasTaintFlow=h | Missing result:hasTaintFlow=h |
|
||||
| test.kt:63:53:63:71 | // $ hasTaintFlow=h | Missing result:hasTaintFlow=h |
|
||||
| test.kt:66:53:66:71 | // $ hasTaintFlow=i | Missing result:hasTaintFlow=i |
|
||||
| test.kt:67:53:67:71 | // $ hasTaintFlow=i | Missing result:hasTaintFlow=i |
|
||||
| test.kt:68:53:68:71 | // $ hasTaintFlow=i | Missing result:hasTaintFlow=i |
|
||||
| test.kt:71:53:71:71 | // $ hasTaintFlow=i | Missing result:hasTaintFlow=i |
|
||||
|
||||
75
java/ql/test/kotlin/library-tests/dataflow/summaries/test.kt
Normal file
75
java/ql/test/kotlin/library-tests/dataflow/summaries/test.kt
Normal file
@@ -0,0 +1,75 @@
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.ExperimentalTime
|
||||
import kotlin.time.TimedValue
|
||||
|
||||
class Test {
|
||||
fun <T> taint(t: T) = t
|
||||
fun sink(a: Any) {}
|
||||
|
||||
@OptIn(ExperimentalTime::class)
|
||||
fun test(b: ByteArray,
|
||||
f: kotlin.io.FileTreeWalk,
|
||||
c1: CharArray,
|
||||
c2: CharArray,
|
||||
c3: CharArray,) {
|
||||
|
||||
sink(taint(b).copyOf()) // $ hasTaintFlow
|
||||
sink(taint(f).maxDepth(1)) // $ hasTaintFlow
|
||||
|
||||
val sb = StringBuilder()
|
||||
sink(sb.insertRange(0, taint(c1), 0, 0)) // $ hasTaintFlow
|
||||
sink(sb) // $ hasTaintFlow
|
||||
|
||||
sink(taint(c2) + c3) // $ hasTaintFlow
|
||||
|
||||
val p = Pair(taint("a"), "")
|
||||
sink(p) // $ hasTaintFlow=a
|
||||
sink(p.component1()) // $ hasTaintFlow=a
|
||||
sink(p.second)
|
||||
|
||||
sink(taint("b").capitalize()) // $ hasTaintFlow=b
|
||||
sink(taint("c").replaceFirstChar { _ -> 'x' }) // $ hasTaintFlow=c
|
||||
|
||||
val t = Triple("", taint("d"), "")
|
||||
sink(t) // $ hasTaintFlow=d
|
||||
sink(t.component1())
|
||||
sink(t.second) // $ hasTaintFlow=d
|
||||
|
||||
val p1 = taint("e") to ""
|
||||
sink(p1) // $ hasTaintFlow=e
|
||||
sink(p1.component1()) // $ hasTaintFlow=e
|
||||
sink(p1.second)
|
||||
|
||||
val l = p.toList()
|
||||
sink(l) // $ hasTaintFlow=a
|
||||
sink(l[0]) // $ hasTaintFlow=a
|
||||
for (s in l) {
|
||||
sink(s) // $ hasTaintFlow=a
|
||||
}
|
||||
|
||||
val tv = TimedValue(taint("f"), Duration.parse(""))
|
||||
sink(tv) // $ hasTaintFlow=f
|
||||
sink(tv.component1()) // $ hasTaintFlow=f
|
||||
sink(tv.duration)
|
||||
|
||||
val mg0 = MatchGroup(taint("g"), IntRange(0, 10))
|
||||
sink(mg0) // $ hasTaintFlow=g
|
||||
sink(mg0.value) // $ hasTaintFlow=g
|
||||
sink(mg0.component2())
|
||||
|
||||
val iv = IndexedValue<String>(5, taint("h"))
|
||||
sink(iv) // $ hasTaintFlow=h
|
||||
sink(iv.index)
|
||||
sink(iv.component2()) // $ hasTaintFlow=h
|
||||
|
||||
val strings = arrayOf("", taint("i"))
|
||||
sink(strings.withIndex()) // $ hasTaintFlow=i
|
||||
sink(strings.withIndex().toList()) // $ hasTaintFlow=i
|
||||
sink(strings.withIndex().toList()[0].value) // $ hasTaintFlow=i
|
||||
sink(strings.withIndex().toList()[0].index)
|
||||
for (x in strings.withIndex()) {
|
||||
sink(x.value) // $ hasTaintFlow=i
|
||||
sink(x.index)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,2 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
import semmle.code.java.dataflow.ExternalFlow
|
||||
|
||||
class Conf extends TaintTracking::Configuration {
|
||||
Conf() { this = "qltest:mad-summaries" }
|
||||
|
||||
override predicate isSource(DataFlow::Node n) {
|
||||
n.asExpr().(Argument).getCall().getCallee().hasName("taint")
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node n) {
|
||||
n.asExpr().(Argument).getCall().getCallee().hasName("sink")
|
||||
}
|
||||
}
|
||||
|
||||
from DataFlow::Node src, DataFlow::Node sink, Conf conf
|
||||
where conf.hasFlow(src, sink)
|
||||
select src, sink
|
||||
import TestUtilities.InlineFlowTest
|
||||
|
||||
Reference in New Issue
Block a user