Bug 653794: Improve management of plugin MIME types, MIME descriptions, and extensions. r=bsmedberg

This commit is contained in:
Josh Aas 2011-05-10 09:47:43 -04:00
Родитель 00f03f2123
Коммит 0d7eb5afa2
3 изменённых файлов: 92 добавлений и 187 удалений

Просмотреть файл

@ -1454,11 +1454,9 @@ public:
{
if (!aTag)
return;
CopyUTF8toUTF16(aTag->mMimeDescriptionArray[aMimeTypeIndex], mDescription);
if (aTag->mExtensionsArray)
CopyUTF8toUTF16(aTag->mExtensionsArray[aMimeTypeIndex], mSuffixes);
if (aTag->mMimeTypeArray)
CopyUTF8toUTF16(aTag->mMimeTypeArray[aMimeTypeIndex], mType);
CopyUTF8toUTF16(aTag->mMimeDescriptions[aMimeTypeIndex], mDescription);
CopyUTF8toUTF16(aTag->mExtensions[aMimeTypeIndex], mSuffixes);
CopyUTF8toUTF16(aTag->mMimeTypes[aMimeTypeIndex], mType);
}
virtual ~DOMMimeTypeImpl() {
@ -1543,7 +1541,7 @@ public:
NS_METHOD GetLength(PRUint32* aLength)
{
*aLength = mPluginTag.mVariants;
*aLength = mPluginTag.mMimeTypes.Length();
return NS_OK;
}
@ -1557,8 +1555,8 @@ public:
NS_METHOD NamedItem(const nsAString& aName, nsIDOMMimeType** aReturn)
{
for (int i = mPluginTag.mVariants - 1; i >= 0; --i) {
if (aName.Equals(NS_ConvertUTF8toUTF16(mPluginTag.mMimeTypeArray[i])))
for (int i = mPluginTag.mMimeTypes.Length() - 1; i >= 0; --i) {
if (aName.Equals(NS_ConvertUTF8toUTF16(mPluginTag.mMimeTypes[i])))
return Item(i, aReturn);
}
return NS_OK;
@ -1650,10 +1648,9 @@ nsPluginHost::FindPluginForType(const char* aMimeType,
nsPluginTag *plugin = mPlugins;
while (plugin) {
if (!aCheckEnabled || plugin->IsEnabled()) {
PRInt32 mimeCount = plugin->mVariants;
PRInt32 mimeCount = plugin->mMimeTypes.Length();
for (PRInt32 i = 0; i < mimeCount; i++) {
if (plugin->mMimeTypeArray[i] &&
(0 == PL_strcasecmp(plugin->mMimeTypeArray[i], aMimeType))) {
if (0 == PL_strcasecmp(plugin->mMimeTypes[i].get(), aMimeType)) {
return plugin;
}
}
@ -1668,31 +1665,25 @@ nsPluginTag*
nsPluginHost::FindPluginEnabledForExtension(const char* aExtension,
const char*& aMimeType)
{
nsPluginTag *plugins = nsnull;
PRInt32 variants, cnt;
if (!aExtension) {
return nsnull;
}
LoadPlugins();
// if we have a mimetype passed in, search the mPlugins linked
// list for a match
if (aExtension) {
plugins = mPlugins;
while (plugins) {
variants = plugins->mVariants;
if (plugins->mExtensionsArray) {
for (cnt = 0; cnt < variants; cnt++) {
// mExtensionsArray[cnt] is a list of extensions separated
// by commas
if (plugins->IsEnabled() &&
0 == CompareExtensions(plugins->mExtensionsArray[cnt], aExtension)) {
aMimeType = plugins->mMimeTypeArray[cnt];
return plugins;
}
nsPluginTag *plugin = mPlugins;
while (plugin) {
if (plugin->IsEnabled()) {
PRInt32 variants = plugin->mExtensions.Length();
for (PRInt32 i = 0; i < variants; i++) {
// mExtensionsArray[cnt] is a list of extensions separated by commas
if (0 == CompareExtensions(plugin->mExtensions[i].get(), aExtension)) {
aMimeType = plugin->mMimeTypes[i].get();
return plugin;
}
}
plugins = plugins->mNext;
}
plugin = plugin->mNext;
}
return nsnull;
@ -2679,13 +2670,13 @@ nsPluginHost::WritePluginInfo()
// filename & fullpath are on separate line
// because they can contain field delimiter char
PR_fprintf(fd, "%s%c%c\n%s%c%c\n%s%c%c\n",
(!tag->mFileName.IsEmpty() ? tag->mFileName.get() : ""),
(tag->mFileName.get()),
PLUGIN_REGISTRY_FIELD_DELIMITER,
PLUGIN_REGISTRY_END_OF_LINE_MARKER,
(!tag->mFullPath.IsEmpty() ? tag->mFullPath.get() : ""),
(tag->mFullPath.get()),
PLUGIN_REGISTRY_FIELD_DELIMITER,
PLUGIN_REGISTRY_END_OF_LINE_MARKER,
(!tag->mVersion.IsEmpty() ? tag->mVersion.get() : ""),
(tag->mVersion.get()),
PLUGIN_REGISTRY_FIELD_DELIMITER,
PLUGIN_REGISTRY_END_OF_LINE_MARKER);
@ -2701,30 +2692,30 @@ nsPluginHost::WritePluginInfo()
//description, name & mtypecount are on separate line
PR_fprintf(fd, "%s%c%c\n%s%c%c\n%d\n",
(!tag->mDescription.IsEmpty() ? tag->mDescription.get() : ""),
(tag->mDescription.get()),
PLUGIN_REGISTRY_FIELD_DELIMITER,
PLUGIN_REGISTRY_END_OF_LINE_MARKER,
(!tag->mName.IsEmpty() ? tag->mName.get() : ""),
(tag->mName.get()),
PLUGIN_REGISTRY_FIELD_DELIMITER,
PLUGIN_REGISTRY_END_OF_LINE_MARKER,
tag->mVariants + (tag->mIsNPRuntimeEnabledJavaPlugin ? 1 : 0));
tag->mMimeTypes.Length() + (tag->mIsNPRuntimeEnabledJavaPlugin ? 1 : 0));
// Add in each mimetype this plugin supports
for (int i=0; i<tag->mVariants; i++) {
for (PRUint32 i = 0; i < tag->mMimeTypes.Length(); i++) {
PR_fprintf(fd, "%d%c%s%c%s%c%s%c%c\n",
i,PLUGIN_REGISTRY_FIELD_DELIMITER,
(tag->mMimeTypeArray && tag->mMimeTypeArray[i] ? tag->mMimeTypeArray[i] : ""),
(tag->mMimeTypes[i].get()),
PLUGIN_REGISTRY_FIELD_DELIMITER,
(!tag->mMimeDescriptionArray[i].IsEmpty() ? tag->mMimeDescriptionArray[i].get() : ""),
(tag->mMimeDescriptions[i].get()),
PLUGIN_REGISTRY_FIELD_DELIMITER,
(tag->mExtensionsArray && tag->mExtensionsArray[i] ? tag->mExtensionsArray[i] : ""),
(tag->mExtensions[i].get()),
PLUGIN_REGISTRY_FIELD_DELIMITER,
PLUGIN_REGISTRY_END_OF_LINE_MARKER);
}
if (tag->mIsNPRuntimeEnabledJavaPlugin) {
PR_fprintf(fd, "%d%c%s%c%s%c%s%c%c\n",
tag->mVariants, PLUGIN_REGISTRY_FIELD_DELIMITER,
tag->mMimeTypes.Length(), PLUGIN_REGISTRY_FIELD_DELIMITER,
"application/x-java-vm-npruntime",
PLUGIN_REGISTRY_FIELD_DELIMITER,
"",

Просмотреть файл

@ -76,10 +76,9 @@ nsPluginTag::nsPluginTag(nsPluginTag* aPluginTag)
: mPluginHost(nsnull),
mName(aPluginTag->mName),
mDescription(aPluginTag->mDescription),
mVariants(aPluginTag->mVariants),
mMimeTypeArray(nsnull),
mMimeDescriptionArray(aPluginTag->mMimeDescriptionArray),
mExtensionsArray(nsnull),
mMimeTypes(aPluginTag->mMimeTypes),
mMimeDescriptions(aPluginTag->mMimeDescriptions),
mExtensions(aPluginTag->mExtensions),
mLibrary(nsnull),
mCanUnloadLibrary(PR_TRUE),
mIsJavaPlugin(aPluginTag->mIsJavaPlugin),
@ -91,26 +90,12 @@ mVersion(aPluginTag->mVersion),
mLastModifiedTime(0),
mFlags(NS_PLUGIN_FLAG_ENABLED)
{
if (aPluginTag->mMimeTypeArray != nsnull) {
mMimeTypeArray = new char*[mVariants];
for (int i = 0; i < mVariants; i++)
mMimeTypeArray[i] = new_str(aPluginTag->mMimeTypeArray[i]);
}
if (aPluginTag->mExtensionsArray != nsnull) {
mExtensionsArray = new char*[mVariants];
for (int i = 0; i < mVariants; i++)
mExtensionsArray[i] = new_str(aPluginTag->mExtensionsArray[i]);
}
}
nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo)
: mPluginHost(nsnull),
mName(aPluginInfo->fName),
mDescription(aPluginInfo->fDescription),
mVariants(aPluginInfo->fVariantCount),
mMimeTypeArray(nsnull),
mExtensionsArray(nsnull),
mLibrary(nsnull),
#ifdef XP_MACOSX
mCanUnloadLibrary(PR_FALSE),
@ -126,39 +111,37 @@ mVersion(aPluginInfo->fVersion),
mLastModifiedTime(0),
mFlags(NS_PLUGIN_FLAG_ENABLED)
{
PRInt32 javaSentinelVariant = -1;
if (aPluginInfo->fMimeTypeArray) {
mMimeTypeArray = new char*[mVariants];
for (int i = 0; i < mVariants; i++) {
char* currentMIMEType = aPluginInfo->fMimeTypeArray[i];
if (!currentMIMEType) {
continue;
}
if (!aPluginInfo->fMimeTypeArray) {
return;
}
for (PRUint32 i = 0; i < aPluginInfo->fVariantCount; i++) {
// First fill in the MIME types.
char* currentMIMEType = aPluginInfo->fMimeTypeArray[i];
if (currentMIMEType) {
if (mIsJavaPlugin) {
if (strcmp(currentMIMEType, "application/x-java-vm-npruntime") == 0) {
// This "magic MIME type" should not be exposed, but is just a signal
// to the browser that this is new-style java.
// Remove it and its associated MIME description from our arrays.
// Don't add it or its associated information to our arrays.
mIsNPRuntimeEnabledJavaPlugin = PR_TRUE;
javaSentinelVariant = i;
continue;
}
}
mMimeTypeArray[i] = new_str(currentMIMEType);
if (nsPluginHost::IsJavaMIMEType(mMimeTypeArray[i])) {
mMimeTypes.AppendElement(nsCString(currentMIMEType));
if (nsPluginHost::IsJavaMIMEType(currentMIMEType)) {
mIsJavaPlugin = PR_TRUE;
}
else if (strcmp(currentMIMEType, "application/x-shockwave-flash") == 0) {
mIsFlashPlugin = PR_TRUE;
}
} else {
continue;
}
}
if (aPluginInfo->fMimeDescriptionArray) {
for (int i = 0; i < mVariants; i++) {
// Now fill in the MIME descriptions.
if (aPluginInfo->fMimeDescriptionArray &&
aPluginInfo->fMimeDescriptionArray[i]) {
// we should cut off the list of suffixes which the mime
// description string may have, see bug 53895
// it is usually in form "some description (*.sf1, *.sf2)"
@ -174,27 +157,25 @@ mFlags(NS_PLUGIN_FLAG_ENABLED)
cur = *p;
*p = '\0';
}
}
mMimeDescriptionArray.AppendElement(
aPluginInfo->fMimeDescriptionArray[i]);
mMimeDescriptions.AppendElement(nsCString(aPluginInfo->fMimeDescriptionArray[i]));
// restore the original string
if (cur != '\0')
*p = cur;
if (pre != '\0')
*(p - 1) = pre;
*(p - 1) = pre;
} else {
mMimeDescriptions.AppendElement(nsCString());
}
// Now fill in the extensions.
if (aPluginInfo->fExtensionArray &&
aPluginInfo->fExtensionArray[i]) {
mExtensions.AppendElement(nsCString(aPluginInfo->fExtensionArray[i]));
} else {
mExtensions.AppendElement(nsCString());
}
} else {
mMimeDescriptionArray.SetLength(mVariants);
}
if (aPluginInfo->fExtensionArray != nsnull) {
mExtensionsArray = new char*[mVariants];
for (int i = 0; i < mVariants; i++)
mExtensionsArray[i] = new_str(aPluginInfo->fExtensionArray[i]);
}
RemoveJavaSentinel(javaSentinelVariant);
EnsureMembersAreUTF8();
}
@ -214,9 +195,6 @@ nsPluginTag::nsPluginTag(const char* aName,
: mPluginHost(nsnull),
mName(aName),
mDescription(aDescription),
mVariants(aVariants),
mMimeTypeArray(nsnull),
mExtensionsArray(nsnull),
mLibrary(nsnull),
mCanUnloadLibrary(aCanUnload),
mIsJavaPlugin(PR_FALSE),
@ -227,29 +205,20 @@ mVersion(aVersion),
mLastModifiedTime(aLastModifiedTime),
mFlags(0) // Caller will read in our flags from cache
{
PRInt32 javaSentinelVariant = -1;
if (aVariants) {
mMimeTypeArray = new char*[mVariants];
mExtensionsArray = new char*[mVariants];
for (PRInt32 i = 0; i < aVariants; ++i) {
if (mIsJavaPlugin && aMimeTypes[i] &&
strcmp(aMimeTypes[i], "application/x-java-vm-npruntime") == 0) {
mIsNPRuntimeEnabledJavaPlugin = PR_TRUE;
javaSentinelVariant = i;
}
mMimeTypeArray[i] = new_str(aMimeTypes[i]);
mMimeDescriptionArray.AppendElement(aMimeDescriptions[i]);
mExtensionsArray[i] = new_str(aExtensions[i]);
if (nsPluginHost::IsJavaMIMEType(mMimeTypeArray[i]))
mIsJavaPlugin = PR_TRUE;
for (PRInt32 i = 0; i < aVariants; i++) {
if (mIsJavaPlugin && aMimeTypes[i] &&
strcmp(aMimeTypes[i], "application/x-java-vm-npruntime") == 0) {
mIsNPRuntimeEnabledJavaPlugin = PR_TRUE;
continue;
}
mMimeTypes.AppendElement(nsCString(aMimeTypes[i]));
mMimeDescriptions.AppendElement(nsCString(aMimeDescriptions[i]));
mExtensions.AppendElement(nsCString(aExtensions[i]));
if (nsPluginHost::IsJavaMIMEType(mMimeTypes[i].get())) {
mIsJavaPlugin = PR_TRUE;
}
}
RemoveJavaSentinel(javaSentinelVariant);
if (!aArgsAreUTF8)
EnsureMembersAreUTF8();
}
@ -257,22 +226,6 @@ mFlags(0) // Caller will read in our flags from cache
nsPluginTag::~nsPluginTag()
{
NS_ASSERTION(!mNext, "Risk of exhausting the stack space, bug 486349");
if (mMimeTypeArray) {
for (int i = 0; i < mVariants; i++)
delete[] mMimeTypeArray[i];
delete[] (mMimeTypeArray);
mMimeTypeArray = nsnull;
}
if (mExtensionsArray) {
for (int i = 0; i < mVariants; i++)
delete[] mExtensionsArray[i];
delete[] (mExtensionsArray);
mExtensionsArray = nsnull;
}
}
NS_IMPL_ISUPPORTS1(nsPluginTag, nsIPluginTag)
@ -334,8 +287,8 @@ nsresult nsPluginTag::EnsureMembersAreUTF8()
ConvertToUTF8(decoder, mName);
ConvertToUTF8(decoder, mDescription);
for (PRUint32 i = 0; i < mMimeDescriptionArray.Length(); ++i) {
ConvertToUTF8(decoder, mMimeDescriptionArray[i]);
for (PRUint32 i = 0; i < mMimeDescriptions.Length(); ++i) {
ConvertToUTF8(decoder, mMimeDescriptions[i]);
}
}
return NS_OK;
@ -430,9 +383,6 @@ void
nsPluginTag::RegisterWithCategoryManager(PRBool aOverrideInternalTypes,
nsPluginTag::nsRegisterType aType)
{
if (!mMimeTypeArray)
return;
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
("nsPluginTag::RegisterWithCategoryManager plugin=%s, removing = %s\n",
mFileName.get(), aType == ePluginUnregister ? "yes" : "no"));
@ -464,16 +414,16 @@ nsPluginTag::RegisterWithCategoryManager(PRBool aOverrideInternalTypes,
}
nsACString::const_iterator start, end;
for (int i = 0; i < mVariants; i++) {
for (PRUint32 i = 0; i < mMimeTypes.Length(); i++) {
if (aType == ePluginUnregister) {
nsXPIDLCString value;
if (NS_SUCCEEDED(catMan->GetCategoryEntry("Gecko-Content-Viewers",
mMimeTypeArray[i],
mMimeTypes[i].get(),
getter_Copies(value)))) {
// Only delete the entry if a plugin registered for it
if (strcmp(value, contractId) == 0) {
catMan->DeleteCategoryEntry("Gecko-Content-Viewers",
mMimeTypeArray[i],
mMimeTypes[i].get(),
PR_TRUE);
}
}
@ -481,14 +431,13 @@ nsPluginTag::RegisterWithCategoryManager(PRBool aOverrideInternalTypes,
overrideTypesFormatted.BeginReading(start);
overrideTypesFormatted.EndReading(end);
nsDependentCString mimeType(mMimeTypeArray[i]);
nsCAutoString commaSeparated;
commaSeparated.Assign(',');
commaSeparated += mimeType;
commaSeparated += mMimeTypes[i];
commaSeparated.Append(',');
if (!FindInReadable(commaSeparated, start, end)) {
catMan->AddCategoryEntry("Gecko-Content-Viewers",
mMimeTypeArray[i],
mMimeTypes[i].get(),
contractId,
PR_FALSE, /* persist: broken by bug 193031 */
aOverrideInternalTypes, /* replace if we're told to */
@ -498,7 +447,7 @@ nsPluginTag::RegisterWithCategoryManager(PRBool aOverrideInternalTypes,
PLUGIN_LOG(PLUGIN_LOG_NOISY,
("nsPluginTag::RegisterWithCategoryManager mime=%s, plugin=%s\n",
mMimeTypeArray[i], mFileName.get()));
mMimeTypes[i].get(), mFileName.get()));
}
}
@ -549,15 +498,16 @@ PRBool nsPluginTag::Equals(nsPluginTag *aPluginTag)
if ((!mName.Equals(aPluginTag->mName)) ||
(!mDescription.Equals(aPluginTag->mDescription)) ||
(mVariants != aPluginTag->mVariants))
(mMimeTypes.Length() != aPluginTag->mMimeTypes.Length())) {
return PR_FALSE;
if (mVariants && mMimeTypeArray && aPluginTag->mMimeTypeArray) {
for (PRInt32 i = 0; i < mVariants; i++) {
if (PL_strcmp(mMimeTypeArray[i], aPluginTag->mMimeTypeArray[i]) != 0)
return PR_FALSE;
}
for (PRUint32 i = 0; i < mMimeTypes.Length(); i++) {
if (!mMimeTypes[i].Equals(aPluginTag->mMimeTypes[i])) {
return PR_FALSE;
}
}
return PR_TRUE;
}
@ -586,33 +536,3 @@ void nsPluginTag::TryUnloadPlugin()
RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginUnregister);
}
}
void
nsPluginTag::RemoveJavaSentinel(PRInt32 sentinelIndex)
{
if (sentinelIndex == -1)
return;
delete[] mMimeTypeArray[sentinelIndex];
mMimeDescriptionArray.RemoveElementAt(sentinelIndex);
if (mExtensionsArray)
delete[] mExtensionsArray[sentinelIndex];
// Move the subsequent entries in the arrays.
if (mVariants > sentinelIndex + 1) {
memmove(mMimeTypeArray + sentinelIndex,
mMimeTypeArray + sentinelIndex + 1,
(mVariants - sentinelIndex - 1) * sizeof(mMimeTypeArray[0]));
if (mExtensionsArray) {
memmove(mExtensionsArray + sentinelIndex,
mExtensionsArray + sentinelIndex + 1,
(mVariants - sentinelIndex - 1) * sizeof(mExtensionsArray[0]));
}
}
--mVariants;
mMimeTypeArray[mVariants] = NULL;
if (mExtensionsArray)
mExtensionsArray[mVariants] = NULL;
}

Просмотреть файл

@ -100,20 +100,14 @@ public:
PRBool IsEnabled();
void RegisterWithCategoryManager(PRBool aOverrideInternalTypes,
nsRegisterType aType = ePluginRegister);
// Remove the MIME/description/extension entry associated with the magic Java sentinel
// which informs us that the Java plugin is NPAPI-enabled. If sentinelIndex is -1, no
// action will be performed.
void RemoveJavaSentinel(PRInt32 sentinelIndex);
nsRefPtr<nsPluginTag> mNext;
nsPluginHost *mPluginHost;
nsCString mName; // UTF-8
nsCString mDescription; // UTF-8
PRInt32 mVariants;
char **mMimeTypeArray;
nsTArray<nsCString> mMimeDescriptionArray; // UTF-8
char **mExtensionsArray;
nsTArray<nsCString> mMimeTypes; // UTF-8
nsTArray<nsCString> mMimeDescriptions; // UTF-8
nsTArray<nsCString> mExtensions; // UTF-8
PRLibrary *mLibrary;
nsRefPtr<nsNPAPIPlugin> mEntryPoint;
PRPackedBool mCanUnloadLibrary;