diff --git a/modules/plugin/base/src/nsPluginsDirDarwin.cpp b/modules/plugin/base/src/nsPluginsDirDarwin.cpp index 1e912fa0e9d..6123538ff1b 100644 --- a/modules/plugin/base/src/nsPluginsDirDarwin.cpp +++ b/modules/plugin/base/src/nsPluginsDirDarwin.cpp @@ -171,69 +171,165 @@ static char* CFStringRefToUTF8Buffer(CFStringRef cfString) return newBuffer; } +class AutoCFTypeObject { +public: + AutoCFTypeObject(CFTypeRef object) + { + mObject = object; + } + ~AutoCFTypeObject() + { + ::CFRelease(mObject); + } +private: + CFTypeRef mObject; +}; + +static CFDictionaryRef ParsePlistForMIMETypesFilename(CFBundleRef bundle) +{ + CFTypeRef mimeFileName = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginMIMETypesFilename")); + if (!mimeFileName || ::CFGetTypeID(mimeFileName) != ::CFStringGetTypeID()) { + return NULL; + } + + FSRef homeDir; + if (::FSFindFolder(kUserDomain, kCurrentUserFolderType, kDontCreateFolder, &homeDir) != noErr) { + return NULL; + } + + CFURLRef userDirURL = ::CFURLCreateFromFSRef(kCFAllocatorDefault, &homeDir); + if (!userDirURL) { + return NULL; + } + + AutoCFTypeObject userDirURLAutorelease(userDirURL); + CFStringRef mimeFilePath = ::CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("Library/Preferences/%@"), static_cast(mimeFileName)); + if (!mimeFilePath) { + return NULL; + } + + AutoCFTypeObject mimeFilePathAutorelease(mimeFilePath); + CFURLRef mimeFileURL = ::CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorDefault, mimeFilePath, kCFURLPOSIXPathStyle, false, userDirURL); + if (!mimeFileURL) { + return NULL; + } + + AutoCFTypeObject mimeFileURLAutorelease(mimeFileURL); + SInt32 errorCode = 0; + CFDataRef mimeFileData = NULL; + Boolean result = ::CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, mimeFileURL, &mimeFileData, NULL, NULL, &errorCode); + if (!result) { + return NULL; + } + + AutoCFTypeObject mimeFileDataAutorelease(mimeFileData); + if (errorCode != 0) { + return NULL; + } + + CFPropertyListRef propertyList = ::CFPropertyListCreateFromXMLData(kCFAllocatorDefault, mimeFileData, kCFPropertyListImmutable, NULL); + if (!propertyList) { + return NULL; + } + + AutoCFTypeObject propertyListAutorelease(propertyList); + if (::CFGetTypeID(propertyList) != ::CFDictionaryGetTypeID()) { + return NULL; + } + + CFTypeRef localizedName = ::CFDictionaryGetValue(static_cast(propertyList), CFSTR("WebPluginLocalizationName")); + if (!localizedName || ::CFGetTypeID(localizedName) != ::CFStringGetTypeID()) { + return NULL; + } + + CFLocaleRef currentLocale = ::CFLocaleCopyCurrent(); + if (!currentLocale) { + return NULL; + } + + AutoCFTypeObject currentLocaleAutorelease(currentLocale); + if (::CFStringCompare(static_cast(localizedName), ::CFLocaleGetIdentifier(currentLocale), 0) != kCFCompareEqualTo) { + return NULL; + } + + CFTypeRef mimeTypes = ::CFDictionaryGetValue(static_cast(propertyList), CFSTR("WebPluginMIMETypes")); + if (!mimeTypes || ::CFGetTypeID(mimeTypes) != ::CFDictionaryGetTypeID() || ::CFDictionaryGetCount(static_cast(mimeTypes)) == 0) { + return NULL; + } + + return static_cast(::CFRetain(mimeTypes)); +} + static void ParsePlistPluginInfo(nsPluginInfo& info, CFBundleRef bundle) { - CFTypeRef mimeDict = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginMIMETypes")); - if (mimeDict && ::CFGetTypeID(mimeDict) == ::CFDictionaryGetTypeID() && ::CFDictionaryGetCount(static_cast(mimeDict)) > 0) { - int mimeDictKeyCount = ::CFDictionaryGetCount(static_cast(mimeDict)); + CFDictionaryRef mimeDict = ParsePlistForMIMETypesFilename(bundle); + + if (!mimeDict) { + CFTypeRef mimeTypes = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginMIMETypes")); + if (!mimeTypes || ::CFGetTypeID(mimeTypes) != ::CFDictionaryGetTypeID() || ::CFDictionaryGetCount(static_cast(mimeTypes)) == 0) + return; + mimeDict = static_cast(::CFRetain(mimeTypes)); + } + + AutoCFTypeObject mimeDictAutorelease(mimeDict); + int mimeDictKeyCount = ::CFDictionaryGetCount(mimeDict); - // Allocate memory for mime data - int mimeDataArraySize = mimeDictKeyCount * sizeof(char*); - info.fMimeTypeArray = static_cast(NS_Alloc(mimeDataArraySize)); - if (!info.fMimeTypeArray) - return; - memset(info.fMimeTypeArray, 0, mimeDataArraySize); - info.fExtensionArray = static_cast(NS_Alloc(mimeDataArraySize)); - if (!info.fExtensionArray) - return; - memset(info.fExtensionArray, 0, mimeDataArraySize); - info.fMimeDescriptionArray = static_cast(NS_Alloc(mimeDataArraySize)); - if (!info.fMimeDescriptionArray) - return; - memset(info.fMimeDescriptionArray, 0, mimeDataArraySize); + // Allocate memory for mime data + int mimeDataArraySize = mimeDictKeyCount * sizeof(char*); + info.fMimeTypeArray = static_cast(NS_Alloc(mimeDataArraySize)); + if (!info.fMimeTypeArray) + return; + memset(info.fMimeTypeArray, 0, mimeDataArraySize); + info.fExtensionArray = static_cast(NS_Alloc(mimeDataArraySize)); + if (!info.fExtensionArray) + return; + memset(info.fExtensionArray, 0, mimeDataArraySize); + info.fMimeDescriptionArray = static_cast(NS_Alloc(mimeDataArraySize)); + if (!info.fMimeDescriptionArray) + return; + memset(info.fMimeDescriptionArray, 0, mimeDataArraySize); - // Allocate memory for mime dictionary keys and values - nsAutoArrayPtr keys(new CFTypeRef[mimeDictKeyCount]); - if (!keys) - return; - nsAutoArrayPtr values(new CFTypeRef[mimeDictKeyCount]); - if (!values) - return; + // Allocate memory for mime dictionary keys and values + nsAutoArrayPtr keys(new CFTypeRef[mimeDictKeyCount]); + if (!keys) + return; + nsAutoArrayPtr values(new CFTypeRef[mimeDictKeyCount]); + if (!values) + return; - // Set the variant count now that we have safely allocated memory - info.fVariantCount = mimeDictKeyCount; + // Set the variant count now that we have safely allocated memory + info.fVariantCount = mimeDictKeyCount; - ::CFDictionaryGetKeysAndValues(static_cast(mimeDict), keys, values); - for (int i = 0; i < mimeDictKeyCount; i++) { - CFTypeRef mimeString = keys[i]; - if (mimeString && ::CFGetTypeID(mimeString) == ::CFStringGetTypeID()) { - info.fMimeTypeArray[i] = CFStringRefToUTF8Buffer(static_cast(mimeString)); - } - else { - info.fVariantCount -= 1; - continue; - } - CFTypeRef mimeDict = values[i]; - if (mimeDict && ::CFGetTypeID(mimeDict) == ::CFDictionaryGetTypeID()) { - CFTypeRef extensions = ::CFDictionaryGetValue(static_cast(mimeDict), CFSTR("WebPluginExtensions")); - if (extensions && ::CFGetTypeID(extensions) == ::CFArrayGetTypeID()) { - int extensionCount = ::CFArrayGetCount(static_cast(extensions)); - CFMutableStringRef extensionList = ::CFStringCreateMutable(kCFAllocatorDefault, 0); - for (int j = 0; j < extensionCount; j++) { - CFTypeRef extension = ::CFArrayGetValueAtIndex(static_cast(extensions), j); - if (extension && ::CFGetTypeID(extension) == ::CFStringGetTypeID()) { - if (j > 0) - ::CFStringAppend(extensionList, CFSTR(",")); - ::CFStringAppend(static_cast(extensionList), static_cast(extension)); - } + ::CFDictionaryGetKeysAndValues(mimeDict, keys, values); + for (int i = 0; i < mimeDictKeyCount; i++) { + CFTypeRef mimeString = keys[i]; + if (mimeString && ::CFGetTypeID(mimeString) == ::CFStringGetTypeID()) { + info.fMimeTypeArray[i] = CFStringRefToUTF8Buffer(static_cast(mimeString)); + } + else { + info.fVariantCount -= 1; + continue; + } + CFTypeRef mimeDict = values[i]; + if (mimeDict && ::CFGetTypeID(mimeDict) == ::CFDictionaryGetTypeID()) { + CFTypeRef extensions = ::CFDictionaryGetValue(static_cast(mimeDict), CFSTR("WebPluginExtensions")); + if (extensions && ::CFGetTypeID(extensions) == ::CFArrayGetTypeID()) { + int extensionCount = ::CFArrayGetCount(static_cast(extensions)); + CFMutableStringRef extensionList = ::CFStringCreateMutable(kCFAllocatorDefault, 0); + for (int j = 0; j < extensionCount; j++) { + CFTypeRef extension = ::CFArrayGetValueAtIndex(static_cast(extensions), j); + if (extension && ::CFGetTypeID(extension) == ::CFStringGetTypeID()) { + if (j > 0) + ::CFStringAppend(extensionList, CFSTR(",")); + ::CFStringAppend(static_cast(extensionList), static_cast(extension)); } - info.fExtensionArray[i] = CFStringRefToUTF8Buffer(static_cast(extensionList)); - ::CFRelease(extensionList); } - CFTypeRef description = ::CFDictionaryGetValue(static_cast(mimeDict), CFSTR("WebPluginTypeDescription")); - if (description && ::CFGetTypeID(description) == ::CFStringGetTypeID()) - info.fMimeDescriptionArray[i] = CFStringRefToUTF8Buffer(static_cast(description)); + info.fExtensionArray[i] = CFStringRefToUTF8Buffer(static_cast(extensionList)); + ::CFRelease(extensionList); } + CFTypeRef description = ::CFDictionaryGetValue(static_cast(mimeDict), CFSTR("WebPluginTypeDescription")); + if (description && ::CFGetTypeID(description) == ::CFStringGetTypeID()) + info.fMimeDescriptionArray[i] = CFStringRefToUTF8Buffer(static_cast(description)); } } }