Bug 611910 - (try again with leak fixed) r=josh a=blocking2.0BetaN+

This commit is contained in:
Steven Michaud 2010-11-19 14:58:59 -06:00
Родитель 49bcdf72cf
Коммит 262e06c735
4 изменённых файлов: 172 добавлений и 4 удалений

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

@ -106,6 +106,8 @@
#include "nsIHttpAuthManager.h"
#include "nsICookieService.h"
#include "nsNetUtil.h"
#include "mozilla/PluginLibrary.h"
using mozilla::PluginLibrary;
@ -1706,7 +1708,92 @@ _getproperty(NPP npp, NPObject* npobj, NPIdentifier property,
("NPN_GetProperty(npp %p, npobj %p, property %p) called\n",
npp, npobj, property));
return npobj->_class->getProperty(npobj, property, result);
if (!npobj->_class->getProperty(npobj, property, result))
return false;
// If a Java plugin tries to get the document.URL or document.documentURI
// property from us, don't pass back a value that Java won't be able to
// understand -- one that will make the URL(String) constructor throw a
// MalformedURL exception. Passing such a value causes Java Plugin2 to
// crash (to throw a RuntimeException in Plugin2Manager.getDocumentBase()).
// Also don't pass back a value that Java is likely to mishandle.
nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*) npp->ndata;
if (!inst)
return false;
nsNPAPIPlugin* plugin = inst->GetPlugin();
if (!plugin)
return false;
nsRefPtr<nsPluginHost> host = dont_AddRef(nsPluginHost::GetInst());
nsPluginTag* pluginTag = host->TagForPlugin(plugin);
if (!pluginTag->mIsJavaPlugin)
return true;
if (!NPVARIANT_IS_STRING(*result))
return true;
NPUTF8* propertyName = _utf8fromidentifier(property);
if (!propertyName)
return true;
bool notURL =
(PL_strcasecmp(propertyName, "URL") &&
PL_strcasecmp(propertyName, "documentURI"));
_memfree(propertyName);
if (notURL)
return true;
NPObject* window_obj = _getwindowobject(npp);
if (!window_obj)
return true;
NPVariant doc_v;
NPObject* document_obj = nsnull;
NPIdentifier doc_id = _getstringidentifier("document");
bool ok = npobj->_class->getProperty(window_obj, doc_id, &doc_v);
_releaseobject(window_obj);
if (ok) {
if (NPVARIANT_IS_OBJECT(doc_v)) {
document_obj = NPVARIANT_TO_OBJECT(doc_v);
} else {
_releasevariantvalue(&doc_v);
return true;
}
} else {
return true;
}
_releaseobject(document_obj);
if (document_obj != npobj)
return true;
NPString urlnp = NPVARIANT_TO_STRING(*result);
nsXPIDLCString url;
url.Assign(urlnp.UTF8Characters, urlnp.UTF8Length);
PRBool javaCompatible = PR_FALSE;
if (NS_FAILED(NS_CheckIsJavaCompatibleURLString(url, &javaCompatible)))
javaCompatible = PR_FALSE;
if (javaCompatible)
return true;
// If Java won't be able to interpret the original value of document.URL or
// document.documentURI, or is likely to mishandle it, pass back something
// that Java will understand but won't be able to use to access the network,
// and for which same-origin checks will always fail.
if (inst->mFakeURL.IsVoid()) {
// Abort (do an error return) if NS_MakeRandomInvalidURLString() fails.
if (NS_FAILED(NS_MakeRandomInvalidURLString(inst->mFakeURL))) {
_releasevariantvalue(result);
return false;
}
}
_releasevariantvalue(result);
char* fakeurl = (char *) _memalloc(inst->mFakeURL.Length() + 1);
strcpy(fakeurl, inst->mFakeURL);
STRINGZ_TO_NPVARIANT(fakeurl, *result);
return true;
}
bool NP_CALLBACK

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

@ -177,6 +177,8 @@ public:
// True while creating the plugin, or calling NPP_SetWindow() on it.
PRPackedBool mInPluginInitCall;
nsXPIDLCString mFakeURL;
private:
nsNPAPIPlugin* mPlugin;

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

