mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Kotlin: Add a Kotlin 2 copy of the testsuite
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
import kotlinx.coroutines.*
|
||||
|
||||
suspend fun fn() {
|
||||
GlobalScope.launch {
|
||||
val x: Deferred<String> = async { Helper.taint() }
|
||||
Helper.sink(x.await()) // TODO: not found
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
class FunctionReference {
|
||||
|
||||
fun fn1(s: String) = s
|
||||
|
||||
suspend fun test() {
|
||||
fun fn2(s: String) = s
|
||||
|
||||
Helper.sink(Processor().process(this::fn1, Helper.taint()))
|
||||
Helper.sink(Processor().processSusp(this::fn1Susp, Helper.taint()))
|
||||
Helper.sink(Processor().process(FunctionReference::fn1, this, Helper.taint()))
|
||||
Helper.sink(Processor().process(this::fn1, Helper.notaint()))
|
||||
Helper.sink(Processor().process(::fn2, Helper.taint()))
|
||||
Helper.sink(Processor().process(::fn2, Helper.notaint()))
|
||||
|
||||
Helper.sink(Processor().process(this::prop))
|
||||
}
|
||||
|
||||
val prop: String
|
||||
get() = Helper.taint()
|
||||
|
||||
suspend fun fn1Susp(s: String) = s
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Stubs for `kotlinx.coroutines`
|
||||
*/
|
||||
|
||||
@file:JvmName("BuildersKt") // Required for `async`
|
||||
|
||||
package kotlinx.coroutines
|
||||
|
||||
public interface CoroutineScope
|
||||
public interface CoroutineContext
|
||||
public enum class CoroutineStart { DEFAULT }
|
||||
public interface Job
|
||||
public interface Deferred<out T> : Job {
|
||||
public suspend fun await(): T
|
||||
}
|
||||
|
||||
public object GlobalScope : CoroutineScope
|
||||
|
||||
public fun CoroutineScope.launch(
|
||||
context: CoroutineContext = null!!,
|
||||
start: CoroutineStart = CoroutineStart.DEFAULT,
|
||||
block: suspend CoroutineScope.() -> Unit
|
||||
): Job {
|
||||
return null!!
|
||||
}
|
||||
|
||||
public fun <T> CoroutineScope.async(
|
||||
context: CoroutineContext = null!!,
|
||||
start: CoroutineStart = CoroutineStart.DEFAULT,
|
||||
block: suspend CoroutineScope.() -> T
|
||||
): Deferred<T> {
|
||||
return null!!
|
||||
}
|
||||
|
||||
// Diagnostic Matches: % Couldn't get owner of KDoc. The comment is extracted without an owner. ...while extracting a file (kotlinx_coroutines_stubs.kt) at %kotlinx_coroutines_stubs.kt:1:1:36:0%
|
||||
33
java/ql/test-kotlin2/library-tests/dataflow/func/lambda.kt
Normal file
33
java/ql/test-kotlin2/library-tests/dataflow/func/lambda.kt
Normal file
@@ -0,0 +1,33 @@
|
||||
class Lambda {
|
||||
suspend fun test() {
|
||||
Helper.sink(Processor().process({ it: String -> Helper.notaint() }, ""))
|
||||
Helper.sink(Processor().process({ it: String -> Helper.taint() }, ""))
|
||||
Helper.sink(Processor().processSusp({ it: String -> Helper.taint() }, ""))
|
||||
Helper.sink(Processor().process({ i -> i }, Helper.taint()))
|
||||
Helper.sink(Processor().process(fun (i: String) = i, Helper.taint()))
|
||||
|
||||
Helper.sink(Processor().processExt({ i -> i }, Helper.taint(), Helper.notaint()))
|
||||
Helper.sink(Processor().processExt({ i -> i }, Helper.notaint(), Helper.taint()))
|
||||
Helper.sink(Processor().processExt({ i -> this }, Helper.taint(), Helper.notaint()))
|
||||
Helper.sink(Processor().processExt({ i -> this }, Helper.notaint(), Helper.taint()))
|
||||
|
||||
Helper.sink(Processor().process({ i0,i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15,i16,i17,i18,i19,i20,i21,i22,i23 -> i0 }, Helper.taint(), Helper.notaint()))
|
||||
Helper.sink(Processor().process({ i0,i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15,i16,i17,i18,i19,i20,i21,i22,i23 -> i0 }, Helper.notaint(), Helper.taint())) // False positive
|
||||
}
|
||||
}
|
||||
|
||||
class ManualBigLambda {
|
||||
fun invoke(s0: String, s1: String): String {
|
||||
return s0
|
||||
}
|
||||
fun invoke(a: Array<Any?>): String {
|
||||
return invoke(a[0] as String, a[1] as String)
|
||||
}
|
||||
|
||||
fun call() {
|
||||
Helper.sink(invoke(Helper.taint(), Helper.notaint()))
|
||||
Helper.sink(invoke(Helper.notaint(), Helper.taint()))
|
||||
Helper.sink(invoke(arrayOf(Helper.taint(), Helper.notaint())))
|
||||
Helper.sink(invoke(arrayOf(Helper.notaint(), Helper.taint()))) // False positive
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
class LocalFunction {
|
||||
suspend fun test() {
|
||||
fun fn1() = Helper.taint()
|
||||
fun fn2(s: String) = s
|
||||
|
||||
Helper.sink(fn1())
|
||||
Helper.sink(fn2(Helper.taint()))
|
||||
|
||||
suspend fun fn3() = Helper.taint()
|
||||
suspend fun fn4(s: String) = s
|
||||
|
||||
Helper.sink(fn3())
|
||||
Helper.sink(fn4(Helper.taint()))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
fun interface Predicate {
|
||||
fun go(s: String): String
|
||||
}
|
||||
|
||||
fun interface PredicateSusp {
|
||||
suspend fun go(s: String): String
|
||||
}
|
||||
|
||||
class SamConversion {
|
||||
suspend fun test() {
|
||||
val p1 = Predicate { Helper.taint() }
|
||||
val p2 = Predicate { it -> it }
|
||||
|
||||
Helper.sink(p1.go(""))
|
||||
Helper.sink(p2.go(Helper.taint()))
|
||||
|
||||
val p3 = PredicateSusp { Helper.taint() }
|
||||
val p4 = PredicateSusp { it -> it }
|
||||
|
||||
Helper.sink(p3.go(""))
|
||||
Helper.sink(p4.go(Helper.taint()))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
| functionReference.kt:8:52:8:65 | taint(...) | functionReference.kt:8:21:8:66 | process(...) |
|
||||
| functionReference.kt:10:71:10:84 | taint(...) | functionReference.kt:10:21:10:85 | process(...) |
|
||||
| functionReference.kt:12:48:12:61 | taint(...) | functionReference.kt:12:21:12:62 | process(...) |
|
||||
| functionReference.kt:19:17:19:30 | taint(...) | functionReference.kt:15:21:15:51 | process(...) |
|
||||
| lambda.kt:4:57:4:70 | taint(...) | lambda.kt:4:21:4:77 | process(...) |
|
||||
| lambda.kt:6:53:6:66 | taint(...) | lambda.kt:6:21:6:67 | process(...) |
|
||||
| lambda.kt:7:62:7:75 | taint(...) | lambda.kt:7:21:7:76 | process(...) |
|
||||
| lambda.kt:10:74:10:87 | taint(...) | lambda.kt:10:21:10:88 | processExt(...) |
|
||||
| lambda.kt:11:59:11:72 | taint(...) | lambda.kt:11:21:11:91 | processExt(...) |
|
||||
| lambda.kt:14:138:14:151 | taint(...) | lambda.kt:14:21:14:170 | process(...) |
|
||||
| lambda.kt:15:156:15:169 | taint(...) | lambda.kt:15:21:15:170 | process(...) |
|
||||
| lambda.kt:28:28:28:41 | taint(...) | lambda.kt:28:21:28:60 | invoke(...) |
|
||||
| lambda.kt:30:36:30:49 | taint(...) | lambda.kt:30:21:30:69 | invoke(...) |
|
||||
| lambda.kt:31:54:31:67 | taint(...) | lambda.kt:31:21:31:69 | invoke(...) |
|
||||
| localFunction.kt:3:21:3:34 | taint(...) | localFunction.kt:6:21:6:25 | fn1(...) |
|
||||
| localFunction.kt:7:25:7:38 | taint(...) | localFunction.kt:7:21:7:39 | fn2(...) |
|
||||
| localFunction.kt:9:29:9:42 | taint(...) | localFunction.kt:12:21:12:25 | fn3(...) |
|
||||
| localFunction.kt:13:25:13:38 | taint(...) | localFunction.kt:13:21:13:39 | fn4(...) |
|
||||
| samConversion.kt:11:30:11:43 | taint(...) | samConversion.kt:14:21:14:29 | go(...) |
|
||||
| samConversion.kt:15:27:15:40 | taint(...) | samConversion.kt:15:21:15:41 | go(...) |
|
||||
| samConversion.kt:17:34:17:47 | taint(...) | samConversion.kt:20:21:20:29 | go(...) |
|
||||
| samConversion.kt:21:27:21:40 | taint(...) | samConversion.kt:21:21:21:41 | go(...) |
|
||||
14
java/ql/test-kotlin2/library-tests/dataflow/func/test.ql
Normal file
14
java/ql/test-kotlin2/library-tests/dataflow/func/test.ql
Normal file
@@ -0,0 +1,14 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.TaintTracking
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node n) { n.asExpr().(MethodCall).getMethod().hasName("taint") }
|
||||
|
||||
predicate isSink(DataFlow::Node n) { n.asExpr().(Argument).getCall().getCallee().hasName("sink") }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
from DataFlow::Node src, DataFlow::Node sink
|
||||
where Flow::flow(src, sink)
|
||||
select src, sink
|
||||
35
java/ql/test-kotlin2/library-tests/dataflow/func/util.kt
Normal file
35
java/ql/test-kotlin2/library-tests/dataflow/func/util.kt
Normal file
@@ -0,0 +1,35 @@
|
||||
class Processor {
|
||||
fun <R1> process(f: () -> R1) : R1 {
|
||||
return f()
|
||||
}
|
||||
|
||||
fun <T, R2> process(f: (T) -> R2, arg: T) : R2 {
|
||||
return f(arg)
|
||||
}
|
||||
|
||||
suspend fun <T, R2> processSusp(f: suspend (T) -> R2, arg: T) : R2 {
|
||||
return f(arg)
|
||||
}
|
||||
|
||||
fun <T0, T1, R3> process(f: (T0, T1) -> R3, arg0: T0, arg1: T1) : R3 {
|
||||
return f(arg0, arg1)
|
||||
}
|
||||
|
||||
fun <T, R4> process(
|
||||
f: (T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,T) -> R4,
|
||||
a: T, b: T) : R4 {
|
||||
return f(a,b,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a)
|
||||
}
|
||||
|
||||
fun <T, R5> processExt(f: T.(T) -> R5, ext: T, arg: T) : R5 {
|
||||
return ext.f(arg)
|
||||
}
|
||||
}
|
||||
|
||||
class Helper {
|
||||
companion object {
|
||||
fun taint(): String = "taint"
|
||||
fun notaint(): String = "notaint"
|
||||
fun sink(a: Any?) { }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user