-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Fix incorrect early exit in SortKey.Compare and seal type #31779
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
There's another interesting behavior here. Since under the invariant mode sort keys are a raw projection of chars to bytes, there are endianness issues to consider. For example, under the invariant mode: Open question: Is this discrepancy allowable? I don't know if there's a valid scenario in which somebody uses |
|
I wouldn't care much if someone using InvarantMode and Sort Keys. sort keys are really useful for scenarios that use real cultures and cares about linguistic behavior. The invariant mode is not for such scenarios at all. |
|
Would it make sense for us to block the |
src/libraries/System.Private.CoreLib/src/System/Globalization/SortKey.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/Globalization/SortKey.cs
Show resolved
Hide resolved
|
Another possible solution (if we do care about if (GlobalizationMode.Invariant)
{
return key1._bytes.AsChars().SequenceCompareTo(key2._bytes.AsChars());
}
else
{
return key1._bytes.SequenceCompareTo(key2._bytes);
} |
Would it make sense to swap the bytes when creating the sort key in InvariantMode to fix this?
|
Sounds like that's two votes for "don't bother with endianness concerns"? :) |
|
That, or if you would like to write the few lines of code to swap endianess in the invariantmode sort key generation - that's fine too. |
|
Making |
|
Latest iteration:
|
GetHashCode doesn't allow CompareOptions.StringSort I think. |
It has to. This same logic applies to |
|
Latest iteration:
|
The method
SortKey.Comparecontains an early incorrect exit which can cause it to return 0 if all of the below conditions hold:sortKey1norsortKey2represents the empty string, andsortKey1is a prefix ofsortKey2(or vice versa).In a nutshell, this means that under the invariant globalization mode, the expression
compareInfo.GetSortKey("he").Equals(compareInfo.GetSortKey("hello!"))incorrectly returns true.There may also be some inputs under the non-invariant mode which trigger this incorrect output, but I didn't attempt this since it would be highly dependent on how the active version of NLS or ICU produces sort keys. It's far easier to trigger this bug under the invariant mode.
This PR addresses that issue in
SortKey.Compare. Additionally, there are some performance optimizations made toSortKey.EqualsandSortKey.GetHashCode. This also builds on #31761 by sealing theSortKeytype and devirtualizing the methods.