import org.checkerframework.checker.tainting.qual.Untainted import org.checkerframework.checker.tainting.qual.Tainted open class LocalInference { fun simpleInit() { val s1 = source() val s = s1 sink(s) } fun concatInit() { val s1 = "foo" + source() + "bar" val s = "foo" + s1 + "bar" sink(s) } fun recursive() { var s1 = source() val s = s1 s1 = s sink(s) } fun blocks() { var s1: String? run { s1 = source() run { val s = s1 sink(s) } } } fun transitive() { val s2: String = source() + source() val s1 = s2 + safe() val s = s1 sink(s) } fun transitiveRecursive(b: Boolean) { var s = "" val s1 = s val s2 = s1 + foo() val s3 = s2 if (b) s = s3 sink(s) } open fun foo(): String { return "" } fun safe(): @Untainted String { return "safe" } @Tainted fun source(): String { return "tainted" } fun sink(s1: @Untainted String?) {} inline fun T.run(block: T.() -> R): R { return block() } }