avm2: Normalize flash.globalization.Collator.compare to -1/0/1 - #24148
Open
falpi wants to merge 1 commit into
Open
avm2: Normalize flash.globalization.Collator.compare to -1/0/1#24148falpi wants to merge 1 commit into
falpi wants to merge 1 commit into
Conversation
falpi
force-pushed
the
fix-collator-compare-normalization
branch
2 times, most recently
from
July 7, 2026 11:03
925ff17 to
490807d
Compare
falpi
force-pushed
the
fix-collator-compare-normalization
branch
from
July 7, 2026 21:01
490807d to
0f435fa
Compare
flash.globalization.Collator.compare delegated to String.localeCompare,
which returns a raw character-code delta (e.g. 16), not a normalized
comparison result. Flash Player's Collator.compare returns exactly -1, 0,
or 1.
mx and spark collections' Sort.findItem runs a binary search whose body is
`switch (compareResult) { case -1: ...; case 0: ...; case 1: ... }`. A raw
delta matches none of those cases, so neither bound is updated and the
search spins forever. This froze the app (CPU pegged, no error) when
sorting a Spark DataGrid by clicking a column header.
Normalize the result to the sign, matching Flash Player.
falpi
force-pushed
the
fix-collator-compare-normalization
branch
from
July 7, 2026 23:31
0f435fa to
c0fe40d
Compare
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.
Summary
flash.globalization.Collator.compare()returned a raw character-code delta instead of anormalized
-1/0/1. Flash Player'sCollator.comparealways returns exactly the sign,and the Flex framework's collection sorting relies on that: the mismatch drives
spark.collections.Sort.findItem()'s binary search into an infinite loop, freezing any appthat sorts a Spark
DataGridstring column by clicking its header (CPU pegged, no error thrown).Root cause
Ruffle's
Collator.comparestub delegated toString.localeCompare, which returns acharacter-code difference rather than a normalized result:
spark.collections.Sort.findItem()(the binary search used when the collection view resolves anitem's index) branches on the comparison result with an exact switch:
A delta such as
16matches none of these cases, so neither bound is updated,lowerBound <= upperBoundstays true forever, and the comparator(
SortField.stringCompare→Collator.compare) is called endlessly.The path reached from a header click is:
Reproduction
A minimal Spark
DataGridwith inline data. Compile with the Flex 4.6 SDK and open the SWF inRuffle, then click the Name column header to sort. Before this patch the player hangs; after
it, the column sorts normally.
Any string values whose comparison delta is not exactly
±1reproduce it (i.e. almost all realdata — here
'R' - 'B' == 16).Fix
Normalize the comparison result to its sign in
Collator.compare, matching Flash Player:Notes
Collator.compareis still a stub for locale-aware collation (it uses code-point ordering);this change only corrects the shape of the return value, which is what the framework depends on.
sortCompareFunctions that already return-1/0/1were unaffected and keep working; thisfixes the default string-sort path that goes through the
Collator.Checklist