From bc8e89050c05113363c1772ec1e8fdba2eb7c1e5 Mon Sep 17 00:00:00 2001 From: Nils Maier Date: Thu, 31 Oct 2013 23:04:11 -0400 Subject: [PATCH] Bug 929120 - Add a way to get compartment locations ignoring non-addon locations. r=njn Use that new way to map compartments to add-ons. As an added bonus, fix a currently unproblematic off-by-one error in the location parser. --- js/xpconnect/src/XPCJSRuntime.cpp | 81 ++++++++++++++++++------------- js/xpconnect/src/xpcprivate.h | 22 ++++++--- 2 files changed, 62 insertions(+), 41 deletions(-) diff --git a/js/xpconnect/src/XPCJSRuntime.cpp b/js/xpconnect/src/XPCJSRuntime.cpp index 8996e5ab17b2..e37b8b4efe2b 100644 --- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -289,12 +289,46 @@ CompartmentPrivate::~CompartmentPrivate() --kLivingAdopters; } -bool CompartmentPrivate::TryParseLocationURI() +static bool +TryParseLocationURICandidate(const nsACString& uristr, + CompartmentPrivate::LocationHint aLocationHint, + nsIURI** aURI) { - // Already tried parsing the location before - if (locationWasParsed) - return false; - locationWasParsed = true; + static NS_NAMED_LITERAL_CSTRING(kGRE, "resource://gre/"); + static NS_NAMED_LITERAL_CSTRING(kToolkit, "chrome://global/"); + static NS_NAMED_LITERAL_CSTRING(kBrowser, "chrome://browser/"); + + if (aLocationHint == CompartmentPrivate::LocationHintAddon) { + // Blacklist some known locations which are clearly not add-on related. + if (StringBeginsWith(uristr, kGRE) || + StringBeginsWith(uristr, kToolkit) || + StringBeginsWith(uristr, kBrowser)) + return false; + } + + nsCOMPtr uri; + if (NS_FAILED(NS_NewURI(getter_AddRefs(uri), uristr))) + return false; + + nsAutoCString scheme; + if (NS_FAILED(uri->GetScheme(scheme))) + return false; + + // Cannot really map data: and blob:. + // Also, data: URIs are pretty memory hungry, which is kinda bad + // for memory reporter use. + if (scheme.EqualsLiteral("data") || scheme.EqualsLiteral("blob")) + return false; + + uri.forget(aURI); + return true; +} + +bool CompartmentPrivate::TryParseLocationURI(CompartmentPrivate::LocationHint aLocationHint, + nsIURI **aURI) +{ + if (!aURI) + return false; // Need to parse the URI. if (location.IsEmpty()) @@ -320,12 +354,13 @@ bool CompartmentPrivate::TryParseLocationURI() // See: XPCComponents.cpp#AssembleSandboxMemoryReporterName int32_t idx = location.Find(from); if (idx < 0) - return TryParseLocationURICandidate(location); + return TryParseLocationURICandidate(location, aLocationHint, aURI); // When parsing we're looking for the right-most URI. This URI may be in // , so we try this first. - if (TryParseLocationURICandidate(Substring(location, 0, idx))) + if (TryParseLocationURICandidate(Substring(location, 0, idx), aLocationHint, + aURI)) return true; // Not in so we need to inspect and @@ -343,42 +378,21 @@ bool CompartmentPrivate::TryParseLocationURI() idx = chain.RFind(arrow); if (idx < 0) { // This is the last chain item. Try to parse what is left. - return TryParseLocationURICandidate(chain); + return TryParseLocationURICandidate(chain, aLocationHint, aURI); } // Try to parse current chain item - if (TryParseLocationURICandidate(Substring(chain, idx + arrowLength))) + if (TryParseLocationURICandidate(Substring(chain, idx + arrowLength), + aLocationHint, aURI)) return true; // Current chain item couldn't be parsed. - // Don't forget whitespace in " -> " - idx -= 1; - // Strip current item and continue + // Strip current item and continue. chain = Substring(chain, 0, idx); } MOZ_ASSUME_UNREACHABLE("Chain parser loop does not terminate"); } -bool CompartmentPrivate::TryParseLocationURICandidate(const nsACString& uristr) -{ - nsCOMPtr uri; - if (NS_FAILED(NS_NewURI(getter_AddRefs(uri), uristr))) - return false; - - nsAutoCString scheme; - if (NS_FAILED(uri->GetScheme(scheme))) - return false; - - // Cannot really map data: and blob:. - // Also, data: URIs are pretty memory hungry, which is kinda bad - // for memory reporter use. - if (scheme.EqualsLiteral("data") || scheme.EqualsLiteral("blob")) - return false; - - locationURI = uri.forget(); - return true; -} - CompartmentPrivate* EnsureCompartmentPrivate(JSObject *obj) { @@ -2534,7 +2548,8 @@ class XPCJSRuntimeStats : public JS::RuntimeStats if (mGetLocations) { CompartmentPrivate *cp = GetCompartmentPrivate(c); if (cp) - cp->GetLocationURI(getter_AddRefs(extras->location)); + cp->GetLocationURI(CompartmentPrivate::LocationHintAddon, + getter_AddRefs(extras->location)); // Note: cannot use amIAddonManager implementation at this point, // as it is a JS service and the JS heap is currently not idle. // Otherwise, we could have computed the add-on id at this point. diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 1f49e6c26aff..1884de58fcec 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -3741,13 +3741,17 @@ namespace xpc { class CompartmentPrivate { public: + enum LocationHint { + LocationHintRegular, + LocationHintAddon + }; + CompartmentPrivate() : wantXrays(false) , universalXPConnectEnabled(false) , adoptedNode(false) , donatedNode(false) , scope(nullptr) - , locationWasParsed(false) { MOZ_COUNT_CTOR(xpc::CompartmentPrivate); } @@ -3778,10 +3782,14 @@ public: return location; } bool GetLocationURI(nsIURI **aURI) { - if (!locationURI && !TryParseLocationURI()) - return false; - NS_IF_ADDREF(*aURI = locationURI); - return true; + return GetLocationURI(LocationHintRegular, aURI); + } + bool GetLocationURI(LocationHint aLocationHint, nsIURI **aURI) { + if (locationURI) { + NS_IF_ADDREF(*aURI = locationURI); + return true; + } + return TryParseLocationURI(aLocationHint, aURI); } void SetLocation(const nsACString& aLocation) { if (aLocation.IsEmpty()) @@ -3801,10 +3809,8 @@ public: private: nsCString location; nsCOMPtr locationURI; - bool locationWasParsed; - bool TryParseLocationURI(); - bool TryParseLocationURICandidate(const nsACString& uristr); + bool TryParseLocationURI(LocationHint aType, nsIURI** aURI); }; CompartmentPrivate*