dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.37k stars 4.75k forks source link

string.IndexOf() incorrect return value for full stop for Thai culture #76137

Closed aquaticus closed 2 years ago

aquaticus commented 2 years ago

Description

When Thai th-TH culture is set for a thread, string.IndexOf(string) returns always 0 if the argument contains full stop character . (U+002E).

This may be specific for Thai script but works as described in documentation for older .NET Core/NetFrameworks.

Reproduction Steps

CultureInfo th = new CultureInfo("th-TH", false);
Thread.CurrentThread.CurrentCulture = th;

var index1 = "012".IndexOf("."); // returns 0, it should be -1
var index2 = "01.".IndexOf("."); // returns 0, it should be 2

Expected behavior

"012".IndexOf(".") returns -1 "01.".IndexOf(".") returns 2

Actual behavior

"012".IndexOf(".") returns 0 "01.".IndexOf(".") returns 0

Regression?

For

it works as documented.

Known Workarounds

Use char type insted of string as an argument for IndexOf(), e.g. IndexOf('.')

Configuration

Windows 10 x64

Ubuntu 20 x64

Other information

No response

ghost commented 2 years ago

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

Issue Details
### Description When Thai `th-TH` culture is set for a thread, `string.IndexOf(string)` returns always `0` if the argument contains full stop character `.` (U+002E). This may be specific for Thai script but works as described in documentation for older .NET Core/NetFrameworks. ### Reproduction Steps ```c# CultureInfo th = new CultureInfo("th-TH", false); Thread.CurrentThread.CurrentCulture = th; var index1 = "012".IndexOf("."); // returns 0, it should be -1 var index2 = "01.".IndexOf("."); // returns 0, it should be 2 ``` ### Expected behavior `"012".IndexOf(".")` returns `-1` `"01.".IndexOf(".")` returns `2` ### Actual behavior `"012".IndexOf(".")` returns `0` `"01.".IndexOf(".")` returns `0` ### Regression? For * .NET Core 3.1 * NetFramework 4.7.2 * NetFramework 4.8.0 it works as documented. ### Known Workarounds Use char type insted of string as an argument for `IndexOf()`, e.g. `IndexOf('.')` ### Configuration Windows 10 x64 * .NET 5 * .NET 6 * .NET 7 Ubuntu 20 x64 * .NET 6 ### Other information _No response_
Author: aquaticus
Assignees: -
Labels: `area-System.Globalization`, `untriaged`
Milestone: -
danmoseley commented 2 years ago

Can you please force NLS mode and confirm you get the previous behavior? See

https://learn.microsoft.com/en-us/dotnet/core/compatibility/globalization/5.0/icu-globalization-api

gfoidl commented 2 years ago

See https://github.com/dotnet/runtime/issues/59120#issuecomment-923209271, https://github.com/dotnet/runtime/issues/75616#issuecomment-1247072121, ...

aquaticus commented 2 years ago

Enabling NLS solves the issue.

Duplicate of #59120, #75616

danmoseley commented 2 years ago

@aquaticus Thanks for the confirmation. Enabling NLS would probably not be your long term plan. You may want to pass StringComparison.Ordinal

aquaticus commented 2 years ago

Thanks for the confirmation. Enabling NLS would probably not be your long term plan. You may want to pass StringComparison.Ordinal

Yeah, I need quick solution at the moment. Applying proper patch takes time in my case.