summaryrefslogtreecommitdiff
path: root/src/corefx
diff options
context:
space:
mode:
authorMatt Ellis <matell@microsoft.com>2016-05-19 11:48:56 -0700
committerMatt Ellis <matell@microsoft.com>2016-05-19 16:12:35 -0700
commit4cdc520c627c655d9ebe52cc715baf2a30f2337d (patch)
tree119329702bb75c38e3f23dfe06c2ccff96b2e57f /src/corefx
parentf1d6f7abbc5dd716cea4dc75b3da8043b9759ded (diff)
downloadcoreclr-4cdc520c627c655d9ebe52cc715baf2a30f2337d.tar.gz
coreclr-4cdc520c627c655d9ebe52cc715baf2a30f2337d.tar.bz2
coreclr-4cdc520c627c655d9ebe52cc715baf2a30f2337d.zip
Ignore empty collation elements in EndsWith
We should ignore empty collaction elements at the end of the string when doing our EndsWith checks. This means the match ICU finds might not span to the end of string, but the only elements after the match before the end are completely ignorable. U+00AD (SOFT HYPHEN) is one such case where the codepoint is completely ignorable. Fixes dotnet/corefx#3467
Diffstat (limited to 'src/corefx')
-rw-r--r--src/corefx/System.Globalization.Native/collation.cpp70
1 files changed, 41 insertions, 29 deletions
diff --git a/src/corefx/System.Globalization.Native/collation.cpp b/src/corefx/System.Globalization.Native/collation.cpp
index f1ec6f4051..6039a9ef39 100644
--- a/src/corefx/System.Globalization.Native/collation.cpp
+++ b/src/corefx/System.Globalization.Native/collation.cpp
@@ -295,6 +295,40 @@ UCollator* CloneCollatorWithOptions(const UCollator* pCollator, int32_t options,
return pClonedCollator;
}
+// Returns TRUE if all the collation elements in str are completely ignorable
+bool CanIgnoreAllCollationElements(const UCollator* pColl, const UChar* lpStr, int32_t length)
+{
+ bool result = FALSE;
+ UErrorCode err = U_ZERO_ERROR;
+ UCollationElements* pCollElem = ucol_openElements(pColl, lpStr, length, &err);
+
+ if (U_SUCCESS(err))
+ {
+ int32_t curCollElem = UCOL_NULLORDER;
+
+ result = TRUE;
+
+ while ((curCollElem = ucol_next(pCollElem, &err)) != UCOL_NULLORDER)
+ {
+ if (curCollElem != 0)
+ {
+ result = FALSE;
+ break;
+ }
+ }
+
+ if (U_FAILURE(err))
+ {
+ result = FALSE;
+ }
+
+ ucol_closeElements(pCollElem);
+ }
+
+ return result;
+
+}
+
extern "C" SortHandle* GlobalizationNative_GetSortHandle(const char* lpLocaleName)
{
SortHandle* pSortHandle = new SortHandle();
@@ -551,32 +585,7 @@ extern "C" int32_t GlobalizationNative_StartsWith(
}
else
{
- UCollationElements* pCollElem = ucol_openElements(pColl, lpSource, idx, &err);
-
- if (U_SUCCESS(err))
- {
- int32_t curCollElem = UCOL_NULLORDER;
-
- result = TRUE;
-
- while ((curCollElem = ucol_next(pCollElem, &err)) != UCOL_NULLORDER)
- {
- if (curCollElem != 0)
- {
- // Non ignorable collation element found between start of the
- // string and the first match for lpTarget.
- result = FALSE;
- break;
- }
- }
-
- if (U_FAILURE(err))
- {
- result = FALSE;
- }
-
- ucol_closeElements(pCollElem);
- }
+ result = CanIgnoreAllCollationElements(pColl, lpSource, idx);
}
}
@@ -617,10 +626,13 @@ extern "C" int32_t GlobalizationNative_EndsWith(
{
result = TRUE;
}
+ else
+ {
+ int32_t matchEnd = idx + usearch_getMatchedLength(pSearch);
+ int32_t remainingStringLength = cwSourceLength - matchEnd;
- // TODO (dotnet/corefx#3467): We should do something similar to what
- // StartsWith does where we can ignore
- // some collation elements at the end of the string if they are zero.
+ result = CanIgnoreAllCollationElements(pColl, lpSource + matchEnd, remainingStringLength);
+ }
}
usearch_close(pSearch);