Skip to content

Commit 59e6789

Browse files
authored
Fix CFTimeZone crashes on Windows (#5070) (#5072)
* Fix CFTimeZone crashes on Windows * Fix build failure
1 parent c48fff0 commit 59e6789

8 files changed

+583
-1149
lines changed

Sources/CoreFoundation/CFTimeZone.c

+12-123
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
#if TARGET_OS_WIN32
4040
#include <tchar.h>
4141

42-
#include "WindowsResources.h"
42+
#include "CFTimeZone_WindowsMapping.h"
4343
#define NOMINMAX
4444
#define WIN32_LEAN_AND_MEAN
4545
#include "Windows.h"
@@ -92,11 +92,6 @@ static CFArrayRef __CFKnownTimeZoneList = NULL;
9292
static CFMutableDictionaryRef __CFTimeZoneCache = NULL;
9393
static CFLock_t __CFTimeZoneGlobalLock = CFLockInit;
9494

95-
#if TARGET_OS_WIN32
96-
static CFDictionaryRef __CFTimeZoneWinToOlsonDict = NULL;
97-
static CFLock_t __CFTimeZoneWinToOlsonLock = CFLockInit;
98-
#endif
99-
10095
CF_INLINE void __CFTimeZoneLockGlobal(void) {
10196
__CFLock(&__CFTimeZoneGlobalLock);
10297
}
@@ -672,110 +667,7 @@ CFTypeID CFTimeZoneGetTypeID(void) {
672667
return _kCFRuntimeIDCFTimeZone;
673668
}
674669

675-
#if TARGET_OS_WIN32
676-
CF_INLINE void __CFTimeZoneLockWinToOlson(void) {
677-
__CFLock(&__CFTimeZoneWinToOlsonLock);
678-
}
679-
680-
CF_INLINE void __CFTimeZoneUnlockWinToOlson(void) {
681-
__CFUnlock(&__CFTimeZoneWinToOlsonLock);
682-
}
683-
684-
static Boolean CFTimeZoneLoadPlistResource(LPCSTR lpName, LPVOID *ppResource, LPDWORD pdwSize) {
685-
HRSRC hResource;
686-
HGLOBAL hMemory;
687-
HMODULE hModule;
688-
689-
if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
690-
(LPCWSTR)&CFTimeZoneLoadPlistResource, &hModule)) {
691-
return FALSE;
692-
}
693-
694-
hResource = FindResourceA(hModule, lpName, "PLIST");
695-
if (hResource == NULL) {
696-
return FALSE;
697-
}
698-
699-
hMemory = LoadResource(hModule, hResource);
700-
if (hMemory == NULL) {
701-
return FALSE;
702-
}
703-
704-
*pdwSize = SizeofResource(hModule, hResource);
705-
*ppResource = LockResource(hMemory);
706-
707-
return *pdwSize && *ppResource;
708-
}
709-
710-
CFDictionaryRef CFTimeZoneCopyWinToOlsonDictionary(void) {
711-
CFDictionaryRef dict;
712-
713-
__CFTimeZoneLockWinToOlson();
714-
if (NULL == __CFTimeZoneWinToOlsonDict) {
715-
const uint8_t *plist;
716-
DWORD dwSize;
717-
718-
if (CFTimeZoneLoadPlistResource(MAKEINTRESOURCEA(IDR_WINDOWS_OLSON_MAPPING), (LPVOID *)&plist, &dwSize)) {
719-
CFDataRef data = CFDataCreate(kCFAllocatorSystemDefault, plist, dwSize);
720-
__CFTimeZoneWinToOlsonDict = (CFDictionaryRef)CFPropertyListCreateFromXMLData(kCFAllocatorSystemDefault, data, kCFPropertyListImmutable, NULL);
721-
CFRelease(data);
722-
}
723-
}
724-
if (NULL == __CFTimeZoneWinToOlsonDict) {
725-
__CFTimeZoneWinToOlsonDict = CFDictionaryCreate(kCFAllocatorSystemDefault, NULL, NULL, 0, NULL, NULL);
726-
}
727-
dict = __CFTimeZoneWinToOlsonDict ? (CFDictionaryRef)CFRetain(__CFTimeZoneWinToOlsonDict) : NULL;
728-
__CFTimeZoneUnlockWinToOlson();
729-
730-
return dict;
731-
}
732-
733-
static CFDictionaryRef CFTimeZoneCopyOlsonToWindowsDictionary(void) {
734-
static CFDictionaryRef dict;
735-
static CFLock_t lock;
736-
737-
__CFLock(&lock);
738-
if (dict == NULL) {
739-
const uint8_t *plist;
740-
DWORD dwSize;
741-
742-
if (CFTimeZoneLoadPlistResource(MAKEINTRESOURCEA(IDR_OLSON_WINDOWS_MAPPING), (LPVOID *)&plist, &dwSize)) {
743-
CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorSystemDefault, plist, dwSize, kCFAllocatorNull);
744-
dict = CFPropertyListCreateFromXMLData(kCFAllocatorSystemDefault, data, kCFPropertyListImmutable, NULL);
745-
CFRelease(data);
746-
}
747-
}
748-
__CFUnlock(&lock);
749-
750-
return dict ? CFRetain(dict) : NULL;
751-
}
752-
753-
void CFTimeZoneSetWinToOlsonDictionary(CFDictionaryRef dict) {
754-
__CFGenericValidateType(dict, CFDictionaryGetTypeID());
755-
__CFTimeZoneLockWinToOlson();
756-
if (dict != __CFTimeZoneWinToOlsonDict) {
757-
CFDictionaryRef oldDict = __CFTimeZoneWinToOlsonDict;
758-
__CFTimeZoneWinToOlsonDict = dict ? CFRetain(dict) : NULL;
759-
CFRelease(oldDict);
760-
}
761-
__CFTimeZoneUnlockWinToOlson();
762-
}
763-
764-
CFTimeZoneRef CFTimeZoneCreateWithWindowsName(CFAllocatorRef allocator, CFStringRef winName) {
765-
if (!winName) return NULL;
766-
767-
CFDictionaryRef winToOlson = CFTimeZoneCopyWinToOlsonDictionary();
768-
if (!winToOlson) return NULL;
769-
770-
CFStringRef olsonName = CFDictionaryGetValue(winToOlson, winName);
771-
CFTimeZoneRef retval = NULL;
772-
if (olsonName) {
773-
retval = CFTimeZoneCreateWithName(allocator, olsonName, false);
774-
}
775-
CFRelease(winToOlson);
776-
return retval;
777-
}
778-
#elif TARGET_OS_MAC
670+
#if TARGET_OS_MAC
779671
static void __InitTZStrings(void) {
780672
static dispatch_once_t initOnce = 0;
781673

@@ -810,7 +702,7 @@ static void __InitTZStrings(void) {
810702
});
811703
}
812704

