nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info) { info.fVersion = nsnull; // Passing NULL for a file path will prevent a call to NP_Initialize. nsCOMPtr<nsIPlugin> plugin; nsresult rv = nsNPAPIPlugin::CreatePlugin(NULL, pLibrary, getter_AddRefs(plugin)); if (NS_FAILED(rv)) return rv; if (plugin) { const char* (*npGetPluginVersion)() = (const char* (*)()) PR_FindFunctionSymbol(pLibrary, "NP_GetPluginVersion"); if (npGetPluginVersion) info.fVersion = PL_strdup(npGetPluginVersion()); const char *mimedescr = NULL; plugin->GetMIMEDescription(&mimedescr); #ifdef NS_DEBUG printf("GetMIMEDescription() returned \"%s\"\n", mimedescr); #endif if (NS_FAILED(rv = ParsePluginMimeDescription(mimedescr, info))) return rv; nsCAutoString path; if (NS_FAILED(rv = mPlugin->GetNativePath(path))) return rv; info.fFullPath = PL_strdup(path.get()); nsCAutoString fileName; if (NS_FAILED(rv = mPlugin->GetNativeLeafName(fileName))) return rv; info.fFileName = PL_strdup(fileName.get()); const char *name = NULL; plugin->GetValue(nsPluginVariable_NameString, &name); if (name) info.fName = PL_strdup(name); else info.fName = PL_strdup(fileName.get()); const char *description = NULL; plugin->GetValue(nsPluginVariable_DescriptionString, &description); if (!description) description = ""; info.fDescription = PL_strdup(description); } return NS_OK; }
/** * Obtains all of the information currently available for this plugin. */ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary) { *outLibrary = nullptr; nsresult rv = NS_OK; if (!IsCompatibleArch(mPlugin)) { return NS_ERROR_FAILURE; } // clear out the info, except for the first field. memset(&info, 0, sizeof(info)); // Try to get a bundle reference. nsAutoCString path; if (NS_FAILED(rv = mPlugin->GetNativePath(path))) return rv; CFBundleRef bundle = getPluginBundle(path.get()); // fill in full path info.fFullPath = PL_strdup(path.get()); // fill in file name nsAutoCString fileName; if (NS_FAILED(rv = mPlugin->GetNativeLeafName(fileName))) return rv; info.fFileName = PL_strdup(fileName.get()); // Get fName if (bundle) { CFTypeRef name = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginName")); if (name && ::CFGetTypeID(name) == ::CFStringGetTypeID()) info.fName = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(name)); } // Get fDescription if (bundle) { CFTypeRef description = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginDescription")); if (description && ::CFGetTypeID(description) == ::CFStringGetTypeID()) info.fDescription = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(description)); } // Get fVersion if (bundle) { // Look for the release version first CFTypeRef version = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("CFBundleShortVersionString")); if (!version) // try the build version version = ::CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleVersionKey); if (version && ::CFGetTypeID(version) == ::CFStringGetTypeID()) info.fVersion = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(version)); } // The last thing we need to do is get MIME data // fVariantCount, fMimeTypeArray, fExtensionArray, fMimeDescriptionArray // First look for data in a bundle plist if (bundle) { ParsePlistPluginInfo(info, bundle); ::CFRelease(bundle); if (info.fVariantCount > 0) return NS_OK; } // It's possible that our plugin has 2 entry points that'll give us mime type // info. Quicktime does this to get around the need of having admin rights to // change mime info in the resource fork. We need to use this info instead of // the resource. See bug 113464. // Sadly we have to load the library for this to work. rv = LoadPlugin(outLibrary); if (NS_FAILED(rv)) return rv; // Try to get data from NP_GetMIMEDescription if (pLibrary) { NP_GETMIMEDESCRIPTION pfnGetMimeDesc = (NP_GETMIMEDESCRIPTION)PR_FindFunctionSymbol(pLibrary, NP_GETMIMEDESCRIPTION_NAME); if (pfnGetMimeDesc) ParsePluginMimeDescription(pfnGetMimeDesc(), info); if (info.fVariantCount) return NS_OK; } // We'll fill this in using BP_GetSupportedMIMETypes and/or resource fork data BPSupportedMIMETypes mi = {kBPSupportedMIMETypesStructVers_1, NULL, NULL}; // Try to get data from BP_GetSupportedMIMETypes if (pLibrary) { BP_GETSUPPORTEDMIMETYPES pfnMime = (BP_GETSUPPORTEDMIMETYPES)PR_FindFunctionSymbol(pLibrary, "BP_GetSupportedMIMETypes"); if (pfnMime && noErr == pfnMime(&mi, 0) && mi.typeStrings) { info.fVariantCount = (**(short**)mi.typeStrings) / 2; ::HLock(mi.typeStrings); if (mi.infoStrings) // it's possible some plugins have infoStrings missing ::HLock(mi.infoStrings); } } // Fill in the info struct based on the data in the BPSupportedMIMETypes struct int variantCount = info.fVariantCount; info.fMimeTypeArray = static_cast<char**>(NS_Alloc(variantCount * sizeof(char*))); if (!info.fMimeTypeArray) return NS_ERROR_OUT_OF_MEMORY; info.fExtensionArray = static_cast<char**>(NS_Alloc(variantCount * sizeof(char*))); if (!info.fExtensionArray) return NS_ERROR_OUT_OF_MEMORY; if (mi.infoStrings) { info.fMimeDescriptionArray = static_cast<char**>(NS_Alloc(variantCount * sizeof(char*))); if (!info.fMimeDescriptionArray) return NS_ERROR_OUT_OF_MEMORY; } short mimeIndex = 2; short descriptionIndex = 2; for (int i = 0; i < variantCount; i++) { info.fMimeTypeArray[i] = GetNextPluginStringFromHandle(mi.typeStrings, &mimeIndex); info.fExtensionArray[i] = GetNextPluginStringFromHandle(mi.typeStrings, &mimeIndex); if (mi.infoStrings) info.fMimeDescriptionArray[i] = GetNextPluginStringFromHandle(mi.infoStrings, &descriptionIndex); } ::HUnlock(mi.typeStrings); ::DisposeHandle(mi.typeStrings); if (mi.infoStrings) { ::HUnlock(mi.infoStrings); ::DisposeHandle(mi.infoStrings); } return NS_OK; }
/** * Obtains all of the information currently available for this plugin. */ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary) { *outLibrary = nullptr; nsresult rv = NS_OK; if (!IsCompatibleArch(mPlugin)) { return NS_ERROR_FAILURE; } // clear out the info, except for the first field. memset(&info, 0, sizeof(info)); // Try to get a bundle reference. nsAutoCString path; if (NS_FAILED(rv = mPlugin->GetNativePath(path))) return rv; CFBundleRef bundle = getPluginBundle(path.get()); // fill in full path info.fFullPath = PL_strdup(path.get()); // fill in file name nsAutoCString fileName; if (NS_FAILED(rv = mPlugin->GetNativeLeafName(fileName))) return rv; info.fFileName = PL_strdup(fileName.get()); // Get fName if (bundle) { CFTypeRef name = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginName")); if (name && ::CFGetTypeID(name) == ::CFStringGetTypeID()) info.fName = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(name)); } // Get fDescription if (bundle) { CFTypeRef description = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginDescription")); if (description && ::CFGetTypeID(description) == ::CFStringGetTypeID()) info.fDescription = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(description)); } // Get fVersion if (bundle) { // Look for the release version first CFTypeRef version = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("CFBundleShortVersionString")); if (!version) // try the build version version = ::CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleVersionKey); if (version && ::CFGetTypeID(version) == ::CFStringGetTypeID()) info.fVersion = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(version)); } // The last thing we need to do is get MIME data // fVariantCount, fMimeTypeArray, fExtensionArray, fMimeDescriptionArray // First look for data in a bundle plist if (bundle) { ParsePlistPluginInfo(info, bundle); ::CFRelease(bundle); if (info.fVariantCount > 0) return NS_OK; } // Don't load "fbplugin" or any plugins whose name starts with "fbplugin_" // (Facebook plugins) if we're running on OS X 10.10 (Yosemite) or later. // A "fbplugin" file crashes on load, in the call to LoadPlugin() below. // See bug 1086977. if (nsCocoaFeatures::OnYosemiteOrLater()) { if (fileName.EqualsLiteral("fbplugin") || StringBeginsWith(fileName, NS_LITERAL_CSTRING("fbplugin_"))) { nsAutoCString msg; msg.AppendPrintf("Preventing load of %s (see bug 1086977)", fileName.get()); NS_WARNING(msg.get()); return NS_ERROR_FAILURE; } #if defined(MOZ_CRASHREPORTER) // The block above assumes that "fbplugin" is the filename of the plugin // to be blocked, or that the filename starts with "fbplugin_". But we // don't yet know for sure if this is always true. So for the time being // record extra information in our crash logs. CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Bug_1086977"), fileName); #endif } // It's possible that our plugin has 2 entry points that'll give us mime type // info. Quicktime does this to get around the need of having admin rights to // change mime info in the resource fork. We need to use this info instead of // the resource. See bug 113464. // Sadly we have to load the library for this to work. rv = LoadPlugin(outLibrary); #if defined(MOZ_CRASHREPORTER) if (nsCocoaFeatures::OnYosemiteOrLater()) { // If we didn't crash in LoadPlugin(), change the previous annotation so we // don't sow confusion. CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Bug_1086977"), NS_LITERAL_CSTRING("Didn't crash, please ignore")); } #endif if (NS_FAILED(rv)) return rv; // Try to get data from NP_GetMIMEDescription if (pLibrary) { NP_GETMIMEDESCRIPTION pfnGetMimeDesc = (NP_GETMIMEDESCRIPTION)PR_FindFunctionSymbol(pLibrary, NP_GETMIMEDESCRIPTION_NAME); if (pfnGetMimeDesc) ParsePluginMimeDescription(pfnGetMimeDesc(), info); if (info.fVariantCount) return NS_OK; } // We'll fill this in using BP_GetSupportedMIMETypes and/or resource fork data BPSupportedMIMETypes mi = {kBPSupportedMIMETypesStructVers_1, nullptr, nullptr}; // Try to get data from BP_GetSupportedMIMETypes if (pLibrary) { BP_GETSUPPORTEDMIMETYPES pfnMime = (BP_GETSUPPORTEDMIMETYPES)PR_FindFunctionSymbol(pLibrary, "BP_GetSupportedMIMETypes"); if (pfnMime && noErr == pfnMime(&mi, 0) && mi.typeStrings) { info.fVariantCount = (**(short**)mi.typeStrings) / 2; ::HLock(mi.typeStrings); if (mi.infoStrings) // it's possible some plugins have infoStrings missing ::HLock(mi.infoStrings); } } // Fill in the info struct based on the data in the BPSupportedMIMETypes struct int variantCount = info.fVariantCount; info.fMimeTypeArray = static_cast<char**>(moz_xmalloc(variantCount * sizeof(char*))); if (!info.fMimeTypeArray) return NS_ERROR_OUT_OF_MEMORY; info.fExtensionArray = static_cast<char**>(moz_xmalloc(variantCount * sizeof(char*))); if (!info.fExtensionArray) return NS_ERROR_OUT_OF_MEMORY; if (mi.infoStrings) { info.fMimeDescriptionArray = static_cast<char**>(moz_xmalloc(variantCount * sizeof(char*))); if (!info.fMimeDescriptionArray) return NS_ERROR_OUT_OF_MEMORY; } short mimeIndex = 2; short descriptionIndex = 2; for (int i = 0; i < variantCount; i++) { info.fMimeTypeArray[i] = GetNextPluginStringFromHandle(mi.typeStrings, &mimeIndex); info.fExtensionArray[i] = GetNextPluginStringFromHandle(mi.typeStrings, &mimeIndex); if (mi.infoStrings) info.fMimeDescriptionArray[i] = GetNextPluginStringFromHandle(mi.infoStrings, &descriptionIndex); } ::HUnlock(mi.typeStrings); ::DisposeHandle(mi.typeStrings); if (mi.infoStrings) { ::HUnlock(mi.infoStrings); ::DisposeHandle(mi.infoStrings); } return NS_OK; }
nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary) { *outLibrary = nullptr; info.fVersion = nullptr; // Sadly we have to load the library for this to work. nsresult rv = LoadPlugin(outLibrary); if (NS_FAILED(rv)) return rv; const char* (*npGetPluginVersion)() = (const char* (*)()) PR_FindFunctionSymbol(pLibrary, "NP_GetPluginVersion"); if (npGetPluginVersion) { info.fVersion = PL_strdup(npGetPluginVersion()); } const char* (*npGetMIMEDescription)() = (const char* (*)()) PR_FindFunctionSymbol(pLibrary, "NP_GetMIMEDescription"); if (!npGetMIMEDescription) { return NS_ERROR_FAILURE; } const char* mimedescr = npGetMIMEDescription(); if (!mimedescr) { return NS_ERROR_FAILURE; } rv = ParsePluginMimeDescription(mimedescr, info); if (NS_FAILED(rv)) { return rv; } nsAutoCString path; if (NS_FAILED(rv = mPlugin->GetNativePath(path))) return rv; info.fFullPath = PL_strdup(path.get()); nsAutoCString fileName; if (NS_FAILED(rv = mPlugin->GetNativeLeafName(fileName))) return rv; info.fFileName = PL_strdup(fileName.get()); NP_GetValueFunc npGetValue = (NP_GetValueFunc)PR_FindFunctionSymbol(pLibrary, "NP_GetValue"); if (!npGetValue) { return NS_ERROR_FAILURE; } const char *name = NULL; npGetValue(NULL, NPPVpluginNameString, &name); if (name) { info.fName = PL_strdup(name); } else { info.fName = PL_strdup(fileName.get()); } const char *description = NULL; npGetValue(NULL, NPPVpluginDescriptionString, &description); if (description) { info.fDescription = PL_strdup(description); } else { info.fDescription = PL_strdup(""); } return NS_OK; }
/** * Obtains all of the information currently available for this plugin. */ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info) { // clear out the info, except for the first field. memset(&info.fName, 0, sizeof(info) - sizeof(PRUint32)); // need to open the plugin's resource file and read some resources. short refNum = OpenPluginResource(); if (refNum >= 0) { if (info.fPluginInfoSize >= sizeof(nsPluginInfo)) { // 'STR#', 126, 2 => plugin name. info.fName = GetPluginString(126, 2); // 'STR#', 126, 1 => plugin description. info.fDescription = GetPluginString(126, 1); nsCString path; mPlugin->GetNativePath(path); FSSpec spec; toFSSpec(mPlugin, spec); info.fFileName = p2cstrdup(spec.name); info.fFullPath = PL_strdup(path.get()); CFBundleRef bundle = getPluginBundle(path.get()); if (bundle) { info.fBundle = PR_TRUE; CFRelease(bundle); } else info.fBundle = PR_FALSE; // It's possible that our plugin has 2 special extra entry points that'll give us more // mime type info. Quicktime does this to get around the need of having admin rights // to change mime info in the resource fork. We need to use this info instead of the // resource. See bug 113464. BPSupportedMIMETypes mi = {kBPSupportedMIMETypesStructVers_1, NULL, NULL}; if (pLibrary) { // First, check for NP_GetMIMEDescription NP_GETMIMEDESCRIPTION pfnGetMimeDesc = (NP_GETMIMEDESCRIPTION)PR_FindSymbol(pLibrary, NP_GETMIMEDESCRIPTION_NAME); if (pfnGetMimeDesc) { nsresult rv = ParsePluginMimeDescription(pfnGetMimeDesc(), info); if (NS_SUCCEEDED(rv)) { // if we could parse the mime types from NP_GetMIMEDescription, ::CloseResFile(refNum); // we've got what we need, close the resource, we're done return rv; } } // Next check for mime info from BP_GetSupportedMIMETypes BP_GETSUPPORTEDMIMETYPES pfnMime = (BP_GETSUPPORTEDMIMETYPES)PR_FindSymbol(pLibrary, "BP_GetSupportedMIMETypes"); if (pfnMime && noErr == pfnMime(&mi, 0) && mi.typeStrings) { info.fVariantCount = (**(short**)mi.typeStrings) / 2; ::HLock(mi.typeStrings); if (mi.infoStrings) // it's possible some plugins have infoStrings missing ::HLock(mi.infoStrings); } } // Last, we couldn't get info from an extra entry point for some reason, // Lets get info from normal resources if (!info.fVariantCount) { mi.typeStrings = ::Get1Resource('STR#', 128); if (mi.typeStrings) { info.fVariantCount = (**(short**)mi.typeStrings) / 2; ::DetachResource(mi.typeStrings); ::HLock(mi.typeStrings); } else { // Don't add this plugin because no mime types could be found ::CloseResFile(refNum); return NS_ERROR_FAILURE; } mi.infoStrings = ::Get1Resource('STR#', 127); if (mi.infoStrings) { ::DetachResource(mi.infoStrings); ::HLock(mi.infoStrings); } } // fill-in rest of info struct int variantCount = info.fVariantCount; info.fMimeTypeArray = new char*[variantCount]; info.fExtensionArray = new char*[variantCount]; if (mi.infoStrings) info.fMimeDescriptionArray = new char*[variantCount]; short mimeIndex = 2, descriptionIndex = 2; for (int i = 0; i < variantCount; i++) { info.fMimeTypeArray[i] = GetNextPluginStringFromHandle(mi.typeStrings, &mimeIndex); info.fExtensionArray[i] = GetNextPluginStringFromHandle(mi.typeStrings, &mimeIndex); if (mi.infoStrings) info.fMimeDescriptionArray[i] = GetNextPluginStringFromHandle(mi.infoStrings, &descriptionIndex); } ::HUnlock(mi.typeStrings); ::DisposeHandle(mi.typeStrings); if (mi.infoStrings) { ::HUnlock(mi.infoStrings); ::DisposeHandle(mi.infoStrings); } } ::CloseResFile(refNum); } return NS_OK; }