[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.LockBasedStorageManager
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
import org.jetbrains.kotlin.util.DummyLogger
|
||||||
import org.jetbrains.kotlin.utils.*
|
import org.jetbrains.kotlin.utils.*
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.ifTrue
|
import org.jetbrains.kotlin.utils.addToStdlib.ifTrue
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -53,10 +54,14 @@ import org.jetbrains.kotlin.backend.common.serialization.IrFlags as ProtoFlags
|
|||||||
|
|
||||||
@ExperimentalLibraryAbiReader
|
@ExperimentalLibraryAbiReader
|
||||||
internal class LibraryAbiReaderImpl(libraryFile: File, filters: List<AbiReadingFilter>) {
|
internal class LibraryAbiReaderImpl(libraryFile: File, filters: List<AbiReadingFilter>) {
|
||||||
private val library = resolveSingleFileKlib(
|
private val library: KotlinLibrary = try {
|
||||||
KFile(libraryFile.absolutePath),
|
ToolingSingleFileKlibResolveStrategy.tryResolve(KFile(libraryFile.absolutePath), DummyLogger)?.apply {
|
||||||
strategy = ToolingSingleFileKlibResolveStrategy
|
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
|
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> {
|
private fun readSupportedSignatureVersions(): Set<AbiSignatureVersion> {
|
||||||
return library.versions.irSignatureVersions.mapTo(hashSetOf()) { AbiSignatureVersions.resolveByVersionNumber(it.number) }
|
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
|
@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.DummyLogger
|
||||||
import org.jetbrains.kotlin.util.Logger
|
import org.jetbrains.kotlin.util.Logger
|
||||||
|
|
||||||
interface SingleFileKlibResolveStrategy {
|
fun interface SingleFileKlibResolveStrategy {
|
||||||
fun resolve(libraryFile: File, logger: Logger): KotlinLibrary
|
fun resolve(libraryFile: File, logger: Logger): KotlinLibrary
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user