mirror of
https://github.com/github/codeql.git
synced 2025-12-22 11:46:32 +01:00
Merge branch 'main' into post-release-prep/codeql-cli-2.10.0
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
import java
|
||||
|
||||
from MethodAccess ma
|
||||
where not exists(ma.getQualifier()) and ma.getFile().isKotlinSourceFile()
|
||||
// Generally Kotlin calls will always use an explicit qualifier, except for calls
|
||||
// to the synthetic instance initializer <obinit>, which use an implicit `this`.
|
||||
where
|
||||
not exists(ma.getQualifier()) and
|
||||
ma.getFile().isKotlinSourceFile() and
|
||||
not ma.getCallee() instanceof InstanceInitializer
|
||||
select ma
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
a.kt:
|
||||
# 0| [CompilationUnit] a
|
||||
# 1| 1: [Class] A
|
||||
# 0| 1: [Method] <fn>
|
||||
# 0| 3: [TypeAccess] int
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [ReturnStmt] return ...
|
||||
# 0| 0: [IntegerLiteral] 42
|
||||
# 1| 2: [Constructor] A
|
||||
# 1| 5: [BlockStmt] { ... }
|
||||
# 1| 0: [SuperConstructorInvocationStmt] super(...)
|
||||
# 1| 1: [BlockStmt] { ... }
|
||||
# 2| 3: [Method] f1
|
||||
# 2| 3: [TypeAccess] int
|
||||
# 2| 5: [BlockStmt] { ... }
|
||||
# 2| 0: [ReturnStmt] return ...
|
||||
# 2| 0: [IntegerLiteral] 1
|
||||
b.kt:
|
||||
# 0| [CompilationUnit] b
|
||||
# 1| 1: [Class] B
|
||||
# 0| 1: [Method] <fn>
|
||||
# 0| 3: [TypeAccess] int
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [ReturnStmt] return ...
|
||||
# 0| 0: [UnsafeCoerceExpr] <unsafe coerce>
|
||||
# 0| 0: [TypeAccess] int
|
||||
# 0| 1: [IntegerLiteral] 1
|
||||
# 1| 2: [Constructor] B
|
||||
# 1| 5: [BlockStmt] { ... }
|
||||
# 1| 0: [SuperConstructorInvocationStmt] super(...)
|
||||
# 1| 1: [BlockStmt] { ... }
|
||||
c.kt:
|
||||
# 0| [CompilationUnit] c
|
||||
# 1| 1: [Class] C
|
||||
# 0| 1: [Method] <fn>
|
||||
# 0| 3: [TypeAccess] Unit
|
||||
#-----| 4: (Parameters)
|
||||
# 0| 0: [Parameter] param
|
||||
# 0| 0: [TypeAccess] ProcessBuilder
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [ReturnStmt] return ...
|
||||
# 0| 0: [MethodAccess] start(...)
|
||||
# 0| -1: [VarAccess] param
|
||||
# 1| 2: [Constructor] C
|
||||
# 1| 5: [BlockStmt] { ... }
|
||||
# 1| 0: [SuperConstructorInvocationStmt] super(...)
|
||||
# 1| 1: [BlockStmt] { ... }
|
||||
d.kt:
|
||||
# 0| [CompilationUnit] d
|
||||
# 1| 1: [Class] D
|
||||
# 0| 1: [FieldDeclaration] String bar;
|
||||
# 0| -1: [TypeAccess] String
|
||||
# 0| 0: [StringLiteral] Foobar
|
||||
# 1| 3: [Constructor] D
|
||||
# 1| 5: [BlockStmt] { ... }
|
||||
# 1| 0: [SuperConstructorInvocationStmt] super(...)
|
||||
# 1| 1: [BlockStmt] { ... }
|
||||
e.kt:
|
||||
# 0| [CompilationUnit] e
|
||||
# 1| 1: [Class] E
|
||||
# 0| 1: [Method] <fn_ArrayListAdd>
|
||||
# 0| 3: [TypeAccess] boolean
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [ReturnStmt] return ...
|
||||
# 0| 0: [MethodAccess] add(...)
|
||||
# 0| -1: [ClassInstanceExpr] new ArrayList<Object>(...)
|
||||
# 0| -3: [TypeAccess] ArrayList<Object>
|
||||
# 0| 0: [IntegerLiteral] 1
|
||||
# 0| 0: [NullLiteral] null
|
||||
# 0| 1: [Method] <fn_LinkedHashMap>
|
||||
# 0| 3: [TypeAccess] Object
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [ReturnStmt] return ...
|
||||
# 0| 0: [MethodAccess] put(...)
|
||||
# 0| -1: [ClassInstanceExpr] new LinkedHashMap<Object,Object>(...)
|
||||
# 0| -3: [TypeAccess] LinkedHashMap<Object,Object>
|
||||
# 0| 0: [IntegerLiteral] 1
|
||||
# 0| 0: [NullLiteral] null
|
||||
# 0| 1: [NullLiteral] null
|
||||
# 1| 3: [Constructor] E
|
||||
# 1| 5: [BlockStmt] { ... }
|
||||
# 1| 0: [SuperConstructorInvocationStmt] super(...)
|
||||
# 1| 1: [BlockStmt] { ... }
|
||||
@@ -0,0 +1 @@
|
||||
semmle/code/java/PrintAst.ql
|
||||
@@ -0,0 +1,3 @@
|
||||
class A {
|
||||
fun f1() = 1
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
class B {
|
||||
}
|
||||
53
java/ql/integration-tests/linux-only/kotlin/custom_plugin/build_plugin
Executable file
53
java/ql/integration-tests/linux-only/kotlin/custom_plugin/build_plugin
Executable file
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import subprocess
|
||||
import shutil
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
import shlex
|
||||
|
||||
|
||||
def run_process(cmd):
|
||||
try:
|
||||
print("Running command: " + shlex.join(cmd))
|
||||
return subprocess.run(cmd, check=True, capture_output=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
print("In: " + os.getcwd(), file=sys.stderr)
|
||||
print("Command failed: " + shlex.join(cmd), file=sys.stderr)
|
||||
print("stdout output:\n" + e.stdout.decode(encoding='UTF-8',
|
||||
errors='strict'), file=sys.stderr)
|
||||
print("stderr output:\n" + e.stderr.decode(encoding='UTF-8',
|
||||
errors='strict'), file=sys.stderr)
|
||||
raise e
|
||||
|
||||
root = '../../../../../../../../..'
|
||||
|
||||
sys.path.append(root + '/ql/java/kotlin-extractor')
|
||||
import kotlin_plugin_versions
|
||||
defaultKotlinDependencyVersion = kotlin_plugin_versions.get_single_version()
|
||||
|
||||
builddir = 'build'
|
||||
dependency_dir = root + '/resources/kotlin-dependencies/'
|
||||
dependencies = ['kotlin-stdlib-' + defaultKotlinDependencyVersion +
|
||||
'.jar', 'kotlin-compiler-' + defaultKotlinDependencyVersion + '.jar']
|
||||
classpath = ':'.join([dependency_dir + dep for dep in dependencies])
|
||||
srcs = ['plugin/Plugin.kt']
|
||||
output = 'plugin.jar'
|
||||
|
||||
if os.path.exists(builddir):
|
||||
shutil.rmtree(builddir)
|
||||
os.makedirs(builddir)
|
||||
|
||||
run_process(['kotlinc',
|
||||
'-J-Xmx2G',
|
||||
'-d', builddir,
|
||||
'-module-name', 'test',
|
||||
'-no-reflect', '-no-stdlib',
|
||||
'-jvm-target', '1.8',
|
||||
'-classpath', classpath] + srcs)
|
||||
|
||||
run_process(['jar', '-c', '-f', output,
|
||||
'-C', builddir, '.',
|
||||
'-C', 'plugin/resources', 'META-INF'])
|
||||
shutil.rmtree(builddir)
|
||||
@@ -0,0 +1 @@
|
||||
class C { }
|
||||
@@ -0,0 +1 @@
|
||||
class D { }
|
||||
@@ -0,0 +1,2 @@
|
||||
| CodeQL Kotlin extractor | 2 | | IrProperty without a getter | d.kt:0:0:0:0 | d.kt:0:0:0:0 |
|
||||
| CodeQL Kotlin extractor | 2 | | Not rewriting trap file for: Boolean -1.0-0- -1.0-0-null test-db/trap/java/classes/kotlin/Boolean.members.trap.gz | file://:0:0:0:0 | file://:0:0:0:0 |
|
||||
13
java/ql/integration-tests/linux-only/kotlin/custom_plugin/diagnostics.ql
Executable file
13
java/ql/integration-tests/linux-only/kotlin/custom_plugin/diagnostics.ql
Executable file
@@ -0,0 +1,13 @@
|
||||
import java
|
||||
|
||||
from string genBy, int severity, string tag, string msg, Location l
|
||||
where
|
||||
diagnostics(_, genBy, severity, tag, msg, _, l) and
|
||||
(
|
||||
// Different installations get different sets of these messages,
|
||||
// so we filter out all but one that happens everywhere.
|
||||
msg.matches("Not rewriting trap file for: %")
|
||||
implies
|
||||
msg.matches("Not rewriting trap file for: Boolean %")
|
||||
)
|
||||
select genBy, severity, tag, msg, l
|
||||
@@ -0,0 +1 @@
|
||||
class E { }
|
||||
@@ -0,0 +1,7 @@
|
||||
| a.kt:0:0:0:0 | <fn> | has body |
|
||||
| a.kt:2:5:2:16 | f1 | has body |
|
||||
| b.kt:0:0:0:0 | <fn> | has body |
|
||||
| c.kt:0:0:0:0 | <fn> | has body |
|
||||
| d.kt:0:0:0:0 | <clinit> | has body |
|
||||
| e.kt:0:0:0:0 | <fn_ArrayListAdd> | has body |
|
||||
| e.kt:0:0:0:0 | <fn_LinkedHashMap> | has body |
|
||||
7
java/ql/integration-tests/linux-only/kotlin/custom_plugin/methods.ql
Executable file
7
java/ql/integration-tests/linux-only/kotlin/custom_plugin/methods.ql
Executable file
@@ -0,0 +1,7 @@
|
||||
import java
|
||||
|
||||
from Method m, string body
|
||||
where
|
||||
m.fromSource() and
|
||||
if exists(m.getBody()) then body = "has body" else body = "has no body"
|
||||
select m, body
|
||||
@@ -0,0 +1,280 @@
|
||||
package com.github.codeql
|
||||
|
||||
import com.intellij.mock.MockProject
|
||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
|
||||
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
|
||||
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.*
|
||||
import org.jetbrains.kotlin.ir.builders.irCall
|
||||
import org.jetbrains.kotlin.ir.builders.irExprBody
|
||||
import org.jetbrains.kotlin.ir.builders.irGet
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.defaultType
|
||||
import org.jetbrains.kotlin.ir.types.typeWith
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class TestComponentRegistrar : ComponentRegistrar {
|
||||
override fun registerProjectComponents(
|
||||
project: MockProject,
|
||||
configuration: CompilerConfiguration
|
||||
) {
|
||||
IrGenerationExtension.registerExtension(project, IrAdder())
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||
class IrAdder : IrGenerationExtension {
|
||||
override fun generate(moduleFragment: IrModuleFragment, pluginContext: IrPluginContext) {
|
||||
|
||||
class AndroidSymbols {
|
||||
private val irFactory: IrFactory = IrFactoryImpl
|
||||
private val kotlinJvmInternalPackage: IrPackageFragment = createPackage("kotlin.jvm.internal")
|
||||
private val javaUtil: IrPackageFragment = createPackage("java.util")
|
||||
|
||||
private fun createPackage(packageName: String): IrPackageFragment =
|
||||
IrExternalPackageFragmentImpl.createEmptyExternalPackageFragment(
|
||||
moduleFragment.descriptor,
|
||||
FqName(packageName)
|
||||
)
|
||||
|
||||
private fun createClass(
|
||||
irPackage: IrPackageFragment,
|
||||
shortName: String,
|
||||
classKind: ClassKind,
|
||||
classModality: Modality
|
||||
): IrClassSymbol = irFactory.buildClass {
|
||||
name = Name.identifier(shortName)
|
||||
kind = classKind
|
||||
modality = classModality
|
||||
}.apply {
|
||||
parent = irPackage
|
||||
createImplicitParameterDeclarationWithWrappedDescriptor()
|
||||
}.symbol
|
||||
|
||||
val unsafeCoerceIntrinsic: IrSimpleFunctionSymbol =
|
||||
irFactory.buildFun {
|
||||
name = Name.special("<unsafe-coerce>")
|
||||
origin = IrDeclarationOrigin.IR_BUILTINS_STUB
|
||||
}.apply {
|
||||
parent = kotlinJvmInternalPackage
|
||||
val src = addTypeParameter("T", pluginContext.irBuiltIns.anyNType)
|
||||
val dst = addTypeParameter("R", pluginContext.irBuiltIns.anyNType)
|
||||
addValueParameter("v", src.defaultType)
|
||||
returnType = dst.defaultType
|
||||
}.symbol
|
||||
|
||||
val javaUtilArrayList: IrClassSymbol =
|
||||
createClass(javaUtil, "ArrayList", ClassKind.CLASS, Modality.OPEN)
|
||||
|
||||
val javaUtilLinkedHashMap: IrClassSymbol =
|
||||
createClass(javaUtil, "LinkedHashMap", ClassKind.CLASS, Modality.OPEN)
|
||||
|
||||
val arrayListConstructor: IrConstructorSymbol = javaUtilArrayList.owner.addConstructor().apply {
|
||||
addValueParameter("p_0", pluginContext.irBuiltIns.intType)
|
||||
}.symbol
|
||||
|
||||
val arrayListAdd: IrSimpleFunctionSymbol =
|
||||
javaUtilArrayList.owner.addFunction("add", pluginContext.irBuiltIns.booleanType).apply {
|
||||
addValueParameter("p_0", pluginContext.irBuiltIns.anyNType)
|
||||
}.symbol
|
||||
|
||||
val linkedHashMapConstructor: IrConstructorSymbol =
|
||||
javaUtilLinkedHashMap.owner.addConstructor().apply {
|
||||
addValueParameter("p_0", pluginContext.irBuiltIns.intType)
|
||||
}.symbol
|
||||
|
||||
val linkedHashMapPut: IrSimpleFunctionSymbol =
|
||||
javaUtilLinkedHashMap.owner.addFunction("put", pluginContext.irBuiltIns.anyNType).apply {
|
||||
addValueParameter("p_0", pluginContext.irBuiltIns.anyNType)
|
||||
addValueParameter("p_1", pluginContext.irBuiltIns.anyNType)
|
||||
}.symbol
|
||||
}
|
||||
|
||||
moduleFragment.transform(object: IrElementTransformerVoidWithContext() {
|
||||
override fun visitClassNew(declaration: IrClass): IrStatement {
|
||||
if (declaration.name.asString() == "A") {
|
||||
addFunWithExprBody(declaration)
|
||||
} else if (declaration.name.asString() == "B") {
|
||||
addFunWithUnsafeCoerce(declaration)
|
||||
} else if (declaration.name.asString() == "C") {
|
||||
addFunWithStubClass(declaration)
|
||||
} else if (declaration.name.asString() == "D") {
|
||||
addStaticFieldWithExprInit(declaration)
|
||||
} else if (declaration.name.asString() == "E") {
|
||||
addFunWithArrayListAdd(declaration)
|
||||
addFunWithLinkedHashMapPut(declaration)
|
||||
}
|
||||
|
||||
return super.visitClassNew(declaration)
|
||||
}
|
||||
|
||||
fun unsafeCoerce(value: IrExpression, fromType: IrType, toType: IrType): IrExpression {
|
||||
return IrCallImpl.fromSymbolOwner(-1, -1, toType, AndroidSymbols().unsafeCoerceIntrinsic).apply {
|
||||
putTypeArgument(0, fromType)
|
||||
putTypeArgument(1, toType)
|
||||
putValueArgument(0, value)
|
||||
}
|
||||
}
|
||||
|
||||
private fun arrayListAdd(): IrExpression {
|
||||
// ArrayList(1).add(null)
|
||||
var androidSymbols = AndroidSymbols()
|
||||
return IrCallImpl.fromSymbolOwner(-1, -1, pluginContext.irBuiltIns.booleanType, androidSymbols.arrayListAdd).apply {
|
||||
dispatchReceiver = IrConstructorCallImpl.fromSymbolOwner(-1,-1, androidSymbols.javaUtilArrayList.typeWith(), androidSymbols.arrayListConstructor).apply {
|
||||
putValueArgument(0, IrConstImpl.int(-1, -1, pluginContext.irBuiltIns.intType, 1))
|
||||
}
|
||||
putValueArgument(0, IrConstImpl.constNull(-1,-1, pluginContext.irBuiltIns.anyNType))
|
||||
}
|
||||
}
|
||||
|
||||
private fun linkedHashMapPut(): IrExpression {
|
||||
// LinkedHashMap(1).put(null, null)
|
||||
var androidSymbols = AndroidSymbols()
|
||||
return IrCallImpl.fromSymbolOwner(-1, -1, pluginContext.irBuiltIns.anyNType, androidSymbols.linkedHashMapPut).apply {
|
||||
dispatchReceiver = IrConstructorCallImpl.fromSymbolOwner(-1,-1, androidSymbols.javaUtilLinkedHashMap.typeWith(), androidSymbols.linkedHashMapConstructor).apply {
|
||||
putValueArgument(0, IrConstImpl.int(-1, -1, pluginContext.irBuiltIns.intType, 1))
|
||||
}
|
||||
putValueArgument(0, IrConstImpl.constNull(-1,-1, pluginContext.irBuiltIns.anyNType))
|
||||
putValueArgument(1, IrConstImpl.constNull(-1,-1, pluginContext.irBuiltIns.anyNType))
|
||||
}
|
||||
}
|
||||
|
||||
private fun addFunWithArrayListAdd(declaration: IrClass) {
|
||||
declaration.declarations.add(pluginContext.irFactory.buildFun {
|
||||
name = Name.identifier("<fn_ArrayListAdd>")
|
||||
returnType = pluginContext.irBuiltIns.booleanType
|
||||
}. also {
|
||||
it.body = DeclarationIrBuilder(pluginContext, it.symbol)
|
||||
.irExprBody(
|
||||
arrayListAdd()
|
||||
)
|
||||
it.parent = declaration
|
||||
})
|
||||
}
|
||||
|
||||
private fun addFunWithLinkedHashMapPut(declaration: IrClass) {
|
||||
declaration.declarations.add(pluginContext.irFactory.buildFun {
|
||||
name = Name.identifier("<fn_LinkedHashMap>")
|
||||
returnType = pluginContext.irBuiltIns.anyNType
|
||||
}. also {
|
||||
it.body = DeclarationIrBuilder(pluginContext, it.symbol)
|
||||
.irExprBody(
|
||||
linkedHashMapPut()
|
||||
)
|
||||
it.parent = declaration
|
||||
})
|
||||
}
|
||||
|
||||
private fun addFunWithUnsafeCoerce(declaration: IrClass) {
|
||||
val uintType = pluginContext.referenceClass(FqName("kotlin.UInt"))!!.owner.typeWith()
|
||||
declaration.declarations.add(pluginContext.irFactory.buildFun {
|
||||
name = Name.identifier("<fn>")
|
||||
returnType = uintType
|
||||
}. also {
|
||||
it.body = DeclarationIrBuilder(pluginContext, it.symbol)
|
||||
.irExprBody(
|
||||
unsafeCoerce(IrConstImpl.int(-1, -1, pluginContext.irBuiltIns.intType, 1), pluginContext.irBuiltIns.intType, uintType)
|
||||
)
|
||||
it.parent = declaration
|
||||
})
|
||||
}
|
||||
|
||||
private fun addFunWithExprBody(declaration: IrClass) {
|
||||
declaration.declarations.add(pluginContext.irFactory.buildFun {
|
||||
name = Name.identifier("<fn>")
|
||||
returnType = pluginContext.irBuiltIns.intType
|
||||
}. also {
|
||||
it.body = DeclarationIrBuilder(pluginContext, it.symbol)
|
||||
.irExprBody(
|
||||
IrConstImpl.int(-1, -1, pluginContext.irBuiltIns.intType, 42)
|
||||
)
|
||||
it.parent = declaration
|
||||
})
|
||||
}
|
||||
|
||||
private fun addStaticFieldWithExprInit(declaration: IrClass) {
|
||||
declaration.declarations.add(pluginContext.irFactory.buildProperty {
|
||||
name = Name.identifier("bar")
|
||||
isConst = true
|
||||
visibility = DescriptorVisibilities.PRIVATE
|
||||
}.also { irProperty ->
|
||||
irProperty.backingField = pluginContext.irFactory.buildField {
|
||||
name = Name.identifier("bar")
|
||||
type = pluginContext.irBuiltIns.stringType
|
||||
isStatic = true
|
||||
visibility = DescriptorVisibilities.PRIVATE
|
||||
}.also { irField ->
|
||||
irField.initializer = DeclarationIrBuilder(pluginContext, irField.symbol)
|
||||
.irExprBody(
|
||||
IrConstImpl.string(-1, -1, pluginContext.irBuiltIns.stringType, "Foobar")
|
||||
)
|
||||
irField.parent = declaration
|
||||
}
|
||||
irProperty.parent = declaration
|
||||
})
|
||||
}
|
||||
|
||||
val javaLangPackage = IrExternalPackageFragmentImpl.createEmptyExternalPackageFragment(pluginContext.moduleDescriptor, FqName("java.lang"))
|
||||
|
||||
private fun makeJavaLangClass(fnName: String) = pluginContext.irFactory.buildClass {
|
||||
name = Name.identifier(fnName)
|
||||
kind = ClassKind.CLASS
|
||||
origin = IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB
|
||||
}.apply {
|
||||
parent = javaLangPackage
|
||||
createImplicitParameterDeclarationWithWrappedDescriptor()
|
||||
}
|
||||
|
||||
// This adds a function with a parameter whose type is a real class without its supertypes specified,
|
||||
// mimicking the behaviour of the Kotlin android extensions gradle plugin, which refers to some real
|
||||
// Android classes through these sorts of synthetic, incomplete references. The extractor should
|
||||
// respond by replacing them with the real version available on the classpath.
|
||||
// I pick the particular java.lang class "ProcessBuilder" since it is (a) always available and
|
||||
// (b) not normally extracted by this project.
|
||||
private fun addFunWithStubClass(declaration: IrClass) {
|
||||
declaration.declarations.add(pluginContext.irFactory.buildFun {
|
||||
name = Name.identifier("<fn>")
|
||||
returnType = pluginContext.irBuiltIns.unitType
|
||||
}. also { addedFn ->
|
||||
val processBuilderStub = makeJavaLangClass("ProcessBuilder")
|
||||
val processBuilderStubType = processBuilderStub.defaultType
|
||||
val startProcessMethod = processBuilderStub.addFunction {
|
||||
name = Name.identifier("start")
|
||||
origin = IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB
|
||||
modality = Modality.FINAL
|
||||
returnType = pluginContext.referenceClass(FqName("java.lang.Process"))!!.owner.defaultType
|
||||
}.apply {
|
||||
addDispatchReceiver { type = processBuilderStubType }
|
||||
}
|
||||
|
||||
val paramSymbol = addedFn.addValueParameter("param", processBuilderStubType)
|
||||
DeclarationIrBuilder(pluginContext, addedFn.symbol).apply {
|
||||
addedFn.body = irExprBody(irCall(startProcessMethod).apply { dispatchReceiver = irGet(paramSymbol) })
|
||||
addedFn.parent = declaration
|
||||
}
|
||||
})
|
||||
}
|
||||
}, null)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
com.github.codeql.TestComponentRegistrar
|
||||
@@ -0,0 +1,4 @@
|
||||
| file://:0:0:0:0 | fake.kotlin | FakeKotlinClass |
|
||||
| file://:0:0:0:0 | java.lang | Object |
|
||||
| file://:0:0:0:0 | kotlin | Any |
|
||||
| file://:0:0:0:0 | kotlin | TypeParam |
|
||||
@@ -0,0 +1,5 @@
|
||||
import java
|
||||
|
||||
from ClassOrInterface ci
|
||||
where not exists(ci.getASupertype())
|
||||
select ci.getPackage(), ci.toString()
|
||||
@@ -0,0 +1 @@
|
||||
| d.kt:0:0:0:0 | bar | d.kt:0:0:0:0 | Foobar |
|
||||
@@ -0,0 +1,5 @@
|
||||
import java
|
||||
|
||||
from Field f, Expr init
|
||||
where init = f.getInitializer()
|
||||
select f, init
|
||||
@@ -0,0 +1,6 @@
|
||||
from create_database_utils import *
|
||||
import subprocess
|
||||
|
||||
subprocess.call("./build_plugin", shell=True)
|
||||
run_codeql_database_create(
|
||||
["kotlinc -J-Xmx2G -Xplugin=plugin.jar a.kt b.kt c.kt d.kt e.kt"], lang="java")
|
||||
2
java/ql/integration-tests/linux-only/kotlin/qlpack.yml
Normal file
2
java/ql/integration-tests/linux-only/kotlin/qlpack.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
libraryPathDependencies:
|
||||
- codeql-java
|
||||
@@ -0,0 +1,8 @@
|
||||
package extlib;
|
||||
|
||||
public class BoundedGenericTest<T extends CharSequence> {
|
||||
|
||||
public void method(T t) { }
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package extlib;
|
||||
|
||||
public class ComplexBoundedGenericTest<A extends CharSequence, B extends A> {
|
||||
|
||||
public void method(A a, B b) { }
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
package extlib;
|
||||
|
||||
public class GenericTest<T> {
|
||||
|
||||
public void method(T t) { }
|
||||
|
||||
public void takesSelfMethod(GenericTest<T> selfLike) { }
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package extlib;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class Lib {
|
||||
|
||||
public void testParameterTypes(
|
||||
char p1,
|
||||
byte p2,
|
||||
short p3,
|
||||
int p4,
|
||||
long p5,
|
||||
float p6,
|
||||
double p7,
|
||||
boolean p8,
|
||||
Lib simpleClass,
|
||||
GenericTest<String> simpleGeneric,
|
||||
BoundedGenericTest<String> boundedGeneric,
|
||||
ComplexBoundedGenericTest<CharSequence, String> complexBoundedGeneric,
|
||||
int[] primitiveArray,
|
||||
Integer[] boxedTypeArray,
|
||||
int [][] multiDimensionalPrimitiveArray,
|
||||
Integer[][] multiDimensionalBoxedTypeArray,
|
||||
List<String>[] genericTypeArray,
|
||||
List<? extends CharSequence> producerWildcard,
|
||||
List<? super CharSequence> consumerWildcard,
|
||||
List<? extends List<? extends CharSequence>> nestedWildcard,
|
||||
List<?> unboundedWildcard) { }
|
||||
|
||||
public List<Integer> returnErasureTest() { return null; }
|
||||
|
||||
public <T> void paramErasureTest(List<String> param) { }
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
parameterTypes
|
||||
| extlib.jar/extlib/GenericTest.class:0:0:0:0 | p0 | GenericTest<String> |
|
||||
| javasrc/extlib/GenericTest.java:7:31:7:53 | selfLike | GenericTest |
|
||||
| javasrc/extlib/Lib.java:8:5:8:11 | p1 | char |
|
||||
| javasrc/extlib/Lib.java:9:5:9:11 | p2 | byte |
|
||||
| javasrc/extlib/Lib.java:10:5:10:12 | p3 | short |
|
||||
| javasrc/extlib/Lib.java:11:5:11:10 | p4 | int |
|
||||
| javasrc/extlib/Lib.java:12:5:12:11 | p5 | long |
|
||||
| javasrc/extlib/Lib.java:13:5:13:12 | p6 | float |
|
||||
| javasrc/extlib/Lib.java:14:5:14:13 | p7 | double |
|
||||
| javasrc/extlib/Lib.java:15:5:15:14 | p8 | boolean |
|
||||
| javasrc/extlib/Lib.java:16:5:16:19 | simpleClass | Lib |
|
||||
| javasrc/extlib/Lib.java:17:5:17:37 | simpleGeneric | GenericTest<String> |
|
||||
| javasrc/extlib/Lib.java:18:5:18:45 | boundedGeneric | BoundedGenericTest<String> |
|
||||
| javasrc/extlib/Lib.java:19:5:19:73 | complexBoundedGeneric | ComplexBoundedGenericTest<CharSequence,String> |
|
||||
| javasrc/extlib/Lib.java:20:5:20:24 | primitiveArray | int[] |
|
||||
| javasrc/extlib/Lib.java:21:5:21:28 | boxedTypeArray | Integer[] |
|
||||
| javasrc/extlib/Lib.java:22:5:22:43 | multiDimensionalPrimitiveArray | int[][] |
|
||||
| javasrc/extlib/Lib.java:23:5:23:46 | multiDimensionalBoxedTypeArray | Integer[][] |
|
||||
| javasrc/extlib/Lib.java:24:5:24:35 | genericTypeArray | List<String>[] |
|
||||
| javasrc/extlib/Lib.java:25:5:25:49 | producerWildcard | List<? extends CharSequence> |
|
||||
| javasrc/extlib/Lib.java:26:5:26:47 | consumerWildcard | List<? super CharSequence> |
|
||||
| javasrc/extlib/Lib.java:27:5:27:63 | nestedWildcard | List<? extends List<? extends CharSequence>> |
|
||||
| javasrc/extlib/Lib.java:28:5:28:29 | unboundedWildcard | List<?> |
|
||||
arrayTypes
|
||||
| javasrc/extlib/Lib.java:20:5:20:24 | primitiveArray | file://:0:0:0:0 | int[] | int | 1 | int |
|
||||
| javasrc/extlib/Lib.java:21:5:21:28 | boxedTypeArray | file://:0:0:0:0 | Integer[] | Integer | 1 | Integer |
|
||||
| javasrc/extlib/Lib.java:22:5:22:43 | multiDimensionalPrimitiveArray | file://:0:0:0:0 | int[][] | int | 2 | int[] |
|
||||
| javasrc/extlib/Lib.java:23:5:23:46 | multiDimensionalBoxedTypeArray | file://:0:0:0:0 | Integer[][] | Integer | 2 | Integer[] |
|
||||
| javasrc/extlib/Lib.java:24:5:24:35 | genericTypeArray | file://:0:0:0:0 | List<String>[] | List<String> | 1 | List<String> |
|
||||
wildcardTypes
|
||||
| javasrc/extlib/Lib.java:25:5:25:49 | producerWildcard | file://:0:0:0:0 | ? extends CharSequence | upper | CharSequence |
|
||||
| javasrc/extlib/Lib.java:26:5:26:47 | consumerWildcard | file://:0:0:0:0 | ? super CharSequence | lower | CharSequence |
|
||||
| javasrc/extlib/Lib.java:26:5:26:47 | consumerWildcard | file://:0:0:0:0 | ? super CharSequence | upper | Object |
|
||||
| javasrc/extlib/Lib.java:27:5:27:63 | nestedWildcard | file://:0:0:0:0 | ? extends List<? extends CharSequence> | upper | List<? extends CharSequence> |
|
||||
| javasrc/extlib/Lib.java:28:5:28:29 | unboundedWildcard | file://:0:0:0:0 | ? | upper | Object |
|
||||
parameterizedTypes
|
||||
| extlib.jar/extlib/GenericTest.class:0:0:0:0 | p0 | GenericTest<String> | String |
|
||||
| javasrc/extlib/GenericTest.java:7:31:7:53 | selfLike | GenericTest | T |
|
||||
| javasrc/extlib/Lib.java:17:5:17:37 | simpleGeneric | GenericTest<String> | String |
|
||||
| javasrc/extlib/Lib.java:18:5:18:45 | boundedGeneric | BoundedGenericTest<String> | String |
|
||||
| javasrc/extlib/Lib.java:19:5:19:73 | complexBoundedGeneric | ComplexBoundedGenericTest<CharSequence,String> | CharSequence |
|
||||
| javasrc/extlib/Lib.java:19:5:19:73 | complexBoundedGeneric | ComplexBoundedGenericTest<CharSequence,String> | String |
|
||||
| javasrc/extlib/Lib.java:25:5:25:49 | producerWildcard | List<? extends CharSequence> | ? extends CharSequence |
|
||||
| javasrc/extlib/Lib.java:26:5:26:47 | consumerWildcard | List<? super CharSequence> | ? super CharSequence |
|
||||
| javasrc/extlib/Lib.java:27:5:27:63 | nestedWildcard | List<? extends List<? extends CharSequence>> | ? extends List<? extends CharSequence> |
|
||||
| javasrc/extlib/Lib.java:28:5:28:29 | unboundedWildcard | List<?> | ? |
|
||||
libCallables
|
||||
| javasrc/extlib/Lib.java:5:14:5:16 | Lib |
|
||||
| javasrc/extlib/Lib.java:7:15:7:32 | testParameterTypes |
|
||||
| javasrc/extlib/Lib.java:30:24:30:40 | returnErasureTest |
|
||||
| javasrc/extlib/Lib.java:32:19:32:34 | paramErasureTest |
|
||||
@@ -0,0 +1,40 @@
|
||||
import java
|
||||
|
||||
class ExtLibParameter extends Parameter {
|
||||
ExtLibParameter() { this.getCallable().getName() = ["testParameterTypes", "takesSelfMethod"] }
|
||||
}
|
||||
|
||||
query predicate parameterTypes(ExtLibParameter p, string t) { p.getType().toString() = t }
|
||||
|
||||
query predicate arrayTypes(
|
||||
ExtLibParameter p, Array at, string elementType, int dimension, string componentType
|
||||
) {
|
||||
p.getType() = at and
|
||||
at.getElementType().toString() = elementType and
|
||||
at.getDimension() = dimension and
|
||||
at.getComponentType().toString() = componentType
|
||||
}
|
||||
|
||||
query predicate wildcardTypes(ExtLibParameter p, Wildcard wc, string boundKind, string bound) {
|
||||
// Expose details of wildcard types:
|
||||
wc =
|
||||
[
|
||||
p.getType().(ParameterizedType).getATypeArgument(),
|
||||
p.getType().(ParameterizedType).getATypeArgument().(ParameterizedType).getATypeArgument()
|
||||
] and
|
||||
(
|
||||
boundKind = "upper" and bound = wc.getUpperBoundType().toString()
|
||||
or
|
||||
boundKind = "lower" and bound = wc.getLowerBoundType().toString()
|
||||
)
|
||||
}
|
||||
|
||||
query predicate parameterizedTypes(ExtLibParameter p, string ptstr, string typeArg) {
|
||||
exists(ParameterizedType pt |
|
||||
p.getType() = pt and
|
||||
pt.getATypeArgument().toString() = typeArg and
|
||||
ptstr = pt.toString()
|
||||
)
|
||||
}
|
||||
|
||||
query predicate libCallables(Callable c) { c.getFile().getBaseName().matches("%Lib.java") }
|
||||
@@ -0,0 +1,8 @@
|
||||
from create_database_utils import *
|
||||
import glob
|
||||
|
||||
os.mkdir('build')
|
||||
javaccmd = " ".join(["javac"] + glob.glob("javasrc/extlib/*.java") + ["-d", "build"])
|
||||
jarcmd = " ".join(["jar", "-c", "-f", "extlib.jar", "-C", "build", "extlib"])
|
||||
run_codeql_database_create([javaccmd, jarcmd, "kotlinc user.kt -cp extlib.jar"], lang="java")
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import extlib.*
|
||||
import java.util.*
|
||||
|
||||
fun test() {
|
||||
|
||||
// Pending better varargs support, avoiding listOf and mutableListOf
|
||||
val stringList = ArrayList<String>()
|
||||
val objectList = ArrayList<Any>()
|
||||
val stringStringList = ArrayList<ArrayList<String>>()
|
||||
|
||||
val lib = Lib()
|
||||
lib.testParameterTypes(
|
||||
'a',
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5.0f,
|
||||
6.0,
|
||||
true,
|
||||
Lib(),
|
||||
GenericTest<String>(),
|
||||
BoundedGenericTest<String>(),
|
||||
ComplexBoundedGenericTest<CharSequence, String>(),
|
||||
intArrayOf(1),
|
||||
arrayOf(1),
|
||||
arrayOf(intArrayOf(1)),
|
||||
arrayOf(arrayOf(1)),
|
||||
arrayOf(stringList),
|
||||
stringList,
|
||||
objectList,
|
||||
stringStringList,
|
||||
objectList)
|
||||
|
||||
val returnedList = lib.returnErasureTest()
|
||||
lib.paramErasureTest<Int>(listOf("Hello"))
|
||||
|
||||
// Check trap labelling consistency for methods that instantiate a generic type
|
||||
// with its own generic parameters -- for example, class MyList<T> { void addAll(MyList<T> l) { } },
|
||||
// which has the trap labelling oddity of looking like plain MyList, not MyList<T>, even though
|
||||
// this is a generic instantiation.
|
||||
val takesSelfTest = GenericTest<String>()
|
||||
takesSelfTest.takesSelfMethod(takesSelfTest)
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
class KotlinDefault {}
|
||||
@@ -0,0 +1 @@
|
||||
class KotlinDisabled {}
|
||||
@@ -0,0 +1 @@
|
||||
class KotlinEnabled {}
|
||||
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from create_database_utils import *
|
||||
|
||||
runSuccessfully(["kotlinc", "KotlinDefault.kt"])
|
||||
os.environ['CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN'] = 'true'
|
||||
runSuccessfully(["kotlinc", "KotlinDisabled.kt"])
|
||||
del(os.environ['CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN'])
|
||||
os.environ['CODEQL_EXTRACTOR_JAVA_AGENT_ENABLE_KOTLIN'] = 'true'
|
||||
runSuccessfully(["kotlinc", "KotlinEnabled.kt"])
|
||||
@@ -0,0 +1 @@
|
||||
| KotlinEnabled.kt:1:1:1:22 | KotlinEnabled |
|
||||
@@ -0,0 +1,5 @@
|
||||
import java
|
||||
|
||||
from Class c
|
||||
where c.fromSource()
|
||||
select c
|
||||
@@ -0,0 +1,9 @@
|
||||
from create_database_utils import *
|
||||
|
||||
for var in ['CODEQL_EXTRACTOR_JAVA_AGENT_ENABLE_KOTLIN',
|
||||
'CODEQL_EXTRACTOR_JAVA_AGENT_DISABLE_KOTLIN']:
|
||||
if var in os.environ:
|
||||
del(os.environ[var])
|
||||
|
||||
run_codeql_database_create(['"%s" build.py' % sys.executable], lang="java")
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
| code/A.kt:2:1:2:10 | A |
|
||||
| code/C.kt:2:1:2:10 | C |
|
||||
@@ -0,0 +1,5 @@
|
||||
import java
|
||||
|
||||
from Class c
|
||||
where c.fromSource()
|
||||
select c
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
class A {}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
class B {}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
class C {}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
os.environ['CODEQL_KOTLIN_INTERNAL_EXCEPTION_WHILE_EXTRACTING_FILE'] = 'B.kt'
|
||||
|
||||
subprocess.check_call(['kotlinc', 'A.kt', 'B.kt', 'C.kt', ])
|
||||
@@ -0,0 +1,3 @@
|
||||
| <compilation> | 0 | code/A.kt:0:0:0:0 | A | Extraction successful | Not recoverable errors | Not non-recoverable errors |
|
||||
| <compilation> | 1 | code/B.kt:0:0:0:0 | code/B.kt | Not extraction successful | Not recoverable errors | Non-recoverable errors |
|
||||
| <compilation> | 2 | code/C.kt:0:0:0:0 | C | Extraction successful | Not recoverable errors | Not non-recoverable errors |
|
||||
@@ -0,0 +1,24 @@
|
||||
import java
|
||||
|
||||
class AnonymousCompilation extends Compilation {
|
||||
override string toString() { result = "<compilation>" }
|
||||
}
|
||||
|
||||
from Compilation c, int i, File f
|
||||
where f = c.getFileCompiled(i)
|
||||
select c, i, f,
|
||||
any(string s |
|
||||
if c.fileCompiledSuccessful(i)
|
||||
then s = "Extraction successful"
|
||||
else s = "Not extraction successful"
|
||||
),
|
||||
any(string s |
|
||||
if c.fileCompiledRecoverableErrors(i)
|
||||
then s = "Recoverable errors"
|
||||
else s = "Not recoverable errors"
|
||||
),
|
||||
any(string s |
|
||||
if c.fileCompiledNonRecoverableErrors(i)
|
||||
then s = "Non-recoverable errors"
|
||||
else s = "Not non-recoverable errors"
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
| <compilation> | Normal termination | Not extraction successful | Not recoverable errors | Non-recoverable errors |
|
||||
@@ -0,0 +1,24 @@
|
||||
import java
|
||||
|
||||
class AnonymousCompilation extends Compilation {
|
||||
override string toString() { result = "<compilation>" }
|
||||
}
|
||||
|
||||
from Compilation c
|
||||
select c,
|
||||
any(string s |
|
||||
if c.normalTermination() then s = "Normal termination" else s = "Not normal termination"
|
||||
),
|
||||
any(string s |
|
||||
if c.extractionSuccessful()
|
||||
then s = "Extraction successful"
|
||||
else s = "Not extraction successful"
|
||||
),
|
||||
any(string s |
|
||||
if c.recoverableErrors() then s = "Recoverable errors" else s = "Not recoverable errors"
|
||||
),
|
||||
any(string s |
|
||||
if c.nonRecoverableErrors()
|
||||
then s = "Non-recoverable errors"
|
||||
else s = "Not non-recoverable errors"
|
||||
)
|
||||
@@ -0,0 +1,7 @@
|
||||
import sys
|
||||
|
||||
from create_database_utils import *
|
||||
|
||||
run_codeql_database_create(
|
||||
['"%s" build.py' % sys.executable],
|
||||
source="code", lang="java")
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* This file was generated by the Gradle 'init' task.
|
||||
*
|
||||
* This generated file contains a sample Kotlin application project to get you started.
|
||||
* For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle
|
||||
* User Manual available at https://docs.gradle.org/7.0.2/userguide/building_java_projects.html
|
||||
*/
|
||||
|
||||
plugins {
|
||||
// Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin.
|
||||
id 'org.jetbrains.kotlin.jvm' version '1.5.31'
|
||||
|
||||
// Apply the application plugin to add support for building a CLI application in Java.
|
||||
id 'application'
|
||||
}
|
||||
|
||||
repositories {
|
||||
// Use Maven Central for resolving dependencies.
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
application {
|
||||
// Define the main class for the application.
|
||||
mainClass = 'testProject.AppKt'
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* This Kotlin source file was generated by the Gradle 'init' task.
|
||||
*/
|
||||
package testProject
|
||||
|
||||
class App {
|
||||
val greeting: String
|
||||
get() {
|
||||
return "Hello World!"
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
// TODO: println(App().greeting)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
| 1 |
|
||||
@@ -0,0 +1,3 @@
|
||||
import java
|
||||
|
||||
select count(Compilation c)
|
||||
@@ -0,0 +1,2 @@
|
||||
| app/src/main/kotlin/testProject/App.kt:8:9:10:9 | getGreeting |
|
||||
| app/src/main/kotlin/testProject/App.kt:13:1:15:1 | main |
|
||||
@@ -0,0 +1,5 @@
|
||||
import java
|
||||
|
||||
from Method m
|
||||
where exists(m.getFile().getRelativePath())
|
||||
select m
|
||||
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* This file was generated by the Gradle 'init' task.
|
||||
*
|
||||
* The settings file is used to specify which projects to include in your build.
|
||||
*
|
||||
* Detailed information about configuring a multi-project build in Gradle can be found
|
||||
* in the user manual at https://docs.gradle.org/7.0.2/userguide/multi_project_builds.html
|
||||
*/
|
||||
|
||||
rootProject.name = 'testProject'
|
||||
include('app')
|
||||
@@ -0,0 +1,4 @@
|
||||
from create_database_utils import *
|
||||
|
||||
run_codeql_database_create(["gradle build --no-daemon --no-build-cache"], lang="java")
|
||||
runSuccessfully(["gradle", "clean"])
|
||||
@@ -0,0 +1,432 @@
|
||||
app/src/main/kotlin/testProject/App.kt:
|
||||
# 0| [CompilationUnit] App
|
||||
# 7| 1: [Class] Project
|
||||
# 0| 1: [Constructor] Project
|
||||
#-----| 4: (Parameters)
|
||||
# 0| 0: [Parameter] seen1
|
||||
# 0| 0: [TypeAccess] int
|
||||
# 0| 1: [Parameter] name
|
||||
# 0| 0: [TypeAccess] String
|
||||
# 0| 2: [Parameter] language
|
||||
# 0| 0: [TypeAccess] int
|
||||
# 0| 3: [Parameter] serializationConstructorMarker
|
||||
# 0| 0: [TypeAccess] SerializationConstructorMarker
|
||||
# 7| 5: [BlockStmt] { ... }
|
||||
# 7| 0: [ExprStmt] <Expr>;
|
||||
# 7| 0: [WhenExpr] when ...
|
||||
# 7| 0: [WhenBranch] ... -> ...
|
||||
# 7| 0: [ValueNEExpr] ... (value not-equals) ...
|
||||
# 7| 0: [IntegerLiteral] 3
|
||||
# 7| 1: [MethodAccess] and(...)
|
||||
# 7| -1: [IntegerLiteral] 3
|
||||
# 7| 0: [VarAccess] seen1
|
||||
# 7| 1: [ExprStmt] <Expr>;
|
||||
# 7| 0: [MethodAccess] throwMissingFieldException(...)
|
||||
# 7| -1: [TypeAccess] PluginExceptionsKt
|
||||
# 7| 0: [VarAccess] seen1
|
||||
# 7| 1: [IntegerLiteral] 3
|
||||
# 7| 2: [MethodAccess] getDescriptor(...)
|
||||
# 7| -1: [VarAccess] INSTANCE
|
||||
# 7| 1: [SuperConstructorInvocationStmt] super(...)
|
||||
# 7| 2: [ExprStmt] <Expr>;
|
||||
# 7| 0: [AssignExpr] ...=...
|
||||
# 7| 0: [VarAccess] Project.this.name
|
||||
# 7| -1: [ThisAccess] Project.this
|
||||
# 7| 0: [TypeAccess] Project
|
||||
# 7| 1: [VarAccess] name
|
||||
# 7| 3: [ExprStmt] <Expr>;
|
||||
# 7| 0: [AssignExpr] ...=...
|
||||
# 7| 0: [VarAccess] Project.this.language
|
||||
# 7| -1: [ThisAccess] Project.this
|
||||
# 7| 0: [TypeAccess] Project
|
||||
# 7| 1: [VarAccess] language
|
||||
# 0| 1: [Method] write$Self
|
||||
# 0| 3: [TypeAccess] Unit
|
||||
#-----| 4: (Parameters)
|
||||
# 0| 0: [Parameter] self
|
||||
# 0| 0: [TypeAccess] Project
|
||||
# 0| 1: [Parameter] output
|
||||
# 0| 0: [TypeAccess] CompositeEncoder
|
||||
# 0| 2: [Parameter] serialDesc
|
||||
# 0| 0: [TypeAccess] SerialDescriptor
|
||||
# 7| 5: [BlockStmt] { ... }
|
||||
# 7| 0: [ExprStmt] <Expr>;
|
||||
# 7| 0: [MethodAccess] encodeStringElement(...)
|
||||
# 7| -1: [VarAccess] output
|
||||
# 7| 0: [VarAccess] serialDesc
|
||||
# 7| 1: [IntegerLiteral] 0
|
||||
# 7| 2: [MethodAccess] getName(...)
|
||||
# 7| -1: [VarAccess] self
|
||||
# 7| 1: [ExprStmt] <Expr>;
|
||||
# 7| 0: [MethodAccess] encodeIntElement(...)
|
||||
# 7| -1: [VarAccess] output
|
||||
# 7| 0: [VarAccess] serialDesc
|
||||
# 7| 1: [IntegerLiteral] 1
|
||||
# 7| 2: [MethodAccess] getLanguage(...)
|
||||
# 7| -1: [VarAccess] self
|
||||
# 0| 1: [Method] component1
|
||||
# 0| 3: [TypeAccess] String
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [ReturnStmt] return ...
|
||||
# 0| 0: [VarAccess] this.name
|
||||
# 0| -1: [ThisAccess] this
|
||||
# 0| 1: [Method] component2
|
||||
# 0| 3: [TypeAccess] int
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [ReturnStmt] return ...
|
||||
# 0| 0: [VarAccess] this.language
|
||||
# 0| -1: [ThisAccess] this
|
||||
# 0| 1: [Method] copy
|
||||
# 0| 3: [TypeAccess] Project
|
||||
#-----| 4: (Parameters)
|
||||
# 8| 0: [Parameter] name
|
||||
# 8| 0: [TypeAccess] String
|
||||
# 8| 1: [Parameter] language
|
||||
# 8| 0: [TypeAccess] int
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [ReturnStmt] return ...
|
||||
# 0| 0: [ClassInstanceExpr] new Project(...)
|
||||
# 0| -3: [TypeAccess] Project
|
||||
# 0| 0: [VarAccess] name
|
||||
# 0| 1: [VarAccess] language
|
||||
# 0| 1: [Method] toString
|
||||
# 0| 3: [TypeAccess] String
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [ReturnStmt] return ...
|
||||
# 0| 0: [StringTemplateExpr] "..."
|
||||
# 0| 0: [StringLiteral] Project(
|
||||
# 0| 1: [StringLiteral] name=
|
||||
# 0| 2: [VarAccess] this.name
|
||||
# 0| -1: [ThisAccess] this
|
||||
# 0| 3: [StringLiteral] ,
|
||||
# 0| 4: [StringLiteral] language=
|
||||
# 0| 5: [VarAccess] this.language
|
||||
# 0| -1: [ThisAccess] this
|
||||
# 0| 6: [StringLiteral] )
|
||||
# 0| 1: [Method] hashCode
|
||||
# 0| 3: [TypeAccess] int
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [LocalVariableDeclStmt] var ...;
|
||||
# 0| 1: [LocalVariableDeclExpr] result
|
||||
# 0| 0: [MethodAccess] hashCode(...)
|
||||
# 0| -1: [VarAccess] this.name
|
||||
# 0| -1: [ThisAccess] this
|
||||
# 0| 1: [ExprStmt] <Expr>;
|
||||
# 0| 0: [AssignExpr] ...=...
|
||||
# 0| 0: [VarAccess] result
|
||||
# 0| 1: [MethodAccess] plus(...)
|
||||
# 0| -1: [MethodAccess] times(...)
|
||||
# 0| -1: [VarAccess] result
|
||||
# 0| 0: [IntegerLiteral] 31
|
||||
# 0| 0: [MethodAccess] hashCode(...)
|
||||
# 0| -1: [VarAccess] this.language
|
||||
# 0| -1: [ThisAccess] this
|
||||
# 0| 2: [ReturnStmt] return ...
|
||||
# 0| 0: [VarAccess] result
|
||||
# 0| 1: [Method] equals
|
||||
# 0| 3: [TypeAccess] boolean
|
||||
#-----| 4: (Parameters)
|
||||
# 0| 0: [Parameter] other
|
||||
# 0| 0: [TypeAccess] Object
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [ExprStmt] <Expr>;
|
||||
# 0| 0: [WhenExpr] when ...
|
||||
# 0| 0: [WhenBranch] ... -> ...
|
||||
# 0| 0: [EQExpr] ... == ...
|
||||
# 0| 0: [ThisAccess] this
|
||||
# 0| 1: [VarAccess] other
|
||||
# 0| 1: [ReturnStmt] return ...
|
||||
# 0| 0: [BooleanLiteral] true
|
||||
# 0| 1: [ExprStmt] <Expr>;
|
||||
# 0| 0: [WhenExpr] when ...
|
||||
# 0| 0: [WhenBranch] ... -> ...
|
||||
# 0| 0: [NotInstanceOfExpr] ... !is ...
|
||||
# 0| 0: [VarAccess] other
|
||||
# 0| 1: [TypeAccess] Project
|
||||
# 0| 1: [ReturnStmt] return ...
|
||||
# 0| 0: [BooleanLiteral] false
|
||||
# 0| 2: [LocalVariableDeclStmt] var ...;
|
||||
# 0| 1: [LocalVariableDeclExpr] tmp0_other_with_cast
|
||||
# 0| 0: [CastExpr] (...)...
|
||||
# 0| 0: [TypeAccess] Project
|
||||
# 0| 1: [VarAccess] other
|
||||
# 0| 3: [ExprStmt] <Expr>;
|
||||
# 0| 0: [WhenExpr] when ...
|
||||
# 0| 0: [WhenBranch] ... -> ...
|
||||
# 0| 0: [ValueNEExpr] ... (value not-equals) ...
|
||||
# 0| 0: [VarAccess] this.name
|
||||
# 0| -1: [ThisAccess] this
|
||||
# 0| 1: [VarAccess] tmp0_other_with_cast.name
|
||||
# 0| -1: [VarAccess] tmp0_other_with_cast
|
||||
# 0| 1: [ReturnStmt] return ...
|
||||
# 0| 0: [BooleanLiteral] false
|
||||
# 0| 4: [ExprStmt] <Expr>;
|
||||
# 0| 0: [WhenExpr] when ...
|
||||
# 0| 0: [WhenBranch] ... -> ...
|
||||
# 0| 0: [ValueNEExpr] ... (value not-equals) ...
|
||||
# 0| 0: [VarAccess] this.language
|
||||
# 0| -1: [ThisAccess] this
|
||||
# 0| 1: [VarAccess] tmp0_other_with_cast.language
|
||||
# 0| -1: [VarAccess] tmp0_other_with_cast
|
||||
# 0| 1: [ReturnStmt] return ...
|
||||
# 0| 0: [BooleanLiteral] false
|
||||
# 0| 5: [ReturnStmt] return ...
|
||||
# 0| 0: [BooleanLiteral] true
|
||||
# 7| 9: [Class] Companion
|
||||
# 0| 1: [Method] serializer
|
||||
# 0| 3: [TypeAccess] KSerializer<Project>
|
||||
# 0| 0: [TypeAccess] Project
|
||||
# 7| 5: [BlockStmt] { ... }
|
||||
# 7| 0: [ReturnStmt] return ...
|
||||
# 7| 0: [VarAccess] INSTANCE
|
||||
# 7| 2: [Constructor] Companion
|
||||
# 7| 5: [BlockStmt] { ... }
|
||||
# 7| 0: [SuperConstructorInvocationStmt] super(...)
|
||||
# 7| 1: [BlockStmt] { ... }
|
||||
# 7| 9: [Class] $serializer
|
||||
# 0| 1: [Method] getDescriptor
|
||||
# 0| 3: [TypeAccess] SerialDescriptor
|
||||
# 0| 5: [BlockStmt] { ... }
|
||||
# 0| 0: [ReturnStmt] return ...
|
||||
# 0| 0: [VarAccess] this.descriptor
|
||||
# 0| -1: [ThisAccess] this
|
||||
# 0| 1: [FieldDeclaration] SerialDescriptor descriptor;
|
||||
# 0| -1: [TypeAccess] SerialDescriptor
|
||||
# 0| 1: [Method] childSerializers
|
||||
# 0| 3: [TypeAccess] KSerializer<?>[]
|
||||
# 0| 0: [TypeAccess] KSerializer<?>
|
||||
# 0| 0: [WildcardTypeAccess] ? ...
|
||||
# 7| 5: [BlockStmt] { ... }
|
||||
# 7| 0: [ReturnStmt] return ...
|
||||
# 7| 0: [ArrayCreationExpr] new KSerializer<?>[]
|
||||
# 7| -2: [ArrayInit] {...}
|
||||
# 7| 0: [VarAccess] INSTANCE
|
||||
# 7| 1: [VarAccess] INSTANCE
|
||||
# 7| -1: [TypeAccess] KSerializer<?>
|
||||
# 7| 0: [IntegerLiteral] 2
|
||||
# 0| 1: [Method] deserialize
|
||||
# 0| 3: [TypeAccess] Project
|
||||
#-----| 4: (Parameters)
|
||||
# 0| 0: [Parameter] decoder
|
||||
# 0| 0: [TypeAccess] Decoder
|
||||
# 7| 5: [BlockStmt] { ... }
|
||||
# 7| 0: [LocalVariableDeclStmt] var ...;
|
||||
# 7| 1: [LocalVariableDeclExpr] tmp0_desc
|
||||
# 7| 0: [MethodAccess] getDescriptor(...)
|
||||
# 7| -1: [ThisAccess] this
|
||||
# 7| 1: [LocalVariableDeclStmt] var ...;
|
||||
# 7| 1: [LocalVariableDeclExpr] tmp1_flag
|
||||
# 7| 0: [BooleanLiteral] true
|
||||
# 7| 2: [LocalVariableDeclStmt] var ...;
|
||||
# 7| 1: [LocalVariableDeclExpr] tmp2_index
|
||||
# 7| 0: [IntegerLiteral] 0
|
||||
# 7| 3: [LocalVariableDeclStmt] var ...;
|
||||
# 7| 1: [LocalVariableDeclExpr] tmp3_bitMask0
|
||||
# 7| 0: [IntegerLiteral] 0
|
||||
# 7| 4: [LocalVariableDeclStmt] var ...;
|
||||
# 7| 1: [LocalVariableDeclExpr] tmp4_local0
|
||||
# 7| 0: [NullLiteral] null
|
||||
# 7| 5: [LocalVariableDeclStmt] var ...;
|
||||
# 7| 1: [LocalVariableDeclExpr] tmp5_local1
|
||||
# 7| 0: [IntegerLiteral] 0
|
||||
# 7| 6: [LocalVariableDeclStmt] var ...;
|
||||
# 7| 1: [LocalVariableDeclExpr] tmp6_input
|
||||
# 7| 0: [MethodAccess] beginStructure(...)
|
||||
# 7| -1: [VarAccess] decoder
|
||||
# 7| 0: [VarAccess] tmp0_desc
|
||||
# 7| 7: [ExprStmt] <Expr>;
|
||||
# 7| 0: [WhenExpr] when ...
|
||||
# 7| 0: [WhenBranch] ... -> ...
|
||||
# 7| 0: [MethodAccess] decodeSequentially(...)
|
||||
# 7| -1: [VarAccess] tmp6_input
|
||||
# 7| 1: [BlockStmt] { ... }
|
||||
# 7| 0: [BlockStmt] { ... }
|
||||
# 7| 0: [ExprStmt] <Expr>;
|
||||
# 7| 0: [AssignExpr] ...=...
|
||||
# 7| 0: [VarAccess] tmp4_local0
|
||||
# 7| 1: [MethodAccess] decodeStringElement(...)
|
||||
# 7| -1: [VarAccess] tmp6_input
|
||||
# 7| 0: [VarAccess] tmp0_desc
|
||||
# 7| 1: [IntegerLiteral] 0
|
||||
# 7| 1: [ExprStmt] <Expr>;
|
||||
# 7| 0: [AssignExpr] ...=...
|
||||
# 7| 0: [VarAccess] tmp3_bitMask0
|
||||
# 7| 1: [MethodAccess] or(...)
|
||||
# 7| -1: [VarAccess] tmp3_bitMask0
|
||||
# 7| 0: [IntegerLiteral] 1
|
||||
# 7| 1: [BlockStmt] { ... }
|
||||
# 7| 0: [ExprStmt] <Expr>;
|
||||
# 7| 0: [AssignExpr] ...=...
|
||||
# 7| 0: [VarAccess] tmp5_local1
|
||||
# 7| 1: [MethodAccess] decodeIntElement(...)
|
||||
# 7| -1: [VarAccess] tmp6_input
|
||||
# 7| 0: [VarAccess] tmp0_desc
|
||||
# 7| 1: [IntegerLiteral] 1
|
||||
# 7| 1: [ExprStmt] <Expr>;
|
||||
# 7| 0: [AssignExpr] ...=...
|
||||
# 7| 0: [VarAccess] tmp3_bitMask0
|
||||
# 7| 1: [MethodAccess] or(...)
|
||||
# 7| -1: [VarAccess] tmp3_bitMask0
|
||||
# 7| 0: [IntegerLiteral] 2
|
||||
# 7| 1: [WhenBranch] ... -> ...
|
||||
# 7| 0: [BooleanLiteral] true
|
||||
# 7| 1: [WhileStmt] while (...)
|
||||
# 7| 0: [VarAccess] tmp1_flag
|
||||
# 7| 1: [BlockStmt] { ... }
|
||||
# 7| 0: [ExprStmt] <Expr>;
|
||||
# 7| 0: [AssignExpr] ...=...
|
||||
# 7| 0: [VarAccess] tmp2_index
|
||||
# 7| 1: [MethodAccess] decodeElementIndex(...)
|
||||
# 7| -1: [VarAccess] tmp6_input
|
||||
# 7| 0: [VarAccess] tmp0_desc
|
||||
# 7| 1: [ExprStmt] <Expr>;
|
||||
# 7| 0: [WhenExpr] when ...
|
||||
# 7| 0: [WhenBranch] ... -> ...
|
||||
# 7| 0: [ValueEQExpr] ... (value equals) ...
|
||||
# 7| 0: [VarAccess] tmp2_index
|
||||
# 7| 1: [IntegerLiteral] -1
|
||||
# 7| 1: [ExprStmt] <Expr>;
|
||||
# 7| 0: [AssignExpr] ...=...
|
||||
# 7| 0: [VarAccess] tmp1_flag
|
||||
# 7| 1: [BooleanLiteral] false
|
||||
# 7| 1: [WhenBranch] ... -> ...
|
||||
# 7| 0: [ValueEQExpr] ... (value equals) ...
|
||||
# 7| 0: [VarAccess] tmp2_index
|
||||
# 7| 1: [IntegerLiteral] 0
|
||||
# 7| 1: [BlockStmt] { ... }
|
||||
# 7| 0: [ExprStmt] <Expr>;
|
||||
# 7| 0: [AssignExpr] ...=...
|
||||
# 7| 0: [VarAccess] tmp4_local0
|
||||
# 7| 1: [MethodAccess] decodeStringElement(...)
|
||||
# 7| -1: [VarAccess] tmp6_input
|
||||
# 7| 0: [VarAccess] tmp0_desc
|
||||
# 7| 1: [IntegerLiteral] 0
|
||||
# 7| 1: [ExprStmt] <Expr>;
|
||||
# 7| 0: [AssignExpr] ...=...
|
||||
# 7| 0: [VarAccess] tmp3_bitMask0
|
||||
# 7| 1: [MethodAccess] or(...)
|
||||
# 7| -1: [VarAccess] tmp3_bitMask0
|
||||
# 7| 0: [IntegerLiteral] 1
|
||||
# 7| 2: [WhenBranch] ... -> ...
|
||||
# 7| 0: [ValueEQExpr] ... (value equals) ...
|
||||
# 7| 0: [VarAccess] tmp2_index
|
||||
# 7| 1: [IntegerLiteral] 1
|
||||
# 7| 1: [BlockStmt] { ... }
|
||||
# 7| 0: [ExprStmt] <Expr>;
|
||||
# 7| 0: [AssignExpr] ...=...
|
||||
# 7| 0: [VarAccess] tmp5_local1
|
||||
# 7| 1: [MethodAccess] decodeIntElement(...)
|
||||
# 7| -1: [VarAccess] tmp6_input
|
||||
# 7| 0: [VarAccess] tmp0_desc
|
||||
# 7| 1: [IntegerLiteral] 1
|
||||
# 7| 1: [ExprStmt] <Expr>;
|
||||
# 7| 0: [AssignExpr] ...=...
|
||||
# 7| 0: [VarAccess] tmp3_bitMask0
|
||||
# 7| 1: [MethodAccess] or(...)
|
||||
# 7| -1: [VarAccess] tmp3_bitMask0
|
||||
# 7| 0: [IntegerLiteral] 2
|
||||
# 7| 3: [WhenBranch] ... -> ...
|
||||
# 7| 0: [BooleanLiteral] true
|
||||
# 7| 1: [ThrowStmt] throw ...
|
||||
# 7| 0: [ClassInstanceExpr] new UnknownFieldException(...)
|
||||
# 7| -3: [TypeAccess] UnknownFieldException
|
||||
# 7| 0: [VarAccess] tmp2_index
|
||||
# 7| 8: [ExprStmt] <Expr>;
|
||||
# 7| 0: [MethodAccess] endStructure(...)
|
||||
# 7| -1: [VarAccess] tmp6_input
|
||||
# 7| 0: [VarAccess] tmp0_desc
|
||||
# 7| 9: [ReturnStmt] return ...
|
||||
# 7| 0: [ClassInstanceExpr] new Project(...)
|
||||
# 7| -3: [TypeAccess] Project
|
||||
# 7| 0: [VarAccess] tmp3_bitMask0
|
||||
# 7| 1: [VarAccess] tmp4_local0
|
||||
# 7| 2: [VarAccess] tmp5_local1
|
||||
# 7| 3: [NullLiteral] null
|
||||
# 0| 1: [Method] serialize
|
||||
# 0| 3: [TypeAccess] Unit
|
||||
#-----| 4: (Parameters)
|
||||
# 0| 0: [Parameter] encoder
|
||||
# 0| 0: [TypeAccess] Encoder
|
||||
# 0| 1: [Parameter] value
|
||||
# 0| 0: [TypeAccess] Project
|
||||
# 7| 5: [BlockStmt] { ... }
|
||||
# 7| 0: [LocalVariableDeclStmt] var ...;
|
||||
# 7| 1: [LocalVariableDeclExpr] tmp0_desc
|
||||
# 7| 0: [MethodAccess] getDescriptor(...)
|
||||
# 7| -1: [ThisAccess] this
|
||||
# 7| 1: [LocalVariableDeclStmt] var ...;
|
||||
# 7| 1: [LocalVariableDeclExpr] tmp1_output
|
||||
# 7| 0: [MethodAccess] beginStructure(...)
|
||||
# 7| -1: [VarAccess] encoder
|
||||
# 7| 0: [VarAccess] tmp0_desc
|
||||
# 7| 2: [ExprStmt] <Expr>;
|
||||
# 7| 0: [MethodAccess] write$Self(...)
|
||||
# 7| -1: [TypeAccess] Project
|
||||
# 7| 0: [VarAccess] value
|
||||
# 7| 1: [VarAccess] tmp1_output
|
||||
# 7| 2: [VarAccess] tmp0_desc
|
||||
# 7| 3: [ExprStmt] <Expr>;
|
||||
# 7| 0: [MethodAccess] endStructure(...)
|
||||
# 7| -1: [VarAccess] tmp1_output
|
||||
# 7| 0: [VarAccess] tmp0_desc
|
||||
# 7| 6: [Constructor] $serializer
|
||||
# 7| 5: [BlockStmt] { ... }
|
||||
# 7| 0: [SuperConstructorInvocationStmt] super(...)
|
||||
# 7| 1: [BlockStmt] { ... }
|
||||
# 7| 0: [LocalVariableDeclStmt] var ...;
|
||||
# 7| 1: [LocalVariableDeclExpr] tmp0_serialDesc
|
||||
# 7| 0: [ClassInstanceExpr] new PluginGeneratedSerialDescriptor(...)
|
||||
# 7| -3: [TypeAccess] PluginGeneratedSerialDescriptor
|
||||
# 7| 0: [StringLiteral] testProject.Project
|
||||
# 7| 1: [ThisAccess] $serializer.this
|
||||
# 7| 0: [TypeAccess] $serializer
|
||||
# 7| 2: [IntegerLiteral] 2
|
||||
# 7| 1: [ExprStmt] <Expr>;
|
||||
# 7| 0: [MethodAccess] addElement(...)
|
||||
# 7| -1: [VarAccess] tmp0_serialDesc
|
||||
# 7| 0: [StringLiteral] name
|
||||
# 7| 1: [BooleanLiteral] false
|
||||
# 7| 2: [ExprStmt] <Expr>;
|
||||
# 7| 0: [MethodAccess] addElement(...)
|
||||
# 7| -1: [VarAccess] tmp0_serialDesc
|
||||
# 7| 0: [StringLiteral] language
|
||||
# 7| 1: [BooleanLiteral] false
|
||||
# 7| 3: [ExprStmt] <Expr>;
|
||||
# 7| 0: [AssignExpr] ...=...
|
||||
# 7| 0: [VarAccess] $serializer.this.descriptor
|
||||
# 7| -1: [ThisAccess] $serializer.this
|
||||
# 7| 0: [TypeAccess] $serializer
|
||||
# 7| 1: [VarAccess] tmp0_serialDesc
|
||||
# 8| 11: [Constructor] Project
|
||||
#-----| 4: (Parameters)
|
||||
# 8| 0: [Parameter] name
|
||||
# 8| 0: [TypeAccess] String
|
||||
# 8| 1: [Parameter] language
|
||||
# 8| 0: [TypeAccess] int
|
||||
# 7| 5: [BlockStmt] { ... }
|
||||
# 7| 0: [SuperConstructorInvocationStmt] super(...)
|
||||
# 8| 1: [BlockStmt] { ... }
|
||||
# 8| 0: [ExprStmt] <Expr>;
|
||||
# 8| 0: [KtInitializerAssignExpr] ...=...
|
||||
# 8| 0: [VarAccess] name
|
||||
# 8| 1: [ExprStmt] <Expr>;
|
||||
# 8| 0: [KtInitializerAssignExpr] ...=...
|
||||
# 8| 0: [VarAccess] language
|
||||
# 8| 12: [Method] getName
|
||||
# 8| 3: [TypeAccess] String
|
||||
# 8| 5: [BlockStmt] { ... }
|
||||
# 8| 0: [ReturnStmt] return ...
|
||||
# 8| 0: [VarAccess] this.name
|
||||
# 8| -1: [ThisAccess] this
|
||||
# 8| 12: [FieldDeclaration] String name;
|
||||
# 8| -1: [TypeAccess] String
|
||||
# 8| 0: [VarAccess] name
|
||||
# 8| 14: [Method] getLanguage
|
||||
# 8| 3: [TypeAccess] int
|
||||
# 8| 5: [BlockStmt] { ... }
|
||||
# 8| 0: [ReturnStmt] return ...
|
||||
# 8| 0: [VarAccess] this.language
|
||||
# 8| -1: [ThisAccess] this
|
||||
# 8| 14: [FieldDeclaration] int language;
|
||||
# 8| -1: [TypeAccess] int
|
||||
# 8| 0: [VarAccess] language
|
||||
@@ -0,0 +1 @@
|
||||
semmle/code/java/PrintAst.ql
|
||||
@@ -0,0 +1,13 @@
|
||||
plugins {
|
||||
id 'org.jetbrains.kotlin.jvm' version '1.6.10'
|
||||
id 'org.jetbrains.kotlin.plugin.serialization' version '1.6.10'
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-serialization:1.6.10"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package testProject
|
||||
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.json.*
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class Project(val name: String, val language: Int)
|
||||
@@ -0,0 +1 @@
|
||||
| CodeQL Kotlin extractor | 2 | | Unbound object value, trying to use class stub from descriptor | app/src/main/kotlin/testProject/App.kt:7:1:8:55 | app/src/main/kotlin/testProject/App.kt:7:1:8:55 |
|
||||
@@ -0,0 +1,5 @@
|
||||
import java
|
||||
|
||||
from string genBy, int severity, string tag, string msg, Location l
|
||||
where diagnostics(_, genBy, severity, tag, msg, _, l)
|
||||
select genBy, severity, tag, msg, l
|
||||
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* This file was generated by the Gradle 'init' task.
|
||||
*
|
||||
* The settings file is used to specify which projects to include in your build.
|
||||
*
|
||||
* Detailed information about configuring a multi-project build in Gradle can be found
|
||||
* in the user manual at https://docs.gradle.org/7.0.2/userguide/multi_project_builds.html
|
||||
*/
|
||||
|
||||
rootProject.name = 'testProject'
|
||||
include('app')
|
||||
@@ -0,0 +1,4 @@
|
||||
from create_database_utils import *
|
||||
|
||||
run_codeql_database_create(["gradle build --no-daemon --no-build-cache"], lang="java")
|
||||
runSuccessfully(["gradle", "clean"])
|
||||
@@ -0,0 +1,24 @@
|
||||
| JavaSeesFirst/JarMtimesEqual/ClassFileMtimesEqual/seen_by_kotlin/dep.jar/Dep___JavaSeesFirst___JarMtimesEqual___ClassFileMtimesEqual.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___JavaSeesFirst___JarMtimesEqual___ClassFileMtimesEqual |
|
||||
| JavaSeesFirst/JarMtimesEqual/JavaClassFileNewer/seen_by_kotlin/dep.jar/Dep___JavaSeesFirst___JarMtimesEqual___JavaClassFileNewer.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___JavaSeesFirst___JarMtimesEqual___JavaClassFileNewer |
|
||||
| JavaSeesFirst/JarMtimesEqual/KotlinClassFileNewer/seen_by_kotlin/dep.jar/Dep___JavaSeesFirst___JarMtimesEqual___KotlinClassFileNewer.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___JavaSeesFirst___JarMtimesEqual___KotlinClassFileNewer |
|
||||
| JavaSeesFirst/JavaJarNewer/ClassFileMtimesEqual/seen_by_kotlin/dep.jar/Dep___JavaSeesFirst___JavaJarNewer___ClassFileMtimesEqual.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___JavaSeesFirst___JavaJarNewer___ClassFileMtimesEqual |
|
||||
| JavaSeesFirst/JavaJarNewer/JavaClassFileNewer/seen_by_kotlin/dep.jar/Dep___JavaSeesFirst___JavaJarNewer___JavaClassFileNewer.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___JavaSeesFirst___JavaJarNewer___JavaClassFileNewer |
|
||||
| JavaSeesFirst/JavaJarNewer/KotlinClassFileNewer/seen_by_kotlin/dep.jar/Dep___JavaSeesFirst___JavaJarNewer___KotlinClassFileNewer.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___JavaSeesFirst___JavaJarNewer___KotlinClassFileNewer |
|
||||
| JavaSeesFirst/KotlinJarNewer/ClassFileMtimesEqual/seen_by_kotlin/dep.jar/Dep___JavaSeesFirst___KotlinJarNewer___ClassFileMtimesEqual.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___JavaSeesFirst___KotlinJarNewer___ClassFileMtimesEqual |
|
||||
| JavaSeesFirst/KotlinJarNewer/JavaClassFileNewer/seen_by_kotlin/dep.jar/Dep___JavaSeesFirst___KotlinJarNewer___JavaClassFileNewer.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___JavaSeesFirst___KotlinJarNewer___JavaClassFileNewer |
|
||||
| JavaSeesFirst/KotlinJarNewer/KotlinClassFileNewer/seen_by_kotlin/dep.jar/Dep___JavaSeesFirst___KotlinJarNewer___KotlinClassFileNewer.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___JavaSeesFirst___KotlinJarNewer___KotlinClassFileNewer |
|
||||
| JavaSeesFirst/NoJar/ClassFileMtimesEqual/seen_by_kotlin/Dep___JavaSeesFirst___NoJar___ClassFileMtimesEqual.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___JavaSeesFirst___NoJar___ClassFileMtimesEqual |
|
||||
| JavaSeesFirst/NoJar/JavaClassFileNewer/seen_by_kotlin/Dep___JavaSeesFirst___NoJar___JavaClassFileNewer.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___JavaSeesFirst___NoJar___JavaClassFileNewer |
|
||||
| JavaSeesFirst/NoJar/KotlinClassFileNewer/seen_by_kotlin/Dep___JavaSeesFirst___NoJar___KotlinClassFileNewer.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___JavaSeesFirst___NoJar___KotlinClassFileNewer |
|
||||
| KotlinSeesFirst/JarMtimesEqual/ClassFileMtimesEqual/seen_by_kotlin/dep.jar/Dep___KotlinSeesFirst___JarMtimesEqual___ClassFileMtimesEqual.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___KotlinSeesFirst___JarMtimesEqual___ClassFileMtimesEqual |
|
||||
| KotlinSeesFirst/JarMtimesEqual/JavaClassFileNewer/seen_by_kotlin/dep.jar/Dep___KotlinSeesFirst___JarMtimesEqual___JavaClassFileNewer.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___KotlinSeesFirst___JarMtimesEqual___JavaClassFileNewer |
|
||||
| KotlinSeesFirst/JarMtimesEqual/KotlinClassFileNewer/seen_by_kotlin/dep.jar/Dep___KotlinSeesFirst___JarMtimesEqual___KotlinClassFileNewer.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___KotlinSeesFirst___JarMtimesEqual___KotlinClassFileNewer |
|
||||
| KotlinSeesFirst/JavaJarNewer/ClassFileMtimesEqual/seen_by_kotlin/dep.jar/Dep___KotlinSeesFirst___JavaJarNewer___ClassFileMtimesEqual.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___KotlinSeesFirst___JavaJarNewer___ClassFileMtimesEqual |
|
||||
| KotlinSeesFirst/JavaJarNewer/JavaClassFileNewer/seen_by_kotlin/dep.jar/Dep___KotlinSeesFirst___JavaJarNewer___JavaClassFileNewer.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___KotlinSeesFirst___JavaJarNewer___JavaClassFileNewer |
|
||||
| KotlinSeesFirst/JavaJarNewer/KotlinClassFileNewer/seen_by_kotlin/dep.jar/Dep___KotlinSeesFirst___JavaJarNewer___KotlinClassFileNewer.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___KotlinSeesFirst___JavaJarNewer___KotlinClassFileNewer |
|
||||
| KotlinSeesFirst/KotlinJarNewer/ClassFileMtimesEqual/seen_by_kotlin/dep.jar/Dep___KotlinSeesFirst___KotlinJarNewer___ClassFileMtimesEqual.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___KotlinSeesFirst___KotlinJarNewer___ClassFileMtimesEqual |
|
||||
| KotlinSeesFirst/KotlinJarNewer/JavaClassFileNewer/seen_by_kotlin/dep.jar/Dep___KotlinSeesFirst___KotlinJarNewer___JavaClassFileNewer.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___KotlinSeesFirst___KotlinJarNewer___JavaClassFileNewer |
|
||||
| KotlinSeesFirst/KotlinJarNewer/KotlinClassFileNewer/seen_by_kotlin/dep.jar/Dep___KotlinSeesFirst___KotlinJarNewer___KotlinClassFileNewer.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___KotlinSeesFirst___KotlinJarNewer___KotlinClassFileNewer |
|
||||
| KotlinSeesFirst/NoJar/ClassFileMtimesEqual/seen_by_kotlin/Dep___KotlinSeesFirst___NoJar___ClassFileMtimesEqual.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___KotlinSeesFirst___NoJar___ClassFileMtimesEqual |
|
||||
| KotlinSeesFirst/NoJar/JavaClassFileNewer/seen_by_kotlin/Dep___KotlinSeesFirst___NoJar___JavaClassFileNewer.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___KotlinSeesFirst___NoJar___JavaClassFileNewer |
|
||||
| KotlinSeesFirst/NoJar/KotlinClassFileNewer/seen_by_kotlin/Dep___KotlinSeesFirst___NoJar___KotlinClassFileNewer.class:0:0:0:0 | memberOnlySeenByKotlin | Dep___KotlinSeesFirst___NoJar___KotlinClassFileNewer |
|
||||
@@ -0,0 +1,128 @@
|
||||
from create_database_utils import *
|
||||
import os
|
||||
import os.path
|
||||
import subprocess
|
||||
|
||||
# Build a family of dependencies outside tracing, then refer to them from a traced build:
|
||||
|
||||
older_datetime = "202201010101"
|
||||
newer_datetime = "202202020202"
|
||||
|
||||
classpath_entries = dict()
|
||||
|
||||
extraction_orders = ["JavaSeesFirst", "KotlinSeesFirst"]
|
||||
jar_states = ["NoJar", "JarMtimesEqual", "JavaJarNewer", "KotlinJarNewer"]
|
||||
class_file_states = ["ClassFileMtimesEqual", "JavaClassFileNewer", "KotlinClassFileNewer"]
|
||||
|
||||
# Create test classes for each combination of which extractor will see the file first, the relative timestamps of the jar files seen by each, and the relative timestamps of the class file inside:
|
||||
|
||||
jobs = []
|
||||
|
||||
for first_extraction in extraction_orders:
|
||||
for jar_state in jar_states:
|
||||
for class_file_state in class_file_states:
|
||||
dep_dir = os.path.join(first_extraction, jar_state, class_file_state)
|
||||
dep_classname = "Dep___%s___%s___%s" % (first_extraction, jar_state, class_file_state)
|
||||
dep_seen_by_java_dir = os.path.join(dep_dir, "seen_by_java")
|
||||
dep_seen_by_kotlin_dir = os.path.join(dep_dir, "seen_by_kotlin")
|
||||
os.makedirs(dep_seen_by_java_dir)
|
||||
os.makedirs(dep_seen_by_kotlin_dir)
|
||||
dep_seen_by_java_sourcefile = os.path.join(dep_seen_by_java_dir, dep_classname + ".java")
|
||||
dep_seen_by_kotlin_sourcefile = os.path.join(dep_seen_by_kotlin_dir, dep_classname + ".java")
|
||||
with open(dep_seen_by_java_sourcefile, "w") as f:
|
||||
f.write("public class %s { }" % dep_classname)
|
||||
with open(dep_seen_by_kotlin_sourcefile, "w") as f:
|
||||
f.write("public class %s { void memberOnlySeenByKotlin() { } }" % dep_classname)
|
||||
jobs.append({
|
||||
"first_extraction": first_extraction,
|
||||
"jar_state": jar_state,
|
||||
"class_file_state": class_file_state,
|
||||
"dep_dir": dep_dir,
|
||||
"dep_classname": dep_classname,
|
||||
"dep_seen_by_java_dir": dep_seen_by_java_dir,
|
||||
"dep_seen_by_kotlin_dir": dep_seen_by_kotlin_dir,
|
||||
"dep_seen_by_java_sourcefile": dep_seen_by_java_sourcefile,
|
||||
"dep_seen_by_kotlin_sourcefile": dep_seen_by_kotlin_sourcefile
|
||||
})
|
||||
|
||||
# Compile all the test classes we just generated, in two commands (since javac objects to seeing the same class file twice in one run)
|
||||
|
||||
subprocess.check_call(["javac"] + [j["dep_seen_by_java_sourcefile"] for j in jobs])
|
||||
subprocess.check_call(["javac"] + [j["dep_seen_by_kotlin_sourcefile"] for j in jobs])
|
||||
|
||||
# Create jar files and set class and jar files' relative timestamps for each dependency the two extractors will see:
|
||||
|
||||
for j in jobs:
|
||||
os.remove(j["dep_seen_by_java_sourcefile"])
|
||||
os.remove(j["dep_seen_by_kotlin_sourcefile"])
|
||||
dep_seen_by_java_classfile = j["dep_seen_by_java_sourcefile"].replace(".java", ".class")
|
||||
dep_seen_by_kotlin_classfile = j["dep_seen_by_kotlin_sourcefile"].replace(".java", ".class")
|
||||
|
||||
subprocess.check_call(["touch", "-t", newer_datetime if j["class_file_state"] == "JavaClassFileNewer" else older_datetime, dep_seen_by_java_classfile])
|
||||
subprocess.check_call(["touch", "-t", newer_datetime if j["class_file_state"] == "KotlinClassFileNewer" else older_datetime, dep_seen_by_kotlin_classfile])
|
||||
|
||||
if j["jar_state"] != "NoJar":
|
||||
classfile_name = os.path.basename(dep_seen_by_java_classfile)
|
||||
jar_command = ["jar", "cf", "dep.jar", classfile_name]
|
||||
subprocess.check_call(jar_command, cwd = j["dep_seen_by_java_dir"])
|
||||
subprocess.check_call(jar_command, cwd = j["dep_seen_by_kotlin_dir"])
|
||||
jar_seen_by_java = os.path.join(j["dep_seen_by_java_dir"], "dep.jar")
|
||||
jar_seen_by_kotlin = os.path.join(j["dep_seen_by_kotlin_dir"], "dep.jar")
|
||||
subprocess.check_call(["touch", "-t", newer_datetime if j["jar_state"] == "JavaJarNewer" else older_datetime, jar_seen_by_java])
|
||||
subprocess.check_call(["touch", "-t", newer_datetime if j["jar_state"] == "KotlinJarNewer" else older_datetime, jar_seen_by_kotlin])
|
||||
j["javac_classpath_entry"] = jar_seen_by_java
|
||||
j["kotlinc_classpath_entry"] = jar_seen_by_kotlin
|
||||
else:
|
||||
# No jar file involved, just add the dependency build directory to the classpath:
|
||||
j["javac_classpath_entry"] = j["dep_seen_by_java_dir"]
|
||||
j["kotlinc_classpath_entry"] = j["dep_seen_by_kotlin_dir"]
|
||||
|
||||
# Create source files that instantiate each dependency type:
|
||||
|
||||
kotlin_first_jobs = [j for j in jobs if j["first_extraction"] == "KotlinSeesFirst"]
|
||||
java_first_jobs = [j for j in jobs if j["first_extraction"] == "JavaSeesFirst"]
|
||||
kotlin_first_classes = [j["dep_classname"] for j in kotlin_first_jobs]
|
||||
java_first_classes = [j["dep_classname"] for j in java_first_jobs]
|
||||
|
||||
kotlin_first_user = "kotlinFirstUser.kt"
|
||||
kotlin_second_user = "kotlinSecondUser.kt"
|
||||
java_first_user = "JavaFirstUser.java"
|
||||
java_second_user = "JavaSecondUser.java"
|
||||
|
||||
def kotlin_instantiate_classes(classes):
|
||||
return "; ".join(["noop(%s())" % c for c in classes])
|
||||
|
||||
def make_kotlin_user(user_filename, classes):
|
||||
with open(user_filename, "w") as f:
|
||||
f.write("fun noop(x: Any) { } fun user() { %s }" % kotlin_instantiate_classes(classes))
|
||||
|
||||
make_kotlin_user(kotlin_first_user, kotlin_first_classes)
|
||||
make_kotlin_user(kotlin_second_user, java_first_classes)
|
||||
|
||||
def java_instantiate_classes(classes):
|
||||
return " ".join(["noop(new %s());" % c for c in classes])
|
||||
|
||||
def make_java_user(user_filename, classes):
|
||||
with open(user_filename, "w") as f:
|
||||
f.write("public class %s { private static void noop(Object x) { } public static void user() { %s } }" % (user_filename.replace(".java", ""), java_instantiate_classes(classes)))
|
||||
|
||||
make_java_user(java_first_user, java_first_classes)
|
||||
make_java_user(java_second_user, kotlin_first_classes)
|
||||
|
||||
# Now finally make a database, including classes where Java sees them first followed by Kotlin and vice versa.
|
||||
# In all cases the Kotlin extraction should take precedence.
|
||||
|
||||
def make_classpath(jobs, entry_name):
|
||||
return ":".join([j[entry_name] for j in jobs])
|
||||
|
||||
kotlin_first_classpath = make_classpath(kotlin_first_jobs, "kotlinc_classpath_entry")
|
||||
java_first_classpath = make_classpath(java_first_jobs, "javac_classpath_entry")
|
||||
kotlin_second_classpath = make_classpath(java_first_jobs, "kotlinc_classpath_entry")
|
||||
java_second_classpath = make_classpath(kotlin_first_jobs, "javac_classpath_entry")
|
||||
|
||||
run_codeql_database_create([
|
||||
"kotlinc -cp %s %s" % (kotlin_first_classpath, kotlin_first_user),
|
||||
"javac -cp %s %s" % (java_first_classpath, java_first_user),
|
||||
"kotlinc -cp %s %s" % (kotlin_second_classpath, kotlin_second_user),
|
||||
"javac -cp %s %s" % (java_second_classpath, java_second_user)
|
||||
], lang="java")
|
||||
@@ -0,0 +1,5 @@
|
||||
import java
|
||||
|
||||
from Method m
|
||||
where m.getName() = "memberOnlySeenByKotlin"
|
||||
select m, m.getDeclaringType().getName()
|
||||
@@ -0,0 +1 @@
|
||||
public class J<T> { }
|
||||
@@ -0,0 +1 @@
|
||||
fun user1(j: J<Int>) { }
|
||||
@@ -0,0 +1 @@
|
||||
fun user2(j: J<String>) { }
|
||||
@@ -0,0 +1,3 @@
|
||||
| J.java:1:14:1:14 | J |
|
||||
| build/J.class:0:0:0:0 | J<String> |
|
||||
| file:///!unknown-binary-location/J.class:0:0:0:0 | J<Integer> |
|
||||
@@ -0,0 +1,5 @@
|
||||
import java
|
||||
|
||||
from Class c
|
||||
where c.getSourceDeclaration().getName() = "J"
|
||||
select c
|
||||
@@ -0,0 +1,8 @@
|
||||
from create_database_utils import *
|
||||
|
||||
os.mkdir('build')
|
||||
# Steps:
|
||||
# 1. Compile Kotlin passing Java source code. J.class is extracted with an unknown binary location
|
||||
# 2. Compile Java producing a class file. J.class should be re-extracted this time with a known binary location
|
||||
# 3. Compile a Kotlin user passing a Java class file on the classpath. Should reference the class file location that step 1 didn't know, but step 2 did.
|
||||
run_codeql_database_create(["kotlinc J.java K.kt -d build", "javac J.java -d build", "kotlinc K2.kt -cp build -d build"], lang="java")
|
||||
@@ -0,0 +1,7 @@
|
||||
package abcdefghij.abcdefghij.abcdefghij.abcdefghij.abcdefghij.abcdefghij.abcdefghij.abcdefghij.abcdefghij.abcdefghij;
|
||||
|
||||
class Param {
|
||||
|
||||
}
|
||||
|
||||
fun f(p1: Param, p2: Param, p3: Param, p4: Param, p5: Param) { }
|
||||
@@ -0,0 +1 @@
|
||||
| <prefix>/abcdefghij/abcdefghij/abcdefghij/abcdefghij/abcdefghij/abcdefghij/abcdefghij/abcdefghij/abcdefghij/abcdefghij/LongsigKt.class:0:0:0:0 | f |
|
||||
@@ -0,0 +1,11 @@
|
||||
from create_database_utils import *
|
||||
import glob
|
||||
|
||||
# Compile library Kotlin file untraced. Note the library is hidden under `libsrc` so the Kotlin compiler
|
||||
# will certainly reference the jar, not the source or class file.
|
||||
|
||||
os.mkdir('build')
|
||||
runSuccessfully(["kotlinc"] + glob.glob("libsrc/*.kt") + ["-d", "build"])
|
||||
runSuccessfully(["jar", "cf", "extlib.jar", "-C", "build", "abcdefghij", "-C", "build", "META-INF"])
|
||||
run_codeql_database_create(["kotlinc user.kt -cp extlib.jar"], lang="java")
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import java
|
||||
|
||||
from Method m
|
||||
where m.getDeclaringType().getName() = "LongsigKt"
|
||||
select m.getLocation()
|
||||
.toString()
|
||||
.regexpReplaceAll(".*(extlib.jar|!unknown-binary-location)/", "<prefix>/"), m.toString()
|
||||
@@ -0,0 +1,7 @@
|
||||
import abcdefghij.abcdefghij.abcdefghij.abcdefghij.abcdefghij.abcdefghij.abcdefghij.abcdefghij.abcdefghij.abcdefghij.*
|
||||
|
||||
fun user() {
|
||||
|
||||
f(Param(), Param(), Param(), Param(), Param())
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
public class JavaDefns {
|
||||
|
||||
// Currently known not to work: the Comparable<? extends X> case, which Kotlin sees as Comparable<*> because the
|
||||
// wildcard goes the opposite direction to the variance declared on Comparable's type parameter.
|
||||
|
||||
public static void takesComparable(Comparable<CharSequence> invar, Comparable<? super CharSequence> contravar) { }
|
||||
|
||||
public static void takesNestedComparable(Comparable<Comparable<? super CharSequence>> innerContravar, Comparable<? super Comparable<CharSequence>> outerContravar) { }
|
||||
|
||||
public static void takesArrayOfComparable(Comparable<CharSequence>[] invar, Comparable<? super CharSequence>[] contravar) { }
|
||||
|
||||
public static Comparable<? super CharSequence> returnsWildcard() { return null; }
|
||||
|
||||
public static Comparable<CharSequence> returnsInvariant() { return null; }
|
||||
|
||||
public JavaDefns(Comparable<CharSequence> invar, Comparable<? super CharSequence> contravar) { }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import java.util.List;
|
||||
|
||||
public class JavaUser {
|
||||
|
||||
public static void test() {
|
||||
|
||||
KotlinDefns kd = new KotlinDefns();
|
||||
|
||||
kd.takesInvariantType((List<CharSequence>)null, (List<? extends CharSequence>)null, (List<? super CharSequence>)null);
|
||||
|
||||
kd.takesCovariantType((List<? extends CharSequence>)null, (List<? extends CharSequence>)null);
|
||||
|
||||
kd.takesContravariantType((Comparable<? super CharSequence>)null, (Comparable<? super CharSequence>)null);
|
||||
|
||||
kd.takesNestedType((List<List<CharSequence>>) null, (List<? extends List<? extends CharSequence>>)null, (Comparable<? super Comparable<? super CharSequence>>)null, (List<? extends Comparable<? super CharSequence>>)null, (Comparable<? super List<? extends CharSequence>>)null);
|
||||
|
||||
kd.takesFinalParameter((List<String>)null, (List<String>)null, (Comparable<? super String>)null);
|
||||
|
||||
kd.takesFinalParameterForceWildcard((List<String>)null, (List<? extends String>)null, (Comparable<? super String>)null);
|
||||
|
||||
kd.takesAnyParameter((List<Object>)null, (List<? extends Object>)null, (Comparable<Object>)null);
|
||||
|
||||
kd.takesAnyQParameter((List<Object>)null, (List<? extends Object>)null, (Comparable<Object>)null);
|
||||
|
||||
kd.takesAnyParameterForceWildcard((List<Object>)null, (List<? extends Object>)null, (Comparable<? super Object>)null);
|
||||
|
||||
kd.takesVariantTypesSuppressedWildcards((List<CharSequence>)null, (Comparable<CharSequence>)null);
|
||||
|
||||
List<CharSequence> r1 = kd.returnsInvar();
|
||||
|
||||
List<CharSequence> r2 = kd.returnsCovar();
|
||||
|
||||
Comparable<CharSequence> r3 = kd.returnsContravar();
|
||||
|
||||
List<? extends CharSequence> r4 = kd.returnsCovarForced();
|
||||
|
||||
Comparable<? super CharSequence> r5 = kd.returnsContravarForced();
|
||||
|
||||
KotlinDefnsSuppressedOuter kdso = new KotlinDefnsSuppressedOuter();
|
||||
kdso.outerFn((List<CharSequence>)null, (Comparable<CharSequence>)null);
|
||||
KotlinDefnsSuppressedOuter.Inner kdsoi = new KotlinDefnsSuppressedOuter.Inner();
|
||||
kdsoi.innerFn((List<CharSequence>)null, (Comparable<CharSequence>)null);
|
||||
|
||||
KotlinDefnsSuppressedInner kdsi = new KotlinDefnsSuppressedInner();
|
||||
kdsi.outerFn((List<? extends CharSequence>)null, (Comparable<? super CharSequence>)null);
|
||||
KotlinDefnsSuppressedInner.Inner kdsii = new KotlinDefnsSuppressedInner.Inner();
|
||||
kdsii.innerFn((List<CharSequence>)null, (Comparable<CharSequence>)null);
|
||||
|
||||
KotlinDefnsSuppressedFn kdsf = new KotlinDefnsSuppressedFn();
|
||||
kdsf.outerFn((List<CharSequence>)null, (Comparable<CharSequence>)null);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
// Note throughout, using:
|
||||
// MutableList as a type whose parameter is invariant
|
||||
// List as a type whose parameter is covariant (List<out T>)
|
||||
// Comparable as a type whose parameter is contravariant (Comparable<int T>)
|
||||
// CharSequence as a non-final type
|
||||
// String as a final type
|
||||
|
||||
class ComparableCs : Comparable<CharSequence> {
|
||||
override fun compareTo(other: CharSequence): Int = 1
|
||||
}
|
||||
|
||||
class KotlinDefns {
|
||||
|
||||
fun takesInvariantType(noUseSiteVariance: MutableList<CharSequence>, useSiteCovariant: MutableList<out CharSequence>, useSiteContravariant: MutableList<in CharSequence>) { }
|
||||
|
||||
// Note List<in CharSequence> is a static error (contradictory variance)
|
||||
fun takesCovariantType(noUseSiteVariance: List<CharSequence>, useSiteCovariant: List<out CharSequence>) { }
|
||||
|
||||
// Note Comparable<out CharSequence> is a static error (contradictory variance)
|
||||
fun takesContravariantType(noUseSiteVariance: Comparable<CharSequence>, useSiteContravariant: Comparable<in CharSequence>) { }
|
||||
|
||||
fun takesNestedType(invar: MutableList<MutableList<CharSequence>>, covar: List<List<CharSequence>>, contravar: Comparable<Comparable<CharSequence>>, mixed1: List<Comparable<CharSequence>>, mixed2: Comparable<List<CharSequence>>) { }
|
||||
|
||||
fun takesFinalParameter(invar: MutableList<String>, covar: List<String>, contravar: Comparable<String>) { }
|
||||
|
||||
fun takesFinalParameterForceWildcard(invar: MutableList<@JvmWildcard String>, covar: List<@JvmWildcard String>, contravar: Comparable<@JvmWildcard String>) { }
|
||||
|
||||
fun takesAnyParameter(invar: MutableList<Any>, covar: List<Any>, contravar: Comparable<Any>) { }
|
||||
|
||||
fun takesAnyQParameter(invar: MutableList<Any?>, covar: List<Any?>, contravar: Comparable<Any?>) { }
|
||||
|
||||
fun takesAnyParameterForceWildcard(invar: MutableList<@JvmWildcard Any>, covar: List<@JvmWildcard Any>, contravar: Comparable<@JvmWildcard Any>) { }
|
||||
|
||||
fun takesVariantTypesSuppressedWildcards(covar: List<@JvmSuppressWildcards CharSequence>, contravar: Comparable<@JvmSuppressWildcards CharSequence>) { }
|
||||
|
||||
fun returnsInvar() : MutableList<CharSequence> = mutableListOf()
|
||||
|
||||
fun returnsCovar(): List<CharSequence> = listOf()
|
||||
|
||||
fun returnsContravar(): Comparable<CharSequence> = ComparableCs()
|
||||
|
||||
fun returnsCovarForced(): List<@JvmWildcard CharSequence> = listOf()
|
||||
|
||||
fun returnsContravarForced(): Comparable<@JvmWildcard CharSequence> = ComparableCs()
|
||||
|
||||
}
|
||||
|
||||
@JvmSuppressWildcards
|
||||
class KotlinDefnsSuppressedOuter {
|
||||
|
||||
fun outerFn(covar: List<CharSequence>, contravar: Comparable<CharSequence>) { }
|
||||
|
||||
class Inner {
|
||||
|
||||
fun innerFn(covar: List<CharSequence>, contravar: Comparable<CharSequence>) { }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class KotlinDefnsSuppressedInner {
|
||||
|
||||
fun outerFn(covar: List<CharSequence>, contravar: Comparable<CharSequence>) { }
|
||||
|
||||
@JvmSuppressWildcards
|
||||
class Inner {
|
||||
|
||||
fun innerFn(covar: List<CharSequence>, contravar: Comparable<CharSequence>) { }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class KotlinDefnsSuppressedFn {
|
||||
|
||||
@JvmSuppressWildcards fun outerFn(covar: List<CharSequence>, contravar: Comparable<CharSequence>) { }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
|
||||
fun user() {
|
||||
val cs = ComparableCs()
|
||||
val acs = arrayOf(cs)
|
||||
|
||||
JavaDefns.takesComparable(cs, cs)
|
||||
JavaDefns.takesArrayOfComparable(acs, acs)
|
||||
|
||||
val constructed = JavaDefns(cs, cs)
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
| JavaDefns | JavaDefns | contravar | Comparable<? super CharSequence> |
|
||||
| JavaDefns | JavaDefns | invar | Comparable<CharSequence> |
|
||||
| JavaDefns | returnsInvariant | return | Comparable<CharSequence> |
|
||||
| JavaDefns | returnsWildcard | return | Comparable<? super CharSequence> |
|
||||
| JavaDefns | takesArrayOfComparable | contravar | Comparable<? super CharSequence>[] |
|
||||
| JavaDefns | takesArrayOfComparable | invar | Comparable<CharSequence>[] |
|
||||
| JavaDefns | takesComparable | contravar | Comparable<? super CharSequence> |
|
||||
| JavaDefns | takesComparable | invar | Comparable<CharSequence> |
|
||||
| JavaDefns | takesNestedComparable | innerContravar | Comparable<Comparable<? super CharSequence>> |
|
||||
| JavaDefns | takesNestedComparable | outerContravar | Comparable<? super Comparable<CharSequence>> |
|
||||
| KotlinDefns | returnsContravar | return | Comparable<CharSequence> |
|
||||
| KotlinDefns | returnsContravarForced | return | Comparable<? super CharSequence> |
|
||||
| KotlinDefns | returnsCovar | return | List<CharSequence> |
|
||||
| KotlinDefns | returnsCovarForced | return | List<? extends CharSequence> |
|
||||
| KotlinDefns | returnsInvar | return | List<CharSequence> |
|
||||
| KotlinDefns | takesAnyParameter | contravar | Comparable<Object> |
|
||||
| KotlinDefns | takesAnyParameter | covar | List<? extends Object> |
|
||||
| KotlinDefns | takesAnyParameter | invar | List<Object> |
|
||||
| KotlinDefns | takesAnyParameterForceWildcard | contravar | Comparable<? super Object> |
|
||||
| KotlinDefns | takesAnyParameterForceWildcard | covar | List<? extends Object> |
|
||||
| KotlinDefns | takesAnyParameterForceWildcard | invar | List<Object> |
|
||||
| KotlinDefns | takesAnyQParameter | contravar | Comparable<Object> |
|
||||
| KotlinDefns | takesAnyQParameter | covar | List<? extends Object> |
|
||||
| KotlinDefns | takesAnyQParameter | invar | List<Object> |
|
||||
| KotlinDefns | takesContravariantType | noUseSiteVariance | Comparable<? super CharSequence> |
|
||||
| KotlinDefns | takesContravariantType | useSiteContravariant | Comparable<? super CharSequence> |
|
||||
| KotlinDefns | takesCovariantType | noUseSiteVariance | List<? extends CharSequence> |
|
||||
| KotlinDefns | takesCovariantType | useSiteCovariant | List<? extends CharSequence> |
|
||||
| KotlinDefns | takesFinalParameter | contravar | Comparable<? super String> |
|
||||
| KotlinDefns | takesFinalParameter | covar | List<String> |
|
||||
| KotlinDefns | takesFinalParameter | invar | List<String> |
|
||||
| KotlinDefns | takesFinalParameterForceWildcard | contravar | Comparable<? super String> |
|
||||
| KotlinDefns | takesFinalParameterForceWildcard | covar | List<? extends String> |
|
||||
| KotlinDefns | takesFinalParameterForceWildcard | invar | List<String> |
|
||||
| KotlinDefns | takesInvariantType | noUseSiteVariance | List<CharSequence> |
|
||||
| KotlinDefns | takesInvariantType | useSiteContravariant | List<? super CharSequence> |
|
||||
| KotlinDefns | takesInvariantType | useSiteCovariant | List<? extends CharSequence> |
|
||||
| KotlinDefns | takesNestedType | contravar | Comparable<? super Comparable<? super CharSequence>> |
|
||||
| KotlinDefns | takesNestedType | covar | List<? extends List<? extends CharSequence>> |
|
||||
| KotlinDefns | takesNestedType | invar | List<List<CharSequence>> |
|
||||
| KotlinDefns | takesNestedType | mixed1 | List<? extends Comparable<? super CharSequence>> |
|
||||
| KotlinDefns | takesNestedType | mixed2 | Comparable<? super List<? extends CharSequence>> |
|
||||
| KotlinDefns | takesVariantTypesSuppressedWildcards | contravar | Comparable<CharSequence> |
|
||||
| KotlinDefns | takesVariantTypesSuppressedWildcards | covar | List<CharSequence> |
|
||||
| KotlinDefnsSuppressedFn | outerFn | contravar | Comparable<CharSequence> |
|
||||
| KotlinDefnsSuppressedFn | outerFn | covar | List<CharSequence> |
|
||||
| KotlinDefnsSuppressedInner | outerFn | contravar | Comparable<? super CharSequence> |
|
||||
| KotlinDefnsSuppressedInner | outerFn | covar | List<? extends CharSequence> |
|
||||
| KotlinDefnsSuppressedInner$Inner | innerFn | contravar | Comparable<CharSequence> |
|
||||
| KotlinDefnsSuppressedInner$Inner | innerFn | covar | List<CharSequence> |
|
||||
| KotlinDefnsSuppressedOuter | outerFn | contravar | Comparable<CharSequence> |
|
||||
| KotlinDefnsSuppressedOuter | outerFn | covar | List<CharSequence> |
|
||||
| KotlinDefnsSuppressedOuter$Inner | innerFn | contravar | Comparable<CharSequence> |
|
||||
| KotlinDefnsSuppressedOuter$Inner | innerFn | covar | List<CharSequence> |
|
||||
@@ -0,0 +1,3 @@
|
||||
from create_database_utils import *
|
||||
|
||||
run_codeql_database_create(["kotlinc kotlindefns.kt", "javac JavaUser.java JavaDefns.java -cp .", "kotlinc -cp . kotlinuser.kt"], lang="java")
|
||||
@@ -0,0 +1,22 @@
|
||||
import java
|
||||
|
||||
predicate isInterestingClass(Class c) {
|
||||
[c, c.(NestedType).getEnclosingType()].getName().matches(["KotlinDefns%", "JavaDefns"])
|
||||
}
|
||||
|
||||
from Callable c, string paramOrReturnName, Type paramOrReturnType
|
||||
where
|
||||
isInterestingClass(c.getDeclaringType()) and
|
||||
(
|
||||
exists(Parameter p |
|
||||
p = c.getAParameter() and
|
||||
paramOrReturnName = p.getName() and
|
||||
paramOrReturnType = p.getType()
|
||||
)
|
||||
or
|
||||
paramOrReturnName = "return" and
|
||||
paramOrReturnType = c.getReturnType() and
|
||||
not paramOrReturnType instanceof VoidType
|
||||
)
|
||||
select c.getDeclaringType().getQualifiedName(), c.getName(), paramOrReturnName,
|
||||
paramOrReturnType.toString()
|
||||
@@ -0,0 +1,13 @@
|
||||
public class ReadsFields {
|
||||
|
||||
public static void read() {
|
||||
|
||||
sink(HasFields.constField);
|
||||
sink(HasFields.lateinitField);
|
||||
sink(HasFields.jvmFieldAnnotatedField);
|
||||
|
||||
}
|
||||
|
||||
public static void sink(String x) { }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
public class HasFields {
|
||||
|
||||
companion object {
|
||||
|
||||
const val constField = "taint"
|
||||
|
||||
lateinit var lateinitField: String
|
||||
|
||||
@JvmField val jvmFieldAnnotatedField = "taint"
|
||||
|
||||
}
|
||||
|
||||
fun doLateInit() {
|
||||
lateinitField = "taint"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
edges
|
||||
| hasFields.kt:5:5:5:34 | constField : String | ReadsFields.java:5:10:5:29 | HasFields.constField |
|
||||
| hasFields.kt:5:28:5:34 | taint : String | hasFields.kt:5:5:5:34 | constField : String |
|
||||
| hasFields.kt:7:5:7:38 | lateinitField : String | ReadsFields.java:6:10:6:32 | HasFields.lateinitField |
|
||||
| hasFields.kt:7:14:7:38 | <set-?> : String | hasFields.kt:7:5:7:38 | lateinitField : String |
|
||||
| hasFields.kt:7:14:7:38 | <set-?> : String | hasFields.kt:7:14:7:38 | <set-?> : String |
|
||||
| hasFields.kt:9:5:9:50 | jvmFieldAnnotatedField : String | ReadsFields.java:7:10:7:41 | HasFields.jvmFieldAnnotatedField |
|
||||
| hasFields.kt:9:44:9:50 | taint : String | hasFields.kt:9:5:9:50 | jvmFieldAnnotatedField : String |
|
||||
| hasFields.kt:14:22:14:26 | taint : String | hasFields.kt:7:14:7:38 | <set-?> : String |
|
||||
nodes
|
||||
| ReadsFields.java:5:10:5:29 | HasFields.constField | semmle.label | HasFields.constField |
|
||||
| ReadsFields.java:6:10:6:32 | HasFields.lateinitField | semmle.label | HasFields.lateinitField |
|
||||
| ReadsFields.java:7:10:7:41 | HasFields.jvmFieldAnnotatedField | semmle.label | HasFields.jvmFieldAnnotatedField |
|
||||
| hasFields.kt:5:5:5:34 | constField : String | semmle.label | constField : String |
|
||||
| hasFields.kt:5:28:5:34 | taint : String | semmle.label | taint : String |
|
||||
| hasFields.kt:7:5:7:38 | lateinitField : String | semmle.label | lateinitField : String |
|
||||
| hasFields.kt:7:14:7:38 | <set-?> : String | semmle.label | <set-?> : String |
|
||||
| hasFields.kt:7:14:7:38 | <set-?> : String | semmle.label | <set-?> : String |
|
||||
| hasFields.kt:9:5:9:50 | jvmFieldAnnotatedField : String | semmle.label | jvmFieldAnnotatedField : String |
|
||||
| hasFields.kt:9:44:9:50 | taint : String | semmle.label | taint : String |
|
||||
| hasFields.kt:14:22:14:26 | taint : String | semmle.label | taint : String |
|
||||
subpaths
|
||||
#select
|
||||
| hasFields.kt:5:28:5:34 | taint : String | hasFields.kt:5:28:5:34 | taint : String | ReadsFields.java:5:10:5:29 | HasFields.constField | flow path |
|
||||
| hasFields.kt:9:44:9:50 | taint : String | hasFields.kt:9:44:9:50 | taint : String | ReadsFields.java:7:10:7:41 | HasFields.jvmFieldAnnotatedField | flow path |
|
||||
| hasFields.kt:14:22:14:26 | taint : String | hasFields.kt:14:22:14:26 | taint : String | ReadsFields.java:6:10:6:32 | HasFields.lateinitField | flow path |
|
||||
@@ -0,0 +1,4 @@
|
||||
from create_database_utils import *
|
||||
|
||||
os.mkdir('build')
|
||||
run_codeql_database_create(["kotlinc ReadsFields.java hasFields.kt -d kbuild", "javac ReadsFields.java -cp kbuild"], lang="java")
|
||||
@@ -0,0 +1,17 @@
|
||||
import java
|
||||
import semmle.code.java.dataflow.DataFlow
|
||||
import DataFlow::PathGraph
|
||||
|
||||
class Config extends DataFlow::Configuration {
|
||||
Config() { this = "Config" }
|
||||
|
||||
override predicate isSource(DataFlow::Node n) { n.asExpr().(StringLiteral).getValue() = "taint" }
|
||||
|
||||
override predicate isSink(DataFlow::Node n) {
|
||||
n.asExpr().(Argument).getCall().getCallee().getName() = "sink"
|
||||
}
|
||||
}
|
||||
|
||||
from DataFlow::PathNode source, DataFlow::PathNode sink, Config c
|
||||
where c.hasFlowPath(source, sink)
|
||||
select source, source, sink, "flow path"
|
||||
@@ -0,0 +1,9 @@
|
||||
package foo.bar;
|
||||
|
||||
// import foo.bar.ClassB;
|
||||
|
||||
class ClassA {
|
||||
fun f(b: ClassB) {
|
||||
b.called();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package foo.bar;
|
||||
|
||||
class ClassB {
|
||||
fun called() {
|
||||
}
|
||||
fun notCalled() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from create_database_utils import *
|
||||
|
||||
runSuccessfully(["kotlinc", "FileA.kt", "FileB.kt"])
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
| 1 |
|
||||
@@ -0,0 +1,3 @@
|
||||
import java
|
||||
|
||||
select count(Compilation c)
|
||||
@@ -0,0 +1,3 @@
|
||||
| FileA.kt:6:2:8:2 | f |
|
||||
| FileB.kt:4:2:5:2 | called |
|
||||
| FileB.kt:6:2:7:2 | notCalled |
|
||||
@@ -0,0 +1,5 @@
|
||||
import java
|
||||
|
||||
from Method m
|
||||
where exists(m.getFile().getRelativePath())
|
||||
select m
|
||||
@@ -0,0 +1,3 @@
|
||||
from create_database_utils import *
|
||||
|
||||
run_codeql_database_create(['"%s" ./build.py' % sys.executable], lang="java")
|
||||
18
java/ql/integration-tests/posix-only/kotlin/logs/build.py
Normal file
18
java/ql/integration-tests/posix-only/kotlin/logs/build.py
Normal file
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
from create_database_utils import *
|
||||
|
||||
# Make a source file to keep codeql happy
|
||||
srcDir = os.environ['CODEQL_EXTRACTOR_JAVA_SOURCE_ARCHIVE_DIR']
|
||||
srcFile = srcDir + '/Source.java'
|
||||
os.makedirs(srcDir)
|
||||
with open(srcFile, 'w') as f:
|
||||
pass
|
||||
|
||||
for t in ['Test1', 'sun.something.Test2']:
|
||||
print('Test ' + t + ' started.')
|
||||
sys.stdout.flush()
|
||||
runSuccessfully(['java', t])
|
||||
print('Test ' + t + ' ended.')
|
||||
sys.stdout.flush()
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import csv
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from create_database_utils import *
|
||||
|
||||
# Make a source file to keep codeql happy
|
||||
src_dir = os.environ['CODEQL_EXTRACTOR_JAVA_SOURCE_ARCHIVE_DIR']
|
||||
src_file = src_dir + '/Source.java'
|
||||
os.makedirs(src_dir)
|
||||
with open(src_file, 'w') as f:
|
||||
pass
|
||||
|
||||
line_index = 0
|
||||
file_index = 0
|
||||
with open('logs.csv', 'w', newline='') as f_out:
|
||||
csv_writer = csv.writer(f_out)
|
||||
def write_line(origin, kind, msg):
|
||||
global file_index, line_index
|
||||
csv_writer.writerow([str(file_index), str(line_index), origin, kind, msg])
|
||||
line_index += 1
|
||||
log_dir = 'kt-db/log'
|
||||
for file_name in os.listdir(log_dir):
|
||||
if file_name.startswith('kotlin-extractor'):
|
||||
file_index += 1
|
||||
line_index = 1
|
||||
write_line('Test script', 'Log file', str(file_index))
|
||||
with open(log_dir + '/' + file_name) as f_in:
|
||||
for line in f_in:
|
||||
j = json.loads(line)
|
||||
msg = j['message']
|
||||
msg = re.sub('(?<=Extraction for invocation TRAP file ).*/kt-db/trap/java/invocations/kotlin\..*\.trap', '<FILENAME>', msg)
|
||||
if msg.startswith('Peak memory: '):
|
||||
# Peak memory information varies from run to run, so just ignore it
|
||||
continue
|
||||
write_line(j['origin'], j['kind'], msg)
|
||||
|
||||
runSuccessfully(["codeql", "database", "index-files", "--language=csv", "--include=logs.csv", "test-db"])
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
| 1 | 1 | Test script | Log file | 1 |
|
||||
| 1 | 2 | CodeQL Kotlin extractor | INFO | Extraction started |
|
||||
| 1 | 3 | CodeQL Kotlin extractor | INFO | Extraction for invocation TRAP file <FILENAME> |
|
||||
| 1 | 4 | CodeQL Kotlin extractor | INFO | Extracting file test.kt |
|
||||
| 1 | 5 | CodeQL Kotlin extractor | INFO | Extraction completed |
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user