From 312f25515b4cf36fc4e82114c0273fa81e0031ee Mon Sep 17 00:00:00 2001 From: Mike Beaton Date: Thu, 4 Jan 2024 10:12:07 +0000 Subject: [PATCH] LogoutHook: Convert all CFString to CFData before saving Works round fact that OpenCore XML parser does not automatically decode any XML entities. --- Changelog.md | 1 + Utilities/LogoutHook/nvramdump.c | 32 +++++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 7b79c7ab..f57e1ce3 100644 --- a/Changelog.md +++ b/Changelog.md @@ -8,6 +8,7 @@ OpenCore Changelog - Fixed intro animation getting stuck in OpenCanopy if an entry which returns to menu is selected before animation ends - Modified OpenCanopy to require presence of label images only when used due to `OC_ATTR_USE_GENERIC_LABEL_IMAGE` - Provided `OC_ATTR_REDUCE_MOTION` to optionally disable non-required OpenCanopy menu animations +- Modified NVRAM logout hook to handle XML entities in string vars #### v0.9.7 - Updated recovery_urls.txt diff --git a/Utilities/LogoutHook/nvramdump.c b/Utilities/LogoutHook/nvramdump.c index 5176cfc2..236e4d1a 100644 --- a/Utilities/LogoutHook/nvramdump.c +++ b/Utilities/LogoutHook/nvramdump.c @@ -40,9 +40,30 @@ static kern_return_t GetOFVariable(char *name, CFStringRef *nameRef, *valueRef = IORegistryEntryCreateCFProperty(gOptionsRef, *nameRef, 0, 0); if (*valueRef == 0) return kIOReturnNotFound; + if (CFGetTypeID(*valueRef) == CFStringGetTypeID()) { + CFTypeRef oldValue = *valueRef; + *valueRef = CFStringCreateExternalRepresentation(kCFAllocatorDefault, *valueRef, kCFStringEncodingUTF8, 0); + CFRelease(oldValue); + if (*valueRef == 0) return kIOReturnNotFound; + } + return KERN_SUCCESS; } +static CFMutableDictionaryRef dict4; + +static void ConvertStringValues (const void* key, const void* value, void* context) { + if (CFGetTypeID(value) == CFStringGetTypeID()) { + CFDataRef dataValue = CFStringCreateExternalRepresentation(kCFAllocatorDefault, value, kCFStringEncodingUTF8, 0); + if (dataValue != NULL) { + CFDictionaryAddValue(dict4, key, dataValue); + } + } else { + CFDictionaryAddValue(dict4, key, value); + } +} + + CFDictionaryRef CreateMyDictionary(void) { char *guid; @@ -69,8 +90,17 @@ CFDictionaryRef CreateMyDictionary(void) { if (result != KERN_SUCCESS) { errx(1, "Error getting the firmware variables: %s", mach_error_string(result)); } - CFDictionarySetValue(dict0, CFSTR("7C436110-AB2A-4BBB-A880-FE41995C9F82"), dict1); + + // To work round limitations of OpenCore XML parser (i.e. XML entities not + // automatically processed), force all string values to save as data. + dict4 = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFDictionaryApplyFunction(dict1, ConvertStringValues, NULL); + + CFDictionarySetValue(dict0, CFSTR("7C436110-AB2A-4BBB-A880-FE41995C9F82"), dict4); CFRelease(dict1); + CFRelease(dict4); CFMutableDictionaryRef dict2 = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);