From f59e6f156107ac38ff408f9ea27a5855d42ea73f Mon Sep 17 00:00:00 2001 From: hg-ms <53219833+hg-ms@users.noreply.github.com> Date: Mon, 3 Aug 2026 08:19:36 +0200 Subject: [PATCH] Read HashTable field offsets from HashTable, not EqHashTable XCollectionsInternals computed the size, keys and values offsets from EqHashTable and applied them to HashTable instances. EqHashTable has an additional field, so its layout is shifted and the offsets do not address the intended fields. Every restored HashTable was therefore written at wrong offsets by BinaryHandlerHashTable.updateState. With standard object headers the writes still landed inside the larger instance and silently corrupted a neighbouring field. With compact object headers the instance is smaller and the offset points past its end, so the write hits the following object's mark word, which then carries the klass pointer: the next garbage collection decodes a corrupt klass and the JVM dies. --- .../collections/XCollectionsInternals.java | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/persistence/binary/src/main/java/org/eclipse/serializer/persistence/binary/org/eclipse/serializer/collections/XCollectionsInternals.java b/persistence/binary/src/main/java/org/eclipse/serializer/persistence/binary/org/eclipse/serializer/collections/XCollectionsInternals.java index db55a432..7ed66c98 100644 --- a/persistence/binary/src/main/java/org/eclipse/serializer/persistence/binary/org/eclipse/serializer/collections/XCollectionsInternals.java +++ b/persistence/binary/src/main/java/org/eclipse/serializer/persistence/binary/org/eclipse/serializer/collections/XCollectionsInternals.java @@ -14,14 +14,27 @@ * #L% */ -import org.eclipse.serializer.collections.*; +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import org.eclipse.serializer.collections.BulkList; +import org.eclipse.serializer.collections.ConstHashEnum; +import org.eclipse.serializer.collections.ConstHashTable; +import org.eclipse.serializer.collections.ConstList; +import org.eclipse.serializer.collections.EqBulkList; +import org.eclipse.serializer.collections.EqConstHashEnum; +import org.eclipse.serializer.collections.EqConstHashTable; +import org.eclipse.serializer.collections.EqConstList; +import org.eclipse.serializer.collections.EqHashEnum; +import org.eclipse.serializer.collections.EqHashTable; +import org.eclipse.serializer.collections.HashEnum; +import org.eclipse.serializer.collections.HashTable; +import org.eclipse.serializer.collections.LimitList; +import org.eclipse.serializer.collections.Singleton; import org.eclipse.serializer.hashing.HashEqualator; import org.eclipse.serializer.memory.XMemory; import org.eclipse.serializer.reflect.XReflect; -import java.lang.reflect.Field; -import java.lang.reflect.Method; - final class XCollectionsInternals { // CHECKSTYLE.OFF: ConstantName: type names are intentionally unchanged @@ -41,9 +54,9 @@ final class XCollectionsInternals OFFSET_EqHashTable_keys = getFieldOffset(EqHashTable .class, "keys" ), OFFSET_EqHashTable_values = getFieldOffset(EqHashTable .class, "values" ), OFFSET_HashEnum_size = getFieldOffset(HashEnum .class, "size" ), - OFFSET_HashTable_size = getFieldOffset(EqHashTable .class, "size" ), - OFFSET_HashTable_keys = getFieldOffset(EqHashTable .class, "keys" ), - OFFSET_HashTable_values = getFieldOffset(EqHashTable .class, "values" ), + OFFSET_HashTable_size = getFieldOffset(HashTable .class, "size" ), + OFFSET_HashTable_keys = getFieldOffset(HashTable .class, "keys" ), + OFFSET_HashTable_values = getFieldOffset(HashTable .class, "values" ), OFFSET_LimitList_data = getFieldOffset(LimitList .class, "data" ), OFFSET_LimitList_size = getFieldOffset(LimitList .class, "size" ), OFFSET_Singleton_element = getFieldOffset(Singleton .class, "element" )