Skip to content

Conversation

@xtqqczze
Copy link
Contributor

@xtqqczze xtqqczze commented Jul 23, 2024

cc: @tarekgh

Existing logic appears to be incorrect:

BinaryPrimitives.WriteUInt16BigEndian(sortKey, hr);
BinaryPrimitives.WriteUInt16BigEndian(sortKey, lr)

@dotnet-policy-service dotnet-policy-service bot added the community-contribution Indicates that the PR has been added by a community member label Jul 23, 2024
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-globalization
See info in area-owners.md if you want to be subscribed.

@tarekgh
Copy link
Member

tarekgh commented Jul 23, 2024

@xtqqczze Thanks for your contribution. At the moment, we are only accepting critical changes for the .NET 9.0 release. Nice-to-have fixes will need to wait until we fork the main branch to accept changes for future releases. Since this PR is already a draft, we can keep it open for a while until the fork. Alternatively, you can close it and reopen it later after the fork. I wanted to set the expectation in case you notice no traction on the PR.

CC @ericstj @stephentoub

@tarekgh tarekgh added this to the Future milestone Jul 23, 2024
@xtqqczze xtqqczze changed the title Fix span write in InvariantCreateSortKeyOrdinalIgnoreCase Fix probable bug in InvariantCreateSortKeyOrdinalIgnoreCase Jul 23, 2024
@xtqqczze
Copy link
Contributor Author

@tarekgh This fixes a probable bug.

@tarekgh
Copy link
Member

tarekgh commented Jul 23, 2024

@xtqqczze I'll take a look. Thanks!

@tarekgh
Copy link
Member

tarekgh commented Jul 23, 2024

@xtqqczze could you please explain more why you think there is a bug?

InvariantCreateSortKeyOrdinalIgnoreCase is called guaranteeing the condition Debug.Assert(sortKey.Length >= source.Length * sizeof(char));.

@xtqqczze
Copy link
Contributor Author

@xtqqczze could you please explain more why you think there is a bug?

@tarekgh When writing to the span, we overwrite the high surrogate with the low surrogate:

BinaryPrimitives.WriteUInt16BigEndian(sortKey, hr);
BinaryPrimitives.WriteUInt16BigEndian(sortKey, lr);

This is unexpected, at least.

@stephentoub
Copy link
Member

Can you share a test that fails because of the issue?

@tarekgh
Copy link
Member

tarekgh commented Jul 23, 2024

When writing to the span, we overwrite the high surrogate with the low surrogate:

I see. I was confused with the line Span<byte> tmp = sortKey.Slice(0, 2 * sizeof(ushort)); // help with bounds check elimination which I don't think we need it.

Can you share a test that fails because of the issue?

This is a good idea to add a test for this case.

@tarekgh
Copy link
Member

tarekgh commented Jul 23, 2024

Here is the code can be used in the test case:

            CultureInfo culture = CultureInfo.InvariantCulture;
            var sortKey = culture.CompareInfo.GetSortKey("\uD800\uDC00", CompareOptions.IgnoreCase);

            foreach (var b in sortKey.KeyData)
            {
                Console.Write($"{b:X2} "); // should produce something like D8-00-DC-00
            }

We need to add the test to https://github.com/dotnet/runtime/tree/main/src/libraries/System.Runtime/tests/System.Globalization.Tests/Invariant

@xtqqczze
Copy link
Contributor Author

This is technically a breaking change to GetSortKey(ReadOnlySpan, Span, CompareOptions) in the Bucket 3: Unlikely Grey Area category.

@xtqqczze
Copy link
Contributor Author

@MihuBot

@tarekgh
Copy link
Member

tarekgh commented Jul 23, 2024

This is technically a breaking change to GetSortKey(ReadOnlySpan, Span, CompareOptions) in the Bucket 3: Unlikely Grey Area category.

I am not worried about that. The issue is specific for Invariant Globalization mode with Surrogate pairs. Sort keys usually interesting with the full globalization support.

Copy link
Member

@tarekgh tarekgh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @xtqqczze!

@xtqqczze xtqqczze changed the title Fix probable bug in InvariantCreateSortKeyOrdinalIgnoreCase Fix span write in InvariantCreateSortKeyOrdinalIgnoreCase Jul 24, 2024
@stephentoub
Copy link
Member

/ba-g failures are known

@stephentoub stephentoub merged commit a70e8ab into dotnet:main Jul 24, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Aug 23, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Globalization community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants