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.
This commit is contained in:
Nils Maier 2013-10-31 23:04:11 -04:00
parent ab4aae2e25
commit bc8e89050c
2 changed files with 62 additions and 41 deletions

View File

@ -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<nsIURI> 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
// <sandboxName>, so we try this first.
if (TryParseLocationURICandidate(Substring(location, 0, idx)))
if (TryParseLocationURICandidate(Substring(location, 0, idx), aLocationHint,
aURI))
return true;
// Not in <sandboxName> so we need to inspect <js-stack-frame-filename> 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<nsIURI> 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.

View File

@ -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<nsIURI> locationURI;
bool locationWasParsed;
bool TryParseLocationURI();
bool TryParseLocationURICandidate(const nsACString& uristr);
bool TryParseLocationURI(LocationHint aType, nsIURI** aURI);
};
CompartmentPrivate*