mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Kotlin: Implement JvmOverloads annotation
This generates functions that omit parameters with default values, rightmost first, such that Java can achieve a similar experience to Kotlin (which represents calls internally as if the default was supplied explicitly, and/or uses a $default method that supplies the needed arguments). A complication: combining JvmOverloads with JvmStatic means that both the companion object and the surrounding class get overloads.
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
public class User {
|
||||
|
||||
public static String source() { return "taint"; }
|
||||
|
||||
public static void test(Test2 t2, GenericTest<Integer> gt) {
|
||||
|
||||
Test.taintSuppliedAsDefault(1, "no taint", 2);
|
||||
Test.taintSuppliedAsDefault(1, 2);
|
||||
Test.noTaintByDefault(1, source(), 2, 3);
|
||||
Test.noTaintByDefault(1, source(), 2);
|
||||
|
||||
Test2.taintSuppliedAsDefaultStatic(1, "no taint", 2);
|
||||
Test2.taintSuppliedAsDefaultStatic(1, 2);
|
||||
Test2.noTaintByDefaultStatic(1, source(), 2, 3);
|
||||
Test2.noTaintByDefaultStatic(1, source(), 2);
|
||||
|
||||
t2.taintSuppliedAsDefault(1, "no taint", 2);
|
||||
t2.taintSuppliedAsDefault(1, 2);
|
||||
t2.noTaintByDefault(1, source(), 2, 3);
|
||||
t2.noTaintByDefault(1, source(), 2);
|
||||
|
||||
gt.taintSuppliedAsDefault(1, "no taint", 2);
|
||||
gt.taintSuppliedAsDefault(1, 2);
|
||||
gt.noTaintByDefault(1, source(), 2, 3);
|
||||
gt.noTaintByDefault(1, source(), 2);
|
||||
|
||||
new ConstructorTaintsByDefault(1, "no taint", 2);
|
||||
new ConstructorTaintsByDefault(1, 2);
|
||||
new ConstructorDoesNotTaintByDefault(1, source(), 2, 3);
|
||||
new ConstructorDoesNotTaintByDefault(1, source(), 2);
|
||||
|
||||
new GenericConstructorTaintsByDefault<Integer>(1, "no taint", 2);
|
||||
new GenericConstructorTaintsByDefault<Integer>(1, 2);
|
||||
new GenericConstructorDoesNotTaintByDefault<Integer>(1, source(), 2, 3);
|
||||
new GenericConstructorDoesNotTaintByDefault<Integer>(1, source(), 2);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
| User.java:9:30:9:37 | source(...) | test.kt:13:97:13:97 | s |
|
||||
| User.java:10:30:10:37 | source(...) | test.kt:13:97:13:97 | s |
|
||||
| User.java:14:37:14:44 | source(...) | test.kt:25:105:25:105 | s |
|
||||
| User.java:15:37:15:44 | source(...) | test.kt:25:105:25:105 | s |
|
||||
| User.java:19:28:19:35 | source(...) | test.kt:33:97:33:97 | s |
|
||||
| User.java:20:28:20:35 | source(...) | test.kt:33:97:33:97 | s |
|
||||
| User.java:24:28:24:35 | source(...) | test.kt:43:93:43:93 | s |
|
||||
| User.java:25:28:25:35 | source(...) | test.kt:43:93:43:93 | s |
|
||||
| User.java:29:45:29:52 | source(...) | test.kt:58:10:58:10 | s |
|
||||
| User.java:30:45:30:52 | source(...) | test.kt:58:10:58:10 | s |
|
||||
| User.java:34:61:34:68 | source(...) | test.kt:74:10:74:10 | s |
|
||||
| User.java:35:61:35:68 | source(...) | test.kt:74:10:74:10 | s |
|
||||
| test.kt:10:55:10:62 | source(...) | test.kt:10:84:10:84 | s |
|
||||
| test.kt:22:63:22:70 | source(...) | test.kt:22:92:22:92 | s |
|
||||
| test.kt:22:63:22:70 | source(...) | test.kt:22:92:22:92 | s |
|
||||
| test.kt:30:55:30:62 | source(...) | test.kt:30:84:30:84 | s |
|
||||
| test.kt:40:53:40:60 | source(...) | test.kt:40:80:40:80 | s |
|
||||
| test.kt:47:92:47:99 | source(...) | test.kt:50:10:50:10 | s |
|
||||
| test.kt:63:100:63:107 | source(...) | test.kt:66:10:66:10 | s |
|
||||
@@ -0,0 +1,78 @@
|
||||
fun getString() = "Hello world"
|
||||
|
||||
fun source() = "tainted"
|
||||
|
||||
fun sink(s: String) { }
|
||||
|
||||
object Test {
|
||||
|
||||
@JvmOverloads @JvmStatic
|
||||
fun taintSuppliedAsDefault(before: Int, s: String = source(), after: Int) { sink(s) }
|
||||
|
||||
@JvmOverloads @JvmStatic
|
||||
fun noTaintByDefault(before: Int, s: String = "no taint", after: Int, after2: Int = 1) { sink(s) }
|
||||
|
||||
}
|
||||
|
||||
public class Test2 {
|
||||
|
||||
companion object {
|
||||
|
||||
@JvmOverloads @JvmStatic
|
||||
fun taintSuppliedAsDefaultStatic(before: Int, s: String = source(), after: Int) { sink(s) }
|
||||
|
||||
@JvmOverloads @JvmStatic
|
||||
fun noTaintByDefaultStatic(before: Int, s: String = "no taint", after: Int, after2: Int = 1) { sink(s) }
|
||||
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun taintSuppliedAsDefault(before: Int, s: String = source(), after: Int) { sink(s) }
|
||||
|
||||
@JvmOverloads
|
||||
fun noTaintByDefault(before: Int, s: String = "no taint", after: Int, after2: Int = 1) { sink(s) }
|
||||
|
||||
}
|
||||
|
||||
public class GenericTest<T> {
|
||||
|
||||
@JvmOverloads
|
||||
fun taintSuppliedAsDefault(before: T, s: String = source(), after: T) { sink(s) }
|
||||
|
||||
@JvmOverloads
|
||||
fun noTaintByDefault(before: T, s: String = "no taint", after: T, after2: Int = 1) { sink(s) }
|
||||
|
||||
}
|
||||
|
||||
public class ConstructorTaintsByDefault @JvmOverloads constructor(before: Int, s: String = source(), after: Int) {
|
||||
|
||||
init {
|
||||
sink(s)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class ConstructorDoesNotTaintByDefault @JvmOverloads constructor(before: Int, s: String = "no taint", after: Int, after2: Int = 1) {
|
||||
|
||||
init {
|
||||
sink(s)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class GenericConstructorTaintsByDefault<T> @JvmOverloads constructor(before: T, s: String = source(), after: T) {
|
||||
|
||||
init {
|
||||
sink(s)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class GenericConstructorDoesNotTaintByDefault<T> @JvmOverloads constructor(before: T, s: String = "no taint", after: T, after2: T? = null) {
|
||||
|
||||
init {
|
||||
sink(s)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
from create_database_utils import *
|
||||
|
||||
os.mkdir('kbuild')
|
||||
run_codeql_database_create(["kotlinc test.kt -d kbuild", "javac User.java -cp kbuild"], lang="java")
|
||||
@@ -0,0 +1,18 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
|
||||
class Config extends DataFlow::Configuration {
|
||||
Config() { this = "config" }
|
||||
|
||||
override predicate isSource(DataFlow::Node n) {
|
||||
n.asExpr().(MethodAccess).getCallee().getName() = "source"
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node n) {
|
||||
n.asExpr().(Argument).getCall().getCallee().getName() = "sink"
|
||||
}
|
||||
}
|
||||
|
||||
from Config c, DataFlow::Node source, DataFlow::Node sink
|
||||
where c.hasFlow(source, sink)
|
||||
select source, sink
|
||||
Reference in New Issue
Block a user