diff --git a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt index 1c2ed959caf2..79e6ce731202 100644 --- a/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt +++ b/java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt @@ -3903,7 +3903,12 @@ open class KotlinFileExtractor( val prop = getPropertiesByFqName(pluginContext, propertyPkg, propertyName) - .firstOrNull { it.owner.parentClassOrNull?.fqNameWhenAvailable?.asString() == type } + .firstOrNull { + val owner = it.owner + owner.parentClassOrNull?.fqNameWhenAvailable?.asString() == type || + (owner.parent is IrExternalPackageFragment && + getFileClassFqName(owner)?.asString() == type) + } ?.owner if (prop != null) { diff --git a/java/ql/lib/change-notes/2026-05-30-kclass-java-arg-k2-fix.md b/java/ql/lib/change-notes/2026-05-30-kclass-java-arg-k2-fix.md new file mode 100644 index 000000000000..5a51d3919801 --- /dev/null +++ b/java/ql/lib/change-notes/2026-05-30-kclass-java-arg-k2-fix.md @@ -0,0 +1,4 @@ +--- +category: majorAnalysis +--- +* Fixed an issue where `Foo::class.java` arguments were dropped during extraction under the Kotlin K2 compiler, which could cause false positives in queries such as `java/android/implicit-pendingintents`. \ No newline at end of file diff --git a/java/ql/test-kotlin2/library-tests/kclass-java-arg/Test.kt b/java/ql/test-kotlin2/library-tests/kclass-java-arg/Test.kt new file mode 100644 index 000000000000..c3bfc80fd03e --- /dev/null +++ b/java/ql/test-kotlin2/library-tests/kclass-java-arg/Test.kt @@ -0,0 +1,10 @@ +class Target + +class KClassJavaArg { + fun consume(c: Class<*>) {} + + fun test() { + // `Target::class.java` must be extracted as the argument to `consume`. + consume(Target::class.java) + } +} diff --git a/java/ql/test-kotlin2/library-tests/kclass-java-arg/options b/java/ql/test-kotlin2/library-tests/kclass-java-arg/options new file mode 100644 index 000000000000..fad4721475b7 --- /dev/null +++ b/java/ql/test-kotlin2/library-tests/kclass-java-arg/options @@ -0,0 +1 @@ +// codeql-extractor-kotlin-options: -language-version 2.0 -api-version 2.0 diff --git a/java/ql/test-kotlin2/library-tests/kclass-java-arg/test.expected b/java/ql/test-kotlin2/library-tests/kclass-java-arg/test.expected new file mode 100644 index 000000000000..7410c1676f77 --- /dev/null +++ b/java/ql/test-kotlin2/library-tests/kclass-java-arg/test.expected @@ -0,0 +1 @@ +| consume | Class | diff --git a/java/ql/test-kotlin2/library-tests/kclass-java-arg/test.ql b/java/ql/test-kotlin2/library-tests/kclass-java-arg/test.ql new file mode 100644 index 000000000000..e4b98d76d1cd --- /dev/null +++ b/java/ql/test-kotlin2/library-tests/kclass-java-arg/test.ql @@ -0,0 +1,5 @@ +import java + +from MethodCall mc, Argument arg +where mc.getMethod().hasName("consume") and arg = mc.getAnArgument() +select mc.getMethod().getName(), arg.getType().getName()