From c0fe40dce8b46e106c3de68f458a6b294c30de37 Mon Sep 17 00:00:00 2001 From: arjupan Date: Tue, 7 Jul 2026 11:11:18 +0200 Subject: [PATCH] avm2: Normalize flash.globalization.Collator.compare to -1/0/1 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. --- core/src/avm2/globals/flash/globalization/Collator.as | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/src/avm2/globals/flash/globalization/Collator.as b/core/src/avm2/globals/flash/globalization/Collator.as index 1d80b2cc4813c..c667a5d7372b1 100644 --- a/core/src/avm2/globals/flash/globalization/Collator.as +++ b/core/src/avm2/globals/flash/globalization/Collator.as @@ -83,7 +83,13 @@ package flash.globalization { public function compare(string1:String, string2:String):int { stub_method("flash.globalization.Collator", "compare"); - return string1.localeCompare(string2); + // Flash Player normalizes the result to exactly -1, 0, or 1. + // Some callers rely on this: mx/spark collections' Sort.findItem + // does `switch (compareResult) { case -1: ...; case 1: ... }`, so a + // raw comparison delta (e.g. a character-code difference) would + // match no case and spin the binary search forever. + var result:int = string1.localeCompare(string2); + return (result < 0) ? -1 : ((result > 0) ? 1 : 0); } public function equals(string1:String, string2:String):Boolean {