813-
#elif TARGET_OS_ANDROID
705+
#elif TARGET_OS_ANDROID || TARGET_OS_WINDOWS
814706
// Nothing
815707
#elif TARGET_OS_LINUX || TARGET_OS_BSD || TARGET_OS_WASI
816708
static void __InitTZStrings(void) {
@@ -834,12 +726,7 @@ static CFTimeZoneRef __CFTimeZoneCreateSystem(void) {
834726
LPWSTR standardName = (LPWSTR)&tzi.StandardName;
835727
CFStringRef cfStandardName = CFStringCreateWithBytes(kCFAllocatorSystemDefault, (UInt8 *)standardName, wcslen(standardName)*sizeof(WCHAR), kCFStringEncodingUTF16LE, false);
836728
if (cfStandardName) {
837-
CFDictionaryRef winToOlson = CFTimeZoneCopyWinToOlsonDictionary();
838-
if (winToOlson) {
839-
name = CFDictionaryGetValue(winToOlson, cfStandardName);
840-
if (name) CFRetain(name);
841-
CFRelease(winToOlson);
842-
}
729+
name = _CFTimeZoneCopyOlsonNameForWindowsName(cfStandardName);
843730
CFRelease(cfStandardName);
844731
}
845732
} else {
@@ -1326,16 +1213,17 @@ Boolean _CFTimeZoneInit(CFTimeZoneRef timeZone, CFStringRef name, CFDataRef data
13261213

13271214
tzName = CFDictionaryGetValue(abbrevs, name);
13281215
if (tzName == NULL) {
1329-
CFDictionaryRef olson = CFTimeZoneCopyOlsonToWindowsDictionary();
1330-
tzName = CFDictionaryGetValue(olson, name);
1331-
CFRelease(olson);
1216+
tzName = _CFTimeZoneCopyWindowsNameForOlsonName(name);
1217+
} else {
1218+
CFRetain(tzName);
13321219
}
13331220

13341221
CFRelease(abbrevs);
13351222

13361223
if (tzName) {
13371224
__CFTimeZoneGetOffset(tzName, &offset);
13381225
// TODO: handle DST
1226+
CFRelease(tzName);
13391227
return __CFTimeZoneInitFixed(timeZone, offset, name, 0);
13401228
}
13411229

@@ -1542,15 +1430,16 @@ CFTimeZoneRef CFTimeZoneCreateWithName(CFAllocatorRef allocator, CFStringRef nam
15421430

15431431
tzName = CFDictionaryGetValue(abbrevs, name);
15441432
if (tzName == NULL) {
1545-
CFDictionaryRef olson = CFTimeZoneCopyOlsonToWindowsDictionary();
1546-
tzName = CFDictionaryGetValue(olson, name);
1547-
CFRelease(olson);
1433+
tzName = _CFTimeZoneCopyWindowsNameForOlsonName(name);
1434+
} else {
1435+
tzName = CFRetain(tzName);
15481436
}
15491437

15501438
CFRelease(abbrevs);
15511439

15521440
if (tzName) {
15531441
__CFTimeZoneGetOffset(tzName, &offset);
1442+
CFRelease(tzName);
15541443
// TODO: handle DST
15551444
result = __CFTimeZoneCreateFixed(allocator, offset, name, 0);
15561445
}

0 commit comments

Comments
 (0)