@ -181,6 +181,9 @@ public:
nsIPluginInstanceOwner* aOwner,
PRBool aAllowOpeningStreams);
// Does not accept NULL and should never fail.
nsPluginTag* TagForPlugin(nsNPAPIPlugin* aPlugin);
private:
nsresult
TrySetUpPluginInstance(const char *aMimeType, nsIURI *aURL, nsIPluginInstanceOwner *aOwner);
@ -206,9 +209,6 @@ private:
nsPluginTag*
FindPluginEnabledForExtension(const char* aExtension, const char* &aMimeType);
// Does not accept NULL and should never fail.
nsPluginTag* TagForPlugin(nsNPAPIPlugin* aPlugin);
nsresult
FindStoppedPluginForURL(nsIURI* aURL, nsIPluginInstanceOwner *aOwner);

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

@ -52,6 +52,8 @@
#include "nsCRT.h"
#include "nsIURI.h"
#include "nsIStandardURL.h"
#include "nsIURLParser.h"
#include "nsIUUIDGenerator.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsISafeOutputStream.h"
@ -1776,4 +1778,81 @@ NS_IsInternalSameURIRedirect(nsIChannel *aOldChannel,
return NS_SUCCEEDED(oldURI->Equals(newURI, &res)) && res;
}
/**
* Helper function to create a random URL string that's properly formed
* but guaranteed to be invalid.
*/
#define NS_FAKE_SCHEME "http://"
#define NS_FAKE_TLD ".invalid"
inline nsresult
NS_MakeRandomInvalidURLString(nsCString& result)
{
nsresult rv;
nsCOMPtr<nsIUUIDGenerator> uuidgen =
do_GetService("@mozilla.org/uuid-generator;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsID idee;
rv = uuidgen->GenerateUUIDInPlace(&idee);
NS_ENSURE_SUCCESS(rv, rv);
char chars[NSID_LENGTH];
idee.ToProvidedString(chars);
result.AssignLiteral(NS_FAKE_SCHEME);
// Strip off the '{' and '}' at the beginning and end of the UUID
result.Append(chars + 1, NSID_LENGTH - 3);
result.AppendLiteral(NS_FAKE_TLD);
return NS_OK;
}
#undef NS_FAKE_SCHEME
#undef NS_FAKE_TLD
/**
* Helper function to determine whether urlString is Java-compatible --
* whether it can be passed to the Java URL(String) constructor without the
* latter throwing a MalformedURLException, or without Java otherwise
* mishandling it.
*/
inline nsresult
NS_CheckIsJavaCompatibleURLString(nsCString& urlString, PRBool *result)
{
*result = PR_FALSE; // Default to "no"
nsresult rv = NS_OK;
nsCOMPtr<nsIURLParser> urlParser =
do_GetService(NS_STDURLPARSER_CONTRACTID, &rv);
if (NS_FAILED(rv) || !urlParser)
return NS_ERROR_FAILURE;
PRBool compatible = PR_TRUE;
PRUint32 schemePos = 0;
PRInt32 schemeLen = 0;
urlParser->ParseURL(urlString.get(), -1, &schemePos, &schemeLen,
nsnull, nsnull, nsnull, nsnull);
if (schemeLen != -1) {
nsCString scheme;
scheme.Assign(urlString.get() + schemePos, schemeLen);
// By default Java only understands a small number of URL schemes, and of
// these only some are likely to represent user input (for example from a
// link or the location bar) that Java can legitimately be expected to
// handle. (Besides those listed below, Java also understands the "jar",
// "mailto" and "netdoc" schemes. But it probably doesn't expect these
// from a browser, and is therefore likely to mishandle them.)
if (PL_strcasecmp(scheme.get(), "http") &&
PL_strcasecmp(scheme.get(), "https") &&
PL_strcasecmp(scheme.get(), "file") &&
PL_strcasecmp(scheme.get(), "ftp") &&
PL_strcasecmp(scheme.get(), "gopher"))
compatible = PR_FALSE;
} else {
compatible = PR_FALSE;
}
*result = compatible;
return NS_OK;
}
#endif // !nsNetUtil_h__