Skip to content

Commit f7dcaf2

Browse files
committed
SR-11917: Using JSONEncoder's .outputFormatting = .sortedKeys has a memory leak on Linux
- Any use of NSString.compare(_:options:range:locale:) with a non-nil locale would leak on Linux. - _CFCompareStringsWithLocale was leaking the collator on non-macOS platforms. - Use the collator cache on Linux and Win32 the same way that macOS does and for other platforms ensure that any allocated collator is freed.
1 parent 474b5d4 commit f7dcaf2

File tree

1 file changed

+8
-7
lines changed

1 file changed

+8
-7
lines changed

CoreFoundation/String.subproj/CFStringUtilities.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ static UCollator *__CFStringCopyDefaultCollator(CFLocaleRef compareLocale) {
420420
return collator;
421421
}
422422

423-
#if TARGET_OS_MAC
423+
#if TARGET_OS_MAC || TARGET_OS_WIN32 || TARGET_OS_LINUX
424424
static void __collatorFinalize(UCollator *collator) {
425425
CFLocaleRef locale = _CFGetTSD(__CFTSDKeyCollatorLocale);
426426
_CFSetTSD(__CFTSDKeyCollatorUCollator, NULL, NULL);
@@ -603,9 +603,8 @@ CF_PRIVATE CFComparisonResult _CFCompareStringsWithLocale(CFStringInlineBuffer *
603603
if (range2.location > 0) {
604604
range2.location = __extendLocationBackward(range2.location - 1, str2, nonBaseBMP, punctBMP);
605605
}
606-
606+
607607
#if TARGET_OS_MAC || TARGET_OS_WIN32 || TARGET_OS_LINUX
608-
#if TARGET_OS_MAC
609608
// First we try to use the last one used on this thread, if the locale is the same,
610609
// otherwise we try to check out a default one, or then we create one.
611610
UCollator *threadCollator = _CFGetTSD(__CFTSDKeyCollatorUCollator);
@@ -620,11 +619,10 @@ CF_PRIVATE CFComparisonResult _CFCompareStringsWithLocale(CFStringInlineBuffer *
620619
collator = __CFStringCreateCollator((CFLocaleRef)compareLocale);
621620
defaultCollator = false;
622621
}
623-
#if TARGET_OS_MAC
622+
#if TARGET_OS_MAC || TARGET_OS_WIN32 || TARGET_OS_LINUX
624623
}
625624
#endif
626-
#endif
627-
625+
628626
characters1 = CFStringGetCharactersPtrFromInlineBuffer(str1, range1);
629627
characters2 = CFStringGetCharactersPtrFromInlineBuffer(str2, range2);
630628

@@ -739,7 +737,7 @@ CF_PRIVATE CFComparisonResult _CFCompareStringsWithLocale(CFStringInlineBuffer *
739737
if (buffer2Len > 0) CFAllocatorDeallocate(kCFAllocatorSystemDefault, buffer2);
740738
}
741739

742-
#if TARGET_OS_MAC
740+
#if TARGET_OS_MAC || TARGET_OS_WIN32 || TARGET_OS_LINUX
743741
if (collator == threadCollator) {
744742
// do nothing, already cached
745743
} else {
@@ -748,6 +746,9 @@ CF_PRIVATE CFComparisonResult _CFCompareStringsWithLocale(CFStringInlineBuffer *
748746
_CFSetTSD(__CFTSDKeyCollatorUCollator, collator, (void *)__collatorFinalize);
749747
_CFSetTSD(__CFTSDKeyCollatorLocale, (void *)CFRetain(compareLocale), NULL);
750748
}
749+
#else
750+
// Dealloc the collator when the cache isnt used.
751+
if (NULL != collator) ucol_close(collator);
751752
#endif
752753

753754
return compResult;

0 commit comments

Comments
 (0)