summaryrefslogtreecommitdiffstats
path: root/browser
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@gmail.com>2018-05-14 10:50:01 +0200
committerwolfbeast <mcwerewolf@gmail.com>2018-05-14 10:50:01 +0200
commite9dd029f5d00590e1a53e63b0ab805110a10b54c (patch)
tree1126ca5dda925a62be3dc12c99c90e953d08afcf /browser
parent9d6a7ae25d7f5da855a8f8df884de483b4e2a538 (diff)
parent36b8fd734f590eb726ca2e50f8d1ff9cc968b8e1 (diff)
downloadUXP-e9dd029f5d00590e1a53e63b0ab805110a10b54c.tar
UXP-e9dd029f5d00590e1a53e63b0ab805110a10b54c.tar.gz
UXP-e9dd029f5d00590e1a53e63b0ab805110a10b54c.tar.lz
UXP-e9dd029f5d00590e1a53e63b0ab805110a10b54c.tar.xz
UXP-e9dd029f5d00590e1a53e63b0ab805110a10b54c.zip
Merge branch 'master' into Basilisk-release
Diffstat (limited to 'browser')
-rw-r--r--browser/app/application.ini50
-rw-r--r--browser/app/moz.build16
-rw-r--r--browser/app/nsBrowserApp.cpp35
-rw-r--r--browser/app/profile/firefox.js94
-rw-r--r--browser/base/content/browser-addons.js65
-rwxr-xr-xbrowser/base/content/browser.js83
-rw-r--r--browser/base/content/content.js6
-rw-r--r--browser/base/content/nsContextMenu.js5
-rw-r--r--browser/base/content/tabbrowser.xml6
-rw-r--r--browser/base/content/utilityOverlay.js22
-rw-r--r--browser/branding/shared/uaoverrides.inc3
-rw-r--r--browser/branding/unofficial/basilisk.VisualElementsManifest.xml (renamed from browser/branding/unofficial/serpent.VisualElementsManifest.xml)0
-rw-r--r--browser/components/feeds/FeedConverter.js2
-rw-r--r--browser/components/preferences/fonts.xul3
-rw-r--r--browser/components/sessionstore/ContentRestore.jsm5
-rw-r--r--browser/components/sessionstore/SessionHistory.jsm5
-rw-r--r--browser/components/sessionstore/SessionMigration.jsm14
-rw-r--r--browser/components/sessionstore/SessionStore.jsm4
-rw-r--r--browser/installer/package-manifest.in20
-rw-r--r--browser/locales/en-US/chrome/browser/browser.properties2
-rw-r--r--browser/locales/en-US/chrome/browser/preferences/fonts.dtd1
-rw-r--r--browser/modules/ContentClick.jsm1
-rw-r--r--browser/themes/osx/shared.inc2
-rw-r--r--browser/themes/shared/tabs.inc.css5
24 files changed, 181 insertions, 268 deletions
diff --git a/browser/app/application.ini b/browser/app/application.ini
new file mode 100644
index 000000000..05317eee9
--- /dev/null
+++ b/browser/app/application.ini
@@ -0,0 +1,50 @@
+#if MOZ_APP_STATIC_INI
+#ifdef MOZ_BUILD_APP_IS_BROWSER
+; This file is not used. If you modify it and want the application to use
+; your modifications, move it under the browser/ subdirectory and start with
+; the "-app /path/to/browser/application.ini" argument.
+#else
+; This file is not used. If you modify it and want the application to use
+; your modifications, start with the "-app /path/to/application.ini"
+; argument.
+#endif
+#endif
+#if 0
+; 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/.
+#endif
+#filter substitution
+#include @TOPOBJDIR@/buildid.h
+#include @TOPOBJDIR@/source-repo.h
+
+[App]
+# Vendor=@MOZ_APP_VENDOR@
+Vendor=Moonchild Productions
+# Name=@MOZ_APP_BASENAME@
+Name=Basilisk
+RemotingName=@MOZ_APP_REMOTINGNAME@
+#ifdef MOZ_APP_DISPLAYNAME
+CodeName=@MOZ_APP_DISPLAYNAME@
+#endif
+Version=@MOZ_APP_VERSION@
+#ifdef MOZ_APP_PROFILE
+Profile=@MOZ_APP_PROFILE@
+#endif
+BuildID=@MOZ_BUILDID@
+#ifdef MOZ_SOURCE_REPO
+SourceRepository=@MOZ_SOURCE_REPO@
+#endif
+#ifdef MOZ_SOURCE_STAMP
+SourceStamp=@MOZ_SOURCE_STAMP@
+#endif
+ID=@MOZ_APP_ID@
+
+[Gecko]
+MinVersion=@GRE_MILESTONE@
+MaxVersion=@GRE_MILESTONE@
+
+[XRE]
+#ifdef MOZ_PROFILE_MIGRATOR
+EnableProfileMigrator=1
+#endif \ No newline at end of file
diff --git a/browser/app/moz.build b/browser/app/moz.build
index 520ce4425..1004e280c 100644
--- a/browser/app/moz.build
+++ b/browser/app/moz.build
@@ -48,22 +48,6 @@ if CONFIG['OS_ARCH'] == 'WINNT':
for cdm in CONFIG['MOZ_EME_MODULES']:
DEFINES['MOZ_%s_EME' % cdm.upper()] = True
-if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
- # For sandbox includes and the include dependencies those have
- LOCAL_INCLUDES += [
- '/security/sandbox/chromium',
- '/security/sandbox/chromium-shim',
- ]
-
- USE_LIBS += [
- 'sandbox_s',
- ]
-
- DELAYLOAD_DLLS += [
- 'winmm.dll',
- 'user32.dll',
- ]
-
# Control the default heap size.
# This is the heap returned by GetProcessHeap().
# As we use the CRT heap, the default size is too large and wastes VM.
diff --git a/browser/app/nsBrowserApp.cpp b/browser/app/nsBrowserApp.cpp
index 184b1fc2e..66ea8aed5 100644
--- a/browser/app/nsBrowserApp.cpp
+++ b/browser/app/nsBrowserApp.cpp
@@ -26,9 +26,6 @@
#ifdef XP_WIN
#define XRE_WANT_ENVIRON
#define strcasecmp _stricmp
-#ifdef MOZ_SANDBOX
-#include "mozilla/sandboxing/SandboxInitialization.h"
-#endif
#endif
#include "BinaryPath.h"
@@ -38,8 +35,7 @@
#include "mozilla/Telemetry.h"
#include "mozilla/WindowsDllBlocklist.h"
-#if !defined(MOZ_WIDGET_COCOA) && !defined(MOZ_WIDGET_ANDROID) \
- && !(defined(XP_LINUX) && defined(MOZ_SANDBOX))
+#if !defined(MOZ_WIDGET_COCOA) && !defined(MOZ_WIDGET_ANDROID)
#define MOZ_BROWSER_CAN_BE_CONTENTPROC
#include "../../ipc/contentproc/plugin-container.cpp"
#endif
@@ -201,13 +197,7 @@ static int do_main(int argc, char* argv[], char* envp[], nsIFile *xreDirectory)
argv[i] = argv[i + 1];
}
- XREShellData shellData;
-#if defined(XP_WIN) && defined(MOZ_SANDBOX)
- shellData.sandboxBrokerServices =
- sandboxing::GetInitializedBrokerServices();
-#endif
-
- return XRE_XPCShellMain(--argc, argv, envp, &shellData);
+ return XRE_XPCShellMain(--argc, argv, envp);
}
if (appini) {
@@ -257,18 +247,6 @@ static int do_main(int argc, char* argv[], char* envp[], nsIFile *xreDirectory)
DllBlocklist_CheckStatus() ? NS_XRE_DLL_BLOCKLIST_ENABLED : 0;
#endif
-#if defined(XP_WIN) && defined(MOZ_SANDBOX)
- sandbox::BrokerServices* brokerServices =
- sandboxing::GetInitializedBrokerServices();
-#if defined(MOZ_CONTENT_SANDBOX)
- if (!brokerServices) {
- Output("Couldn't initialize the broker services.\n");
- return 255;
- }
-#endif
- appData.sandboxBrokerServices = brokerServices;
-#endif
-
#ifdef LIBFUZZER
if (getenv("LIBFUZZER"))
XRE_LibFuzzerSetMain(argc, argv, libfuzzer_main);
@@ -370,15 +348,6 @@ int main(int argc, char* argv[], char* envp[])
// We are launching as a content process, delegate to the appropriate
// main
if (argc > 1 && IsArg(argv[1], "contentproc")) {
-#if defined(XP_WIN) && defined(MOZ_SANDBOX)
- // We need to initialize the sandbox TargetServices before InitXPCOMGlue
- // because we might need the sandbox broker to give access to some files.
- if (IsSandboxedProcess() && !sandboxing::GetInitializedTargetServices()) {
- Output("Failed to initialize the sandbox target services.");
- return 255;
- }
-#endif
-
nsresult rv = InitXPCOMGlue(argv[0], nullptr);
if (NS_FAILED(rv)) {
return 255;
diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js
index fb85a9fb9..1182741bd 100644
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -909,100 +909,6 @@ pref("dom.ipc.shims.enabledWarnings", false);
pref("browser.tabs.remote.autostart", false);
pref("browser.tabs.remote.desktopbehavior", true);
-#if defined(XP_WIN) && defined(MOZ_SANDBOX)
-// When this pref is true the Windows process sandbox will set up dummy
-// interceptions and log to the browser console when calls fail in the sandboxed
-// process and also if they are subsequently allowed by the broker process.
-// This will require a restart.
-pref("security.sandbox.windows.log", false);
-
-// Controls whether and how the Windows NPAPI plugin process is sandboxed.
-// To get a different setting for a particular plugin replace "default", with
-// the plugin's nice file name, see: nsPluginTag::GetNiceFileName.
-// On windows these levels are:
-// 0 - no sandbox
-// 1 - sandbox with USER_NON_ADMIN access token level
-// 2 - a more strict sandbox, which might cause functionality issues. This now
-// includes running at low integrity.
-// 3 - the strongest settings we seem to be able to use without breaking
-// everything, but will probably cause some functionality restrictions
-pref("dom.ipc.plugins.sandbox-level.default", 0);
-#if defined(_AMD64_)
-// The lines in PluginModuleParent.cpp should be changed in line with this.
-pref("dom.ipc.plugins.sandbox-level.flash", 2);
-#else
-pref("dom.ipc.plugins.sandbox-level.flash", 0);
-#endif
-
-#if defined(MOZ_CONTENT_SANDBOX)
-// This controls the strength of the Windows content process sandbox for testing
-// purposes. This will require a restart.
-// On windows these levels are:
-// See - security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
-// SetSecurityLevelForContentProcess() for what the different settings mean.
-#if defined(NIGHTLY_BUILD)
-pref("security.sandbox.content.level", 2);
-#else
-pref("security.sandbox.content.level", 1);
-#endif
-
-// This controls the depth of stack trace that is logged when Windows sandbox
-// logging is turned on. This is only currently available for the content
-// process because the only other sandbox (for GMP) has too strict a policy to
-// allow stack tracing. This does not require a restart to take effect.
-pref("security.sandbox.windows.log.stackTraceDepth", 0);
-#endif
-#endif
-
-#if defined(XP_MACOSX) && defined(MOZ_SANDBOX) && defined(MOZ_CONTENT_SANDBOX)
-// This pref is discussed in bug 1083344, the naming is inspired from its
-// Windows counterpart, but on Mac it's an integer which means:
-// 0 -> "no sandbox"
-// 1 -> "preliminary content sandboxing enabled: write access to
-// home directory is prevented"
-// 2 -> "preliminary content sandboxing enabled with profile protection:
-// write access to home directory is prevented, read and write access
-// to ~/Library and profile directories are prevented (excluding
-// $PROFILE/{extensions,weave})"
-// This setting is read when the content process is started. On Mac the content
-// process is killed when all windows are closed, so a change will take effect
-// when the 1st window is opened.
-#if defined(NIGHTLY_BUILD)
-pref("security.sandbox.content.level", 2);
-#else
-pref("security.sandbox.content.level", 1);
-#endif
-#endif
-
-#if defined(XP_LINUX) && defined(MOZ_SANDBOX) && defined(MOZ_CONTENT_SANDBOX)
-// This pref is introduced as part of bug 742434, the naming is inspired from
-// its Windows/Mac counterpart, but on Linux it's an integer which means:
-// 0 -> "no sandbox"
-// 1 -> "content sandbox using seccomp-bpf when available"
-// 2 -> "seccomp-bpf + file broker"
-// Content sandboxing on Linux is currently in the stage of
-// 'just getting it enabled', which includes a very permissive whitelist. We
-// enable seccomp-bpf on nightly to see if everything is running, or if we need
-// to whitelist more system calls.
-//
-// So the purpose of this setting is to allow nightly users to disable the
-// sandbox while we fix their problems. This way, they won't have to wait for
-// another nightly release which disables seccomp-bpf again.
-//
-// This setting may not be required anymore once we decide to permanently
-// enable the content sandbox.
-pref("security.sandbox.content.level", 2);
-#endif
-
-#if defined(XP_MACOSX) || defined(XP_WIN)
-#if defined(MOZ_SANDBOX) && defined(MOZ_CONTENT_SANDBOX)
-// ID (a UUID when set by gecko) that is used to form the name of a
-// sandbox-writable temporary directory to be used by content processes
-// when a temporary writable file is required in a level 1 sandbox.
-pref("security.sandbox.content.tempDirSuffix", "");
-#endif
-#endif
-
// This pref governs whether we attempt to work around problems caused by
// plugins using OS calls to manipulate the cursor while running out-of-
// process. These workarounds all involve intercepting (hooking) certain
diff --git a/browser/base/content/browser-addons.js b/browser/base/content/browser-addons.js
index 1f81d1fb0..1d881536a 100644
--- a/browser/base/content/browser-addons.js
+++ b/browser/base/content/browser-addons.js
@@ -459,15 +459,15 @@ var LightWeightThemeWebInstaller = {
switch (message.name) {
case "LightWeightThemeWebInstaller:Install": {
- this._installRequest(data.themeData, data.baseURI);
+ this._installRequest(data.themeData, data.principal, data.baseURI);
break;
}
case "LightWeightThemeWebInstaller:Preview": {
- this._preview(data.themeData, data.baseURI);
+ this._preview(data.themeData, data.principal, data.baseURI);
break;
}
case "LightWeightThemeWebInstaller:ResetPreview": {
- this._resetPreview(data && data.baseURI);
+ this._resetPreview(data && data.principal);
break;
}
}
@@ -489,33 +489,24 @@ var LightWeightThemeWebInstaller = {
return this._manager = temp.LightweightThemeManager;
},
- _installRequest: function (dataString, baseURI) {
+ _installRequest(dataString, principal, baseURI) {
+ // Don't allow installing off null principals.
+ if (!principal.URI) {
+ return;
+ }
+
let data = this._manager.parseTheme(dataString, baseURI);
if (!data) {
return;
}
- let uri = makeURI(baseURI);
-
// A notification bar with the option to undo is normally shown after a
// theme is installed. But the discovery pane served from the url(s)
// below has its own toggle switch for quick undos, so don't show the
// notification in that case.
- let notify = uri.prePath != "https://discovery.addons.mozilla.org";
- if (notify) {
- try {
- if (Services.prefs.getBoolPref("extensions.webapi.testing")
- && (uri.prePath == "https://discovery.addons.allizom.org"
- || uri.prePath == "https://discovery.addons-dev.allizom.org")) {
- notify = false;
- }
- } catch (e) {
- // getBoolPref() throws if the testing pref isn't set. ignore it.
- }
- }
-
- if (this._isAllowed(baseURI)) {
+ let notify = this._shouldShowUndoPrompt(principal);
+ if (this._isAllowed(principal)) {
this._install(data, notify);
return;
}
@@ -526,7 +517,7 @@ var LightWeightThemeWebInstaller = {
gNavigatorBundle.getString("lwthemeInstallRequest.allowButton.accesskey");
let message =
gNavigatorBundle.getFormattedString("lwthemeInstallRequest.message",
- [uri.host]);
+ [principal.URI.host]);
let buttons = [{
label: allowButtonText,
accessKey: allowButtonAccesskey,
@@ -629,8 +620,8 @@ var LightWeightThemeWebInstaller = {
});
},
- _preview: function (dataString, baseURI) {
- if (!this._isAllowed(baseURI))
+ _preview(dataString, principal, baseURI) {
+ if (!this._isAllowed(principal))
return;
let data = this._manager.parseTheme(dataString, baseURI);
@@ -642,29 +633,33 @@ var LightWeightThemeWebInstaller = {
this._manager.previewTheme(data);
},
- _resetPreview: function (baseURI) {
- if (baseURI && !this._isAllowed(baseURI))
+ _resetPreview(principal) {
+ if (!this._isAllowed(principal))
return;
gBrowser.tabContainer.removeEventListener("TabSelect", this, false);
this._manager.resetPreview();
},
- _isAllowed: function (srcURIString) {
- let uri;
- try {
- uri = makeURI(srcURIString);
- }
- catch (e) {
- // makeURI fails if srcURIString is a nonsense URI
+ _isAllowed(principal) {
+ if (!principal || !principal.URI || !principal.URI.schemeIs("https")) {
return false;
}
- if (!uri.schemeIs("https")) {
+ let pm = Services.perms;
+ return pm.testPermission(principal.URI, "install") == pm.ALLOW_ACTION;
+ },
+
+ _shouldShowUndoPrompt(principal) {
+ if (!principal || !principal.URI) {
+ return true;
+ }
+
+ let prePath = principal.URI.prePath;
+ if (prePath == "https://addons.palemoon.org") {
return false;
}
- let pm = Services.perms;
- return pm.testPermission(uri, "install") == pm.ALLOW_ACTION;
+ return true;
}
};
diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js
index 696a2871a..2380f5d21 100755
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -71,6 +71,10 @@ XPCOMUtils.defineLazyModuleGetter(this, "SafeBrowsing",
["gDNSService", "@mozilla.org/network/dns-service;1", "nsIDNSService"],
].forEach(([name, cc, ci]) => XPCOMUtils.defineLazyServiceGetter(this, name, cc, ci));
+XPCOMUtils.defineLazyServiceGetter(this, "gSerializationHelper",
+ "@mozilla.org/network/serialization-helper;1",
+ "nsISerializationHelper");
+
XPCOMUtils.defineLazyGetter(this, "BrowserToolboxProcess", function() {
let tmp = {};
Cu.import("resource://devtools/client/framework/ToolboxProcess.jsm", tmp);
@@ -807,6 +811,7 @@ function _loadURIWithFlags(browser, uri, params) {
if (!uri) {
uri = "about:blank";
}
+ let triggeringPrincipal = params.triggeringPrincipal || null;
let flags = params.flags || 0;
let referrer = params.referrerURI;
let referrerPolicy = ('referrerPolicy' in params ? params.referrerPolicy :
@@ -831,7 +836,7 @@ function _loadURIWithFlags(browser, uri, params) {
browser.webNavigation.loadURIWithOptions(uri, flags,
referrer, referrerPolicy,
- postData, null, null);
+ postData, null, null, triggeringPrincipal);
} else {
// Check if the current browser is allowed to unload.
let {permitUnload, timedOut} = browser.permitUnload();
@@ -845,6 +850,9 @@ function _loadURIWithFlags(browser, uri, params) {
let loadParams = {
uri: uri,
+ triggeringPrincipal: triggeringPrincipal
+ ? gSerializationHelper.serializeToString(triggeringPrincipal)
+ : null,
flags: flags,
referrer: referrer ? referrer.spec : null,
referrerPolicy: referrerPolicy,
@@ -872,7 +880,7 @@ function _loadURIWithFlags(browser, uri, params) {
}
browser.webNavigation.loadURIWithOptions(uri, flags, referrer, referrerPolicy,
- postData, null, null);
+ postData, null, null, triggeringPrincipal);
} else {
throw e;
}
@@ -1164,6 +1172,7 @@ var gBrowserInit = {
// [5]: referrerPolicy (int)
// [6]: userContextId (int)
// [7]: originPrincipal (nsIPrincipal)
+ // [8]: triggeringPrincipal (nsIPrincipal)
else if (window.arguments.length >= 3) {
let referrerURI = window.arguments[2];
if (typeof(referrerURI) == "string") {
@@ -1181,7 +1190,7 @@ var gBrowserInit = {
window.arguments[4] || false, referrerPolicy, userContextId,
// pass the origin principal (if any) and force its use to create
// an initial about:blank viewer if present:
- window.arguments[7], !!window.arguments[7]);
+ window.arguments[7], !!window.arguments[7], window.arguments[8]);
window.focus();
}
// Note: loadOneOrMoreURIs *must not* be called if window.arguments.length >= 3.
@@ -2067,7 +2076,8 @@ function BrowserTryToCloseWindow()
}
function loadURI(uri, referrer, postData, allowThirdPartyFixup, referrerPolicy,
- userContextId, originPrincipal, forceAboutBlankViewerInCurrent) {
+ userContextId, originPrincipal, forceAboutBlankViewerInCurrent,
+ triggeringPrincipal) {
try {
openLinkIn(uri, "current",
{ referrerURI: referrer,
@@ -2076,6 +2086,7 @@ function loadURI(uri, referrer, postData, allowThirdPartyFixup, referrerPolicy,
allowThirdPartyFixup: allowThirdPartyFixup,
userContextId: userContextId,
originPrincipal,
+ triggeringPrincipal,
forceAboutBlankViewerInCurrent,
});
} catch (e) {}
@@ -2779,24 +2790,6 @@ var BrowserOnClick = {
}
},
- handleEvent: function (event) {
- if (!event.isTrusted || // Don't trust synthetic events
- event.button == 2) {
- return;
- }
-
- let originalTarget = event.originalTarget;
- let ownerDoc = originalTarget.ownerDocument;
- if (!ownerDoc) {
- return;
- }
-
- if (gMultiProcessBrowser &&
- ownerDoc.documentURI.toLowerCase() == "about:newtab") {
- this.onE10sAboutNewTab(event, ownerDoc);
- }
- },
-
receiveMessage: function (msg) {
switch (msg.name) {
case "Browser:CertExceptionError":
@@ -2990,28 +2983,6 @@ var BrowserOnClick = {
}
},
- /**
- * This functions prevents navigation from happening directly through the <a>
- * link in about:newtab (which is loaded in the parent and therefore would load
- * the next page also in the parent) and instructs the browser to open the url
- * in the current tab which will make it update the remoteness of the tab.
- */
- onE10sAboutNewTab: function(event, ownerDoc) {
- let isTopFrame = (ownerDoc.defaultView.parent === ownerDoc.defaultView);
- if (!isTopFrame) {
- return;
- }
-
- let anchorTarget = event.originalTarget.parentNode;
-
- if (anchorTarget instanceof HTMLAnchorElement &&
- anchorTarget.classList.contains("newtab-link")) {
- event.preventDefault();
- let where = whereToOpenLink(event, false, false);
- openLinkIn(anchorTarget.href, where, { charset: ownerDoc.characterSet, referrerURI: ownerDoc.documentURIObject });
- }
- },
-
ignoreWarningButton: function (reason) {
// Allow users to override and continue through to the site,
// but add a notify bar as a reminder, so that they don't lose
@@ -4809,13 +4780,9 @@ var TabsProgressListener = {
}
}
- // Attach a listener to watch for "click" events bubbling up from error
- // pages and other similar pages (like about:newtab). This lets us fix bugs
- // like 401575 which require error page UI to do privileged things, without
- // letting error pages have any privilege themselves.
- // We can't look for this during onLocationChange since at that point the
- // document URI is not yet the about:-uri of the error page.
-
+ // We used to listen for clicks in the browser here, but when that
+ // became unnecessary, removing the code below caused focus issues.
+ // This code should be removed. Tracked in bug 1337794.
let isRemoteBrowser = aBrowser.isRemoteBrowser;
// We check isRemoteBrowser here to avoid requesting the doc CPOW
let doc = isRemoteBrowser ? null : aWebProgress.DOMWindow.document;
@@ -4830,11 +4797,9 @@ var TabsProgressListener = {
// STATE_STOP may be received twice for documents, thus store an
// attribute to ensure handling it just once.
doc.documentElement.setAttribute("hasBrowserHandlers", "true");
- aBrowser.addEventListener("click", BrowserOnClick, true);
aBrowser.addEventListener("pagehide", function onPageHide(event) {
if (event.target.defaultView.frameElement)
return;
- aBrowser.removeEventListener("click", BrowserOnClick, true);
aBrowser.removeEventListener("pagehide", onPageHide, true);
if (event.target.documentElement)
event.target.documentElement.removeAttribute("hasBrowserHandlers");
@@ -4883,7 +4848,7 @@ nsBrowserAccess.prototype = {
_openURIInNewTab: function(aURI, aReferrer, aReferrerPolicy, aIsPrivate,
aIsExternal, aForceNotRemote=false,
aUserContextId=Ci.nsIScriptSecurityManager.DEFAULT_USER_CONTEXT_ID,
- aOpener=null) {
+ aOpener = null, aTriggeringPrincipal = null) {
let win, needToFocusWin;
// try the current window. if we're in a popup, fall back on the most recent browser window
@@ -4908,6 +4873,7 @@ nsBrowserAccess.prototype = {
let loadInBackground = gPrefService.getBoolPref("browser.tabs.loadDivertedInBackground");
let tab = win.gBrowser.loadOneTab(aURI ? aURI.spec : "about:blank", {
+ triggeringPrincipal: aTriggeringPrincipal,
referrerURI: aReferrer,
referrerPolicy: aReferrerPolicy,
userContextId: aUserContextId,
@@ -4956,9 +4922,11 @@ nsBrowserAccess.prototype = {
}
let referrer = aOpener ? makeURI(aOpener.location.href) : null;
+ let triggeringPrincipal = null;
let referrerPolicy = Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT;
if (aOpener && aOpener.document) {
referrerPolicy = aOpener.document.referrerPolicy;
+ triggeringPrincipal = aOpener.document.nodePrincipal;
}
let isPrivate = aOpener
? PrivateBrowsingUtils.isContentWindowPrivate(aOpener)
@@ -4992,7 +4960,7 @@ nsBrowserAccess.prototype = {
let browser = this._openURIInNewTab(aURI, referrer, referrerPolicy,
isPrivate, isExternal,
forceNotRemote, userContextId,
- openerWindow);
+ openerWindow, triggeringPrincipal);
if (browser)
newWindow = browser.contentWindow;
break;
@@ -5003,6 +4971,7 @@ nsBrowserAccess.prototype = {
Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL :
Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
gBrowser.loadURIWithFlags(aURI.spec, {
+ triggeringPrincipal,
flags: loadflags,
referrerURI: referrer,
referrerPolicy: referrerPolicy,
@@ -5031,7 +5000,8 @@ nsBrowserAccess.prototype = {
aParams.referrerPolicy,
aParams.isPrivate,
isExternal, false,
- userContextId);
+ userContextId, null,
+ aParams.triggeringPrincipal);
if (browser)
return browser.QueryInterface(Ci.nsIFrameLoaderOwner);
@@ -5584,6 +5554,7 @@ function handleLinkClick(event, href, linkNode) {
referrerPolicy: referrerPolicy,
noReferrer: BrowserUtils.linkHasNoReferrer(linkNode),
originPrincipal: doc.nodePrincipal,
+ triggeringPrincipal: doc.nodePrincipal,
};
// The new tab/window must use the same userContextId
diff --git a/browser/base/content/content.js b/browser/base/content/content.js
index 8d6f0745e..496e0d111 100644
--- a/browser/base/content/content.js
+++ b/browser/base/content/content.js
@@ -482,6 +482,7 @@ var ClickEventHandler = {
ctrlKey: event.ctrlKey, metaKey: event.metaKey,
altKey: event.altKey, href: null, title: null,
bookmark: false, referrerPolicy: referrerPolicy,
+ triggeringPrincipal: principal,
originAttributes: principal ? principal.originAttributes : {},
isContentWindowPrivate: PrivateBrowsingUtils.isContentWindowPrivate(ownerDoc.defaultView)};
@@ -521,6 +522,7 @@ var ClickEventHandler = {
} catch (e) {}
}
json.originPrincipal = ownerDoc.nodePrincipal;
+ json.triggeringPrincipal = ownerDoc.nodePrincipal;
sendAsyncMessage("Content:Click", json);
return;
@@ -894,6 +896,7 @@ var LightWeightThemeWebInstallListener = {
case "InstallBrowserTheme": {
sendAsyncMessage("LightWeightThemeWebInstaller:Install", {
baseURI: event.target.baseURI,
+ principal: event.target.nodePrincipal,
themeData: event.target.getAttribute("data-browsertheme"),
});
break;
@@ -901,6 +904,7 @@ var LightWeightThemeWebInstallListener = {
case "PreviewBrowserTheme": {
sendAsyncMessage("LightWeightThemeWebInstaller:Preview", {
baseURI: event.target.baseURI,
+ principal: event.target.nodePrincipal,
themeData: event.target.getAttribute("data-browsertheme"),
});
this._previewWindow = event.target.ownerGlobal;
@@ -915,7 +919,7 @@ var LightWeightThemeWebInstallListener = {
case "ResetBrowserThemePreview": {
if (this._previewWindow) {
sendAsyncMessage("LightWeightThemeWebInstaller:ResetPreview",
- {baseURI: event.target.baseURI});
+ {principal: event.target.nodePrincipal});
this._resetPreviewWindow();
}
break;
diff --git a/browser/base/content/nsContextMenu.js b/browser/base/content/nsContextMenu.js
index ddf695202..955184f64 100644
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -968,6 +968,7 @@ nsContextMenu.prototype = {
_openLinkInParameters : function (extra) {
let params = { charset: gContextMenuContentData.charSet,
originPrincipal: this.principal,
+ triggeringPrincipal: this.principal,
referrerURI: gContextMenuContentData.documentURIObject,
referrerPolicy: gContextMenuContentData.referrerPolicy,
noReferrer: this.linkHasNoReferrer };
@@ -1147,10 +1148,12 @@ nsContextMenu.prototype = {
// Change current window to the URL of the image, video, or audio.
viewMedia: function(e) {
let referrerURI = gContextMenuContentData.documentURIObject;
+ let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
if (this.onCanvas) {
this._canvasToBlobURL(this.target).then(function(blobURL) {
openUILink(blobURL, e, { disallowInheritPrincipal: true,
- referrerURI: referrerURI });
+ referrerURI: referrerURI,
+ triggeringPrincipal: systemPrincipal});
}, Cu.reportError);
}
else {
diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml
index b27846835..463e74a52 100644
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -1513,6 +1513,7 @@
<parameter name="aAllowThirdPartyFixup"/>
<body>
<![CDATA[
+ var aTriggeringPrincipal;
var aReferrerPolicy;
var aFromExternal;
var aRelatedToCurrent;
@@ -1528,6 +1529,7 @@
typeof arguments[1] == "object" &&
!(arguments[1] instanceof Ci.nsIURI)) {
let params = arguments[1];
+ aTriggeringPrincipal = params.triggeringPrincipal
aReferrerURI = params.referrerURI;
aReferrerPolicy = params.referrerPolicy;
aCharset = params.charset;
@@ -1550,6 +1552,7 @@
Services.prefs.getBoolPref("browser.tabs.loadInBackground");
var owner = bgLoad ? null : this.selectedTab;
var tab = this.addTab(aURI, {
+ triggeringPrincipal: aTriggeringPrincipal,
referrerURI: aReferrerURI,
referrerPolicy: aReferrerPolicy,
charset: aCharset,
@@ -2120,6 +2123,7 @@
"use strict";
const NS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+ var aTriggeringPrincipal;
var aReferrerPolicy;
var aFromExternal;
var aRelatedToCurrent;
@@ -2136,6 +2140,7 @@
typeof arguments[1] == "object" &&
!(arguments[1] instanceof Ci.nsIURI)) {
let params = arguments[1];
+ aTriggeringPrincipal = params.triggeringPrincipal;
aReferrerURI = params.referrerURI;
aReferrerPolicy = params.referrerPolicy;
aCharset = params.charset;
@@ -2267,6 +2272,7 @@
try {
b.loadURIWithFlags(aURI, {
flags,
+ triggeringPrincipal: aTriggeringPrincipal,
referrerURI: aNoReferrer ? null: aReferrerURI,
referrerPolicy: aReferrerPolicy,
charset: aCharset,
diff --git a/browser/base/content/utilityOverlay.js b/browser/base/content/utilityOverlay.js
index 6ceaf773e..b041915a7 100644
--- a/browser/base/content/utilityOverlay.js
+++ b/browser/base/content/utilityOverlay.js
@@ -225,6 +225,7 @@ function openLinkIn(url, where, params) {
var aUserContextId = params.userContextId;
var aIndicateErrorPageLoad = params.indicateErrorPageLoad;
var aPrincipal = params.originPrincipal;
+ var aTriggeringPrincipal = params.triggeringPrincipal;
var aForceAboutBlankViewerInCurrent =
params.forceAboutBlankViewerInCurrent;
@@ -259,6 +260,24 @@ function openLinkIn(url, where, params) {
return;
}
+ // Teach the principal about the right OA to use, e.g. in case when
+ // opening a link in a new private window, or in a new container tab.
+ // Please note we do not have to do that for SystemPrincipals and we
+ // can not do it for NullPrincipals since NullPrincipals are only
+ // identical if they actually are the same object (See Bug: 1346759)
+ function useOAForPrincipal(principal) {
+ if (principal && principal.isCodebasePrincipal) {
+ let attrs = {
+ userContextId: aUserContextId,
+ privateBrowsingId: aIsPrivate || (w && PrivateBrowsingUtils.isWindowPrivate(w)),
+ };
+ return Services.scriptSecurityManager.createCodebasePrincipal(principal.URI, attrs);
+ }
+ return principal;
+ }
+ aPrincipal = useOAForPrincipal(aPrincipal);
+ aTriggeringPrincipal = useOAForPrincipal(aTriggeringPrincipal);
+
if (!w || where == "window") {
// Strip referrer data when opening a new private window, to prevent
// regular browsing data from leaking into it.
@@ -308,6 +327,7 @@ function openLinkIn(url, where, params) {
sa.appendElement(referrerPolicySupports, /* weak =*/ false);
sa.appendElement(userContextIdSupports, /* weak =*/ false);
sa.appendElement(aPrincipal, /* weak =*/ false);
+ sa.appendElement(aTriggeringPrincipal, /* weak =*/ false);
let features = "chrome,dialog=no,all";
if (aIsPrivate) {
@@ -394,6 +414,7 @@ function openLinkIn(url, where, params) {
}
aCurrentBrowser.loadURIWithFlags(url, {
+ triggeringPrincipal: aTriggeringPrincipal,
flags: flags,
referrerURI: aNoReferrer ? null : aReferrerURI,
referrerPolicy: aReferrerPolicy,
@@ -419,6 +440,7 @@ function openLinkIn(url, where, params) {
noReferrer: aNoReferrer,
userContextId: aUserContextId,
originPrincipal: aPrincipal,
+ triggeringPrincipal: aTriggeringPrincipal,
});
browserUsedForLoad = tabUsedForLoad.linkedBrowser;
break;
diff --git a/browser/branding/shared/uaoverrides.inc b/browser/branding/shared/uaoverrides.inc
index 59e413728..f7f7fafa3 100644
--- a/browser/branding/shared/uaoverrides.inc
+++ b/browser/branding/shared/uaoverrides.inc
@@ -19,8 +19,9 @@
#define OS_SLICE Windows NT 6.1; WOW64;
#endif
-// FxA override
+// Mozilla overrides
pref("@GUAO_PREF@.accounts.firefox.com", "Mozilla/5.0 (@OS_SLICE@ rv:@GK_VERSION@) @GK_SLICE@ @FX_SLICE@");
+pref("@GUAO_PREF@.addons.mozilla.org", "Mozilla/5.0 (@OS_SLICE@ rv:@GK_VERSION@) @GK_SLICE@ @FX_SLICE@");
// Required for domains that have proven unresponsive to requests from users
diff --git a/browser/branding/unofficial/serpent.VisualElementsManifest.xml b/browser/branding/unofficial/basilisk.VisualElementsManifest.xml
index 5046ee7da..5046ee7da 100644
--- a/browser/branding/unofficial/serpent.VisualElementsManifest.xml
+++ b/browser/branding/unofficial/basilisk.VisualElementsManifest.xml
diff --git a/browser/components/feeds/FeedConverter.js b/browser/components/feeds/FeedConverter.js
index aa70620d4..c2c565608 100644
--- a/browser/components/feeds/FeedConverter.js
+++ b/browser/components/feeds/FeedConverter.js
@@ -264,7 +264,7 @@ FeedConverter.prototype = {
}
chromeChannel.loadGroup = this._request.loadGroup;
- chromeChannel.asyncOpen(this._listener, null);
+ chromeChannel.asyncOpen2(this._listener);
}
finally {
this._releaseHandles();
diff --git a/browser/components/preferences/fonts.xul b/browser/components/preferences/fonts.xul
index ed1d1ecc2..26b1c6547 100644
--- a/browser/components/preferences/fonts.xul
+++ b/browser/components/preferences/fonts.xul
@@ -255,7 +255,8 @@
control="DefaultCharsetList"/>
<menulist id="DefaultCharsetList" preference="intl.charset.fallback.override">
<menupopup>
- <menuitem label="&languages.customize.Fallback.auto;" value=""/>
+ <menuitem label="&languages.customize.Fallback.auto;" value="*"/>
+ <menuitem label="&languages.customize.Fallback.utf8;" value="UTF-8"/>
<menuitem label="&languages.customize.Fallback.arabic;" value="windows-1256"/>
<menuitem label="&languages.customize.Fallback.baltic;" value="windows-1257"/>
<menuitem label="&languages.customize.Fallback.ceiso;" value="ISO-8859-2"/>
diff --git a/browser/components/sessionstore/ContentRestore.jsm b/browser/components/sessionstore/ContentRestore.jsm
index 976016770..d4972bcaf 100644
--- a/browser/components/sessionstore/ContentRestore.jsm
+++ b/browser/components/sessionstore/ContentRestore.jsm
@@ -204,6 +204,9 @@ ContentRestoreInternal.prototype = {
: Ci.nsIHttpChannel.REFERRER_POLICY_DEFAULT);
let postData = loadArguments.postData ?
Utils.makeInputStream(loadArguments.postData) : null;
+ let triggeringPrincipal = loadArguments.triggeringPrincipal
+ ? Utils.deserializePrincipal(loadArguments.triggeringPrincipal)
+ : null;
if (loadArguments.userContextId) {
webNavigation.setOriginAttributesBeforeLoading({ userContextId: loadArguments.userContextId });
@@ -211,7 +214,7 @@ ContentRestoreInternal.prototype = {
webNavigation.loadURIWithOptions(loadArguments.uri, loadArguments.flags,
referrer, referrerPolicy, postData,
- null, null);
+ null, null, triggeringPrincipal);
} else if (tabData.userTypedValue && tabData.userTypedClear) {
// If the user typed a URL into the URL bar and hit enter right before
// we crashed, we want to start loading that page again. A non-zero
diff --git a/browser/components/sessionstore/SessionHistory.jsm b/browser/components/sessionstore/SessionHistory.jsm
index aa9c10379..3d28d87db 100644
--- a/browser/components/sessionstore/SessionHistory.jsm
+++ b/browser/components/sessionstore/SessionHistory.jsm
@@ -95,7 +95,10 @@ var SessionHistoryInternal = {
// record it. For about:blank we explicitly want an empty array without
// an 'index' property to denote that there are no history entries.
if (uri != "about:blank" || (body && body.hasChildNodes())) {
- data.entries.push({ url: uri });
+ data.entries.push({
+ url: uri,
+ triggeringPrincipal_base64: Utils.SERIALIZED_SYSTEMPRINCIPAL
+ });
data.index = 1;
}
}
diff --git a/browser/components/sessionstore/SessionMigration.jsm b/browser/components/sessionstore/SessionMigration.jsm
index ff339eba9..1aa22f1a9 100644
--- a/browser/components/sessionstore/SessionMigration.jsm
+++ b/browser/components/sessionstore/SessionMigration.jsm
@@ -11,6 +11,9 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm", this);
Cu.import("resource://gre/modules/Task.jsm", this);
Cu.import("resource://gre/modules/osfile.jsm", this);
+XPCOMUtils.defineLazyModuleGetter(this, "Utils",
+ "resource://gre/modules/sessionstore/Utils.jsm");
+
// An encoder to UTF-8.
XPCOMUtils.defineLazyGetter(this, "gEncoder", function () {
return new TextEncoder();
@@ -27,7 +30,7 @@ var SessionMigrationInternal = {
* only contain:
* - open windows
* - with tabs
- * - with history entries with only title, url
+ * - with history entries with only title, url, triggeringPrincipal
* - with pinned state
* - with tab group info (hidden + group id)
* - with selected tab info
@@ -45,9 +48,11 @@ var SessionMigrationInternal = {
var win = {extData: {}};
win.tabs = oldWin.tabs.map(function(oldTab) {
var tab = {};
- // Keep only titles and urls for history entries
+ // Keep only titles, urls and triggeringPrincipals for history entries
tab.entries = oldTab.entries.map(function(entry) {
- return {url: entry.url, title: entry.title};
+ return { url: entry.url,
+ triggeringPrincipal_base64: entry.triggeringPrincipal_base64,
+ title: entry.title };
});
tab.index = oldTab.index;
tab.hidden = oldTab.hidden;
@@ -60,7 +65,8 @@ var SessionMigrationInternal = {
});
let url = "about:welcomeback";
let formdata = {id: {sessionData: state}, url};
- return {windows: [{tabs: [{entries: [{url}], formdata}]}]};
+ let entry = { url, triggeringPrincipal_base64: Utils.SERIALIZED_SYSTEMPRINCIPAL };
+ return { windows: [{ tabs: [{ entries: [ entry ], formdata}]}]};
},
/**
* Asynchronously read session restore state (JSON) from a path
diff --git a/browser/components/sessionstore/SessionStore.jsm b/browser/components/sessionstore/SessionStore.jsm
index 93e21357f..6b30943f3 100644
--- a/browser/components/sessionstore/SessionStore.jsm
+++ b/browser/components/sessionstore/SessionStore.jsm
@@ -603,12 +603,14 @@ var SessionStoreInternal = {
// replace the crashed session with a restore-page-only session
let url = "about:sessionrestore";
let formdata = {id: {sessionData: state}, url};
- state = { windows: [{ tabs: [{ entries: [{url}], formdata }] }] };
+ let entry = {url, triggeringPrincipal_base64: Utils.SERIALIZED_SYSTEMPRINCIPAL };
+ state = { windows: [{ tabs: [{ entries: [entry], formdata }] }] };
} else if (this._hasSingleTabWithURL(state.windows,
"about:welcomeback")) {
// On a single about:welcomeback URL that crashed, replace about:welcomeback
// with about:sessionrestore, to make clear to the user that we crashed.
state.windows[0].tabs[0].entries[0].url = "about:sessionrestore";
+ state.windows[0].tabs[0].entries[0].triggeringPrincipal_base64 = Utils.SERIALIZED_SYSTEMPRINCIPAL;
}
}
diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in
index 5540feed9..4ef8942b5 100644
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -2,7 +2,7 @@
; 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/.
-; Package file for the Firefox build.
+; Package file for the Basilisk build.
;
; Packaging manifest is used to copy files from dist/bin
; to the staging directory.
@@ -260,9 +260,6 @@
@RESPATH@/browser/components/migration.xpt
@RESPATH@/components/mimetype.xpt
@RESPATH@/components/mozfind.xpt
-#ifdef ENABLE_INTL_API
-@RESPATH@/components/mozintl.xpt
-#endif
@RESPATH@/components/necko_about.xpt
@RESPATH@/components/necko_cache.xpt
@RESPATH@/components/necko_cache2.xpt
@@ -740,21 +737,6 @@
@RESPATH@/components/pipnss.xpt
@RESPATH@/components/pippki.xpt
-; For process sandboxing
-#if defined(MOZ_SANDBOX)
-#if defined(XP_WIN)
-#if defined(WOW_HELPER)
-@BINPATH@/wow_helper.exe
-#endif
-#endif
-#endif
-
-#if defined(MOZ_SANDBOX)
-#if defined(XP_LINUX)
-@BINPATH@/@DLL_PREFIX@mozsandbox@DLL_SUFFIX@
-#endif
-#endif
-
; for Solaris SPARC
#ifdef SOLARIS
bin/libfreebl_32fpu_3.so
diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties
index 31f61632b..f7f3e9339 100644
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -85,12 +85,14 @@ addonInstallError-2=The add-on could not be installed because it does not match
addonInstallError-3=The add-on downloaded from this site could not be installed because it appears to be corrupt.
addonInstallError-4=%2$S could not be installed because %1$S cannot modify the needed file.
addonInstallError-5=%1$S has prevented this site from installing an unverified add-on.
+addonInstallError-8=%2$S could not be installed because %1$S does not support Jetpack (SDK) extensions.
addonInstallError-9=%2$S could not be installed because %1$S does not support WebExtensions.
addonLocalInstallError-1=This add-on could not be installed because of a filesystem error.
addonLocalInstallError-2=This add-on could not be installed because it does not match the add-on %1$S expected.
addonLocalInstallError-3=This add-on could not be installed because it appears to be corrupt.
addonLocalInstallError-4=%2$S could not be installed because %1$S cannot modify the needed file.
addonLocalInstallError-5=This add-on could not be installed because it has not been verified.
+addonLocalInstallError-8=%2$S could not be installed because %1$S does not support Jetpack (SDK) extensions.
addonLocalInstallError-9=%2$S could not be installed because %1$S does not support WebExtensions.
diff --git a/browser/locales/en-US/chrome/browser/preferences/fonts.dtd b/browser/locales/en-US/chrome/browser/preferences/fonts.dtd
index 98d697d35..d55bcde8b 100644
--- a/browser/locales/en-US/chrome/browser/preferences/fonts.dtd
+++ b/browser/locales/en-US/chrome/browser/preferences/fonts.dtd
@@ -70,6 +70,7 @@
<!ENTITY languages.customize.Fallback2.desc "This text encoding is used for legacy content that fails to declare its encoding.">
<!ENTITY languages.customize.Fallback.auto "Default for Current Locale">
+<!ENTITY languages.customize.Fallback.utf8 "UTF-8">
<!-- LOCALIZATION NOTE (languages.customize.Fallback.arabic):
Translate "Arabic" as an adjective for an encoding, not as the name of the language. -->
<!ENTITY languages.customize.Fallback.arabic "Arabic">
diff --git a/browser/modules/ContentClick.jsm b/browser/modules/ContentClick.jsm
index 8abc32525..40101d5d3 100644
--- a/browser/modules/ContentClick.jsm
+++ b/browser/modules/ContentClick.jsm
@@ -85,6 +85,7 @@ var ContentClick = {
allowMixedContent: json.allowMixedContent,
isContentWindowPrivate: json.isContentWindowPrivate,
originPrincipal: json.originPrincipal,
+ triggeringPrincipal: json.triggeringPrincipal,
};
// The new tab/window must use the same userContextId.
diff --git a/browser/themes/osx/shared.inc b/browser/themes/osx/shared.inc
index 3076450e2..b3ea4e199 100644
--- a/browser/themes/osx/shared.inc
+++ b/browser/themes/osx/shared.inc
@@ -1,4 +1,4 @@
-%include ../../../../toolkit/themes/osx/global/shared.inc
+%include ../../../toolkit/themes/osx/global/shared.inc
%include ../shared/browser.inc
%filter substitution
diff --git a/browser/themes/shared/tabs.inc.css b/browser/themes/shared/tabs.inc.css
index 632a6e606..c505416e4 100644
--- a/browser/themes/shared/tabs.inc.css
+++ b/browser/themes/shared/tabs.inc.css
@@ -55,8 +55,9 @@
.tab-background-middle {
-moz-box-flex: 1;
background-clip: padding-box;
- border-left: @tabCurveHalfWidth@ solid transparent;
- border-right: @tabCurveHalfWidth@ solid transparent;
+ /* Deliberately create a 1px overlap left/right to cover rounding gaps */
+ border-left: calc(@tabCurveHalfWidth@ - 1px) solid transparent;
+ border-right: calc(@tabCurveHalfWidth@ - 1px) solid transparent;
margin: 0 -@tabCurveHalfWidth@;
}