diff options
32 files changed, 443 insertions, 108 deletions
@@ -12,6 +12,12 @@ applications. This repository will contain at least one application to demonstrate and make use of the platform: The Basilisk web browser, a close twin to Mozilla's Firefox. +## Additional documentation + +Additional documentation relevant to this source code can be found in the `/docs` +directory. This will contain relevant documentation regarding contributing, +using and distributing this code and its binaries. + ### A note about trademarks and branding Although this repository is licensed under Mozilla Public License v2.0, the diff --git a/application/palemoon/app/Makefile.in b/application/palemoon/app/Makefile.in index 6f9bbfaf0..c0f01212c 100644 --- a/application/palemoon/app/Makefile.in +++ b/application/palemoon/app/Makefile.in @@ -76,7 +76,7 @@ AB := $(firstword $(subst -, ,$(AB_CD))) clean clobber repackage:: $(RM) -r $(dist_dest) -MAC_BUNDLE_VERSION = $(shell $(PYTHON) $(srcdir)/macversion.py --version=$(MOZ_APP_VERSION) --buildid=$(DEPTH)/config/buildid) +MAC_BUNDLE_VERSION = $(shell $(PYTHON) $(srcdir)/macversion.py --version=$(MOZ_APP_VERSION) --buildid=$(DEPTH)/buildid.h) .PHONY: repackage tools repackage:: $(PROGRAM) diff --git a/application/palemoon/app/macversion.py b/application/palemoon/app/macversion.py index 8c360368e..839aac1ff 100644 --- a/application/palemoon/app/macversion.py +++ b/application/palemoon/app/macversion.py @@ -28,7 +28,7 @@ if not options.version: # builds), but also so that newly-built older versions (e.g. beta build) aren't # considered "newer" than previously-built newer versions (e.g. a trunk nightly) -buildid = open(options.buildid, 'r').read() +define, MOZ_BUILDID, buildid = open(options.buildid, 'r').read().split() # extract only the major version (i.e. "14" from "14.0b1") majorVersion = re.match(r'^(\d+)[^\d].*', options.version).group(1) diff --git a/application/palemoon/base/content/browser.js b/application/palemoon/base/content/browser.js index 6dbd9677e..9f4d66c07 100644 --- a/application/palemoon/base/content/browser.js +++ b/application/palemoon/base/content/browser.js @@ -122,7 +122,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils", XPCOMUtils.defineLazyModuleGetter(this, "FormValidationHandler", "resource:///modules/FormValidationHandler.jsm"); -let gInitialPages = [ +var gInitialPages = [ "about:blank", "about:newtab", "about:home", @@ -990,12 +990,23 @@ var gBrowserInit = { gBrowser.swapBrowsersAndCloseOther(gBrowser.selectedTab, uriToLoad); } - // window.arguments[2]: referrer (nsIURI) + // window.arguments[2]: referrer (nsIURI | string) // [3]: postData (nsIInputStream) // [4]: allowThirdPartyFixup (bool) + // [5]: referrerPolicy (int) else if (window.arguments.length >= 3) { - loadURI(uriToLoad, window.arguments[2], window.arguments[3] || null, - window.arguments[4] || false); + let referrerURI = window.arguments[2]; + if (typeof(referrerURI) == "string") { + try { + referrerURI = makeURI(referrerURI); + } catch (e) { + referrerURI = null; + } + } + let referrerPolicy = (window.arguments[5] != undefined ? + window.arguments[5] : Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT); + loadURI(uriToLoad, referrerURI, window.arguments[3] || null, + window.arguments[4] || false, referrerPolicy); window.focus(); } // Note: loadOneOrMoreURIs *must not* be called if window.arguments.length >= 3. @@ -1883,7 +1894,7 @@ function BrowserTryToCloseWindow() window.close(); // WindowIsClosing does all the necessary checks } -function loadURI(uri, referrer, postData, allowThirdPartyFixup) { +function loadURI(uri, referrer, postData, allowThirdPartyFixup, referrerPolicy) { if (postData === undefined) postData = null; @@ -1894,7 +1905,12 @@ function loadURI(uri, referrer, postData, allowThirdPartyFixup) { } try { - gBrowser.loadURIWithFlags(uri, flags, referrer, null, postData); + gBrowser.loadURIWithFlags(uri, { + flags: flags, + referrerURI: referrer, + referrerPolicy: referrerPolicy, + postData: postData, + }); } catch (e) {} } @@ -4288,6 +4304,13 @@ nsBrowserAccess.prototype = { else aWhere = gPrefService.getIntPref("browser.link.open_newwindow"); } + + let referrer = aOpener ? makeURI(aOpener.location.href) : null; + let referrerPolicy = Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT; + if (aOpener && aOpener.document) { + referrerPolicy = aOpener.document.referrerPolicy; + } + switch (aWhere) { case Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW : // FIXME: Bug 408379. So how come this doesn't send the @@ -4326,6 +4349,7 @@ nsBrowserAccess.prototype = { let tab = win.gBrowser.loadOneTab(aURI ? aURI.spec : "about:blank", { referrerURI: referrer, + referrerPolicy: referrerPolicy, fromExternal: isExternal, inBackground: loadInBackground}); let browser = win.gBrowser.getBrowserForTab(tab); @@ -4341,11 +4365,14 @@ nsBrowserAccess.prototype = { default : // OPEN_CURRENTWINDOW or an illegal value newWindow = content; if (aURI) { - let referrer = aOpener ? makeURI(aOpener.location.href) : null; let loadflags = isExternal ? Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL : Ci.nsIWebNavigation.LOAD_FLAGS_NONE; - gBrowser.loadURIWithFlags(aURI.spec, loadflags, referrer, null, null); + gBrowser.loadURIWithFlags(aURI.spec, { + flags: loadflags, + referrerURI: referrer, + referrerPolicy: referrerPolicy, + }); } if (!gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground")) window.focus(); @@ -5075,7 +5102,8 @@ function handleLinkClick(event, href, linkNode) { urlSecurityCheck(href, doc.nodePrincipal); openLinkIn(href, where, { referrerURI: doc.documentURIObject, - charset: doc.characterSet }); + charset: doc.characterSet, + referrerPolicy: doc.referrerPolicy }); event.preventDefault(); return true; } diff --git a/application/palemoon/base/content/nsContextMenu.js b/application/palemoon/base/content/nsContextMenu.js index 830c20998..f389491d3 100644 --- a/application/palemoon/base/content/nsContextMenu.js +++ b/application/palemoon/base/content/nsContextMenu.js @@ -753,7 +753,8 @@ nsContextMenu.prototype = { urlSecurityCheck(this.linkURL, doc.nodePrincipal); openLinkIn(this.linkURL, "window", { charset: doc.characterSet, - referrerURI: doc.documentURIObject }); + referrerURI: doc.documentURIObject, + referrerPolicy: doc.referrerPolicy }); }, // Open linked-to URL in a new private window. @@ -763,6 +764,7 @@ nsContextMenu.prototype = { openLinkIn(this.linkURL, "window", { charset: doc.characterSet, referrerURI: doc.documentURIObject, + referrerPolicy: doc.referrerPolicy, private: true }); }, @@ -772,7 +774,8 @@ nsContextMenu.prototype = { urlSecurityCheck(this.linkURL, doc.nodePrincipal); openLinkIn(this.linkURL, "tab", { charset: doc.characterSet, - referrerURI: doc.documentURIObject }); + referrerURI: doc.documentURIObject, + referrerPolicy: doc.referrerPolicy }); }, // open URL in current tab diff --git a/application/palemoon/base/content/tabbrowser.xml b/application/palemoon/base/content/tabbrowser.xml index c06b49af0..1b8099785 100644 --- a/application/palemoon/base/content/tabbrowser.xml +++ b/application/palemoon/base/content/tabbrowser.xml @@ -1264,6 +1264,7 @@ <parameter name="aAllowThirdPartyFixup"/> <body> <![CDATA[ + var aReferrerPolicy; var aFromExternal; var aRelatedToCurrent; if (arguments.length == 2 && @@ -1271,6 +1272,7 @@ !(arguments[1] instanceof Ci.nsIURI)) { let params = arguments[1]; aReferrerURI = params.referrerURI; + aReferrerPolicy = params.referrerPolicy; aCharset = params.charset; aPostData = params.postData; aLoadInBackground = params.inBackground; @@ -1284,6 +1286,7 @@ var owner = bgLoad ? null : this.selectedTab; var tab = this.addTab(aURI, { referrerURI: aReferrerURI, + referrerPolicy: aReferrerPolicy, charset: aCharset, postData: aPostData, ownerTab: owner, @@ -1409,6 +1412,7 @@ <body> <![CDATA[ const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; + var aReferrerPolicy; var aFromExternal; var aRelatedToCurrent; var aSkipAnimation; @@ -1417,6 +1421,7 @@ !(arguments[1] instanceof Ci.nsIURI)) { let params = arguments[1]; aReferrerURI = params.referrerURI; + aReferrerPolicy = params.referrerPolicy; aCharset = params.charset; aPostData = params.postData; aOwner = params.ownerTab; @@ -1588,7 +1593,13 @@ if (aFromExternal) flags |= Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL; try { - b.loadURIWithFlags(aURI, flags, aReferrerURI, aCharset, aPostData); + b.loadURIWithFlags(aURI, { + flags: flags, + referrerURI: aReferrerURI, + referrerPolicy: aReferrerPolicy, + charset: aCharset, + postData: aPostData, + }); } catch (ex) { Cu.reportError(ex); } @@ -2700,6 +2711,11 @@ <parameter name="aPostData"/> <body> <![CDATA[ + // Note - the callee understands both: + // (a) loadURIWithFlags(aURI, aFlags, ...) + // (b) loadURIWithFlags(aURI, { flags: aFlags, ... }) + // Forwarding it as (a) here actually supports both (a) and (b), + // so you can call us either way too. return this.mCurrentBrowser.loadURIWithFlags(aURI, aFlags, aReferrerURI, aCharset, aPostData); ]]> </body> diff --git a/application/palemoon/base/content/utilityOverlay.js b/application/palemoon/base/content/utilityOverlay.js index 86cc5cea5..9763891ba 100644 --- a/application/palemoon/base/content/utilityOverlay.js +++ b/application/palemoon/base/content/utilityOverlay.js @@ -104,7 +104,8 @@ function openUILink(url, event, aIgnoreButton, aIgnoreAlt, aAllowThirdPartyFixup allowThirdPartyFixup: aAllowThirdPartyFixup, postData: aPostData, referrerURI: aReferrerURI, - initiatingDoc: event ? event.target.ownerDocument : null + referrerPolicy: Components.interfaces.nsIHttpChannel.REFERRER_POLICY_DEFAULT, + initiatingDoc: event ? event.target.ownerDocument : null, }; } @@ -196,7 +197,8 @@ function openUILinkIn(url, where, aAllowThirdPartyFixup, aPostData, aReferrerURI params = { allowThirdPartyFixup: aAllowThirdPartyFixup, postData: aPostData, - referrerURI: aReferrerURI + referrerURI: aReferrerURI, + referrerPolicy: Components.interfaces.nsIHttpChannel.REFERRER_POLICY_DEFAULT, }; } @@ -209,12 +211,16 @@ function openUILinkIn(url, where, aAllowThirdPartyFixup, aPostData, aReferrerURI function openLinkIn(url, where, params) { if (!where || !url) return; + const Cc = Components.classes; + const Ci = Components.interfaces; var aFromChrome = params.fromChrome; var aAllowThirdPartyFixup = params.allowThirdPartyFixup; var aPostData = params.postData; var aCharset = params.charset; var aReferrerURI = params.referrerURI; + var aReferrerPolicy = ('referrerPolicy' in params ? + params.referrerPolicy : Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT); var aRelatedToCurrent = params.relatedToCurrent; var aForceAllowDataURI = params.forceAllowDataURI; var aInBackground = params.inBackground; @@ -229,11 +235,10 @@ function openLinkIn(url, where, params) { "where == 'save' but without initiatingDoc. See bug 814264."); return; } + // TODO(1073187): propagate referrerPolicy. saveURL(url, null, null, true, null, aReferrerURI, aInitiatingDoc); return; } - const Cc = Components.classes; - const Ci = Components.interfaces; var w = getTopWin(); if ((where == "tab" || where == "tabshifted") && @@ -243,6 +248,7 @@ function openLinkIn(url, where, params) { } if (!w || where == "window") { + // This propagates to window.arguments. // Strip referrer data when opening a new private window, to prevent // regular browsing data from leaking into it. if (aIsPrivate) { @@ -267,12 +273,23 @@ function openLinkIn(url, where, params) { createInstance(Ci.nsISupportsPRBool); allowThirdPartyFixupSupports.data = aAllowThirdPartyFixup; + var referrerURISupports = null; + if (aReferrerURI && sendReferrerURI) { + referrerURISupports = Cc["@mozilla.org/supports-string;1"]. + createInstance(Ci.nsISupportsString); + referrerURISupports.data = aReferrerURI.spec; + } + + var referrerPolicySupports = Cc["@mozilla.org/supports-PRUint32;1"]. + createInstance(Ci.nsISupportsPRUint32); + referrerPolicySupports.data = aReferrerPolicy; + sa.AppendElement(wuri); sa.AppendElement(charset); - if (sendReferrerURI) - sa.AppendElement(aReferrerURI); + sa.AppendElement(referrerURISupports); sa.AppendElement(aPostData); sa.AppendElement(allowThirdPartyFixupSupports); + sa.AppendElement(referrerPolicySupports); let features = "chrome,dialog=no,all"; if (aIsPrivate) { @@ -320,7 +337,12 @@ function openLinkIn(url, where, params) { if (aForceAllowDataURI) { flags |= Ci.nsIWebNavigation.LOAD_FLAGS_FORCE_ALLOW_DATA_URI; } - w.gBrowser.loadURIWithFlags(url, flags, aReferrerURI, null, aPostData); + w.gBrowser.loadURIWithFlags(url, { + flags: flags, + referrerURI: aReferrerURI, + referrerPolicy: aReferrerPolicy, + postData: aPostData, + }); break; case "tabshifted": loadInBackground = !loadInBackground; @@ -329,6 +351,7 @@ function openLinkIn(url, where, params) { let browser = w.gBrowser; browser.loadOneTab(url, { referrerURI: aReferrerURI, + referrerPolicy: aReferrerPolicy, charset: aCharset, postData: aPostData, inBackground: loadInBackground, @@ -577,9 +600,11 @@ function makeURLAbsolute(aBase, aUrl) * @param [optional] aReferrer * If aDocument is null, then this will be used as the referrer. * There will be no security check. + * @param [optional] aReferrerPolicy + * Referrer policy - Ci.nsIHttpChannel.REFERRER_POLICY_*. */ function openNewTabWith(aURL, aDocument, aPostData, aEvent, - aAllowThirdPartyFixup, aReferrer) { + aAllowThirdPartyFixup, aReferrer, aReferrerPolicy) { if (aDocument) urlSecurityCheck(aURL, aDocument.nodePrincipal); @@ -594,10 +619,13 @@ function openNewTabWith(aURL, aDocument, aPostData, aEvent, { charset: originCharset, postData: aPostData, allowThirdPartyFixup: aAllowThirdPartyFixup, - referrerURI: aDocument ? aDocument.documentURIObject : aReferrer }); + referrerURI: aDocument ? aDocument.documentURIObject : aReferrer, + referrerPolicy: aReferrerPolicy, + }); } -function openNewWindowWith(aURL, aDocument, aPostData, aAllowThirdPartyFixup, aReferrer) { +function openNewWindowWith(aURL, aDocument, aPostData, aAllowThirdPartyFixup, + aReferrer, aReferrerPolicy) { if (aDocument) urlSecurityCheck(aURL, aDocument.nodePrincipal); @@ -614,7 +642,9 @@ function openNewWindowWith(aURL, aDocument, aPostData, aAllowThirdPartyFixup, aR { charset: originCharset, postData: aPostData, allowThirdPartyFixup: aAllowThirdPartyFixup, - referrerURI: aDocument ? aDocument.documentURIObject : aReferrer }); + referrerURI: aDocument ? aDocument.documentURIObject : aReferrer, + referrerPolicy: aReferrerPolicy, + }); } /** diff --git a/build/moz.configure/old.configure b/build/moz.configure/old.configure index ffdea81b0..9f29e68c9 100644 --- a/build/moz.configure/old.configure +++ b/build/moz.configure/old.configure @@ -235,6 +235,7 @@ def old_configure_options(*options): '--enable-system-pixman', '--enable-system-sqlite', '--enable-tasktracer', + '--enable-tests', '--enable-thread-sanitizer', '--enable-trace-logging', '--enable-ui-locale', diff --git a/.github/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 7acdedb4f..7acdedb4f 100644 --- a/.github/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index 33f5f7a44..7056658a7 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -259,8 +259,8 @@ TErrorResult<CleanupPolicy>::ThrowJSException(JSContext* cx, JS::Handle<JS::Valu // Make sure mJSException is initialized _before_ we try to root it. But // don't set it to exn yet, because we don't want to do that until after we // root. - mJSException.setUndefined(); - if (!js::AddRawValueRoot(cx, &mJSException, "TErrorResult::mJSException")) { + mJSException.asValueRef().setUndefined(); + if (!js::AddRawValueRoot(cx, &mJSException.asValueRef(), "TErrorResult::mJSException")) { // Don't use NS_ERROR_DOM_JS_EXCEPTION, because that indicates we have // in fact rooted mJSException. mResult = NS_ERROR_OUT_OF_MEMORY; @@ -289,7 +289,7 @@ TErrorResult<CleanupPolicy>::SetPendingJSException(JSContext* cx) mJSException = exception; // If JS_WrapValue failed, not much we can do about it... No matter // what, go ahead and unroot mJSException. - js::RemoveRawValueRoot(cx, &mJSException); + js::RemoveRawValueRoot(cx, &mJSException.asValueRef()); mResult = NS_OK; #ifdef DEBUG @@ -395,8 +395,8 @@ TErrorResult<CleanupPolicy>::ClearUnionData() if (IsJSException()) { JSContext* cx = dom::danger::GetJSContext(); MOZ_ASSERT(cx); - mJSException.setUndefined(); - js::RemoveRawValueRoot(cx, &mJSException); + mJSException.asValueRef().setUndefined(); + js::RemoveRawValueRoot(cx, &mJSException.asValueRef()); #ifdef DEBUG mUnionState = HasNothing; #endif // DEBUG @@ -439,13 +439,13 @@ TErrorResult<CleanupPolicy>::operator=(TErrorResult<CleanupPolicy>&& aRHS) } else if (aRHS.IsJSException()) { JSContext* cx = dom::danger::GetJSContext(); MOZ_ASSERT(cx); - mJSException.setUndefined(); - if (!js::AddRawValueRoot(cx, &mJSException, "TErrorResult::mJSException")) { + mJSException.asValueRef().setUndefined(); + if (!js::AddRawValueRoot(cx, &mJSException.asValueRef(), "TErrorResult::mJSException")) { MOZ_CRASH("Could not root mJSException, we're about to OOM"); } mJSException = aRHS.mJSException; - aRHS.mJSException.setUndefined(); - js::RemoveRawValueRoot(cx, &aRHS.mJSException); + aRHS.mJSException.asValueRef().setUndefined(); + js::RemoveRawValueRoot(cx, &aRHS.mJSException.asValueRef()); } else if (aRHS.IsDOMException()) { mDOMExceptionInfo = aRHS.mDOMExceptionInfo; aRHS.mDOMExceptionInfo = nullptr; @@ -497,7 +497,7 @@ TErrorResult<CleanupPolicy>::CloneTo(TErrorResult& aRv) const aRv.mUnionState = HasJSException; #endif JSContext* cx = dom::danger::GetJSContext(); - JS::Rooted<JS::Value> exception(cx, mJSException); + JS::Rooted<JS::Value> exception(cx, mJSException.asValueRef()); aRv.ThrowJSException(cx, exception); } } diff --git a/dom/bindings/ErrorResult.h b/dom/bindings/ErrorResult.h index c45e7ea3b..7c3fc9e2f 100644 --- a/dom/bindings/ErrorResult.h +++ b/dom/bindings/ErrorResult.h @@ -461,7 +461,7 @@ private: // (and deallocated) by SetPendingDOMException. union { Message* mMessage; // valid when IsErrorWithMessage() - JS::Value mJSException; // valid when IsJSException() + JS::UninitializedValue mJSException; // valid when IsJSException() DOMExceptionInfo* mDOMExceptionInfo; // valid when IsDOMException() }; diff --git a/dom/media/MediaStreamTrack.cpp b/dom/media/MediaStreamTrack.cpp index 8ccdeb90c..75cdeb1d1 100644 --- a/dom/media/MediaStreamTrack.cpp +++ b/dom/media/MediaStreamTrack.cpp @@ -165,11 +165,15 @@ MediaStreamTrack::Destroy() mPrincipalHandleListener->Forget(); mPrincipalHandleListener = nullptr; } - for (auto l : mTrackListeners) { - RemoveListener(l); + // Remove all listeners -- avoid iterating over the list we're removing from + const nsTArray<RefPtr<MediaStreamTrackListener>> trackListeners(mTrackListeners); + for (auto listener : trackListeners) { + RemoveListener(listener); } - for (auto l : mDirectTrackListeners) { - RemoveDirectListener(l); + // Do the same as above for direct listeners + const nsTArray<RefPtr<DirectMediaStreamTrackListener>> directTrackListeners(mDirectTrackListeners); + for (auto listener : directTrackListeners) { + RemoveDirectListener(listener); } } diff --git a/dom/xslt/xpath/txXPCOMExtensionFunction.cpp b/dom/xslt/xpath/txXPCOMExtensionFunction.cpp index 4913702aa..032161722 100644 --- a/dom/xslt/xpath/txXPCOMExtensionFunction.cpp +++ b/dom/xslt/xpath/txXPCOMExtensionFunction.cpp @@ -322,7 +322,7 @@ public: void trace(JSTracer* trc) { for (uint8_t i = 0; i < mCount; ++i) { if (mArray[i].type == nsXPTType::T_JSVAL) { - JS::UnsafeTraceRoot(trc, &mArray[i].val.j, "txParam value"); + JS::UnsafeTraceRoot(trc, &mArray[i].val.j.asValueRef(), "txParam value"); } } } diff --git a/js/public/Value.h b/js/public/Value.h index a40e65c83..01666ed4e 100644 --- a/js/public/Value.h +++ b/js/public/Value.h @@ -140,12 +140,16 @@ static_assert(sizeof(JSValueShiftedTag) == sizeof(uint64_t), #define JSVAL_TYPE_TO_TAG(type) ((JSValueTag)(JSVAL_TAG_CLEAR | (type))) +#define JSVAL_RAW64_UNDEFINED (uint64_t(JSVAL_TAG_UNDEFINED) << 32) + #define JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET JSVAL_TAG_OBJECT #define JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET JSVAL_TAG_INT32 #define JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET JSVAL_TAG_STRING #elif defined(JS_PUNBOX64) +#define JSVAL_RAW64_UNDEFINED (uint64_t(JSVAL_TAG_UNDEFINED) << JSVAL_TAG_SHIFT) + #define JSVAL_PAYLOAD_MASK 0x00007FFFFFFFFFFFLL #define JSVAL_TAG_MASK 0xFFFF800000000000LL #define JSVAL_TYPE_TO_TAG(type) ((JSValueTag)(JSVAL_TAG_MAX_DOUBLE | (type))) @@ -817,7 +821,7 @@ class MOZ_NON_PARAM alignas(8) Value double asDouble; void* asPtr; - layout() = default; + layout() : asBits(JSVAL_RAW64_UNDEFINED) {} explicit constexpr layout(uint64_t bits) : asBits(bits) {} explicit constexpr layout(double d) : asDouble(d) {} } data; @@ -843,7 +847,7 @@ class MOZ_NON_PARAM alignas(8) Value size_t asWord; uintptr_t asUIntPtr; - layout() = default; + layout() : asBits(JSVAL_RAW64_UNDEFINED) {} explicit constexpr layout(uint64_t bits) : asBits(bits) {} explicit constexpr layout(double d) : asDouble(d) {} } data; @@ -871,7 +875,7 @@ class MOZ_NON_PARAM alignas(8) Value double asDouble; void* asPtr; - layout() = default; + layout() : asBits(JSVAL_RAW64_UNDEFINED) {} explicit constexpr layout(uint64_t bits) : asBits(bits) {} explicit constexpr layout(double d) : asDouble(d) {} } data; @@ -895,7 +899,7 @@ class MOZ_NON_PARAM alignas(8) Value size_t asWord; uintptr_t asUIntPtr; - layout() = default; + layout() : asBits(JSVAL_RAW64_UNDEFINED) {} explicit constexpr layout(uint64_t bits) : asBits(bits) {} explicit constexpr layout(double d) : asDouble(d) {} } data; @@ -948,8 +952,51 @@ class MOZ_NON_PARAM alignas(8) Value } } JS_HAZ_GC_POINTER; +/** + * This is a null-constructible structure that can convert to and from + * a Value, allowing UninitializedValue to be stored in unions. + */ +struct MOZ_NON_PARAM alignas(8) UninitializedValue +{ + private: + uint64_t bits; + + public: + UninitializedValue() = default; + UninitializedValue(const UninitializedValue&) = default; + MOZ_IMPLICIT UninitializedValue(const Value& val) : bits(val.asRawBits()) {} + + inline uint64_t asRawBits() const { + return bits; + } + + inline Value& asValueRef() { + return *reinterpret_cast<Value*>(this); + } + inline const Value& asValueRef() const { + return *reinterpret_cast<const Value*>(this); + } + + inline operator Value&() { + return asValueRef(); + } + inline operator Value const&() const { + return asValueRef(); + } + inline operator Value() const { + return asValueRef(); + } + + inline void operator=(Value const& other) { + asValueRef() = other; + } +}; + static_assert(sizeof(Value) == 8, "Value size must leave three tag bits, be a binary power, and is ubiquitously depended upon everywhere"); +static_assert(sizeof(UninitializedValue) == sizeof(Value), "Value and UninitializedValue must be the same size"); +static_assert(alignof(UninitializedValue) == alignof(Value), "Value and UninitializedValue must have same alignment"); + inline bool IsOptimizedPlaceholderMagicValue(const Value& v) { diff --git a/js/src/jit/BaselineFrameInfo.h b/js/src/jit/BaselineFrameInfo.h index 13bf0358d..1691270ac 100644 --- a/js/src/jit/BaselineFrameInfo.h +++ b/js/src/jit/BaselineFrameInfo.h @@ -67,7 +67,7 @@ class StackValue union { struct { - Value v; + JS::UninitializedValue v; } constant; struct { mozilla::AlignedStorage2<ValueOperand> reg; @@ -112,7 +112,7 @@ class StackValue } Value constant() const { MOZ_ASSERT(kind_ == Constant); - return data.constant.v; + return data.constant.v.asValueRef(); } ValueOperand reg() const { MOZ_ASSERT(kind_ == Register); diff --git a/js/src/jit/RegisterSets.h b/js/src/jit/RegisterSets.h index 0a4045dd7..08ae53f16 100644 --- a/js/src/jit/RegisterSets.h +++ b/js/src/jit/RegisterSets.h @@ -226,13 +226,13 @@ class ConstantOrRegister // Space to hold either a Value or a TypedOrValueRegister. union U { - Value constant; + JS::UninitializedValue constant; TypedOrValueRegister reg; } data; - const Value& dataValue() const { + Value dataValue() const { MOZ_ASSERT(constant()); - return data.constant; + return data.constant.asValueRef(); } void setDataValue(const Value& value) { MOZ_ASSERT(constant()); @@ -268,7 +268,7 @@ class ConstantOrRegister return constant_; } - const Value& value() const { + Value value() const { return dataValue(); } diff --git a/js/src/jit/RematerializedFrame.cpp b/js/src/jit/RematerializedFrame.cpp index cb324220c..32fad1267 100644 --- a/js/src/jit/RematerializedFrame.cpp +++ b/js/src/jit/RematerializedFrame.cpp @@ -61,9 +61,17 @@ RematerializedFrame::New(JSContext* cx, uint8_t* top, InlineFrameIterator& iter, { unsigned numFormals = iter.isFunctionFrame() ? iter.calleeTemplate()->nargs() : 0; unsigned argSlots = Max(numFormals, iter.numActualArgs()); - size_t numBytes = sizeof(RematerializedFrame) + - (argSlots + iter.script()->nfixed()) * sizeof(Value) - - sizeof(Value); // 1 Value included in sizeof(RematerializedFrame) + unsigned extraSlots = argSlots + iter.script()->nfixed(); + + // One Value slot is included in sizeof(RematerializedFrame), so we can + // reduce the extra slot count by one. However, if there are zero slot + // allocations total, then reducing the slots by one will lead to + // the memory allocation being smaller than sizeof(RematerializedFrame). + if (extraSlots > 0) + extraSlots -= 1; + + size_t numBytes = sizeof(RematerializedFrame) + (extraSlots * sizeof(Value)); + MOZ_ASSERT(numBytes >= sizeof(RematerializedFrame)); void* buf = cx->pod_calloc<uint8_t>(numBytes); if (!buf) diff --git a/js/src/jsstr.h b/js/src/jsstr.h index 3b92aa21b..7e9621d4a 100644 --- a/js/src/jsstr.h +++ b/js/src/jsstr.h @@ -9,6 +9,7 @@ #include "mozilla/HashFunctions.h" #include "mozilla/PodOperations.h" +#include "mozilla/TextUtils.h" #include <stdio.h> @@ -95,7 +96,7 @@ struct JSSubString { #define JS7_UNOCT(c) (JS7_UNDEC(c)) #define JS7_ISHEX(c) ((c) < 128 && isxdigit(c)) #define JS7_UNHEX(c) (unsigned)(JS7_ISDEC(c) ? (c) - '0' : 10 + tolower(c) - 'a') -#define JS7_ISLET(c) ((c) < 128 && isalpha(c)) +#define JS7_ISLET(c) (mozilla::IsAsciiAlpha(c)) extern size_t js_strlen(const char16_t* s); diff --git a/js/src/old-configure.in b/js/src/old-configure.in index 7432ab9e2..162a071d7 100644 --- a/js/src/old-configure.in +++ b/js/src/old-configure.in @@ -1534,6 +1534,14 @@ MOZ_ARG_ENABLE_STRING(ui-locale, AC_SUBST(MOZ_UI_LOCALE) dnl ======================================================== +dnl Build the tests? +dnl ======================================================== +MOZ_ARG_ENABLE_BOOL(tests, +[ --enable-tests Build test libraries & programs], + ENABLE_TESTS=1, + ENABLE_TESTS= ) + +dnl ======================================================== dnl = dnl = Module specific options dnl = @@ -2091,6 +2099,8 @@ AC_SUBST(MOZ_DEBUG_LDFLAGS) AC_SUBST(WARNINGS_AS_ERRORS) AC_SUBST(LIBICONV) +AC_SUBST(ENABLE_TESTS) + AC_SUBST(ENABLE_STRIP) AC_SUBST(PKG_SKIP_STRIP) AC_SUBST(INCREMENTAL_LINKER) diff --git a/js/src/wasm/AsmJS.cpp b/js/src/wasm/AsmJS.cpp index b4f41c3d5..7fade24fb 100644 --- a/js/src/wasm/AsmJS.cpp +++ b/js/src/wasm/AsmJS.cpp @@ -857,7 +857,7 @@ class NumLit private: Which which_; union { - Value scalar_; + JS::UninitializedValue scalar_; SimdConstant simd_; } u; @@ -880,7 +880,7 @@ class NumLit int32_t toInt32() const { MOZ_ASSERT(which_ == Fixnum || which_ == NegativeInt || which_ == BigUnsigned); - return u.scalar_.toInt32(); + return u.scalar_.asValueRef().toInt32(); } uint32_t toUint32() const { @@ -889,17 +889,17 @@ class NumLit RawF64 toDouble() const { MOZ_ASSERT(which_ == Double); - return RawF64(u.scalar_.toDouble()); + return RawF64(u.scalar_.asValueRef().toDouble()); } RawF32 toFloat() const { MOZ_ASSERT(which_ == Float); - return RawF32(float(u.scalar_.toDouble())); + return RawF32(float(u.scalar_.asValueRef().toDouble())); } Value scalarValue() const { MOZ_ASSERT(which_ != OutOfRangeInt); - return u.scalar_; + return u.scalar_.asValueRef(); } bool isSimd() const diff --git a/js/xpconnect/src/XPCWrappedNative.cpp b/js/xpconnect/src/XPCWrappedNative.cpp index acf92f3c3..a12e36baa 100644 --- a/js/xpconnect/src/XPCWrappedNative.cpp +++ b/js/xpconnect/src/XPCWrappedNative.cpp @@ -1785,9 +1785,12 @@ CallMethodHelper::ConvertIndependentParam(uint8_t i) // indirectly, regardless of in/out-ness. if (type_tag == nsXPTType::T_JSVAL) { // Root the value. - dp->val.j.setUndefined(); - if (!js::AddRawValueRoot(mCallContext, &dp->val.j, "XPCWrappedNative::CallMethod param")) + dp->val.j.asValueRef().setUndefined(); + if (!js::AddRawValueRoot(mCallContext, &dp->val.j.asValueRef(), + "XPCWrappedNative::CallMethod param")) + { return false; + } } // Flag cleanup for anything that isn't self-contained. diff --git a/mfbt/TextUtils.h b/mfbt/TextUtils.h new file mode 100644 index 000000000..9494296ce --- /dev/null +++ b/mfbt/TextUtils.h @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* Character/text operations. */ + +#ifndef mozilla_TextUtils_h +#define mozilla_TextUtils_h + +#include "mozilla/TypeTraits.h" + +namespace mozilla { + +namespace detail { + +template<typename Char> +class MakeUnsignedChar + : public MakeUnsigned<Char> +{}; + +template<> +class MakeUnsignedChar<char16_t> +{ +public: + using Type = char16_t; +}; + +template<> +class MakeUnsignedChar<char32_t> +{ +public: + using Type = char32_t; +}; + +} // namespace detail + +/** + * Returns true iff |aChar| matches [a-zA-Z]. + * + * This function is basically what you thought isalpha was, except its behavior + * doesn't depend on the user's current locale. + */ +template<typename Char> +constexpr bool +IsAsciiAlpha(Char aChar) +{ + using UnsignedChar = typename detail::MakeUnsignedChar<Char>::Type; + return ('a' <= static_cast<UnsignedChar>(aChar) && + static_cast<UnsignedChar>(aChar) <= 'z') || + ('A' <= static_cast<UnsignedChar>(aChar) && + static_cast<UnsignedChar>(aChar) <= 'Z'); +} + +} // namespace mozilla + +#endif /* mozilla_TextUtils_h */ diff --git a/mfbt/moz.build b/mfbt/moz.build index f23a3b6f5..897a686f4 100644 --- a/mfbt/moz.build +++ b/mfbt/moz.build @@ -87,6 +87,7 @@ EXPORTS.mozilla = [ 'StaticAnalysisFunctions.h', 'TaggedAnonymousMemory.h', 'TemplateLib.h', + 'TextUtils.h', 'ThreadLocal.h', 'ToString.h', 'Tuple.h', diff --git a/mfbt/tests/TestTextUtils.cpp b/mfbt/tests/TestTextUtils.cpp new file mode 100644 index 000000000..db481c138 --- /dev/null +++ b/mfbt/tests/TestTextUtils.cpp @@ -0,0 +1,106 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/Assertions.h" +#include "mozilla/TextUtils.h" + +using mozilla::IsAsciiAlpha; + +// char + +static_assert(!IsAsciiAlpha('@'), "'@' isn't ASCII alpha"); +static_assert('@' == 0x40, "'@' has value 0x40"); + +static_assert('A' == 0x41, "'A' has value 0x41"); +static_assert(IsAsciiAlpha('A'), "'A' is ASCII alpha"); +static_assert(IsAsciiAlpha('B'), "'B' is ASCII alpha"); +static_assert(IsAsciiAlpha('M'), "'M' is ASCII alpha"); +static_assert(IsAsciiAlpha('Y'), "'Y' is ASCII alpha"); +static_assert(IsAsciiAlpha('Z'), "'Z' is ASCII alpha"); + +static_assert('Z' == 0x5A, "'Z' has value 0x5A"); +static_assert('[' == 0x5B, "'[' has value 0x5B"); +static_assert(!IsAsciiAlpha('['), "'[' isn't ASCII alpha"); + +static_assert(!IsAsciiAlpha('`'), "'`' isn't ASCII alpha"); +static_assert('`' == 0x60, "'`' has value 0x60"); + +static_assert('a' == 0x61, "'a' has value 0x61"); +static_assert(IsAsciiAlpha('a'), "'a' is ASCII alpha"); +static_assert(IsAsciiAlpha('b'), "'b' is ASCII alpha"); +static_assert(IsAsciiAlpha('m'), "'m' is ASCII alpha"); +static_assert(IsAsciiAlpha('y'), "'y' is ASCII alpha"); +static_assert(IsAsciiAlpha('z'), "'z' is ASCII alpha"); + +static_assert('z' == 0x7A, "'z' has value 0x7A"); +static_assert('{' == 0x7B, "'{' has value 0x7B"); +static_assert(!IsAsciiAlpha('{'), "'{' isn't ASCII alpha"); + +// char16_t + +static_assert(!IsAsciiAlpha(u'@'), "u'@' isn't ASCII alpha"); +static_assert(u'@' == 0x40, "u'@' has value 0x40"); + +static_assert(u'A' == 0x41, "u'A' has value 0x41"); +static_assert(IsAsciiAlpha(u'A'), "u'A' is ASCII alpha"); +static_assert(IsAsciiAlpha(u'B'), "u'B' is ASCII alpha"); +static_assert(IsAsciiAlpha(u'M'), "u'M' is ASCII alpha"); +static_assert(IsAsciiAlpha(u'Y'), "u'Y' is ASCII alpha"); +static_assert(IsAsciiAlpha(u'Z'), "u'Z' is ASCII alpha"); + +static_assert(u'Z' == 0x5A, "u'Z' has value 0x5A"); +static_assert(u'[' == 0x5B, "u'[' has value 0x5B"); +static_assert(!IsAsciiAlpha(u'['), "u'[' isn't ASCII alpha"); + +static_assert(!IsAsciiAlpha(u'`'), "u'`' isn't ASCII alpha"); +static_assert(u'`' == 0x60, "u'`' has value 0x60"); + +static_assert(u'a' == 0x61, "u'a' has value 0x61"); +static_assert(IsAsciiAlpha(u'a'), "u'a' is ASCII alpha"); +static_assert(IsAsciiAlpha(u'b'), "u'b' is ASCII alpha"); +static_assert(IsAsciiAlpha(u'm'), "u'm' is ASCII alpha"); +static_assert(IsAsciiAlpha(u'y'), "u'y' is ASCII alpha"); +static_assert(IsAsciiAlpha(u'z'), "u'z' is ASCII alpha"); + +static_assert(u'z' == 0x7A, "u'z' has value 0x7A"); +static_assert(u'{' == 0x7B, "u'{' has value 0x7B"); +static_assert(!IsAsciiAlpha(u'{'), "u'{' isn't ASCII alpha"); + +// char32_t + +static_assert(!IsAsciiAlpha(U'@'), "U'@' isn't ASCII alpha"); +static_assert(U'@' == 0x40, "U'@' has value 0x40"); + +static_assert(U'A' == 0x41, "U'A' has value 0x41"); +static_assert(IsAsciiAlpha(U'A'), "U'A' is ASCII alpha"); +static_assert(IsAsciiAlpha(U'B'), "U'B' is ASCII alpha"); +static_assert(IsAsciiAlpha(U'M'), "U'M' is ASCII alpha"); +static_assert(IsAsciiAlpha(U'Y'), "U'Y' is ASCII alpha"); +static_assert(IsAsciiAlpha(U'Z'), "U'Z' is ASCII alpha"); + +static_assert(U'Z' == 0x5A, "U'Z' has value 0x5A"); +static_assert(U'[' == 0x5B, "U'[' has value 0x5B"); +static_assert(!IsAsciiAlpha(U'['), "U'[' isn't ASCII alpha"); + +static_assert(!IsAsciiAlpha(U'`'), "U'`' isn't ASCII alpha"); +static_assert(U'`' == 0x60, "U'`' has value 0x60"); + +static_assert(U'a' == 0x61, "U'a' has value 0x61"); +static_assert(IsAsciiAlpha(U'a'), "U'a' is ASCII alpha"); +static_assert(IsAsciiAlpha(U'b'), "U'b' is ASCII alpha"); +static_assert(IsAsciiAlpha(U'm'), "U'm' is ASCII alpha"); +static_assert(IsAsciiAlpha(U'y'), "U'y' is ASCII alpha"); +static_assert(IsAsciiAlpha(U'z'), "U'z' is ASCII alpha"); + +static_assert(U'z' == 0x7A, "U'z' has value 0x7A"); +static_assert(U'{' == 0x7B, "U'{' has value 0x7B"); +static_assert(!IsAsciiAlpha(U'{'), "U'{' isn't ASCII alpha"); + +int +main() +{ + return 0; +} diff --git a/mfbt/tests/moz.build b/mfbt/tests/moz.build index f96117e03..bd25ab1d0 100644 --- a/mfbt/tests/moz.build +++ b/mfbt/tests/moz.build @@ -42,6 +42,7 @@ CppUnitTests([ 'TestSHA1', 'TestSplayTree', 'TestTemplateLib', + 'TestTextUtils', 'TestTuple', 'TestTypedEnum', 'TestTypeTraits', diff --git a/moz.configure b/moz.configure index cecc1335e..64cdc8ac6 100644 --- a/moz.configure +++ b/moz.configure @@ -52,38 +52,6 @@ def compile_environment(compile_env): set_config('COMPILE_ENVIRONMENT', compile_environment) add_old_configure_assignment('COMPILE_ENVIRONMENT', compile_environment) -js_option('--disable-tests', - help='Do not build test libraries & programs') - -@depends('--disable-tests') -def enable_tests(value): - if value: - return True - -set_config('ENABLE_TESTS', enable_tests) -set_define('ENABLE_TESTS', enable_tests) - -@depends(enable_tests) -def gtest_has_rtti(value): - if value: - return '0' - -set_define('GTEST_HAS_RTTI', gtest_has_rtti) - -@depends(target, enable_tests) -def linux_gtest_defines(target, enable_tests): - if enable_tests and target.os == 'Android': - return namespace(os_linux_android=True, - use_own_tr1_tuple=True, - has_clone='0') - -set_define('GTEST_OS_LINUX_ANDROID', - delayed_getattr(linux_gtest_defines, 'os_linux_android')) -set_define('GTEST_USE_OWN_TR1_TUPLE', - delayed_getattr(linux_gtest_defines, 'use_own_tr1_tuple')) -set_define('GTEST_HAS_CLONE', - delayed_getattr(linux_gtest_defines, 'has_clone')) - js_option('--enable-debug', nargs='?', help='Enable building with developer debug info ' diff --git a/old-configure.in b/old-configure.in index d8a6d01f0..7d336d37f 100644 --- a/old-configure.in +++ b/old-configure.in @@ -2256,6 +2256,7 @@ dnl ======================================================== MOZ_ARG_HEADER(Application) +ENABLE_TESTS= ENABLE_SYSTEM_EXTENSION_DIRS=1 MOZ_BRANDING_DIRECTORY= MOZ_OFFICIAL_BRANDING= @@ -3794,6 +3795,32 @@ if test -n "$MOZ_UPDATER"; then fi dnl ======================================================== +dnl Build the tests? +dnl ======================================================== +MOZ_ARG_ENABLE_BOOL(tests, +[ --enable-tests Build test libraries & programs], + ENABLE_TESTS=1, + ENABLE_TESTS= ) + +if test -n "$ENABLE_TESTS"; then + GTEST_HAS_RTTI=0 + AC_DEFINE(ENABLE_TESTS) + AC_DEFINE_UNQUOTED(GTEST_HAS_RTTI, 0) + AC_SUBST(GTEST_HAS_RTTI) + if test -n "$_WIN32_MSVC"; then + AC_DEFINE_UNQUOTED(_VARIADIC_MAX, 10) + fi + if test "${OS_TARGET}" = "Android"; then + AC_DEFINE(GTEST_OS_LINUX_ANDROID) + AC_DEFINE(GTEST_USE_OWN_TR1_TUPLE) + AC_DEFINE_UNQUOTED(GTEST_HAS_CLONE, 0) + AC_SUBST(GTEST_OS_LINUX_ANDROID) + AC_SUBST(GTEST_USE_OWN_TR1_TUPLE) + AC_SUBST(GTEST_HAS_CLONE) + fi +fi + +dnl ======================================================== dnl parental controls (for Windows Vista) dnl ======================================================== MOZ_ARG_DISABLE_BOOL(parental-controls, @@ -5245,6 +5272,8 @@ AC_SUBST(LIBICONV) AC_SUBST(MOZ_TOOLKIT_SEARCH) AC_SUBST(MOZ_FEEDS) +AC_SUBST(ENABLE_TESTS) + AC_SUBST(MOZ_UNIVERSALCHARDET) AC_SUBST(ACCESSIBILITY) AC_SUBST(MOZ_SPELLCHECK) diff --git a/toolkit/mozapps/extensions/AddonPathService.cpp b/toolkit/mozapps/extensions/AddonPathService.cpp index 006149100..ddfdbe817 100644 --- a/toolkit/mozapps/extensions/AddonPathService.cpp +++ b/toolkit/mozapps/extensions/AddonPathService.cpp @@ -128,6 +128,16 @@ AddonPathService::InsertPath(const nsAString& path, const nsAString& addonIdStri return NS_OK; } +NS_IMETHODIMP +AddonPathService::MapURIToAddonId(nsIURI* aURI, nsAString& addonIdString) +{ + if (JSAddonId* id = MapURIToAddonID(aURI)) { + JSFlatString* flat = JS_ASSERT_STRING_IS_FLAT(JS::StringOfAddonId(id)); + AssignJSFlatString(addonIdString, flat); + } + return NS_OK; +} + static nsresult ResolveURI(nsIURI* aURI, nsAString& out) { diff --git a/toolkit/mozapps/extensions/amIAddonPathService.idl b/toolkit/mozapps/extensions/amIAddonPathService.idl index 863689858..9c9197a61 100644 --- a/toolkit/mozapps/extensions/amIAddonPathService.idl +++ b/toolkit/mozapps/extensions/amIAddonPathService.idl @@ -5,6 +5,8 @@ #include "nsISupports.idl" +interface nsIURI; + /** * This service maps file system paths where add-ons reside to the ID * of the add-on. Paths are added by the add-on manager. They can @@ -26,4 +28,10 @@ interface amIAddonPathService : nsISupports * associated with the given add-on ID. */ void insertPath(in AString path, in AString addonId); + + /** + * Given a URI to a file, return the ID of the add-on that the file belongs + * to. Returns an empty string if there is no add-on there. + */ + AString mapURIToAddonId(in nsIURI aURI); }; diff --git a/toolkit/mozapps/extensions/internal/XPIProvider.jsm b/toolkit/mozapps/extensions/internal/XPIProvider.jsm index c43811ba8..8b49c6600 100644 --- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm +++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm @@ -52,6 +52,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "ResProtocolHandler", "@mozilla.org/network/protocol;1?name=resource", "nsIResProtocolHandler"); +XPCOMUtils.defineLazyServiceGetter(this, + "AddonPathService", + "@mozilla.org/addon-path-service;1", + "amIAddonPathService"); const nsIFile = Components.Constructor("@mozilla.org/file/local;1", "nsIFile", "initWithPath"); @@ -1887,8 +1891,7 @@ this.XPIProvider = { logger.info("Mapping " + aID + " to " + aFile.path); this._addonFileMap.set(aID, aFile.path); - let service = Cc["@mozilla.org/addon-path-service;1"].getService(Ci.amIAddonPathService); - service.insertPath(aFile.path, aID); + AddonPathService.insertPath(aFile.path, aID); }, /** @@ -3916,16 +3919,8 @@ this.XPIProvider = { * @see amIAddonManager.mapURIToAddonID */ mapURIToAddonID: function XPI_mapURIToAddonID(aURI) { - let resolved = this._resolveURIToFile(aURI); - if (!resolved || !(resolved instanceof Ci.nsIFileURL)) - return null; - - for (let [id, path] of this._addonFileMap) { - if (resolved.file.path.startsWith(path)) - return id; - } - - return null; + // Returns `null` instead of empty string if the URI can't be mapped. + return AddonPathService.mapURIToAddonId(aURI) || null; }, /** diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_mapURIToAddonID.js b/toolkit/mozapps/extensions/test/xpcshell/test_mapURIToAddonID.js index a6f9c8052..a153256dc 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_mapURIToAddonID.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_mapURIToAddonID.js @@ -95,8 +95,10 @@ function run_test_early() { "resource://gre/modules/addons/XPIProvider.jsm", {}); // Make the early API call. - do_check_null(s.XPIProvider.mapURIToAddonID(uri)); + // AddonManager still misses its provider and so doesn't work yet. do_check_null(AddonManager.mapURIToAddonID(uri)); + // But calling XPIProvider directly works immediately + do_check_eq(s.XPIProvider.mapURIToAddonID(uri), id); // Actually start up the manager. startupManager(false); diff --git a/xpcom/reflect/xptcall/xptcall.h b/xpcom/reflect/xptcall/xptcall.h index 1f2367b5d..304787635 100644 --- a/xpcom/reflect/xptcall/xptcall.h +++ b/xpcom/reflect/xptcall/xptcall.h @@ -39,7 +39,7 @@ struct nsXPTCMiniVariant // Types below here are unknown to the assembly implementations, and // therefore _must_ be passed with indirect semantics. We put them in // the union here for type safety, so that we can avoid void* tricks. - JS::Value j; + JS::UninitializedValue j; } val; }; |