From 80a41ef75249fe905a5b6b3d4c6866dd97ac5fbf Mon Sep 17 00:00:00 2001 From: ckegel <57967583+CKegel@users.noreply.github.com> Date: Fri, 7 Apr 2023 20:13:04 -0400 Subject: [PATCH 1/2] Add `kCFURLTypeIdentifierKey` to CFURL(and NSURL) --- NSURL.m | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/NSURL.m b/NSURL.m index df3f113..1a020de 100644 --- a/NSURL.m +++ b/NSURL.m @@ -17,6 +17,7 @@ #import #include #include +#include #define STACK_BUFFER_SIZE 100 // pretty safe bet this will be quite unlikely to use more than this since there are only 94 properties @@ -156,6 +157,17 @@ static void posixError(CFErrorRef *error) { CFRelease(err); } +static void dlError(CFErrorRef *error) { + int saved_errno = errno; + const CFStringRef key = kCFErrorUnderlyingErrorKey; + CFStringRef underlyingError = CFStringCreateWithCString(kCFAllocatorDefault, dlerror(), kCFStringEncodingUTF8); + CFTypeRef value = underlyingError; + + if(error != NULL) + *error = CFErrorCreateWithUserInfoKeysAndValues(kCFAllocatorDefault, kCFErrorDomainPOSIX, saved_errno, (const void *const *) &key, (const void *const *) &value, 1); + CFRelease(underlyingError); +}; + static Boolean CFURLStat(CFURLRef url, struct stat *info) { UInt8 path[PATH_MAX] = { 0 }; @@ -351,7 +363,43 @@ static CFTypeRef CFURLCreatePropertyForKey(CFURLRef url, CFStringRef key, CFErro else if (CFEqual(key, kCFURLTypeIdentifierKey)) { // Key for the resource’s uniform type identifier (UTI), returned as a CFString object. + static dispatch_once_t pred; + static void* LaunchServicesHandle; + static CFErrorRef LaunchServicesHandleError; + dispatch_once(&pred, ^{ + LaunchServicesHandle = dlopen("/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/LaunchServices", RTLD_LAZY | RTLD_LOCAL); + if(LaunchServicesHandle == NULL) + dlError(&LaunchServicesHandleError); + }); + + if(LaunchServicesHandle == NULL){ + if (error != NULL) + *error = CFRetain(LaunchServicesHandleError); + return NULL; + } + + static CFStringRef (*UTTypeCreatePreferredIdentifierForTag)(CFStringRef, CFStringRef, _Nullable CFStringRef); + static CFStringRef *tagType; + static dispatch_once_t dlsym_pred; + + dispatch_once(&dlsym_pred, ^{ + UTTypeCreatePreferredIdentifierForTag = dlsym(LaunchServicesHandle, "UTTypeCreatePreferredIdentifierForTag"); + tagType = dlsym(LaunchServicesHandle, "kUTTagClassFilenameExtension"); + if(UTTypeCreatePreferredIdentifierForTag == NULL || tagType == NULL) + dlError(&LaunchServicesHandleError); + }); + + if(UTTypeCreatePreferredIdentifierForTag == NULL || tagType == NULL){ + if (error != NULL) + *error = CFRetain(LaunchServicesHandleError); + return NULL; + } + + CFStringRef extension = CFURLCopyPathExtension(url); + value = UTTypeCreatePreferredIdentifierForTag(*tagType, extension, NULL); + + CFRelease(extension); } else if (CFEqual(key, kCFURLLocalizedTypeDescriptionKey)) { From 464b2b4e474bf529fcdd7597fffb9defa6f52e18 Mon Sep 17 00:00:00 2001 From: ckegel <57967583+CKegel@users.noreply.github.com> Date: Thu, 19 Oct 2023 21:53:19 -0400 Subject: [PATCH 2/2] Correct `CFRunArrayItem` dictionary initialization. --- CFAttributedString.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CFAttributedString.c b/CFAttributedString.c index 81c34d4..caa445d 100644 --- a/CFAttributedString.c +++ b/CFAttributedString.c @@ -83,7 +83,7 @@ static __CFRunArrayItem * _CFRunArrayItemInit(CFRange range, CFDictionaryRef dic { __CFRunArrayItem *obj = (__CFRunArrayItem *)malloc(sizeof(__CFRunArrayItem)); obj->_range = range; - obj->_dictionary = CFRetain(dict); + obj->_dictionary = CFDictionaryCreateCopy(kCFAllocatorDefault, dict); return obj; }