Fix ActivityArrayMap hashCode() using raw registry ids instead of Activity hashes#800
Merged
Dreeam-qwq merged 1 commit intoJul 4, 2026
Conversation
…ivity hashes MapEntry#hashCode() and ActivityArrayMap#hashCode() hashed the raw activity registry id, while the entry key is the Activity itself - getKey() and equals() already use RegistryTypeManager.ACTIVITY_DIRECT[...]. Per the Map/Map.Entry contract an entry's hash is key.hashCode() ^ value.hashCode(), and Activity#hashCode() is name.hashCode(), not the id. As a result an ActivityArrayMap (and its entries) could be equal to an ordinary map with the same contents while returning a different hashCode, breaking the equals/hashCode contract. Hash the Activity instead, matching getKey()/equals().
noramibu
approved these changes
Jul 3, 2026
Contributor
|
This fix looks correct for ActivityArrayMap, but AttributeInstanceArrayMap seems to have the same issue. Maybe a follow-up PR, or dealing with in this PR would be better? |
hayanesuru
approved these changes
Jul 4, 2026
Member
Thanks to your review! We can do it in another PR or commit, it’s fine =w= |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
ActivityArrayMapstores each key as its raw activity registry id (int), and twohashCode()implementations hash that raw id instead of theActivity:MapEntry#hashCode()returnsObjects.hashCode(key) ^ Objects.hashCode(value)wherekeyis the int id — even though the same class'sgetKey()andequals()use the actualActivityviaRegistryTypeManager.ACTIVITY_DIRECT[key]. So an entry'sequals()andhashCode()disagree.ActivityArrayMap#hashCode()sumsObjects.hashCode(k[i]) ^ ...over the raw ids for the same reason.The
Map/Map.Entrycontract defines an entry hash askey.hashCode() ^ value.hashCode(), and the key here is anActivitywhosehashCode()isname.hashCode(), not its id. Sinceequals()compares against arbitraryActivity-keyed maps, anActivityArrayMap(or its entries) can be equal to an ordinaryHashMapholding the same contents while returning a differenthashCode(), breaking theObjectequals/hashCode contract.Fix
Hash the
Activity(viaRegistryTypeManager.ACTIVITY_DIRECT[...], exactly asgetKey()/equals()already do) instead of the raw id, in bothhashCode()methods.Testing
./gradlew applyAllPatchesand./gradlew :leaf-server:compileJavaboth build cleanly on a JDK 25 toolchain. Docs-level behaviour of a single map is unchanged; its hash is now correct when compared against otherMapimplementations.