[KLIB] API 4 ABI: Fail with adequate errors on non-existing/malformed KLIBs
^KT-64395
This commit is contained in:
committed by
Space Team
parent
dd85a81d45
commit
dcf1c7e61d
@@ -0,0 +1 @@
|
||||
this is a malformed klib
|
||||
@@ -0,0 +1 @@
|
||||
this is a malformed klib
|
||||
@@ -0,0 +1 @@
|
||||
this is a malformed klib
|
||||
@@ -0,0 +1,6 @@
|
||||
abi_version=1.8.0
|
||||
builtins_platform=JS
|
||||
compiler_version=2.0.0
|
||||
ir_signature_versions=1,2
|
||||
metadata_version=1.4.1
|
||||
unique_name=malformed-klib4
|
||||
+12
-4
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.storage.CacheWithNotNullValues
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.util.DummyLogger
|
||||
import org.jetbrains.kotlin.utils.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.ifTrue
|
||||
import java.io.File
|
||||
@@ -53,10 +54,14 @@ import org.jetbrains.kotlin.backend.common.serialization.IrFlags as ProtoFlags
|
||||
|
||||
@ExperimentalLibraryAbiReader
|
||||
internal class LibraryAbiReaderImpl(libraryFile: File, filters: List<AbiReadingFilter>) {
|
||||
private val library = resolveSingleFileKlib(
|
||||
KFile(libraryFile.absolutePath),
|
||||
strategy = ToolingSingleFileKlibResolveStrategy
|
||||
)
|
||||
private val library: KotlinLibrary = try {
|
||||
ToolingSingleFileKlibResolveStrategy.tryResolve(KFile(libraryFile.absolutePath), DummyLogger)?.apply {
|
||||
check(uniqueName.isNotEmpty()) { "Can't read unique name from manifest" }
|
||||
check(hasIr) { "Library does not have IR" }
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
throw malformedLibrary(libraryFile, e)
|
||||
} ?: error("Library not found: $libraryFile")
|
||||
|
||||
private val compositeFilter: AbiReadingFilter.Composite? = if (filters.isNotEmpty()) AbiReadingFilter.Composite(filters) else null
|
||||
|
||||
@@ -86,6 +91,9 @@ internal class LibraryAbiReaderImpl(libraryFile: File, filters: List<AbiReadingF
|
||||
private fun readSupportedSignatureVersions(): Set<AbiSignatureVersion> {
|
||||
return library.versions.irSignatureVersions.mapTo(hashSetOf()) { AbiSignatureVersions.resolveByVersionNumber(it.number) }
|
||||
}
|
||||
|
||||
private fun malformedLibrary(libraryFile: File, cause: Exception): Nothing =
|
||||
throw IllegalArgumentException("Malformed library: $libraryFile", cause)
|
||||
}
|
||||
|
||||
@ExperimentalLibraryAbiReader
|
||||
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2010-2024 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.library.abi
|
||||
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertTrue
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.fail
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.io.File
|
||||
|
||||
@ExperimentalLibraryAbiReader
|
||||
class MalformedKlibAbiReaderTest {
|
||||
private lateinit var testDataDir: File
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
testDataDir = File("compiler/testData/klib/dump-abi/malformed").absoluteFile
|
||||
check(testDataDir.isDirectory) { "Test data dir does not exist: $testDataDir" }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testKlibDoesNotExist() {
|
||||
val nonExistingLibraries = listOf(
|
||||
"nonExistingLibrary", "nonExistingLibrary.klib"
|
||||
).map(testDataDir::resolve)
|
||||
|
||||
nonExistingLibraries.forEach { nonExistingLibrary ->
|
||||
assertInvalidKlib(nonExistingLibrary)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMalformedKlib() {
|
||||
val malformedLibraries = listOf(
|
||||
"malformed-klib1.klib",
|
||||
"malformed-klib2",
|
||||
"malformed-klib3",
|
||||
"malformed-klib4",
|
||||
).map(testDataDir::resolve)
|
||||
|
||||
malformedLibraries.forEach { malformedLibrary ->
|
||||
assertTrue(malformedLibrary.exists()) { "Library does not exist, check the test data: $malformedLibrary" }
|
||||
assertInvalidKlib(malformedLibrary)
|
||||
}
|
||||
}
|
||||
|
||||
private fun assertInvalidKlib(libraryFile: File) {
|
||||
try {
|
||||
LibraryAbiReader.readAbiInfo(libraryFile)
|
||||
fail { "Unexpectedly successful read from invalid library $libraryFile" }
|
||||
} catch (e: Exception) {
|
||||
val exceptionMessage = e.message.orEmpty()
|
||||
assertTrue(libraryFile.path in exceptionMessage) {
|
||||
"""
|
||||
Exception message does not contain library path.
|
||||
Message: $exceptionMessage
|
||||
Library file: $libraryFile
|
||||
""".trimIndent()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.konan.file.File
|
||||
import org.jetbrains.kotlin.util.DummyLogger
|
||||
import org.jetbrains.kotlin.util.Logger
|
||||
|
||||
interface SingleFileKlibResolveStrategy {
|
||||
fun interface SingleFileKlibResolveStrategy {
|
||||
fun resolve(libraryFile: File, logger: Logger): KotlinLibrary
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user