165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch/* 265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Copyright (C) 2010 Apple Inc. All rights reserved. 365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Redistribution and use in source and binary forms, with or without 565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * modification, are permitted provided that the following conditions 665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * are met: 765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 1. Redistributions of source code must retain the above copyright 865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * notice, this list of conditions and the following disclaimer. 965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 2. Redistributions in binary form must reproduce the above copyright 1065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * notice, this list of conditions and the following disclaimer in the 1165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * documentation and/or other materials provided with the distribution. 1265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 1365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 1465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 1565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 1765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 1965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 2365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THE POSSIBILITY OF SUCH DAMAGE. 2465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch */ 2565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#import "config.h" 272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#import "NetscapePluginModule.h" 2865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#import <WebCore/WebCoreNSStringExtras.h> 302fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#import <wtf/HashSet.h> 3165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 3265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochusing namespace WebCore; 3365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 3465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochnamespace WebKit { 3565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 3665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic bool getPluginArchitecture(CFBundleRef bundle, cpu_type_t& pluginArchitecture) 3765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 3865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch RetainPtr<CFArrayRef> pluginArchitecturesArray(AdoptCF, CFBundleCopyExecutableArchitectures(bundle)); 3965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!pluginArchitecturesArray) 4065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return false; 4165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 4265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Turn the array into a set. 4365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch HashSet<unsigned> architectures; 4465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch for (CFIndex i = 0, numPluginArchitectures = CFArrayGetCount(pluginArchitecturesArray.get()); i < numPluginArchitectures; ++i) { 4565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch CFNumberRef number = static_cast<CFNumberRef>(CFArrayGetValueAtIndex(pluginArchitecturesArray.get(), i)); 4665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 4765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch SInt32 architecture; 4865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!CFNumberGetValue(number, kCFNumberSInt32Type, &architecture)) 4965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch continue; 5065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch architectures.add(architecture); 5165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 5265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 5365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#ifdef __x86_64__ 5465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // We only support 64-bit Intel plug-ins on 64-bit Intel. 5565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (architectures.contains(kCFBundleExecutableArchitectureX86_64)) { 5665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch pluginArchitecture = CPU_TYPE_X86_64; 5765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return true; 5865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 5965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 6065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // We also support 32-bit Intel plug-ins on 64-bit Intel. 6165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (architectures.contains(kCFBundleExecutableArchitectureI386)) { 6265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch pluginArchitecture = CPU_TYPE_X86; 6365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return true; 6465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 6565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif defined(__i386__) 6665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // We only support 32-bit Intel plug-ins on 32-bit Intel. 6765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (architectures.contains(kCFBundleExecutableArchitectureI386)) { 6865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch pluginArchitecture = CPU_TYPE_X86; 6965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return true; 7065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 7165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif defined(__ppc64__) 7265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // We only support 64-bit PPC plug-ins on 64-bit PPC. 7365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (architectures.contains(kCFBundleExecutableArchitecturePPC64)) { 7465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch pluginArchitecture = CPU_TYPE_POWERPC64; 7565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return true; 7665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 7765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#elif defined(__ppc__) 7865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // We only support 32-bit PPC plug-ins on 32-bit PPC. 7965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (architectures.contains(kCFBundleExecutableArchitecturePPC)) { 8065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch pluginArchitecture = CPU_TYPE_POWERPC; 8165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return true; 8265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 8365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#else 8465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#error "Unhandled architecture" 8565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#endif 8665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 8765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return false; 8865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 892bde8e466a4451c7319e3a072d118917957d6554Steve Block 902bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic RetainPtr<CFDictionaryRef> getMIMETypesFromPluginBundle(CFBundleRef bundle) 912bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 922bde8e466a4451c7319e3a072d118917957d6554Steve Block CFStringRef propertyListFilename = static_cast<CFStringRef>(CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginMIMETypesFilename"))); 932bde8e466a4451c7319e3a072d118917957d6554Steve Block if (propertyListFilename) { 942bde8e466a4451c7319e3a072d118917957d6554Steve Block RetainPtr<CFStringRef> propertyListPath(AdoptCF, CFStringCreateWithFormat(kCFAllocatorDefault, 0, CFSTR("%@/Library/Preferences/%@"), NSHomeDirectory(), propertyListFilename)); 952bde8e466a4451c7319e3a072d118917957d6554Steve Block RetainPtr<CFURLRef> propertyListURL(AdoptCF, CFURLCreateWithFileSystemPath(kCFAllocatorDefault, propertyListPath.get(), kCFURLPOSIXPathStyle, FALSE)); 962bde8e466a4451c7319e3a072d118917957d6554Steve Block 972bde8e466a4451c7319e3a072d118917957d6554Steve Block CFDataRef propertyListData; 982bde8e466a4451c7319e3a072d118917957d6554Steve Block CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, propertyListURL.get(), &propertyListData, 0, 0, 0); 992bde8e466a4451c7319e3a072d118917957d6554Steve Block RetainPtr<CFPropertyListRef> propertyList(AdoptCF, CFPropertyListCreateWithData(kCFAllocatorDefault, propertyListData, kCFPropertyListImmutable, 0, 0)); 1002bde8e466a4451c7319e3a072d118917957d6554Steve Block if (propertyListData) 1012bde8e466a4451c7319e3a072d118917957d6554Steve Block CFRelease(propertyListData); 1022bde8e466a4451c7319e3a072d118917957d6554Steve Block 1032bde8e466a4451c7319e3a072d118917957d6554Steve Block // FIXME: Have the plug-in create the MIME types property list if it doesn't exist. 1042bde8e466a4451c7319e3a072d118917957d6554Steve Block // https://bugs.webkit.org/show_bug.cgi?id=57204 1052bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!propertyList || CFGetTypeID(propertyList.get()) != CFDictionaryGetTypeID()) 1062bde8e466a4451c7319e3a072d118917957d6554Steve Block return 0; 1072bde8e466a4451c7319e3a072d118917957d6554Steve Block 1082bde8e466a4451c7319e3a072d118917957d6554Steve Block return static_cast<CFDictionaryRef>(CFDictionaryGetValue(static_cast<CFDictionaryRef>(propertyList.get()), CFSTR("WebPluginMIMETypes"))); 1092bde8e466a4451c7319e3a072d118917957d6554Steve Block } 1102bde8e466a4451c7319e3a072d118917957d6554Steve Block 1112bde8e466a4451c7319e3a072d118917957d6554Steve Block return static_cast<CFDictionaryRef>(CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginMIMETypes"))); 1122bde8e466a4451c7319e3a072d118917957d6554Steve Block} 11365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 11465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic bool getPluginInfoFromPropertyLists(CFBundleRef bundle, PluginInfo& pluginInfo) 11565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 1162bde8e466a4451c7319e3a072d118917957d6554Steve Block RetainPtr<CFDictionaryRef> mimeTypes = getMIMETypesFromPluginBundle(bundle); 1172bde8e466a4451c7319e3a072d118917957d6554Steve Block if (!mimeTypes || CFGetTypeID(mimeTypes.get()) != CFDictionaryGetTypeID()) 11865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return false; 11965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 12065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Get the plug-in name. 12165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch CFStringRef pluginName = static_cast<CFStringRef>(CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginName"))); 12265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (pluginName && CFGetTypeID(pluginName) == CFStringGetTypeID()) 12365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch pluginInfo.name = pluginName; 12465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 12565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Get the plug-in description. 12665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch CFStringRef pluginDescription = static_cast<CFStringRef>(CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginDescription"))); 12765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (pluginDescription && CFGetTypeID(pluginDescription) == CFStringGetTypeID()) 12865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch pluginInfo.desc = pluginDescription; 12965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 13065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Get the MIME type mapping dictionary. 1312bde8e466a4451c7319e3a072d118917957d6554Steve Block CFIndex numMimeTypes = CFDictionaryGetCount(mimeTypes.get()); 13265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Vector<CFStringRef> mimeTypesVector(numMimeTypes); 13365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Vector<CFDictionaryRef> mimeTypeInfoVector(numMimeTypes); 1342bde8e466a4451c7319e3a072d118917957d6554Steve Block CFDictionaryGetKeysAndValues(mimeTypes.get(), reinterpret_cast<const void**>(mimeTypesVector.data()), reinterpret_cast<const void**>(mimeTypeInfoVector.data())); 13565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 13665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch for (CFIndex i = 0; i < numMimeTypes; ++i) { 13765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch MimeClassInfo mimeClassInfo; 13865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 13965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // If this MIME type is invalid, ignore it. 14065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch CFStringRef mimeType = mimeTypesVector[i]; 14165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!mimeType || CFGetTypeID(mimeType) != CFStringGetTypeID() || CFStringGetLength(mimeType) == 0) 14265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch continue; 14365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 14465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // If this MIME type doesn't have a valid info dictionary, ignore it. 14565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch CFDictionaryRef mimeTypeInfo = mimeTypeInfoVector[i]; 14665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!mimeTypeInfo || CFGetTypeID(mimeTypeInfo) != CFDictionaryGetTypeID()) 14765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch continue; 14865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 14965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Get the MIME type description. 15065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch CFStringRef mimeTypeDescription = static_cast<CFStringRef>(CFDictionaryGetValue(mimeTypeInfo, CFSTR("WebPluginTypeDescription"))); 15165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (mimeTypeDescription && CFGetTypeID(mimeTypeDescription) != CFStringGetTypeID()) 15265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch mimeTypeDescription = 0; 15365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 15465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch mimeClassInfo.type = String(mimeType).lower(); 15565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch mimeClassInfo.desc = mimeTypeDescription; 15665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 15765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Now get the extensions for this MIME type. 15865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch CFIndex numExtensions = 0; 15965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch CFArrayRef extensionsArray = static_cast<CFArrayRef>(CFDictionaryGetValue(mimeTypeInfo, CFSTR("WebPluginExtensions"))); 16065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (extensionsArray && CFGetTypeID(extensionsArray) == CFArrayGetTypeID()) 16165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch numExtensions = CFArrayGetCount(extensionsArray); 16265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 16365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch for (CFIndex i = 0; i < numExtensions; ++i) { 16465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch CFStringRef extension = static_cast<CFStringRef>(CFArrayGetValueAtIndex(extensionsArray, i)); 16565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!extension || CFGetTypeID(extension) != CFStringGetTypeID()) 16665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch continue; 1672bde8e466a4451c7319e3a072d118917957d6554Steve Block 1682bde8e466a4451c7319e3a072d118917957d6554Steve Block // The DivX plug-in lists multiple extensions in a comma separated string instead of using 1692bde8e466a4451c7319e3a072d118917957d6554Steve Block // multiple array elements in the property list. Work around this here by splitting the 1702bde8e466a4451c7319e3a072d118917957d6554Steve Block // extension string into components. 1712bde8e466a4451c7319e3a072d118917957d6554Steve Block Vector<String> extensionComponents; 1722bde8e466a4451c7319e3a072d118917957d6554Steve Block String(extension).lower().split(',', extensionComponents); 1732bde8e466a4451c7319e3a072d118917957d6554Steve Block 1742bde8e466a4451c7319e3a072d118917957d6554Steve Block for (size_t i = 0; i < extensionComponents.size(); ++i) 1752bde8e466a4451c7319e3a072d118917957d6554Steve Block mimeClassInfo.extensions.append(extensionComponents[i]); 17665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 17765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 17865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Add this MIME type. 17965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch pluginInfo.mimes.append(mimeClassInfo); 18065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 18165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 18265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return true; 18365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 18465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 18565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochclass ResourceMap { 18665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochpublic: 18765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch explicit ResourceMap(CFBundleRef bundle) 18865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch : m_bundle(bundle) 18965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch , m_currentResourceFile(CurResFile()) 19065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch , m_bundleResourceMap(CFBundleOpenBundleResourceMap(m_bundle)) 19165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch { 19265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch UseResFile(m_bundleResourceMap); 19365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 19465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 19565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ~ResourceMap() 19665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch { 19765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Close the resource map. 19865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch CFBundleCloseBundleResourceMap(m_bundle, m_bundleResourceMap); 19965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 20065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // And restore the old resource. 20165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch UseResFile(m_currentResourceFile); 20265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 20365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 20465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch bool isValid() const { return m_bundleResourceMap != -1; } 20565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 20665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochprivate: 20765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch CFBundleRef m_bundle; 20865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ResFileRefNum m_currentResourceFile; 20965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ResFileRefNum m_bundleResourceMap; 21065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}; 21165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 21265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic bool getStringListResource(ResID resourceID, Vector<String>& stringList) { 21365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Handle stringListHandle = Get1Resource('STR#', resourceID); 21465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!stringListHandle || !*stringListHandle) 21565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return false; 21665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 21765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Get the string list size. 21865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Size stringListSize = GetHandleSize(stringListHandle); 21965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (stringListSize < static_cast<Size>(sizeof(UInt16))) 22065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return false; 22165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 22265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch CFStringEncoding stringEncoding = stringEncodingForResource(stringListHandle); 22365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 22465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch unsigned char* ptr = reinterpret_cast<unsigned char*>(*stringListHandle); 22565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch unsigned char* end = ptr + stringListSize; 22665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 22765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Get the number of strings in the string list. 22865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch UInt16 numStrings = *reinterpret_cast<UInt16*>(ptr); 22965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ptr += sizeof(UInt16); 23065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 23165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch for (UInt16 i = 0; i < numStrings; ++i) { 23265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // We're past the end of the string, bail. 23365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (ptr >= end) 23465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return false; 23565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 23665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Get the string length. 23765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch unsigned char stringLength = *ptr++; 23865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 23965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch RetainPtr<CFStringRef> cfString(AdoptCF, CFStringCreateWithBytesNoCopy(kCFAllocatorDefault, ptr, stringLength, stringEncoding, false, kCFAllocatorNull)); 24065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!cfString.get()) 24165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return false; 24265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 24365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch stringList.append(cfString.get()); 24465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ptr += stringLength; 24565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 24665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 24765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (ptr != end) 24865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return false; 24965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 25065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return true; 25165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 25265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 25365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic const ResID PluginNameOrDescriptionStringNumber = 126; 25465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic const ResID MIMEDescriptionStringNumber = 127; 25565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic const ResID MIMEListStringStringNumber = 128; 25665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 25765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic bool getPluginInfoFromCarbonResources(CFBundleRef bundle, PluginInfo& pluginInfo) 25865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 25965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch ResourceMap resourceMap(bundle); 26065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!resourceMap.isValid()) 26165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return false; 26265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 26365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Get the description and name string list. 26465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Vector<String> descriptionAndName; 26565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!getStringListResource(PluginNameOrDescriptionStringNumber, descriptionAndName)) 26665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return false; 26765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 26865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Get the MIME types and extensions string list. This list needs to be a multiple of two. 26965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Vector<String> mimeTypesAndExtensions; 27065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!getStringListResource(MIMEListStringStringNumber, mimeTypesAndExtensions)) 27165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return false; 27265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 27365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (mimeTypesAndExtensions.size() % 2) 27465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return false; 27565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 27665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Now get the MIME type descriptions string list. This string list needs to be the same length as the number of MIME types. 27765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Vector<String> mimeTypeDescriptions; 27865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!getStringListResource(MIMEDescriptionStringNumber, mimeTypeDescriptions)) 27965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return false; 28065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 28165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Add all MIME types. 28265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch for (size_t i = 0; i < mimeTypesAndExtensions.size() / 2; ++i) { 28365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch MimeClassInfo mimeClassInfo; 28465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 28565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch const String& mimeType = mimeTypesAndExtensions[i * 2]; 2862daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch String description; 2872daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch if (i < mimeTypeDescriptions.size()) 2882daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch description = mimeTypeDescriptions[i]; 28965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 29065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch mimeClassInfo.type = mimeType.lower(); 29165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch mimeClassInfo.desc = description; 29265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 29365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch Vector<String> extensions; 29465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch mimeTypesAndExtensions[i * 2 + 1].split(',', extensions); 29565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 29665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch for (size_t i = 0; i < extensions.size(); ++i) 29765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch mimeClassInfo.extensions.append(extensions[i].lower()); 29865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 29965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch pluginInfo.mimes.append(mimeClassInfo); 30065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 30165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 30265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Set the description and name if they exist. 30365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (descriptionAndName.size() > 0) 30465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch pluginInfo.desc = descriptionAndName[0]; 30565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (descriptionAndName.size() > 1) 30665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch pluginInfo.name = descriptionAndName[1]; 30765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 30865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return true; 30965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 31065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 31165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochbool NetscapePluginModule::getPluginInfo(const String& pluginPath, PluginInfoStore::Plugin& plugin) 31265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 31365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch RetainPtr<CFStringRef> bundlePath(AdoptCF, pluginPath.createCFString()); 31465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch RetainPtr<CFURLRef> bundleURL(AdoptCF, CFURLCreateWithFileSystemPath(kCFAllocatorDefault, bundlePath.get(), kCFURLPOSIXPathStyle, false)); 31565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 31665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Try to initialize the bundle. 31765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch RetainPtr<CFBundleRef> bundle(AdoptCF, CFBundleCreate(kCFAllocatorDefault, bundleURL.get())); 31865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!bundle) 31965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return false; 32065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 32165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Check if this bundle is an NPAPI plug-in. 32265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch UInt32 packageType = 0; 32365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch CFBundleGetPackageInfo(bundle.get(), &packageType, 0); 32465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (packageType != FOUR_CHAR_CODE('BRPL')) 32565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return false; 32665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 32765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Check that the architecture is valid. 32865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch cpu_type_t pluginArchitecture = 0; 32965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!getPluginArchitecture(bundle.get(), pluginArchitecture)) 33065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return false; 33165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 33265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Check that there's valid info for this plug-in. 33365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!getPluginInfoFromPropertyLists(bundle.get(), plugin.info) && 33465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch !getPluginInfoFromCarbonResources(bundle.get(), plugin.info)) 33565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return false; 33665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 33765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch plugin.path = pluginPath; 33865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch plugin.pluginArchitecture = pluginArchitecture; 33965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch plugin.bundleIdentifier = CFBundleGetIdentifier(bundle.get()); 34065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch plugin.versionNumber = CFBundleGetVersionNumber(bundle.get()); 34165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 34265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch RetainPtr<CFStringRef> filename(AdoptCF, CFURLCopyLastPathComponent(bundleURL.get())); 34365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch plugin.info.file = filename.get(); 34465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 34565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (plugin.info.name.isNull()) 34665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch plugin.info.name = plugin.info.file; 34765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (plugin.info.desc.isNull()) 34865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch plugin.info.desc = plugin.info.file; 34965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 35065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return true; 35165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 35265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 35365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid NetscapePluginModule::determineQuirks() 35465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{ 35565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch PluginInfoStore::Plugin plugin; 35665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (!getPluginInfo(m_pluginPath, plugin)) 35765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch return; 35865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 35965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch if (plugin.bundleIdentifier == "com.macromedia.Flash Player.plugin") { 36065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch // Flash requires that the return value of getprogname() be "WebKitPluginHost". 36165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch m_pluginQuirks.add(PluginQuirks::PrognameShouldBeWebKitPluginHost); 3622bde8e466a4451c7319e3a072d118917957d6554Steve Block 3632bde8e466a4451c7319e3a072d118917957d6554Steve Block // Flash supports snapshotting. 36481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch m_pluginQuirks.add(PluginQuirks::SupportsSnapshotting); 36565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch } 3662bde8e466a4451c7319e3a072d118917957d6554Steve Block 3672bde8e466a4451c7319e3a072d118917957d6554Steve Block if (plugin.bundleIdentifier == "com.microsoft.SilverlightPlugin") { 3682bde8e466a4451c7319e3a072d118917957d6554Steve Block // Silverlight doesn't explicitly opt into transparency, so we'll do it whenever 3692bde8e466a4451c7319e3a072d118917957d6554Steve Block // there's a 'background' attribute. 3702bde8e466a4451c7319e3a072d118917957d6554Steve Block m_pluginQuirks.add(PluginQuirks::MakeTransparentIfBackgroundAttributeExists); 3712bde8e466a4451c7319e3a072d118917957d6554Steve Block } 3722bde8e466a4451c7319e3a072d118917957d6554Steve Block 3732bde8e466a4451c7319e3a072d118917957d6554Steve Block#ifndef NP_NO_QUICKDRAW 3742bde8e466a4451c7319e3a072d118917957d6554Steve Block if (plugin.bundleIdentifier == "com.apple.ist.ds.appleconnect.webplugin") { 3752bde8e466a4451c7319e3a072d118917957d6554Steve Block // The AppleConnect plug-in uses QuickDraw but doesn't paint or receive events 3762bde8e466a4451c7319e3a072d118917957d6554Steve Block // so we'll allow it to be instantiated even though we don't support QuickDraw. 3772bde8e466a4451c7319e3a072d118917957d6554Steve Block m_pluginQuirks.add(PluginQuirks::AllowHalfBakedQuickDrawSupport); 3782bde8e466a4451c7319e3a072d118917957d6554Steve Block } 3792bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif 38065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} 38165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch 38265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} // namespace WebKit 383