Skip to content

Commit d1b4798

Browse files
authored
Update stringshims to always use clocale (#1427)
1 parent ac4b540 commit d1b4798

File tree

6 files changed

+58
-63
lines changed

6 files changed

+58
-63
lines changed

Sources/FoundationEssentials/JSON/JSON5Scanner.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1081,7 +1081,7 @@ extension JSON5Scanner {
10811081
jsonBytes.formIndex(after: &index)
10821082
}
10831083

1084-
let cmp = jsonBytes[index..<endIndex].prefix(2).withUnsafePointer({ _stringshims_strncasecmp_l($0, "0x", $1, nil) })
1084+
let cmp = jsonBytes[index..<endIndex].prefix(2).withUnsafePointer({ _stringshims_strncasecmp_clocale($0, "0x", $1) })
10851085
if cmp == 0 {
10861086
jsonBytes.formIndex(&index, offsetBy: 2)
10871087

Sources/FoundationEssentials/JSON/JSONScanner.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,7 +1179,7 @@ extension Double : PrevalidatedJSONNumberBufferConvertible {
11791179
init?(prevalidatedBuffer buffer: BufferView<UInt8>) {
11801180
let decodedValue = buffer.withUnsafePointer { nptr, count -> Double? in
11811181
var endPtr: UnsafeMutablePointer<CChar>? = nil
1182-
let decodedValue = _stringshims_strtod_l(nptr, &endPtr, nil)
1182+
let decodedValue = _stringshims_strtod_clocale(nptr, &endPtr)
11831183
if let endPtr, nptr.advanced(by: count) == endPtr {
11841184
return decodedValue
11851185
} else {
@@ -1195,7 +1195,7 @@ extension Float : PrevalidatedJSONNumberBufferConvertible {
11951195
init?(prevalidatedBuffer buffer: BufferView<UInt8>) {
11961196
let decodedValue = buffer.withUnsafePointer { nptr, count -> Float? in
11971197
var endPtr: UnsafeMutablePointer<CChar>? = nil
1198-
let decodedValue = _stringshims_strtof_l(nptr, &endPtr, nil)
1198+
let decodedValue = _stringshims_strtof_clocale(nptr, &endPtr)
11991199
if let endPtr, nptr.advanced(by: count) == endPtr {
12001200
return decodedValue
12011201
} else {

Sources/FoundationEssentials/PropertyList/PlistDecoder.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ open class PropertyListDecoder {
231231
}
232232

233233
return try buffer[unchecked: baseIdx..<idx].withUnsafePointer { ptr, encodingLength in
234-
if encodingLength == 5, _stringshims_strncasecmp_l(ptr, "utf-8", 5, nil) == 0 {
234+
if encodingLength == 5, _stringshims_strncasecmp_clocale(ptr, "utf-8", 5) == 0 {
235235
return .utf8
236236
}
237237

Sources/FoundationEssentials/PropertyList/XMLPlistScanner.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ extension XMLPlistMap.Value {
645645
return .nan
646646
}
647647
case (UInt8(ascii: "+"), 9):
648-
if _stringshims_strncasecmp_l(buf.baseAddress, "+infinity", 9, nil) == 0 {
648+
if _stringshims_strncasecmp_clocale(buf.baseAddress, "+infinity", 9) == 0 {
649649
return .infinity
650650
}
651651
case (UInt8(ascii: "+"), 4):
@@ -655,7 +655,7 @@ extension XMLPlistMap.Value {
655655
return .infinity
656656
}
657657
case (UInt8(ascii: "-"), 9):
658-
if _stringshims_strncasecmp_l(buf.baseAddress, "-infinity", 9, nil) == 0 {
658+
if _stringshims_strncasecmp_clocale(buf.baseAddress, "-infinity", 9) == 0 {
659659
return .infinity * -1
660660
}
661661
case (UInt8(ascii: "-"), 4):
@@ -665,7 +665,7 @@ extension XMLPlistMap.Value {
665665
return .infinity * -1
666666
}
667667
case (UInt8(ascii: "i"), 8), (UInt8(ascii: "I"), 8):
668-
if _stringshims_strncasecmp_l(buf.baseAddress, "infinity", 8, nil) == 0 {
668+
if _stringshims_strncasecmp_clocale(buf.baseAddress, "infinity", 8) == 0 {
669669
return .infinity
670670
}
671671
case (.none, 0):
@@ -728,9 +728,9 @@ extension XMLPlistMap.Value {
728728
var parseEndPtr : UnsafeMutablePointer<CChar>?
729729
let res : T
730730
if MemoryLayout<T>.size == MemoryLayout<Float>.size {
731-
res = T(_stringshims_strtof_l(ptr, &parseEndPtr, nil))
731+
res = T(_stringshims_strtof_clocale(ptr, &parseEndPtr))
732732
} else if MemoryLayout<T>.size == MemoryLayout<Double>.size {
733-
res = T(_stringshims_strtod_l(ptr, &parseEndPtr, nil))
733+
res = T(_stringshims_strtod_clocale(ptr, &parseEndPtr))
734734
} else {
735735
preconditionFailure("Only Float and Double are currently supported by PropertyListDecoder, not \(type))")
736736
}

Sources/_FoundationCShims/include/string_shims.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ extern "C" {
3737
#define locale_t void *
3838
#endif
3939

40-
INTERNAL int _stringshims_strncasecmp_l(const char * _Nullable s1, const char * _Nullable s2, size_t n, locale_t _Nullable loc);
40+
INTERNAL int _stringshims_strncasecmp_clocale(const char * _Nullable s1, const char * _Nullable s2, size_t n);
4141

42-
INTERNAL double _stringshims_strtod_l(const char * _Nullable __restrict nptr, char * _Nullable * _Nullable __restrict endptr, locale_t _Nullable loc);
42+
INTERNAL double _stringshims_strtod_clocale(const char * _Nullable __restrict nptr, char * _Nullable * _Nullable __restrict endptr);
4343

44-
INTERNAL float _stringshims_strtof_l(const char * _Nullable __restrict nptr, char * _Nullable * _Nullable __restrict endptr, locale_t _Nullable loc);
44+
INTERNAL float _stringshims_strtof_clocale(const char * _Nullable __restrict nptr, char * _Nullable * _Nullable __restrict endptr);
4545

4646
#define _STRINGSHIMS_MACROMAN_MAP_SIZE 129
4747
INTERNAL const uint8_t _stringshims_macroman_mapping[_STRINGSHIMS_MACROMAN_MAP_SIZE][3];

Sources/_FoundationCShims/string_shims.c

Lines changed: 46 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -23,80 +23,75 @@
2323
#include <strings.h>
2424
#endif
2525

26-
int _stringshims_strncasecmp_l(const char * _Nullable s1,
27-
const char * _Nullable s2,
28-
size_t n,
29-
locale_t _Nullable loc)
30-
{
3126
#if TARGET_OS_WINDOWS
32-
static _locale_t storage;
33-
static _locale_t *cloc = NULL;
34-
if (cloc == NULL) {
35-
storage = _create_locale(LC_ALL, "C");
36-
cloc = &storage;
37-
}
38-
return _strnicmp_l(s1, s2, n, loc ? loc : *cloc);
39-
#else
40-
if (loc != NULL) {
41-
#if (defined(TARGET_OS_EXCLAVEKIT) && TARGET_OS_EXCLAVEKIT) || \
42-
(defined(TARGET_OS_ANDROID) && TARGET_OS_ANDROID && __ANDROID_API__ < 23)
43-
abort();
27+
#define FOUNDATION_C_LOCALE (_clocale())
28+
static _locale_t _clocale() {
29+
static _locale_t storage;
30+
static bool once = false;
31+
if (!once) {
32+
storage = _create_locale(LC_ALL, "C");
33+
once = true;
34+
}
35+
return storage;
36+
}
37+
#elif TARGET_OS_MAC
38+
#define FOUNDATION_C_LOCALE LC_C_LOCALE
4439
#else
45-
return strncasecmp_l(s1, s2, n, loc);
46-
#endif
40+
#define FOUNDATION_C_LOCALE (_clocale())
41+
static locale_t _clocale() {
42+
static locale_t storage;
43+
static bool once = false;
44+
if (!once) {
45+
storage = newlocale(LC_ALL_MASK, "C", (locale_t)0);
46+
once = true;
4747
}
48-
// On Darwin, NULL loc means unlocalized compare.
49-
// Uses the standard C locale for Linux in this case
50-
#if (defined(TARGET_OS_EXCLAVEKIT) && TARGET_OS_EXCLAVEKIT) || \
48+
return storage;
49+
}
50+
#endif
51+
52+
53+
int _stringshims_strncasecmp_clocale(const char * _Nullable s1,
54+
const char * _Nullable s2,
55+
size_t n)
56+
{
57+
#if TARGET_OS_WINDOWS
58+
return _strnicmp_l(s1, s2, n, FOUNDATION_C_LOCALE);
59+
#elif (defined(TARGET_OS_EXCLAVEKIT) && TARGET_OS_EXCLAVEKIT) || \
5160
(defined(TARGET_OS_ANDROID) && TARGET_OS_ANDROID && __ANDROID_API__ < 23)
5261
return strncasecmp(s1, s2, n);
53-
#elif TARGET_OS_MAC
54-
return strncasecmp_l(s1, s2, n, NULL);
5562
#else
56-
locale_t clocale = newlocale(LC_ALL_MASK, "C", (locale_t)0);
57-
return strncasecmp_l(s1, s2, n, clocale);
58-
#endif // TARGET_OS_MAC
59-
#endif // TARGET_OS_WINDOWS
63+
return strncasecmp_l(s1, s2, n, FOUNDATION_C_LOCALE);
64+
#endif
6065
}
6166

62-
double _stringshims_strtod_l(const char * _Nullable restrict nptr,
63-
char * _Nullable * _Nullable restrict endptr,
64-
locale_t _Nullable loc)
67+
double _stringshims_strtod_clocale(const char * _Nullable restrict nptr,
68+
char * _Nullable * _Nullable restrict endptr)
6569
{
66-
#if defined(TARGET_OS_EXCLAVEKIT) && TARGET_OS_EXCLAVEKIT
67-
assert(loc == NULL);
68-
return strtod_l(nptr, endptr, NULL);
69-
#elif TARGET_OS_MAC
70-
return strtod_l(nptr, endptr, loc);
70+
#if TARGET_OS_MAC
71+
return strtod_l(nptr, endptr, FOUNDATION_C_LOCALE);
7172
#elif TARGET_OS_WINDOWS
72-
return _strtod_l(nptr, endptr, loc);
73+
return _strtod_l(nptr, endptr, FOUNDATION_C_LOCALE);
7374
#else
7475
// Use the C locale
75-
locale_t clocale = newlocale(LC_ALL_MASK, "C", (locale_t)0);
76-
locale_t oldLocale = uselocale(clocale);
76+
locale_t oldLocale = uselocale(FOUNDATION_C_LOCALE);
7777
double result = strtod(nptr, endptr);
7878
// Restore locale
7979
uselocale(oldLocale);
8080
return result;
8181
#endif
8282
}
8383

84-
float _stringshims_strtof_l(const char * _Nullable restrict nptr,
85-
char * _Nullable * _Nullable restrict endptr,
86-
locale_t _Nullable loc)
84+
float _stringshims_strtof_clocale(const char * _Nullable restrict nptr,
85+
char * _Nullable * _Nullable restrict endptr)
8786
{
88-
#if defined(TARGET_OS_EXCLAVEKIT) && TARGET_OS_EXCLAVEKIT
89-
assert(loc == NULL);
90-
return strtof_l(nptr, endptr, NULL);
91-
#elif TARGET_OS_MAC
92-
return strtof_l(nptr, endptr, loc);
87+
#if TARGET_OS_MAC
88+
return strtof_l(nptr, endptr, FOUNDATION_C_LOCALE);
9389
#elif TARGET_OS_WINDOWS
94-
return _strtof_l(nptr, endptr, loc);
90+
return _strtof_l(nptr, endptr, FOUNDATION_C_LOCALE);
9591
#else
9692
// Use the C locale
97-
locale_t clocale = newlocale(LC_ALL_MASK, "C", (locale_t)0);
98-
locale_t oldLocale = uselocale(clocale);
99-
float result = strtof(nptr, endptr);
93+
locale_t oldLocale = uselocale(FOUNDATION_C_LOCALE);
94+
double result = strtof(nptr, endptr);
10095
// Restore locale
10196
uselocale(oldLocale);
10297
return result;

0 commit comments

Comments
 (0)