From 4ad828f80ffd4199c258e0a57e6714daf6a5c770 Mon Sep 17 00:00:00 2001 From: Andrey Uskov Date: Mon, 20 Sep 2021 09:58:42 +0300 Subject: [PATCH] [JPS] Improved processing of broken caches If serialized metadata version has evidently incorrect size the module should be marked for rebuild prior to reading serialized version. #KT-42194 Fixed --- .../kotlin/metadata/jvm/deserialization/ModuleMapping.kt | 6 +++++- .../kotlin/metadata/deserialization/BinaryVersion.kt | 8 +++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/core/metadata.jvm/src/org/jetbrains/kotlin/metadata/jvm/deserialization/ModuleMapping.kt b/core/metadata.jvm/src/org/jetbrains/kotlin/metadata/jvm/deserialization/ModuleMapping.kt index f1301776c08..5d8de440f1f 100644 --- a/core/metadata.jvm/src/org/jetbrains/kotlin/metadata/jvm/deserialization/ModuleMapping.kt +++ b/core/metadata.jvm/src/org/jetbrains/kotlin/metadata/jvm/deserialization/ModuleMapping.kt @@ -39,7 +39,11 @@ class ModuleMapping private constructor( fun readVersionNumber(stream: DataInputStream): IntArray? = try { - IntArray(stream.readInt()) { stream.readInt() } + val size = stream.readInt() + if (size < 0 || size > BinaryVersion.MAX_LENGTH) + null // cache is evidently corrupted + else + IntArray(size) { stream.readInt() } } catch (e: IOException) { null } diff --git a/core/metadata/src/org/jetbrains/kotlin/metadata/deserialization/BinaryVersion.kt b/core/metadata/src/org/jetbrains/kotlin/metadata/deserialization/BinaryVersion.kt index 10163e9a308..70a9bc2a423 100644 --- a/core/metadata/src/org/jetbrains/kotlin/metadata/deserialization/BinaryVersion.kt +++ b/core/metadata/src/org/jetbrains/kotlin/metadata/deserialization/BinaryVersion.kt @@ -18,7 +18,12 @@ abstract class BinaryVersion(private vararg val numbers: Int) { val major: Int = numbers.getOrNull(0) ?: UNKNOWN val minor: Int = numbers.getOrNull(1) ?: UNKNOWN val patch: Int = numbers.getOrNull(2) ?: UNKNOWN - val rest: List = if (numbers.size > 3) numbers.asList().subList(3, numbers.size).toList() else emptyList() + val rest: List = if (numbers.size > 3) { + if (numbers.size > MAX_LENGTH) + throw IllegalArgumentException("BinaryVersion with length more than $MAX_LENGTH are not supported. Provided length ${numbers.size}.") + else + numbers.asList().subList(3, numbers.size).toList() + } else emptyList() abstract fun isCompatible(): Boolean @@ -80,6 +85,7 @@ abstract class BinaryVersion(private vararg val numbers: Int) { } companion object { + const val MAX_LENGTH = 1024 private const val UNKNOWN = -1 @JvmStatic