Merge autoland to mozilla-central. a=merge
Merge autoland to mozilla-central. a=merge
--- a/browser/app/moz.build
+++ b/browser/app/moz.build
@@ -79,21 +79,16 @@ if CONFIG['OS_ARCH'] == 'WINNT':
LOCAL_INCLUDES += [
'/browser/app/winlauncher',
]
DELAYLOAD_DLLS += [
'oleaut32.dll',
'ole32.dll',
]
-if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'Darwin':
- USE_LIBS += [
- 'mozsandbox',
- ]
-
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 += [
--- a/browser/app/nsBrowserApp.cpp
+++ b/browser/app/nsBrowserApp.cpp
@@ -38,20 +38,16 @@
#include "mozilla/Sprintf.h"
#include "mozilla/StartupTimeline.h"
#include "mozilla/WindowsDllBlocklist.h"
#ifdef LIBFUZZER
#include "FuzzerDefs.h"
#endif
-#ifdef XP_MACOSX
-#include "mozilla/Sandbox.h"
-#endif
-
#ifdef MOZ_LINUX_32_SSE2_STARTUP_ERROR
#include <cpuid.h>
#include "mozilla/Unused.h"
static bool
IsSSE2Available()
{
// The rest of the app has been compiled to assume that SSE2 is present
@@ -262,26 +258,16 @@ InitXPCOMGlue()
// NB: This must be extern, as this value is checked elsewhere
uint32_t gBlocklistInitFlags = eDllBlocklistInitFlagDefault;
#endif
int main(int argc, char* argv[], char* envp[])
{
mozilla::TimeStamp start = mozilla::TimeStamp::Now();
-#ifdef XP_MACOSX
- if (argc > 1 && IsArg(argv[1], "contentproc")) {
- std::string err;
- if (!mozilla::EarlyStartMacSandboxIfEnabled(argc, argv, err)) {
- Output("Sandbox error: %s\n", err.c_str());
- MOZ_CRASH("Sandbox initialization failed");
- }
- }
-#endif
-
#ifdef MOZ_BROWSER_CAN_BE_CONTENTPROC
// We are launching as a content process, delegate to the appropriate
// main
if (argc > 1 && IsArg(argv[1], "contentproc")) {
#ifdef HAS_DLL_BLOCKLIST
DllBlocklist_Initialize(eDllBlocklistInitFlagIsChildProcess);
#endif
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1021,22 +1021,16 @@ pref("security.sandbox.gpu.level", 0);
// Controls whether we disable win32k for the GMP processes.
// true means that win32k system calls are not permitted.
// Note: win32k is currently _not_ disabled due to intermittent test failures,
// where the GMP process fails very early. See bug 1449348.
pref("security.sandbox.gmp.win32k-disable", false);
#endif
-#if defined(NIGHTLY_BUILD) && defined(XP_MACOSX) && defined(MOZ_SANDBOX)
-// Start the Mac sandbox immediately during child process startup instead
-// of when messaged by the parent after the message loop is running.
-pref("security.sandbox.content.mac.earlyinit", true);
-#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" (nightly only)
// 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
--- a/devtools/client/jar.mn
+++ b/devtools/client/jar.mn
@@ -102,17 +102,16 @@ devtools.jar:
skin/dark-theme.css (themes/dark-theme.css)
skin/light-theme.css (themes/light-theme.css)
skin/toolbars.css (themes/toolbars.css)
skin/toolbox.css (themes/toolbox.css)
skin/tooltips.css (themes/tooltips.css)
skin/images/accessibility.svg (themes/images/accessibility.svg)
skin/images/add.svg (themes/images/add.svg)
skin/images/arrowhead-left.svg (themes/images/arrowhead-left.svg)
- skin/images/arrowhead-right.svg (themes/images/arrowhead-right.svg)
skin/images/arrowhead-down.svg (themes/images/arrowhead-down.svg)
skin/images/arrowhead-up.svg (themes/images/arrowhead-up.svg)
skin/images/breadcrumbs-divider.svg (themes/images/breadcrumbs-divider.svg)
skin/images/filters.svg (themes/images/filters.svg)
skin/images/filter-swatch.svg (themes/images/filter-swatch.svg)
skin/images/aboutdebugging-collapse-icon.svg (themes/images/aboutdebugging-collapse-icon.svg)
skin/images/aboutdebugging-connect-icon.svg (themes/images/aboutdebugging-connect-icon.svg)
skin/images/aboutdebugging-firefox-aurora.svg (themes/images/aboutdebugging-firefox-aurora.svg)
--- a/devtools/client/themes/layout.css
+++ b/devtools/client/themes/layout.css
@@ -212,67 +212,96 @@
.flex-outline-final,
.flex-outline-basis,
.flex-outline-delta {
grid-row: 1;
}
.flex-outline-final {
- border: 1px solid currentColor;
+ border: 2px solid currentColor;
position: relative;
grid-column: final-start / final-end;
}
.flex-outline-final.clamped::after {
content: "";
- background-color: var(--theme-body-background);
background-image: url(chrome://devtools/skin/images/lock.svg);
background-size: 16px;
background-repeat: no-repeat;
background-position: center 1px;
fill: currentColor;
-moz-context-properties: fill;
width: 20px;
height: 20px;
position: absolute;
right: -10px;
top: 6px;
- border-radius: 50%;
+ /* Making sure the icon is visible against any background by creating a plain background
+ around its shape, using a drop-shadow filter. */
+ filter:
+ drop-shadow(1px 0px 0px var(--theme-body-background))
+ drop-shadow(0px 1px 0px var(--theme-body-background))
+ drop-shadow(-1px 0px 0px var(--theme-body-background))
+ drop-shadow(0px -1px 0px var(--theme-body-background));
}
.flex-outline.column .flex-outline-final.clamped::after {
transform: rotate(-.25turn);
}
.flex-outline-basis {
border-style: dotted;
border-width: 3px;
- margin: 1px 0;
+ margin: 1px;
grid-column: basis-start / basis-end;
}
.flex-outline-basis.zero-basis {
border-width: 0 0 0 3px;
}
.flex-outline-delta {
- background-repeat: round;
- fill: currentColor;
- -moz-context-properties: fill;
grid-column: delta-start / delta-end;
- margin: 4px;
+ margin: 3px 0;
+ opacity: .5;
+ position: relative;
+}
+
+.flex-outline-delta::before {
+ content: "";
+ position: absolute;
+ left: 2px;
+ right: 2px;
+ top: calc(50% - .5px);
+ height: 1px;
+ background: currentColor;
}
-.flex-outline.growing .flex-outline-delta {
- background-image: url(chrome://devtools/skin/images/arrowhead-right.svg);
+.flex-outline-delta::after {
+ content: "";
+ position: absolute;
+ width: 5px;
+ height: 5px;
+ top: 50%;
+ border: 1px solid currentColor;
}
-.flex-outline.shrinking .flex-outline-delta {
- background-image: url(chrome://devtools/skin/images/arrowhead-left.svg);
+.flex-outline.growing .flex-outline-delta:after {
+ right: 2px;
+ border-width: 1px 1px 0 0;
+ transform-origin: top right;
+ transform: rotate(.125turn);
+}
+
+.flex-outline.shrinking .flex-outline-delta:after {
+ left: 2px;
+ border-width: 1px 0 0 1px;
+ transform-origin: top left;
+ transform: rotate(-.125turn);
}
.flex-outline-point {
position: relative;
-moz-user-select: none;
}
.flex-outline-point {
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -189,17 +189,16 @@
#ifdef XP_WIN
#include <process.h>
#define getpid _getpid
#include "mozilla/widget/AudioSession.h"
#include "mozilla/audio/AudioNotificationReceiver.h"
#endif
#if defined(XP_MACOSX)
-#include "nsMacUtilsImpl.h"
#include <CoreServices/CoreServices.h>
// Info.plist key associated with the developer repo path
#define MAC_DEV_REPO_KEY "MozillaDeveloperRepoPath"
// Info.plist key associated with the developer repo object directory
#define MAC_DEV_OBJ_KEY "MozillaDeveloperObjPath"
#endif /* XP_MACOSX */
#ifdef MOZ_X11
@@ -1519,16 +1518,120 @@ ContentChild::RecvReinitRenderingForDevi
if (tabChild->GetLayersId().IsValid()) {
tabChild->ReinitRenderingForDeviceReset();
}
}
return IPC_OK();
}
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
+
+#include <stdlib.h>
+
+static bool
+GetAppPaths(nsCString &aAppPath, nsCString &aAppBinaryPath, nsCString &aAppDir)
+{
+ nsAutoCString appPath;
+ nsAutoCString appBinaryPath(
+ (CommandLine::ForCurrentProcess()->argv()[0]).c_str());
+
+ nsAutoCString::const_iterator start, end;
+ appBinaryPath.BeginReading(start);
+ appBinaryPath.EndReading(end);
+ if (RFindInReadable(NS_LITERAL_CSTRING(".app/Contents/MacOS/"), start, end)) {
+ end = start;
+ ++end; ++end; ++end; ++end;
+ appBinaryPath.BeginReading(start);
+ appPath.Assign(Substring(start, end));
+ } else {
+ return false;
+ }
+
+ nsCOMPtr<nsIFile> app, appBinary;
+ nsresult rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(appPath),
+ true, getter_AddRefs(app));
+ if (NS_FAILED(rv)) {
+ return false;
+ }
+ rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(appBinaryPath),
+ true, getter_AddRefs(appBinary));
+ if (NS_FAILED(rv)) {
+ return false;
+ }
+
+ nsCOMPtr<nsIFile> appDir;
+ nsCOMPtr<nsIProperties> dirSvc =
+ do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
+ if (!dirSvc) {
+ return false;
+ }
+ rv = dirSvc->Get(NS_GRE_DIR,
+ NS_GET_IID(nsIFile), getter_AddRefs(appDir));
+ if (NS_FAILED(rv)) {
+ return false;
+ }
+ bool exists;
+ rv = appDir->Exists(&exists);
+ if (NS_FAILED(rv) || !exists) {
+ return false;
+ }
+
+ // appDir points to .app/Contents/Resources, for our purposes we want
+ // .app/Contents.
+ nsCOMPtr<nsIFile> appDirParent;
+ rv = appDir->GetParent(getter_AddRefs(appDirParent));
+ if (NS_FAILED(rv)) {
+ return false;
+ }
+
+ rv = app->Normalize();
+ if (NS_FAILED(rv)) {
+ return false;
+ }
+ app->GetNativePath(aAppPath);
+
+ rv = appBinary->Normalize();
+ if (NS_FAILED(rv)) {
+ return false;
+ }
+ appBinary->GetNativePath(aAppBinaryPath);
+
+ rv = appDirParent->Normalize();
+ if (NS_FAILED(rv)) {
+ return false;
+ }
+ appDirParent->GetNativePath(aAppDir);
+
+ return true;
+}
+
+// This function is only used in an |#ifdef DEBUG| path.
+#ifdef DEBUG
+// Given a path to a file, return the directory which contains it.
+static nsAutoCString
+GetDirectoryPath(const char *aPath) {
+ nsCOMPtr<nsIFile> file = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
+ if (!file ||
+ NS_FAILED(file->InitWithNativePath(nsDependentCString(aPath)))) {
+ MOZ_CRASH("Failed to create or init an nsIFile");
+ }
+ nsCOMPtr<nsIFile> directoryFile;
+ if (NS_FAILED(file->GetParent(getter_AddRefs(directoryFile))) ||
+ !directoryFile) {
+ MOZ_CRASH("Failed to get parent for an nsIFile");
+ }
+ directoryFile->Normalize();
+ nsAutoCString directoryPath;
+ if (NS_FAILED(directoryFile->GetNativePath(directoryPath))) {
+ MOZ_CRASH("Failed to get path for an nsIFile");
+ }
+ return directoryPath;
+}
+#endif // DEBUG
+
extern "C" {
CGError
CGSSetDenyWindowServerConnections(bool);
void CGSShutdownServerConnections();
};
static bool
StartMacOSContentSandbox()
@@ -1550,19 +1653,19 @@ StartMacOSContentSandbox()
"security.sandbox.content.mac.disconnect-windowserver")) {
CGError result = CGSSetDenyWindowServerConnections(true);
MOZ_DIAGNOSTIC_ASSERT(result == kCGErrorSuccess);
#if !MOZ_DIAGNOSTIC_ASSERT_ENABLED
Unused << result;
#endif
}
- nsAutoCString appPath;
- if (!nsMacUtilsImpl::GetAppPath(appPath)) {
- MOZ_CRASH("Error resolving child process app path");
+ nsAutoCString appPath, appBinaryPath, appDir;
+ if (!GetAppPaths(appPath, appBinaryPath, appDir)) {
+ MOZ_CRASH("Error resolving child process path");
}
ContentChild* cc = ContentChild::GetSingleton();
nsresult rv;
nsCOMPtr<nsIFile> profileDir;
cc->GetProfileDir(getter_AddRefs(profileDir));
nsCString profileDirPath;
@@ -1578,19 +1681,19 @@ StartMacOSContentSandbox()
MacSandboxInfo info;
info.type = MacSandboxType_Content;
info.level = sandboxLevel;
info.hasFilePrivileges = isFileProcess;
info.shouldLog = Preferences::GetBool("security.sandbox.logging.enabled") ||
PR_GetEnv("MOZ_SANDBOX_LOGGING");
info.appPath.assign(appPath.get());
+ info.appBinaryPath.assign(appBinaryPath.get());
+ info.appDir.assign(appDir.get());
info.hasAudio = !Preferences::GetBool("media.cubeb.sandbox");
- info.hasWindowServer = !Preferences::GetBool(
- "security.sandbox.content.mac.disconnect-windowserver");
// These paths are used to whitelist certain directories used by the testing
// system. They should not be considered a public API, and are only intended
// for use in automation.
nsAutoCString testingReadPath1;
Preferences::GetCString("security.sandbox.content.mac.testing_read_path1",
testingReadPath1);
if (!testingReadPath1.IsEmpty()) {
@@ -1634,18 +1737,17 @@ StartMacOSContentSandbox()
#ifdef DEBUG
// When a content process dies intentionally (|NoteIntentionalCrash|), for
// tests it wants to log that it did this. Allow writing to this location
// that the testrunner wants.
char *bloatLog = PR_GetEnv("XPCOM_MEM_BLOAT_LOG");
if (bloatLog != nullptr) {
// |bloatLog| points to a specific file, but we actually write to a sibling
// of that path.
- nsAutoCString bloatDirectoryPath =
- nsMacUtilsImpl::GetDirectoryPath(bloatLog);
+ nsAutoCString bloatDirectoryPath = GetDirectoryPath(bloatLog);
info.debugWriteDir.assign(bloatDirectoryPath.get());
}
#endif // DEBUG
std::string err;
if (!mozilla::StartMacSandbox(info, err)) {
NS_WARNING(err.c_str());
MOZ_CRASH("sandbox_init() failed");
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -105,27 +105,25 @@
#include "mozilla/StaticPrefs.h"
#include "mozilla/Telemetry.h"
#include "mozilla/TelemetryIPC.h"
#include "mozilla/WebBrowserPersistDocumentParent.h"
#include "mozilla/widget/ScreenManager.h"
#include "mozilla/Unused.h"
#include "mozilla/HangDetails.h"
#include "nsAnonymousTemporaryFile.h"
-#include "nsAppDirectoryServiceDefs.h"
#include "nsAppRunner.h"
#include "nsCDefaultURIFixup.h"
#include "nsCExternalHandlerService.h"
#include "nsCOMPtr.h"
#include "nsChromeRegistryChrome.h"
#include "nsConsoleMessage.h"
#include "nsConsoleService.h"
#include "nsContentUtils.h"
#include "nsDebugImpl.h"
-#include "nsDirectoryService.h"
#include "nsDirectoryServiceDefs.h"
#include "nsEmbedCID.h"
#include "nsFrameLoader.h"
#include "nsFrameMessageManager.h"
#include "nsHashPropertyBag.h"
#include "nsIAlertsService.h"
#include "nsIClipboard.h"
#include "nsICookie.h"
@@ -211,20 +209,16 @@
#include "nsLayoutStylesheetCache.h"
#include "mozilla/Sprintf.h"
#ifdef MOZ_WEBRTC
#include "signaling/src/peerconnection/WebrtcGlobalParent.h"
#endif
-#if defined(XP_MACOSX)
-#include "nsMacUtilsImpl.h"
-#endif
-
#if defined(ANDROID) || defined(LINUX)
#include "nsSystemInfo.h"
#endif
#if defined(XP_LINUX)
#include "mozilla/Hal.h"
#endif
@@ -610,20 +604,16 @@ static const char* sObserverTopics[] = {
"cacheservice:empty-cache",
"intl:app-locales-changed",
"intl:requested-locales-changed",
"cookie-changed",
"private-cookie-changed",
"clear-site-data-reload-needed",
};
-#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
-bool ContentParent::sEarlySandboxInit = false;
-#endif
-
// PreallocateProcess is called by the PreallocatedProcessManager.
// ContentParent then takes this process back within GetNewOrUsedBrowserProcess.
/*static*/ already_AddRefed<ContentParent>
ContentParent::PreallocateProcess()
{
RefPtr<ContentParent> process =
new ContentParent(/* aOpener = */ nullptr,
NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE),
@@ -2135,130 +2125,16 @@ ContentParent::DestroyTestShell(TestShel
TestShellParent*
ContentParent::GetTestShellSingleton()
{
PTestShellParent* p = LoneManagedOrNullAsserts(ManagedPTestShellParent());
return static_cast<TestShellParent*>(p);
}
-#ifdef XP_MACOSX
-void
-ContentParent::AppendSandboxParams(std::vector<std::string> &aArgs)
-{
- nsCOMPtr<nsIProperties>
- directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
- if (!directoryService) {
- MOZ_CRASH("Failed to get the directory service");
- }
-
- // Indicates the child should startup the sandbox
- aArgs.push_back("-sbStartup");
-
- // The content sandbox level
- int contentSandboxLevel =
- Preferences::GetInt("security.sandbox.content.level");
- std::ostringstream os;
- os << contentSandboxLevel;
- std::string contentSandboxLevelString = os.str();
- aArgs.push_back("-sbLevel");
- aArgs.push_back(contentSandboxLevelString);
-
- // Sandbox logging
- if (Preferences::GetBool("security.sandbox.logging.enabled") ||
- PR_GetEnv("MOZ_SANDBOX_LOGGING")) {
- aArgs.push_back("-sbLogging");
- }
-
- // For file content processes
- if (GetRemoteType().EqualsLiteral(FILE_REMOTE_TYPE)) {
- aArgs.push_back("-sbAllowFileAccess");
- }
-
- // Audio access
- if (!Preferences::GetBool("media.cubeb.sandbox")) {
- aArgs.push_back("-sbAllowAudio");
- }
-
- // Windowserver access
- if (!Preferences::GetBool("security.sandbox.content.mac.disconnect-windowserver")) {
- aArgs.push_back("-sbAllowWindowServer");
- }
-
- // .app path (normalized)
- nsAutoCString appPath;
- if (!nsMacUtilsImpl::GetAppPath(appPath)) {
- MOZ_CRASH("Failed to get app dir paths");
- }
- aArgs.push_back("-sbAppPath");
- aArgs.push_back(appPath.get());
-
- // TESTING_READ_PATH1
- nsAutoCString testingReadPath1;
- Preferences::GetCString("security.sandbox.content.mac.testing_read_path1",
- testingReadPath1);
- if (!testingReadPath1.IsEmpty()) {
- aArgs.push_back("-sbTestingReadPath");
- aArgs.push_back(testingReadPath1.get());
- }
-
- // TESTING_READ_PATH2
- nsAutoCString testingReadPath2;
- Preferences::GetCString("security.sandbox.content.mac.testing_read_path2",
- testingReadPath2);
- if (!testingReadPath2.IsEmpty()) {
- aArgs.push_back("-sbTestingReadPath");
- aArgs.push_back(testingReadPath2.get());
- }
-
- // TESTING_READ_PATH3, TESTING_READ_PATH4. In development builds,
- // these are used to whitelist the repo dir and object dir respectively.
- nsresult rv;
- if (mozilla::IsDevelopmentBuild()) {
- // Repo dir
- nsCOMPtr<nsIFile> repoDir;
- rv = mozilla::GetRepoDir(getter_AddRefs(repoDir));
- if (NS_FAILED(rv)) {
- MOZ_CRASH("Failed to get path to repo dir");
- }
- nsCString repoDirPath;
- Unused << repoDir->GetNativePath(repoDirPath);
- aArgs.push_back("-sbTestingReadPath");
- aArgs.push_back(repoDirPath.get());
-
- // Object dir
- nsCOMPtr<nsIFile> objDir;
- rv = mozilla::GetObjDir(getter_AddRefs(objDir));
- if (NS_FAILED(rv)) {
- MOZ_CRASH("Failed to get path to build object dir");
- }
- nsCString objDirPath;
- Unused << objDir->GetNativePath(objDirPath);
- aArgs.push_back("-sbTestingReadPath");
- aArgs.push_back(objDirPath.get());
- }
-
- // DEBUG_WRITE_DIR
-#ifdef DEBUG
- // When a content process dies intentionally (|NoteIntentionalCrash|), for
- // tests it wants to log that it did this. Allow writing to this location
- // that the testrunner wants.
- char *bloatLog = PR_GetEnv("XPCOM_MEM_BLOAT_LOG");
- if (bloatLog != nullptr) {
- // |bloatLog| points to a specific file, but we actually write to a sibling
- // of that path.
- nsAutoCString bloatDirectoryPath =
- nsMacUtilsImpl::GetDirectoryPath(bloatLog);
- aArgs.push_back("-sbDebugWriteDir");
- aArgs.push_back(bloatDirectoryPath.get());
- }
-#endif // DEBUG
-}
-#endif // XP_MACOSX
-
bool
ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PRIORITY_FOREGROUND */)
{
AUTO_PROFILER_LABEL("ContentParent::LaunchSubprocess", OTHER);
if (!ContentProcessManager::GetSingleton()) {
// Shutdown has begun, we shouldn't spawn any more child processes.
return false;
@@ -2337,25 +2213,16 @@ ContentParent::LaunchSubprocess(ProcessP
nsPrintfCString schedulerPrefs = Scheduler::GetPrefs();
extraArgs.push_back("-schedulerPrefs");
extraArgs.push_back(schedulerPrefs.get());
if (gSafeMode) {
extraArgs.push_back("-safeMode");
}
-#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
- // If we're launching a middleman process for a
- // recording or replay, start the sandbox later.
- if (sEarlySandboxInit && IsContentSandboxEnabled() &&
- !IsRecordingOrReplaying()) {
- AppendSandboxParams(extraArgs);
- }
-#endif
-
nsCString parentBuildID(mozilla::PlatformBuildID());
extraArgs.push_back("-parentBuildID");
extraArgs.push_back(parentBuildID.get());
// Specify whether the process is recording or replaying an execution.
if (mRecordReplayState != eNotRecordingOrReplaying) {
nsPrintfCString buf("%d", mRecordReplayState == eRecording
? (int) recordreplay::ProcessKind::MiddlemanRecording
@@ -2465,27 +2332,16 @@ ContentParent::ContentParent(ContentPare
// channel. Generally only applies to the situation where we get caught in
// a deadlock with the plugin process when sending CPOWs.
GetIPCChannel()->SetChannelFlags(MessageChannel::REQUIRE_DEFERRED_MESSAGE_PROTECTION);
#endif
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
bool isFile = mRemoteType.EqualsLiteral(FILE_REMOTE_TYPE);
mSubprocess = new ContentProcessHost(this, isFile);
-
-#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
- // sEarlySandboxInit is statically initialized to false.
- // Once we've set it to true due to the pref, avoid checking the
- // pref on subsequent calls. As a result, changing the earlyinit
- // pref requires restarting the browser to take effect.
- if (!ContentParent::sEarlySandboxInit) {
- ContentParent::sEarlySandboxInit =
- Preferences::GetBool("security.sandbox.content.mac.earlyinit");
- }
-#endif
}
ContentParent::~ContentParent()
{
if (mForceKillTimer) {
mForceKillTimer->Cancel();
}
@@ -2746,25 +2602,16 @@ ContentParent::InitInternal(ProcessPrior
MaybeFileDesc brokerFd = void_t();
// XXX: Checking the pref here makes it possible to enable/disable sandboxing
// during an active session. Currently the pref is only used for testing
// purpose. If the decision is made to permanently rely on the pref, this
// should be changed so that it is required to restart firefox for the change
// of value to take effect.
shouldSandbox = IsContentSandboxEnabled();
-#ifdef XP_MACOSX
- // If the sandbox was initialized during content process
- // startup, we must not send the SetProcessSandbox message.
- // If early startup was pref'd off or the process is a
- // middleman process, send SetProcessSandbox now.
- shouldSandbox = shouldSandbox &&
- (!sEarlySandboxInit || IsRecordingOrReplaying());
-#endif
-
#ifdef XP_LINUX
if (shouldSandbox) {
MOZ_ASSERT(!mSandboxBroker);
bool isFileProcess = mRemoteType.EqualsLiteral(FILE_REMOTE_TYPE);
UniquePtr<SandboxBroker::Policy> policy =
sSandboxBrokerPolicyFactory->GetContentPolicy(Pid(), isFileProcess);
if (policy) {
brokerFd = FileDescriptor();
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -1257,18 +1257,16 @@ public:
virtual mozilla::ipc::IPCResult
RecvStoreUserInteractionAsPermission(const Principal& aPrincipal) override;
// Notify the ContentChild to enable the input event prioritization when
// initializing.
void MaybeEnableRemoteInputEventQueue();
- void AppendSandboxParams(std::vector<std::string>& aArgs);
-
public:
void SendGetFilesResponseAndForget(const nsID& aID,
const GetFilesResponseResult& aResult);
bool SendRequestMemoryReport(const uint32_t& aGeneration,
const bool& aAnonymize,
const bool& aMinimizeMemoryUsage,
const MaybeFileDesc& aDMDFile) override;
@@ -1384,23 +1382,16 @@ private:
nsTHashtable<nsCStringHashKey> mActivePermissionKeys;
nsTArray<nsCString> mBlobURLs;
UniquePtr<mozilla::ipc::CrashReporterHost> mCrashReporter;
static uint64_t sNextTabParentId;
static nsDataHashtable<nsUint64HashKey, TabParent*> sNextTabParents;
-
-#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
- // When set to true, indicates that content processes should
- // initialize their sandbox during startup instead of waiting
- // for the SetProcessSandbox IPDL message.
- static bool sEarlySandboxInit;
-#endif
};
} // namespace dom
} // namespace mozilla
class ParentIdleListener : public nsIObserver
{
friend class mozilla::dom::ContentParent;
--- a/dom/ipc/ContentProcess.cpp
+++ b/dom/ipc/ContentProcess.cpp
@@ -9,17 +9,16 @@
#include "ContentProcess.h"
#include "base/shared_memory.h"
#include "mozilla/Preferences.h"
#include "mozilla/Scheduler.h"
#include "mozilla/recordreplay/ParentIPC.h"
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
#include <stdlib.h>
-#include "mozilla/Sandbox.h"
#endif
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
#include "mozilla/SandboxSettings.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsDirectoryService.h"
#include "nsDirectoryServiceDefs.h"
#endif
@@ -292,26 +291,17 @@ ContentProcess::Init(int aArgc, char* aA
*parentBuildID,
IOThreadChild::channel(),
*childID,
*isForBrowser);
mXREEmbed.Start();
#if (defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
mContent.SetProfileDir(profileDir);
-#if defined(DEBUG)
- // For WebReplay middleman processes, the sandbox is
- // started after receiving the SetProcessSandbox message.
- if (IsContentSandboxEnabled() &&
- Preferences::GetBool("security.sandbox.content.mac.earlyinit") &&
- !recordreplay::IsMiddleman()) {
- AssertMacSandboxEnabled();
- }
-#endif /* DEBUG */
-#endif /* XP_MACOSX && MOZ_CONTENT_SANDBOX */
+#endif
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
SetUpSandboxEnvironment();
#endif
return true;
}
--- a/dom/media/tests/mochitest/identity/test_fingerprints.html
+++ b/dom/media/tests/mochitest/identity/test_fingerprints.html
@@ -1,122 +1,91 @@
<html>
<head>
<meta charset="utf-8" />
-<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
-<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+<script type="application/javascript">var scriptRelativePath = "../";</script>
+<script type="application/javascript" src="../pc.js"></script>
</head>
<body>
- <script class="testbody" type="application/javascript">
-'use strict';
+<script class="testbody" type="application/javascript">
+createHTML({ title: "Test multiple identity fingerprints", bug: "1005152" });
// here we call the identity provider directly
-function getIdentityAssertion(fpArray) {
- var Cu = SpecialPowers.Cu;
- var rtcid = Cu.import('resource://gre/modules/media/IdpSandbox.jsm');
- var sandbox = new rtcid.IdpSandbox('example.com', 'idp.js', window);
- return sandbox.start()
- .then(idp => SpecialPowers.wrap(idp)
- .generateAssertion(JSON.stringify({ fingerprint: fpArray }),
- 'https://example.com',
- {}))
- .then(assertion => {
- assertion = SpecialPowers.wrap(assertion);
- var assertionString = btoa(JSON.stringify(assertion));
- sandbox.stop();
- return assertionString;
- });
+async function getIdentityAssertion(fingerprint) {
+ const {Cu} = SpecialPowers;
+ const rtcid = Cu.import('resource://gre/modules/media/IdpSandbox.jsm');
+ const sandbox = new rtcid.IdpSandbox('example.com', 'idp.js', window);
+ const idp = SpecialPowers.wrap(await sandbox.start());
+ const assertion = SpecialPowers.wrap(await
+ idp.generateAssertion(JSON.stringify({ fingerprint }),
+ 'https://example.com',
+ {}));
+ const assertionString = btoa(JSON.stringify(assertion));
+ sandbox.stop();
+ return assertionString;
}
// This takes a real fingerprint and makes some extra bad ones.
-function makeFingerprints(algo, digest) {
- var fingerprints = [];
- fingerprints.push({ algorithm: algo, digest: digest });
+function makeFingerprints(algorithm, digest) {
+ const fingerprints = [];
+ fingerprints.push({ algorithm, digest });
for (var i = 0; i < 3; ++i) {
fingerprints.push({
- algorithm: algo,
+ algorithm,
digest: digest.replace(/:./g, ':' + i.toString(16))
});
}
return fingerprints;
}
-var fingerprintRegex = /^a=fingerprint:(\S+) (\S+)/m;
-var identityRegex = /^a=identity:(\S+)/m;
+const fingerprintRegex = /^a=fingerprint:(\S+) (\S+)/m;
+const identityRegex = /^a=identity:(\S+)/m;
function fingerprintSdp(fingerprints) {
return fingerprints.map(fp => 'a=fInGeRpRiNt:' + fp.algorithm +
' ' + fp.digest + '\n').join('');
}
// Firefox only uses a single fingerprint.
// That doesn't mean we have it create SDP that describes two.
// This function synthesizes that SDP and tries to set it.
-function testMultipleFingerprints() {
+
+runNetworkTest(async () => {
// this one fails setRemoteDescription if the identity is not good
- var pcStrict = new RTCPeerConnection({ peerIdentity: 'someone@example.com'});
+ const pcStrict = new RTCPeerConnection({ peerIdentity: 'someone@example.com'});
// this one will be manually tweaked to have two fingerprints
- var pcDouble = new RTCPeerConnection({});
-
- var offer, match, fingerprints;
-
- var fail = msg =>
- (e => ok(false, 'error in ' + msg + ': ' +
- (e.message ? (e.message + '\n' + e.stack) : e)));
-
- navigator.mediaDevices.getUserMedia({ video: true })
- .then(stream => {
- ok(stream, 'Got test stream');
- pcDouble.addStream(stream);
- return pcDouble.createOffer();
- })
- .then(o => {
- offer = o;
- ok(offer, 'Got offer');
-
- match = offer.sdp.match(fingerprintRegex);
- if (!match) {
- throw new Error('No fingerprint in offer SDP');
- }
- fingerprints = makeFingerprints(match[1], match[2]);
- return getIdentityAssertion(fingerprints);
- })
- .then(assertion => {
- ok(assertion, 'Should have assertion');
+ const pcDouble = new RTCPeerConnection({});
- var sdp = offer.sdp.slice(0, match.index) +
- 'a=identity:' + assertion + '\n' +
- fingerprintSdp(fingerprints.slice(1)) +
- offer.sdp.slice(match.index);
+ const stream = await getUserMedia({ video: true });
+ ok(stream, 'Got test stream');
+ const [track] = stream.getTracks();
+ pcDouble.addTrack(track, stream);
+ try {
+ const offer = await pcDouble.createOffer();
+ ok(offer, 'Got offer');
+ const match = offer.sdp.match(fingerprintRegex);
+ if (!match) {
+ throw new Error('No fingerprint in offer SDP');
+ }
+ const fingerprints = makeFingerprints(match[1], match[2]);
+ const assertion = await getIdentityAssertion(fingerprints);
+ ok(assertion, 'Should have assertion');
- return pcStrict.setRemoteDescription({ type: 'offer', sdp });
- })
- .then(() => {
- ok(true, 'Modified fingerprints were accepted');
- }, error => {
- var e = SpecialPowers.wrap(error);
- ok(false, 'error in test: ' +
- (e.message ? (e.message + '\n' + e.stack) : e));
- })
- .then(() => {
- pcStrict.close();
- pcDouble.close();
- SimpleTest.finish();
- });
-}
+ const sdp = offer.sdp.slice(0, match.index) +
+ 'a=identity:' + assertion + '\n' +
+ fingerprintSdp(fingerprints.slice(1)) +
+ offer.sdp.slice(match.index);
-SimpleTest.waitForExplicitFinish();
-SpecialPowers.pushPrefEnv({
- set: [
- [ 'media.peerconnection.identity.enabled', true ],
- // Disable permission to skip prompt when on platforms the use loopback
- // test devices (these would normally trigger a prompt).
- [ 'media.navigator.permission.disabled', true ],
- // Since this test doesn't include head.js or pc.js, we need to set the fake
- // device pref manually. On platforms where loopback devices are used they
- // should still take precedence, however on some platforms no prefs would
- // be set and the test would fail.
- [ 'media.navigator.streams.fake', true ]
- ]
-}, testMultipleFingerprints);
+ await pcStrict.setRemoteDescription({ type: 'offer', sdp });
+ ok(true, 'Modified fingerprints were accepted');
+ } catch (error) {
+ const e = SpecialPowers.wrap(error);
+ ok(false, 'error in test: ' +
+ (e.message ? (e.message + '\n' + e.stack) : e));
+ }
+ pcStrict.close();
+ pcDouble.close();
+ track.stop();
+ networkTestFinished();
+});
</script>
- </body>
+</body>
</html>
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -342,16 +342,18 @@ skip-if = (android_version == '18') # an
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_threeUnbundledConnections.html]
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
[test_selftest.html]
# Bug 1227781: Crash with bogus TURN server.
[test_peerConnection_bug1227781.html]
[test_peerConnection_stats.html]
skip-if = toolkit == 'android' # android(Bug 1189784, timeouts on 4.3 emulator, Bug 1373858)
+[test_peerConnection_stats_relayProtocol.html]
+skip-if = toolkit == 'android' # android(Bug 1189784, timeouts on 4.3 emulator, Bug 1373858)
[test_peerConnection_sender_and_receiver_stats.html]
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_trackless_sender_stats.html]
skip-if = (android_version == '18') # android(Bug 1189784, timeouts on 4.3 emulator)
[test_peerConnection_verifyDescriptions.html]
skip-if = (android_version == '18')
[test_fingerprinting_resistance.html]
[test_getUserMedia_nonDefaultRate.html]
--- a/dom/media/tests/mochitest/test_peerConnection_stats.html
+++ b/dom/media/tests/mochitest/test_peerConnection_stats.html
@@ -576,19 +576,18 @@ var PC_LOCAL_TEST_LOCAL_STATS = test =>
var PC_REMOTE_TEST_REMOTE_STATS = test => {
return waitForSyncedRtcp(test.pcRemote).then(stats => {
checkExpectedFields(stats);
pedanticChecks(stats);
});
}
-var test;
runNetworkTest(function (options) {
- test = new PeerConnectionTest(options);
+ const test = new PeerConnectionTest(options);
test.chain.insertAfter("PC_LOCAL_WAIT_FOR_MEDIA_FLOW",
[PC_LOCAL_TEST_LOCAL_STATS]);
test.chain.insertAfter("PC_REMOTE_WAIT_FOR_MEDIA_FLOW",
[PC_REMOTE_TEST_REMOTE_STATS]);
test.setMediaConstraints([{audio: true}, {video: true}],
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_peerConnection_stats_relayProtocol.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <script type="application/javascript" src="nonTrickleIce.js"></script>
+ <script type="application/javascript" src="pc.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+ createHTML({
+ bug: "1435789",
+ title: "WebRTC local-candidate relayProtocol stats attribute"
+ });
+var PC_LOCAL_TEST_LOCAL_STATS_RELAYCANDIDATE = test => {
+ return test.pcLocal.getStats().then(stats => {
+ let haveRelayProtocol = {};
+ for (let [k, v] of stats) {
+ if (v.type == "local-candidate") {
+ haveRelayProtocol[v.candidateType + "-" + v.relayProtocol] = v.relayProtocol;
+ }
+ }
+ is(haveRelayProtocol["host-undefined"], undefined, "relayProtocol not set for host candidates");
+ is(haveRelayProtocol["serverreflexive-undefined"], undefined, "relayProtocol not set for serverreflexive candidates");
+ ok(haveRelayProtocol["relayed-udp"], "Has UDP relay candidate");
+ ok(haveRelayProtocol["relayed-tcp"], "Has TCP relay candidate");
+ // TURN/TLS does not work, see https://bugzilla.mozilla.org/show_bug.cgi?id=1323439
+ // With TURN/TLS working, we should have exactly five entries in haveRelayProtocol.
+ todo(haveRelayProtocol["relayed-tls"], "Has TLS relay candidate. See https://bugzilla.mozilla.org/show_bug.cgi?id=1323439");
+ is(Object.keys(haveRelayProtocol).length, 4, "All candidate types are accounted for");
+ });
+}
+
+runNetworkTest(options => {
+ // uses NAT simulator in order to get srflx candidates.
+ SpecialPowers.pushPrefEnv(
+ {
+ 'set': [
+ ['media.peerconnection.nat_simulator.filtering_type', 'ENDPOINT_INDEPENDENT'],
+ ['media.peerconnection.nat_simulator.mapping_type', 'ENDPOINT_INDEPENDENT']
+ ]
+ }, function (options) {
+ const test = new PeerConnectionTest(options);
+ makeOffererNonTrickle(test.chain);
+ makeAnswererNonTrickle(test.chain);
+
+ test.chain.removeAfter("PC_LOCAL_WAIT_FOR_MEDIA_FLOW");
+ test.chain.append([PC_LOCAL_TEST_LOCAL_STATS_RELAYCANDIDATE]);
+
+ test.setMediaConstraints([{ audio: true }], [{ audio: true }]);
+ test.run();
+ })
+}, { useIceServer: true });
+</script>
+</pre>
+</body>
+</html>
--- a/dom/media/webrtc/WebrtcGlobal.h
+++ b/dom/media/webrtc/WebrtcGlobal.h
@@ -223,28 +223,30 @@ struct ParamTraits<mozilla::dom::RTCIceC
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mCandidateId);
WriteParam(aMsg, aParam.mCandidateType);
WriteParam(aMsg, aParam.mComponentId);
WriteParam(aMsg, aParam.mIpAddress);
WriteParam(aMsg, aParam.mMozLocalTransport);
+ WriteParam(aMsg, aParam.mRelayProtocol);
WriteParam(aMsg, aParam.mPortNumber);
WriteParam(aMsg, aParam.mTransport);
WriteRTCStats(aMsg, aParam);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
if (!ReadParam(aMsg, aIter, &(aResult->mCandidateId)) ||
!ReadParam(aMsg, aIter, &(aResult->mCandidateType)) ||
!ReadParam(aMsg, aIter, &(aResult->mComponentId)) ||
!ReadParam(aMsg, aIter, &(aResult->mIpAddress)) ||
!ReadParam(aMsg, aIter, &(aResult->mMozLocalTransport)) ||
+ !ReadParam(aMsg, aIter, &(aResult->mRelayProtocol)) ||
!ReadParam(aMsg, aIter, &(aResult->mPortNumber)) ||
!ReadParam(aMsg, aIter, &(aResult->mTransport)) ||
!ReadRTCStats(aMsg, aIter, aResult)) {
return false;
}
return true;
}
--- a/dom/webidl/RTCStatsReport.webidl
+++ b/dom/webidl/RTCStatsReport.webidl
@@ -150,17 +150,18 @@ enum RTCStatsIceCandidateType {
"relayed"
};
dictionary RTCIceCandidateStats : RTCStats {
DOMString componentId;
DOMString candidateId;
DOMString ipAddress;
DOMString transport;
- DOMString mozLocalTransport; // needs standardization
+ DOMString mozLocalTransport; // obsoleted by relayProtocol
+ DOMString relayProtocol;
long portNumber;
RTCStatsIceCandidateType candidateType;
};
dictionary RTCCodecStats : RTCStats {
unsigned long payloadType; // As used in RTP encoding.
DOMString codec; // video/vp8 or equivalent
unsigned long clockRate;
--- a/ipc/app/MozillaRuntimeMain.cpp
+++ b/ipc/app/MozillaRuntimeMain.cpp
@@ -4,33 +4,21 @@
* 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 "../contentproc/plugin-container.cpp"
#include "mozilla/Bootstrap.h"
#include "mozilla/WindowsDllBlocklist.h"
-#ifdef XP_MACOSX
-#include "mozilla/Sandbox.h"
-#endif
-
using namespace mozilla;
int
main(int argc, char *argv[])
{
-#ifdef XP_MACOSX
- std::string err;
- if (!mozilla::EarlyStartMacSandboxIfEnabled(argc, argv, err)) {
- fprintf(stderr, "Sandbox error: %s\n", err.c_str());
- MOZ_CRASH("Sandbox initialization failed");
- }
-#endif
-
#ifdef HAS_DLL_BLOCKLIST
DllBlocklist_Initialize(eDllBlocklistInitFlagIsChildProcess);
#endif
Bootstrap::UniquePtr bootstrap = GetBootstrap();
if (!bootstrap) {
return 2;
}
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -544,22 +544,16 @@ AddAppDirToCommandLine(std::vector<std::
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
// Full path to the profile dir
nsCOMPtr<nsIFile> profileDir;
rv = directoryService->Get(NS_APP_USER_PROFILE_50_DIR,
NS_GET_IID(nsIFile),
getter_AddRefs(profileDir));
if (NS_SUCCEEDED(rv)) {
- // If the profile doesn't exist, normalization will
- // fail. But we don't return an error here because some
- // tests require startup with a missing profile dir.
- // For users, almost universally, the profile will be in
- // the home directory and normalization isn't required.
- mozilla::Unused << profileDir->Normalize();
nsAutoCString path;
MOZ_ALWAYS_SUCCEEDS(profileDir->GetNativePath(path));
aCmdLine.push_back("-profile");
aCmdLine.push_back(path.get());
}
#endif
}
}
--- a/js/src/vm/JSContext-inl.h
+++ b/js/src/vm/JSContext-inl.h
@@ -40,25 +40,25 @@ class ContextChecks
{
}
/*
* Set a breakpoint here (break js::ContextChecks::fail) to debug
* realm/compartment/zone mismatches.
*/
static void fail(JS::Realm* r1, JS::Realm* r2, int argIndex) {
- MOZ_CRASH_UNSAFE_PRINTF("*** Realm mismatch %p vs. %p at argument %d\n",
+ MOZ_CRASH_UNSAFE_PRINTF("*** Realm mismatch %p vs. %p at argument %d",
r1, r2, argIndex);
}
static void fail(JS::Compartment* c1, JS::Compartment* c2, int argIndex) {
- MOZ_CRASH_UNSAFE_PRINTF("*** Compartment mismatch %p vs. %p at argument %d\n",
+ MOZ_CRASH_UNSAFE_PRINTF("*** Compartment mismatch %p vs. %p at argument %d",
c1, c2, argIndex);
}
static void fail(JS::Zone* z1, JS::Zone* z2, int argIndex) {
- MOZ_CRASH_UNSAFE_PRINTF("*** Zone mismatch %p vs. %p at argument %d\n",
+ MOZ_CRASH_UNSAFE_PRINTF("*** Zone mismatch %p vs. %p at argument %d",
z1, z2, argIndex);
}
void check(JS::Realm* r, int argIndex) {
if (r && r != realm()) {
fail(realm(), r, argIndex);
}
}
@@ -89,17 +89,17 @@ class ContextChecks
mozilla::IsSame<T, JS::Symbol>::value,
"Should only be called with JSAtom* or JS::Symbol* argument");
#ifdef DEBUG
// Atoms which move across zone boundaries need to be marked in the new
// zone, see JS_MarkCrossZoneId.
if (zone()) {
if (!cx->runtime()->gc.atomMarking.atomIsMarked(zone(), thing)) {
- MOZ_CRASH_UNSAFE_PRINTF("*** Atom not marked for zone %p at argument %d\n",
+ MOZ_CRASH_UNSAFE_PRINTF("*** Atom not marked for zone %p at argument %d",
zone(), argIndex);
}
}
#endif
}
void check(JSString* str, int argIndex) {
MOZ_ASSERT(JS::CellIsNotGray(str));
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -2670,23 +2670,22 @@ WrapSeparatorTransform(nsDisplayListBuil
}
}
// Try to compute a clip rect to bound the contents of the mask item
// that will be built for |aMaskedFrame|. If we're not able to compute
// one, return an empty Maybe.
// The returned clip rect, if there is one, is relative to |aMaskedFrame|.
static Maybe<nsRect>
-ComputeClipForMaskItem(nsDisplayListBuilder* aBuilder, nsIFrame* aMaskedFrame,
- bool aHandleOpacity)
+ComputeClipForMaskItem(nsDisplayListBuilder* aBuilder, nsIFrame* aMaskedFrame)
{
const nsStyleSVGReset* svgReset = aMaskedFrame->StyleSVGReset();
nsSVGUtils::MaskUsage maskUsage;
- nsSVGUtils::DetermineMaskUsage(aMaskedFrame, aHandleOpacity, maskUsage);
+ nsSVGUtils::DetermineMaskUsage(aMaskedFrame, false, maskUsage);
nsPoint offsetToUserSpace = nsLayoutUtils::ComputeOffsetToUserSpace(aBuilder, aMaskedFrame);
int32_t devPixelRatio = aMaskedFrame->PresContext()->AppUnitsPerDevPixel();
gfxPoint devPixelOffsetToUserSpace = nsLayoutUtils::PointToGfxPoint(
offsetToUserSpace, devPixelRatio);
gfxMatrix cssToDevMatrix = nsSVGUtils::GetCSSPxToDevPxMatrix(aMaskedFrame);
nsPoint toReferenceFrame;
@@ -2930,26 +2929,28 @@ nsIFrame::BuildDisplayListForStackingCon
if (usingSVGEffects) {
dirtyRect =
nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(this, dirtyRect);
visibleRect =
nsSVGIntegrationUtils::GetRequiredSourceForInvalidArea(this, visibleRect);
aBuilder->EnterSVGEffectsContents(&hoistedScrollInfoItemsStorage);
}
-
- bool needsActiveOpacityLayer = false;
- // We build an opacity item if it's not going to be drawn by SVG content, or
- // SVG effects. SVG effects won't handle the opacity if we want an active
- // layer (for async animations), see
- // nsSVGIntegrationsUtils::PaintMaskAndClipPath or
- // nsSVGIntegrationsUtils::PaintFilter.
- bool useOpacity = HasVisualOpacity(effectSet) &&
- !nsSVGUtils::CanOptimizeOpacity(this) &&
- ((needsActiveOpacityLayer = nsDisplayOpacity::NeedsActiveLayer(aBuilder, this)) || !usingSVGEffects);
+ // We build an opacity item if it's not going to be drawn by SVG content.
+ // We could in principle skip creating an nsDisplayOpacity item if
+ // nsDisplayOpacity::NeedsActiveLayer returns false and usingSVGEffects is
+ // true (the nsDisplayFilter/nsDisplayMasksAndClipPaths could handle the
+ // opacity). Since SVG has perf issues where we sometimes spend a lot of
+ // time creating display list items that might be helpful. We'd need to
+ // restore our mechanism to do that (changed in bug 1482403), and we'd
+ // need to invalidate the frame if the value that would be return from
+ // NeedsActiveLayer was to change, which we don't currently do.
+ bool useOpacity =
+ HasVisualOpacity(effectSet) && !nsSVGUtils::CanOptimizeOpacity(this);
+
bool useBlendMode = effects->mMixBlendMode != NS_STYLE_BLEND_NORMAL;
bool useStickyPosition = disp->mPosition == NS_STYLE_POSITION_STICKY &&
IsScrollFrameActive(aBuilder,
nsLayoutUtils::GetNearestScrollableFrame(GetParent(),
nsLayoutUtils::SCROLLABLE_SAME_DOC |
nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN));
bool useFixedPosition = disp->mPosition == NS_STYLE_POSITION_FIXED &&
(nsLayoutUtils::IsFixedPosFrameInDisplayPort(this) || BuilderHasScrolledClip(aBuilder));
@@ -3011,17 +3012,17 @@ nsIFrame::BuildDisplayListForStackingCon
}
if (clipCapturedBy != ContainerItemType::eNone) {
clipState.Clear();
}
Maybe<nsRect> clipForMask;
if (usingMask) {
- clipForMask = ComputeClipForMaskItem(aBuilder, this, !useOpacity);
+ clipForMask = ComputeClipForMaskItem(aBuilder, this);
}
nsDisplayListCollection set(aBuilder);
{
DisplayListClipState::AutoSaveRestore nestedClipState(aBuilder);
nsDisplayListBuilder::AutoInTransformSetter
inTransformSetter(aBuilder, inTransform);
nsDisplayListBuilder::AutoEnterFilter
@@ -3190,25 +3191,19 @@ nsIFrame::BuildDisplayListForStackingCon
if (clipCapturedBy == ContainerItemType::eFilter) {
clipState.Restore();
}
// Revert to the post-filter dirty rect.
aBuilder->SetVisibleRect(visibleRectOutsideSVGEffects);
// Skip all filter effects while generating glyph mask.
if (usingFilter && !aBuilder->IsForGenerateGlyphMask()) {
- // If we are going to create a mask display item, handle opacity effect
- // in that mask display item; Otherwise, take care of opacity in this
- // filter display item.
- bool handleOpacity = !usingMask && !useOpacity;
-
/* List now emptied, so add the new list to the top. */
- resultList.AppendToTop(
- MakeDisplayItem<nsDisplayFilters>(aBuilder, this, &resultList,
- handleOpacity));
+ resultList.AppendToTop(MakeDisplayItem<nsDisplayFilters>(
+ aBuilder, this, &resultList));
}
if (usingMask) {
DisplayListClipState::AutoSaveRestore maskClipState(aBuilder);
// The mask should move with aBuilder->CurrentActiveScrolledRoot(), so
// that's the ASR we prefer to use for the mask item. However, we can
// only do this if the mask if clipped with respect to that ASR, because
// an item always needs to have finite bounds with respect to its ASR.
@@ -3216,19 +3211,18 @@ nsIFrame::BuildDisplayListForStackingCon
// using containerItemASR, which is the lowest common ancestor clip of
// the mask's contents. That's not entirely crrect, but it satisfies
// the base requirement of the ASR system (that items have finite bounds
// wrt. their ASR).
const ActiveScrolledRoot* maskASR = clipForMask.isSome()
? aBuilder->CurrentActiveScrolledRoot()
: containerItemASR;
/* List now emptied, so add the new list to the top. */
- resultList.AppendToTop(
- MakeDisplayItem<nsDisplayMasksAndClipPaths>(aBuilder, this, &resultList,
- !useOpacity, maskASR));
+ resultList.AppendToTop(MakeDisplayItem<nsDisplayMasksAndClipPaths>(
+ aBuilder, this, &resultList, maskASR));
}
// Also add the hoisted scroll info items. We need those for APZ scrolling
// because nsDisplayMasksAndClipPaths items can't build active layers.
aBuilder->ExitSVGEffectsContents();
resultList.AppendToTop(&hoistedScrollInfoItemsStorage);
if (aCreatedContainerItem) {
*aCreatedContainerItem = false;
@@ -3238,16 +3232,19 @@ nsIFrame::BuildDisplayListForStackingCon
/* If the list is non-empty and there is CSS group opacity without SVG
* effects, wrap it up in an opacity item.
*/
if (useOpacity) {
// Don't clip nsDisplayOpacity items. We clip their descendants instead.
// The clip we would set on an element with opacity would clip
// all descendant content, but some should not be clipped.
DisplayListClipState::AutoSaveRestore opacityClipState(aBuilder);
+ const bool needsActiveOpacityLayer =
+ nsDisplayOpacity::NeedsActiveLayer(aBuilder, this);
+
resultList.AppendToTop(
MakeDisplayItem<nsDisplayOpacity>(aBuilder, this, &resultList,
containerItemASR,
opacityItemForEventsAndPluginsOnly,
needsActiveOpacityLayer));
if (aCreatedContainerItem) {
*aCreatedContainerItem = true;
}
--- a/layout/painting/RetainedDisplayListBuilder.cpp
+++ b/layout/painting/RetainedDisplayListBuilder.cpp
@@ -409,16 +409,23 @@ public:
if (type == DisplayItemType::TYPE_CARET) {
// The caret can change position while still being owned by the same frame
// and we don't invalidate in that case. Use the new version since the
// changed bounds are needed for DLBI.
return true;
}
+ if (type == DisplayItemType::TYPE_MASK ||
+ type == DisplayItemType::TYPE_FILTER ||
+ type == DisplayItemType::TYPE_SVG_WRAPPER) {
+ // SVG items have some invalidation issues, see bugs 1494110 and 1494663.
+ return true;
+ }
+
return false;
}
RetainedDisplayList Finalize()
{
for (size_t i = 0; i < mOldDAG.Length(); i++) {
if (mOldItems[i].IsUsed()) {
continue;
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -6534,16 +6534,40 @@ nsDisplayOpacity::ApplyOpacityToChildren
for (uint32_t i = 0; i < childCount; i++) {
children[i].item->ApplyOpacity(aBuilder, mOpacity, mClipChain);
}
mChildOpacityState = ChildOpacityState::Applied;
return true;
}
+/**
+ * Returns true if this nsDisplayOpacity contains only a filter or a mask item
+ * that has the same frame as the opacity item. In this case the opacity item
+ * can be optimized away.
+ */
+bool
+nsDisplayOpacity::IsEffectsWrapper() const
+{
+ if (mList.Count() != 1) {
+ return false;
+ }
+
+ const nsDisplayItem* item = mList.GetBottom();
+
+ if (item->Frame() != mFrame) {
+ // The effect item needs to have the same frame as the opacity item.
+ return false;
+ }
+
+ const DisplayItemType type = item->GetType();
+ return type == DisplayItemType::TYPE_MASK ||
+ type == DisplayItemType::TYPE_FILTER;
+}
+
bool
nsDisplayOpacity::ShouldFlattenAway(nsDisplayListBuilder* aBuilder)
{
if (mFrame->GetPrevContinuation() || mFrame->GetNextContinuation() ||
mFrame->HasAnyStateBits(NS_FRAME_PART_OF_IBSPLIT)) {
// If we've been split, then we might need to merge, so
// don't flatten us away.
return false;
@@ -6556,16 +6580,23 @@ nsDisplayOpacity::ShouldFlattenAway(nsDi
// might trigger repainting).
return false;
}
if (mList.IsEmpty()) {
return false;
}
+ if (IsEffectsWrapper()) {
+ MOZ_ASSERT(nsSVGIntegrationUtils::UsingEffectsForFrame(mFrame));
+ static_cast<nsDisplayEffectsBase*>(mList.GetBottom())->SetHandleOpacity();
+ mChildOpacityState = ChildOpacityState::Applied;
+ return true;
+ }
+
// Return true if we successfully applied opacity to child items, or if
// WebRender is not in use. In the latter case, the opacity gets flattened and
// applied during layer building.
return ApplyOpacityToChildren(aBuilder) || !gfxVars::UseWebRender();
}
nsDisplayItem::LayerState
nsDisplayOpacity::GetLayerState(nsDisplayListBuilder* aBuilder,
@@ -9440,35 +9471,33 @@ nsCharClipDisplayItem::ComputeInvalidati
aInvalidRegion->Or(oldRect, newRect);
}
}
nsDisplayEffectsBase::nsDisplayEffectsBase(
nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
nsDisplayList* aList,
- bool aHandleOpacity,
const ActiveScrolledRoot* aActiveScrolledRoot,
bool aClearClipChain)
: nsDisplayWrapList(aBuilder,
aFrame,
aList,
aActiveScrolledRoot,
aClearClipChain)
- , mHandleOpacity(aHandleOpacity)
+ , mHandleOpacity(false)
{
MOZ_COUNT_CTOR(nsDisplayEffectsBase);
}
nsDisplayEffectsBase::nsDisplayEffectsBase(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
- nsDisplayList* aList,
- bool aHandleOpacity)
+ nsDisplayList* aList)
: nsDisplayWrapList(aBuilder, aFrame, aList)
- , mHandleOpacity(aHandleOpacity)
+ , mHandleOpacity(false)
{
MOZ_COUNT_CTOR(nsDisplayEffectsBase);
}
nsRegion
nsDisplayEffectsBase::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) const
{
@@ -9507,17 +9536,19 @@ nsDisplayEffectsBase::ComputeInvalidatio
const nsDisplayItemGeometry* aGeometry,
nsRegion* aInvalidRegion) const
{
auto* geometry = static_cast<const nsDisplaySVGEffectGeometry*>(aGeometry);
bool snap;
nsRect bounds = GetBounds(aBuilder, &snap);
if (geometry->mFrameOffsetToReferenceFrame != ToReferenceFrame() ||
geometry->mUserSpaceOffset != UserSpaceOffset() ||
- !geometry->mBBox.IsEqualInterior(BBoxInUserSpace())) {
+ !geometry->mBBox.IsEqualInterior(BBoxInUserSpace()) ||
+ geometry->mOpacity != mFrame->StyleEffects()->mOpacity ||
+ geometry->mHandleOpacity != ShouldHandleOpacity()) {
// Filter and mask output can depend on the location of the frame's user
// space and on the frame's BBox. We need to invalidate if either of these
// change relative to the reference frame.
// Invalidations from our inactive layer manager are not enough to catch
// some of these cases because filters can produce output even if there's
// nothing in the filter input.
aInvalidRegion->Or(bounds, geometry->mBounds);
}
@@ -9628,22 +9659,20 @@ ComputeMaskGeometry(PaintFramesParams& a
IntRect result = ComputeClipExtsInDeviceSpace(ctx);
aParams.maskRect = result;
}
nsDisplayMasksAndClipPaths::nsDisplayMasksAndClipPaths(
nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
nsDisplayList* aList,
- bool aHandleOpacity,
const ActiveScrolledRoot* aActiveScrolledRoot)
: nsDisplayEffectsBase(aBuilder,
aFrame,
aList,
- aHandleOpacity,
aActiveScrolledRoot,
true)
{
MOZ_COUNT_CTOR(nsDisplayMasksAndClipPaths);
nsPresContext* presContext = mFrame->PresContext();
uint32_t flags =
aBuilder->GetBackgroundPaintFlags() | nsCSSRendering::PAINTBG_MASK_IMAGE;
@@ -9831,21 +9860,16 @@ nsDisplayMasksAndClipPaths::ComputeInval
nsDisplayEffectsBase::ComputeInvalidationRegion(
aBuilder, aGeometry, aInvalidRegion);
auto* geometry =
static_cast<const nsDisplayMasksAndClipPathsGeometry*>(aGeometry);
bool snap;
nsRect bounds = GetBounds(aBuilder, &snap);
- if (mFrame->StyleEffects()->mOpacity != geometry->mOpacity ||
- mHandleOpacity != geometry->mHandleOpacity) {
- aInvalidRegion->Or(*aInvalidRegion, bounds);
- }
-
if (mDestRects.Length() != geometry->mDestRects.Length()) {
aInvalidRegion->Or(bounds, geometry->mBounds);
} else {
for (size_t i = 0; i < mDestRects.Length(); i++) {
if (!mDestRects[i].IsEqualInterior(geometry->mDestRects[i])) {
aInvalidRegion->Or(bounds, geometry->mBounds);
break;
}
@@ -10027,17 +10051,17 @@ nsDisplayMasksAndClipPaths::GetClipWithR
#ifdef MOZ_DUMP_PAINTING
void
nsDisplayMasksAndClipPaths::PrintEffects(nsACString& aTo)
{
nsIFrame* firstFrame =
nsLayoutUtils::FirstContinuationOrIBSplitSibling(mFrame);
bool first = true;
aTo += " effects=(";
- if (mFrame->StyleEffects()->mOpacity != 1.0f && mHandleOpacity) {
+ if (mHandleOpacity) {
first = false;
aTo += nsPrintfCString("opacity(%f)", mFrame->StyleEffects()->mOpacity);
}
nsSVGClipPathFrame* clipPathFrame;
// XXX Check return value?
SVGObserverUtils::GetAndObserveClipPath(firstFrame, &clipPathFrame);
if (clipPathFrame) {
if (!first) {
@@ -10064,19 +10088,18 @@ nsDisplayMasksAndClipPaths::PrintEffects
aTo += "mask";
}
aTo += ")";
}
#endif
nsDisplayFilters::nsDisplayFilters(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
- nsDisplayList* aList,
- bool aHandleOpacity)
- : nsDisplayEffectsBase(aBuilder, aFrame, aList, aHandleOpacity)
+ nsDisplayList* aList)
+ : nsDisplayEffectsBase(aBuilder, aFrame, aList)
, mEffectsBounds(aFrame->GetVisualOverflowRectRelativeToSelf())
{
MOZ_COUNT_CTOR(nsDisplayFilters);
}
already_AddRefed<Layer>
nsDisplayFilters::BuildLayer(
nsDisplayListBuilder* aBuilder,
@@ -10315,17 +10338,17 @@ nsDisplayFilters::CreateWebRenderCommand
#ifdef MOZ_DUMP_PAINTING
void
nsDisplayFilters::PrintEffects(nsACString& aTo)
{
nsIFrame* firstFrame =
nsLayoutUtils::FirstContinuationOrIBSplitSibling(mFrame);
bool first = true;
aTo += " effects=(";
- if (mFrame->StyleEffects()->mOpacity != 1.0f && mHandleOpacity) {
+ if (mHandleOpacity) {
first = false;
aTo += nsPrintfCString("opacity(%f)", mFrame->StyleEffects()->mOpacity);
}
// We may exist for a mix of CSS filter functions and/or references to SVG
// filters. If we have invalid references to SVG filters then we paint
// nothing, but otherwise we will apply one or more filters.
if (SVGObserverUtils::GetAndObserveFilters(firstFrame, nullptr) !=
SVGObserverUtils::eHasRefsSomeInvalid) {
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -5785,16 +5785,17 @@ public:
const StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder) override;
float GetOpacity() const { return mOpacity; }
private:
bool ApplyOpacityToChildren(nsDisplayListBuilder* aBuilder);
+ bool IsEffectsWrapper() const;
float mOpacity;
bool mForEventsAndPluginsOnly : 1;
enum class ChildOpacityState : uint8_t
{
// Our child list has changed since the last time ApplyOpacityToChildren was
// called.
Unknown,
@@ -6683,23 +6684,21 @@ private:
* A base class for different effects types.
*/
class nsDisplayEffectsBase : public nsDisplayWrapList
{
public:
nsDisplayEffectsBase(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
nsDisplayList* aList,
- bool aHandleOpacity,
const ActiveScrolledRoot* aActiveScrolledRoot,
bool aClearClipChain = false);
nsDisplayEffectsBase(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
- nsDisplayList* aList,
- bool aHandleOpacity);
+ nsDisplayList* aList);
nsDisplayEffectsBase(nsDisplayListBuilder* aBuilder,
const nsDisplayEffectsBase& aOther)
: nsDisplayWrapList(aBuilder, aOther)
, mEffectsBounds(aOther.mEffectsBounds)
, mHandleOpacity(aOther.mHandleOpacity)
{
MOZ_COUNT_CTOR(nsDisplayEffectsBase);
@@ -6711,22 +6710,25 @@ public:
nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap) const override;
void HitTest(nsDisplayListBuilder* aBuilder,
const nsRect& aRect,
HitTestState* aState,
nsTArray<nsIFrame*>* aOutFrames) override;
+ void RestoreState() override { mHandleOpacity = false; }
+
bool ShouldFlattenAway(nsDisplayListBuilder* aBuilder) override
{
return false;
}
- bool ShouldHandleOpacity() { return mHandleOpacity; }
+ void SetHandleOpacity() { mHandleOpacity = true; }
+ bool ShouldHandleOpacity() const { return mHandleOpacity; }
gfxRect BBoxInUserSpace() const;
gfxPoint UserSpaceOffset() const;
void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion* aInvalidRegion) const override;
@@ -6752,17 +6754,16 @@ protected:
class nsDisplayMasksAndClipPaths : public nsDisplayEffectsBase
{
public:
typedef mozilla::layers::ImageLayer ImageLayer;
nsDisplayMasksAndClipPaths(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
nsDisplayList* aList,
- bool aHandleOpacity,
const ActiveScrolledRoot* aActiveScrolledRoot);
nsDisplayMasksAndClipPaths(nsDisplayListBuilder* aBuilder,
const nsDisplayMasksAndClipPaths& aOther)
: nsDisplayEffectsBase(aBuilder, aOther)
, mDestRects(aOther.mDestRects)
{
}
@@ -6864,18 +6865,17 @@ private:
* Note that the filters may just be simple CSS filter functions. That is,
* they won't necessarily be references to SVG 'filter' elements.
*/
class nsDisplayFilters : public nsDisplayEffectsBase
{
public:
nsDisplayFilters(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
- nsDisplayList* aList,
- bool aHandleOpacity);
+ nsDisplayList* aList);
nsDisplayFilters(nsDisplayListBuilder* aBuilder,
const nsDisplayFilters& aOther)
: nsDisplayEffectsBase(aBuilder, aOther)
, mEffectsBounds(aOther.mEffectsBounds)
{
}
--- a/layout/painting/nsDisplayListInvalidation.cpp
+++ b/layout/painting/nsDisplayListInvalidation.cpp
@@ -126,34 +126,34 @@ nsDisplaySolidColorRegionGeometry::MoveB
nsDisplaySVGEffectGeometry::nsDisplaySVGEffectGeometry(
nsDisplayEffectsBase* aItem,
nsDisplayListBuilder* aBuilder)
: nsDisplayItemGeometry(aItem, aBuilder)
, mBBox(aItem->BBoxInUserSpace())
, mUserSpaceOffset(aItem->UserSpaceOffset())
, mFrameOffsetToReferenceFrame(aItem->ToReferenceFrame())
+ , mOpacity(aItem->Frame()->StyleEffects()->mOpacity)
+ , mHandleOpacity(aItem->ShouldHandleOpacity())
{
}
void
nsDisplaySVGEffectGeometry::MoveBy(const nsPoint& aOffset)
{
mBounds.MoveBy(aOffset);
mFrameOffsetToReferenceFrame += aOffset;
}
nsDisplayMasksAndClipPathsGeometry::nsDisplayMasksAndClipPathsGeometry(
nsDisplayMasksAndClipPaths* aItem,
nsDisplayListBuilder* aBuilder)
: nsDisplaySVGEffectGeometry(aItem, aBuilder)
, nsImageGeometryMixin(aItem, aBuilder)
, mDestRects(aItem->GetDestRects())
- , mOpacity(aItem->Frame()->StyleEffects()->mOpacity)
- , mHandleOpacity(aItem->ShouldHandleOpacity())
{
}
nsDisplayFiltersGeometry::nsDisplayFiltersGeometry(nsDisplayFilters* aItem,
nsDisplayListBuilder* aBuilder)
: nsDisplaySVGEffectGeometry(aItem, aBuilder)
, nsImageGeometryMixin(aItem, aBuilder)
{
--- a/layout/painting/nsDisplayListInvalidation.h
+++ b/layout/painting/nsDisplayListInvalidation.h
@@ -297,34 +297,34 @@ public:
nsDisplaySVGEffectGeometry(nsDisplayEffectsBase* aItem,
nsDisplayListBuilder* aBuilder);
void MoveBy(const nsPoint& aOffset) override;
gfxRect mBBox;
gfxPoint mUserSpaceOffset;
nsPoint mFrameOffsetToReferenceFrame;
+ float mOpacity;
+ bool mHandleOpacity;
};
class nsDisplayMasksAndClipPathsGeometry
: public nsDisplaySVGEffectGeometry
, public nsImageGeometryMixin<nsDisplayMasksAndClipPathsGeometry>
{
public:
nsDisplayMasksAndClipPathsGeometry(nsDisplayMasksAndClipPaths* aItem,
nsDisplayListBuilder* aBuilder);
bool InvalidateForSyncDecodeImages() const override
{
return ShouldInvalidateToSyncDecodeImages();
}
nsTArray<nsRect> mDestRects;
- float mOpacity;
- bool mHandleOpacity;
};
class nsDisplayFiltersGeometry
: public nsDisplaySVGEffectGeometry
, public nsImageGeometryMixin<nsDisplayFiltersGeometry>
{
public:
nsDisplayFiltersGeometry(nsDisplayFilters* aItem,
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionMedia.cpp
@@ -1151,16 +1151,20 @@ static void ToRTCIceCandidateStats(
cand.mIpAddress.Construct(
NS_ConvertASCIItoUTF16(candidate.cand_addr.host.c_str()));
cand.mPortNumber.Construct(candidate.cand_addr.port);
cand.mTransport.Construct(
NS_ConvertASCIItoUTF16(candidate.cand_addr.transport.c_str()));
if (candidateType == RTCStatsType::Local_candidate) {
cand.mMozLocalTransport.Construct(
NS_ConvertASCIItoUTF16(candidate.local_addr.transport.c_str()));
+ if (RTCStatsIceCandidateType(candidate.type) == RTCStatsIceCandidateType::Relayed) {
+ cand.mRelayProtocol.Construct(
+ NS_ConvertASCIItoUTF16(candidate.local_addr.transport.c_str()));
+ }
}
report->mIceCandidateStats.Value().AppendElement(cand, fallible);
if (candidate.trickled) {
report->mTrickledIceCandidateStats.Value().AppendElement(cand, fallible);
}
}
}
--- a/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp
+++ b/media/webrtc/signaling/src/peerconnection/WebrtcGlobalInformation.cpp
@@ -975,19 +975,19 @@ static uint32_t GetCandidateIpAndTranspo
CANDIDATE_BITMASK_UDP = 1,
CANDIDATE_BITMASK_TCP = 1 << 1,
CANDIDATE_BITMASK_IPV6 = 1 << 2,
};
uint32_t res = 0;
nsAutoCString transport;
- // prefer local transport for local relay candidates
- if (cand->mMozLocalTransport.WasPassed()) {
- transport.Assign(NS_ConvertUTF16toUTF8(cand->mMozLocalTransport.Value()));
+ // prefer relay transport for local relay candidates
+ if (cand->mRelayProtocol.WasPassed()) {
+ transport.Assign(NS_ConvertUTF16toUTF8(cand->mRelayProtocol.Value()));
} else {
transport.Assign(NS_ConvertUTF16toUTF8(cand->mTransport.Value()));
}
if (transport == kNrIceTransportUdp) {
res |= CANDIDATE_BITMASK_UDP;
} else if (transport == kNrIceTransportTcp) {
res |= CANDIDATE_BITMASK_TCP;
}
--- a/mfbt/tests/moz.build
+++ b/mfbt/tests/moz.build
@@ -4,16 +4,18 @@
# 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/.
if CONFIG['MOZ_WIDGET_TOOLKIT']:
TEST_DIRS += [
'gtest',
]
+# Important: for these tests to be run, they also need to be added
+# to testing/cppunittest.ini.
CppUnitTests([
'TestAlgorithm',
'TestArray',
'TestArrayUtils',
'TestAtomics',
'TestBinarySearch',
'TestBloomFilter',
'TestBufferList',
--- a/security/sandbox/mac/Sandbox.h
+++ b/security/sandbox/mac/Sandbox.h
@@ -40,50 +40,40 @@ typedef struct _MacSandboxPluginInfo {
typedef struct _MacSandboxInfo {
_MacSandboxInfo()
: type(MacSandboxType_Default)
, level(0)
, hasFilePrivileges(false)
, hasSandboxedProfile(false)
, hasAudio(false)
- , hasWindowServer(false)
, shouldLog(true)
{
}
_MacSandboxInfo(const struct _MacSandboxInfo& other) = default;
MacSandboxType type;
int32_t level;
bool hasFilePrivileges;
bool hasSandboxedProfile;
bool hasAudio;
- bool hasWindowServer;
MacSandboxPluginInfo pluginInfo;
std::string appPath;
std::string appBinaryPath;
std::string appDir;
std::string profileDir;
std::string debugWriteDir;
std::string testingReadPath1;
std::string testingReadPath2;
std::string testingReadPath3;
std::string testingReadPath4;
- std::string parentPort;
- std::string crashServerPort;
-
bool shouldLog;
} MacSandboxInfo;
namespace mozilla {
bool StartMacSandbox(MacSandboxInfo const &aInfo, std::string &aErrorMessage);
-bool EarlyStartMacSandboxIfEnabled(int aArgc, char** aArgv,
- std::string &aErrorMessage);
-#ifdef DEBUG
-void AssertMacSandboxEnabled();
-#endif /* DEBUG */
} // namespace mozilla
#endif // mozilla_Sandbox_h
--- a/security/sandbox/mac/Sandbox.mm
+++ b/security/sandbox/mac/Sandbox.mm
@@ -10,18 +10,16 @@
// linking to nsCocoaFeatures.mm in XUL.
#include "Sandbox.h"
#include <stdio.h>
#include <stdlib.h>
#include <CoreFoundation/CoreFoundation.h>
-#include <iostream>
-#include <sstream>
#include <vector>
#include "mozilla/Assertions.h"
// XXX There are currently problems with the /usr/include/sandbox.h file on
// some/all of the Macs in Mozilla's build system. Further,
// sandbox_init_with_parameters is not included in the header. For the time
// being (until this problem is resolved), we refer directly to what we need
@@ -221,32 +219,26 @@ bool StartMacSandbox(MacSandboxInfo cons
params.push_back("SANDBOX_LEVEL_2");
params.push_back(aInfo.level == 2 ? "TRUE" : "FALSE");
params.push_back("SANDBOX_LEVEL_3");
params.push_back(aInfo.level == 3 ? "TRUE" : "FALSE");
params.push_back("MAC_OS_MINOR");
params.push_back(macOSMinor.c_str());
params.push_back("APP_PATH");
params.push_back(aInfo.appPath.c_str());
+ params.push_back("APP_BINARY_PATH");
+ params.push_back(aInfo.appBinaryPath.c_str());
+ params.push_back("APP_DIR");
+ params.push_back(aInfo.appDir.c_str());
params.push_back("PROFILE_DIR");
params.push_back(aInfo.profileDir.c_str());
params.push_back("HOME_PATH");
params.push_back(getenv("HOME"));
params.push_back("HAS_SANDBOXED_PROFILE");
params.push_back(aInfo.hasSandboxedProfile ? "TRUE" : "FALSE");
- params.push_back("HAS_WINDOW_SERVER");
- params.push_back(aInfo.hasWindowServer ? "TRUE" : "FALSE");
- if (!aInfo.parentPort.empty()) {
- params.push_back("PARENT_PORT");
- params.push_back(aInfo.parentPort.c_str());
- }
- if (!aInfo.crashServerPort.empty()) {
- params.push_back("CRASH_PORT");
- params.push_back(aInfo.crashServerPort.c_str());
- }
if (!aInfo.testingReadPath1.empty()) {
params.push_back("TESTING_READ_PATH1");
params.push_back(aInfo.testingReadPath1.c_str());
}
if (!aInfo.testingReadPath2.empty()) {
params.push_back("TESTING_READ_PATH2");
params.push_back(aInfo.testingReadPath2.c_str());
}
@@ -325,191 +317,9 @@ bool StartMacSandbox(MacSandboxInfo cons
}
if (rv) {
return false;
}
return true;
}
-/*
- * Fill |aInfo| with content sandbox params parsed from the provided
- * command line arguments. Return false if any sandbox parameters needed
- * for early startup of the sandbox are not present in the arguments.
- */
-bool
-GetContentSandboxParamsFromArgs(int aArgc, char** aArgv, MacSandboxInfo& aInfo)
-{
- // Ensure we find these paramaters in the command
- // line arguments. Return false if any are missing.
- bool foundSandboxLevel = false;
- bool foundValidSandboxLevel = false;
- bool foundParentPort = false;
- bool foundAppPath = false;
-
- // Read access directories used in testing
- int nTestingReadPaths = 0;
- std::string testingReadPaths[MAX_TESTING_READ_PATHS] = {};
-
- // Collect sandbox params from CLI arguments
- for (int i = 0; i < aArgc; i++) {
-
- if ((strcmp(aArgv[i], "-sbLevel") == 0) && (i + 1 < aArgc)) {
- std::stringstream ss(aArgv[i+1]);
- int level = 0;
- ss >> level;
- foundSandboxLevel = true;
- aInfo.level = level;
- foundValidSandboxLevel = level > 0 && level <= 3 ? true : false;
- if (!foundValidSandboxLevel) {
- break;
- }
- i++;
- continue;
- }
-
- if (strcmp(aArgv[i], "-sbLogging") == 0) {
- aInfo.shouldLog = true;
- continue;
- }
-
- if (strcmp(aArgv[i], "-sbAllowFileAccess") == 0) {
- aInfo.hasFilePrivileges = true;
- continue;
- }
-
- if (strcmp(aArgv[i], "-sbAllowAudio") == 0) {
- aInfo.hasAudio = true;
- continue;
- }
-
- if (strcmp(aArgv[i], "-sbAllowWindowServer") == 0) {
- aInfo.hasWindowServer = true;
- continue;
- }
-
- if ((strcmp(aArgv[i], "-sbAppPath") == 0) && (i + 1 < aArgc)) {
- foundAppPath = true;
- aInfo.appPath.assign(aArgv[i+1]);
- i++;
- continue;
- }
-
- if ((strcmp(aArgv[i], "-sbTestingReadPath") == 0) && (i + 1 < aArgc)) {
- MOZ_ASSERT(nTestingReadPaths < MAX_TESTING_READ_PATHS);
- testingReadPaths[nTestingReadPaths] = aArgv[i+1];
- nTestingReadPaths++;
- i++;
- continue;
- }
-
- if ((strcmp(aArgv[i], "-profile") == 0) && (i + 1 < aArgc)) {
- aInfo.hasSandboxedProfile = true;
- aInfo.profileDir.assign(aArgv[i+1]);
- i++;
- continue;
- }
-
-#ifdef DEBUG
- if ((strcmp(aArgv[i], "-sbDebugWriteDir") == 0) && (i + 1 < aArgc)) {
- aInfo.debugWriteDir.assign(aArgv[i+1]);
- i++;
- continue;
- }
-#endif // DEBUG
-
- // Handle positional arguments
- if (strstr(aArgv[i], "org.mozilla.machname") != NULL) {
- foundParentPort = true;
- aInfo.parentPort.assign(aArgv[i]);
- continue;
- }
-
- if (strstr(aArgv[i], "gecko-crash-server-pipe") != NULL) {
- aInfo.crashServerPort.assign(aArgv[i]);
- continue;
- }
- }
-
- if (!foundSandboxLevel) {
- fprintf(stderr, "Content sandbox disabled due to "
- "missing sandbox CLI level parameter.\n");
- return false;
- }
-
- if (!foundValidSandboxLevel) {
- fprintf(stderr, "Content sandbox disabled due to invalid"
- "sandbox level (%d)\n", aInfo.level);
- return false;
- }
-
- if (!foundParentPort) {
- fprintf(stderr, "Content sandbox disabled due to "
- "missing sandbox CLI parent port parameter.\n");
- return false;
- }
-
- if (!foundAppPath) {
- fprintf(stderr, "Content sandbox disabled due to "
- "missing sandbox CLI app path parameter.\n");
- return false;
- }
-
- aInfo.testingReadPath1 = testingReadPaths[0];
- aInfo.testingReadPath2 = testingReadPaths[1];
- aInfo.testingReadPath3 = testingReadPaths[2];
- aInfo.testingReadPath4 = testingReadPaths[3];
-
- return true;
-}
-
-/*
- * Returns true if no errors were encountered or if early sandbox startup is
- * not enabled for this process. Returns false if an error was encountered.
- */
-bool
-EarlyStartMacSandboxIfEnabled(int aArgc, char** aArgv,
- std::string &aErrorMessage)
-{
- bool earlyStartupEnabled = false;
-
- // Check for the -sbStartup CLI parameter which
- // indicates we should start the sandbox now.
- for (int i = 0; i < aArgc; i++) {
- if (strcmp(aArgv[i], "-sbStartup") == 0) {
- earlyStartupEnabled = true;
- break;
- }
- }
-
- // The sandbox will be started later when/if parent
- // sends the sandbox startup message. Return true
- // indicating no errors occurred.
- if (!earlyStartupEnabled) {
- return true;
- }
-
- MacSandboxInfo info;
- info.type = MacSandboxType_Content;
- if (!GetContentSandboxParamsFromArgs(aArgc, aArgv, info)) {
- return false;
- }
-
- return StartMacSandbox(info, aErrorMessage);
-}
-
-#ifdef DEBUG
-/*
- * Ensures that a process sandbox is enabled by attempting to enable
- * a new sandbox policy and ASSERT'ing that this fails. This depends
- * on sandbox_init() failing when called again after a sandbox has
- * already been successfully enabled.
- */
-void
-AssertMacSandboxEnabled()
-{
- char *errorbuf = NULL;
- int rv = sandbox_init("(version 1)(deny default)", 0, &errorbuf);
- MOZ_ASSERT(rv != 0);
-}
-#endif /* DEBUG */
-
} // namespace mozilla
--- a/security/sandbox/mac/SandboxPolicies.h
+++ b/security/sandbox/mac/SandboxPolicies.h
@@ -1,18 +1,16 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
#ifndef mozilla_SandboxPolicies_h
#define mozilla_SandboxPolicies_h
-#define MAX_TESTING_READ_PATHS 4
-
namespace mozilla {
static const char pluginSandboxRules[] = R"SANDBOX_LITERAL(
(version 1)
(define should-log (param "SHOULD_LOG"))
(define plugin-binary-path (param "PLUGIN_BINARY_PATH"))
(define app-path (param "APP_PATH"))
@@ -47,27 +45,26 @@ static const char contentSandboxRules[]
(version 1)
(define should-log (param "SHOULD_LOG"))
(define sandbox-level-1 (param "SANDBOX_LEVEL_1"))
(define sandbox-level-2 (param "SANDBOX_LEVEL_2"))
(define sandbox-level-3 (param "SANDBOX_LEVEL_3"))
(define macosMinorVersion (string->number (param "MAC_OS_MINOR")))
(define appPath (param "APP_PATH"))
+ (define appBinaryPath (param "APP_BINARY_PATH"))
+ (define appdir-path (param "APP_DIR"))
(define hasProfileDir (param "HAS_SANDBOXED_PROFILE"))
(define profileDir (param "PROFILE_DIR"))
- (define hasWindowServer (param "HAS_WINDOW_SERVER"))
(define home-path (param "HOME_PATH"))
(define debugWriteDir (param "DEBUG_WRITE_DIR"))
(define testingReadPath1 (param "TESTING_READ_PATH1"))
(define testingReadPath2 (param "TESTING_READ_PATH2"))
(define testingReadPath3 (param "TESTING_READ_PATH3"))
(define testingReadPath4 (param "TESTING_READ_PATH4"))
- (define parentPort (param "PARENT_PORT"))
- (define crashPort (param "CRASH_PORT"))
(if (string=? should-log "TRUE")
(deny default)
(deny default (with no-log)))
(debug deny)
; These are not included in (deny default)
(deny process-info*)
; This isn't available in some older macOS releases.
@@ -79,22 +76,22 @@ static const char contentSandboxRules[]
(if (defined? 'file-map-executable)
(deny file-map-executable))
(if (defined? 'file-map-executable)
(allow file-map-executable file-read*
(subpath "/System")
(subpath "/usr/lib")
(subpath "/Library/GPUBundles")
- (subpath appPath))
+ (subpath appdir-path))
(allow file-read*
(subpath "/System")
(subpath "/usr/lib")
(subpath "/Library/GPUBundles")
- (subpath appPath)))
+ (subpath appdir-path)))
; Allow read access to standard system paths.
(allow file-read*
(require-all (file-mode #o0004)
(require-any
(subpath "/Library/Filesystems/NetFSPlugins")
(subpath "/usr/share"))))
@@ -183,24 +180,16 @@ static const char contentSandboxRules[]
(define (allow-shared-list domain)
(allow file-read*
(home-regex (string-append "/Library/Preferences/" (regex-quote domain)))))
(allow ipc-posix-shm-read-data ipc-posix-shm-write-data
(ipc-posix-name-regex #"^CFPBS:"))
(allow signal (target self))
- (if (string? parentPort)
- (allow mach-lookup (global-name parentPort)))
- (if (string? crashPort)
- (allow mach-lookup (global-name crashPort)))
- (if (string=? hasWindowServer "TRUE")
- (allow mach-lookup (global-name "com.apple.windowserver.active")))
- (allow mach-lookup (global-name "com.apple.coreservices.launchservicesd"))
- (allow mach-lookup (global-name "com.apple.lsd.mapdb"))
(if (>= macosMinorVersion 13)
(allow mach-lookup
; bug 1392988
(xpc-service-name "com.apple.coremedia.videodecoder")
(xpc-service-name "com.apple.coremedia.videoencoder")))
; bug 1312273
@@ -236,17 +225,19 @@ static const char contentSandboxRules[]
(literal "/")
(literal "/private/tmp")
(literal "/private/var/tmp")
(home-literal "/.CFUserTextEncoding")
(home-literal "/Library/Preferences/com.apple.DownloadAssessment.plist")
(home-subpath "/Library/Colors")
(home-subpath "/Library/Keyboard Layouts")
(home-subpath "/Library/Input Methods")
- (home-subpath "/Library/Spelling"))
+ (home-subpath "/Library/Spelling")
+ (literal appPath)
+ (literal appBinaryPath))
(if (defined? 'file-map-executable)
(begin
(when testingReadPath1
(allow file-read* file-map-executable (subpath testingReadPath1)))
(when testingReadPath2
(allow file-read* file-map-executable (subpath testingReadPath2)))
(when testingReadPath3
--- a/testing/cppunittest.ini
+++ b/testing/cppunittest.ini
@@ -1,62 +1,74 @@
[ShowSSEConfig]
[TestPrintf]
[TestAppShellSteadyState]
+[TestAlgorithm]
[TestArray]
[TestArrayUtils]
[TestAtomics]
[TestBinarySearch]
[TestBloomFilter]
+[TestBufferList]
[TestCasting]
[TestCeilingFloor]
[TestCheckedInt]
[TestCountPopulation]
[TestCountZeroes]
[TestDefineEnum]
+[TestDoublyLinkedList]
[TestDllInterceptor]
skip-if = os != 'win'
[TestEndian]
[TestEnumeratedArray]
[TestEnumSet]
[TestEnumTypeTraits]
[TestFastBernoulliTrial]
[TestFloatingPoint]
+[TestFunctionTypeTraits]
[TestIntegerPrintfMacros]
[TestIntegerRange]
[TestJSONWriter]
[TestLinkedList]
[TestMacroArgs]
[TestMacroForEach]
[TestMathAlgorithms]
[TestMaybe]
+[TestNonDereferenceable]
+[TestNotNull]
[TestParseFTPList]
[TestPLDHash]
[TestPair]
[TestPoisonArea]
skip-if = os == 'android' # Bug 1147630
+[TestRange]
[TestRefPtr]
+[TestResult]
[TestRollingMean]
[TestScopeExit]
[TestSegmentedVector]
[TestSHA1]
[TestSmallPointerArray]
[TestSaturate]
[TestSplayTree]
[TestSPSCQueue]
[TestSyncRunnable]
[TestTemplateLib]
+[TestTextUtils]
+[TestThreadSafeWeakPtr]
[TestTuple]
[TestTypeTraits]
[TestTypedEnum]
[TestUniquePtr]
+[TestUtf8]
[TestVariant]
[TestVector]
[TestVolatileBuffer]
[TestWeakPtr]
+[TestWrappingOperations]
[TestXorShift128PlusRNG]
[buffered_stun_socket_unittest]
[ice_unittest]
[test_nr_socket_unittest]
[jsapi-tests]
[multi_tcp_socket_unittest]
[nrappkit_unittest]
[rlogringbuffer_unittest]
--- a/toolkit/content/aboutwebrtc/aboutWebrtc.js
+++ b/toolkit/content/aboutwebrtc/aboutWebrtc.js
@@ -845,17 +845,17 @@ ICEStats.prototype = {
candidateToString(c) {
if (!c) {
return "*";
}
var type = c.candidateType;
if (c.type == "local-candidate" && c.candidateType == "relayed") {
- type = `${c.candidateType}-${c.mozLocalTransport}`;
+ type = `${c.candidateType}-${c.relayProtocol}`;
}
return `${c.ipAddress}:${c.portNumber}/${c.transport}(${type})`;
},
};
function FoldableSection(parentElement, options = {}) {
this._foldableElement = document.createElement("div");
--- a/toolkit/recordreplay/ProcessRedirectDarwin.cpp
+++ b/toolkit/recordreplay/ProcessRedirectDarwin.cpp
@@ -711,24 +711,17 @@ Preamble_gettimeofday(CallArguments* aAr
return PreambleResult::PassThrough;
}
return PreambleResult::Redirect;
}
static PreambleResult
Preamble_fcntl(CallArguments* aArguments)
{
- // We don't record any outputs for fcntl other than its return value, but
- // some commands have an output parameter they write additional data to.
- // Handle this by only allowing a limited set of commands to be used when
- // events are not passed through and we are recording/replaying the outputs.
- if (AreThreadEventsPassedThrough()) {
- return PreambleResult::Redirect;
- }
-
+ // Make sure fcntl is only used with a limited set of commands.
auto& cmd = aArguments->Arg<1, size_t>();
switch (cmd) {
case F_GETFL:
case F_SETFL:
case F_GETFD:
case F_SETFD:
case F_NOCACHE:
case F_SETLK:
--- a/xpcom/base/nsMacUtilsImpl.cpp
+++ b/xpcom/base/nsMacUtilsImpl.cpp
@@ -1,23 +1,16 @@
/* -*- 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 "nsMacUtilsImpl.h"
-#include "base/command_line.h"
-#include "nsDirectoryServiceDefs.h"
-#include "nsCOMPtr.h"
-#include "nsIFile.h"
-#include "nsIProperties.h"
-#include "nsServiceManagerUtils.h"
-
#include <CoreFoundation/CoreFoundation.h>
NS_IMPL_ISUPPORTS(nsMacUtilsImpl, nsIMacUtils)
nsresult
nsMacUtilsImpl::GetArchString(nsAString& aArchString)
{
if (!mBinaryArchs.IsEmpty()) {
@@ -127,69 +120,8 @@ nsMacUtilsImpl::GetIsTranslated(bool* aI
#else
// Translation only exists for ppc code. Other architectures aren't
// translated.
*aIsTranslated = false;
#endif
return NS_OK;
}
-
-#if defined(MOZ_CONTENT_SANDBOX)
-bool
-nsMacUtilsImpl::GetAppPath(nsCString &aAppPath)
-{
- nsAutoCString appPath;
- nsAutoCString appBinaryPath(
- (CommandLine::ForCurrentProcess()->argv()[0]).c_str());
-
- nsAutoCString::const_iterator start, end;
- appBinaryPath.BeginReading(start);
- appBinaryPath.EndReading(end);
- if (RFindInReadable(NS_LITERAL_CSTRING(".app/Contents/MacOS/"), start, end)) {
- end = start;
- ++end; ++end; ++end; ++end;
- appBinaryPath.BeginReading(start);
- appPath.Assign(Substring(start, end));
- } else {
- return false;
- }
-
- nsCOMPtr<nsIFile> app;
- nsresult rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(appPath),
- true, getter_AddRefs(app));
- if (NS_FAILED(rv)) {
- return false;
- }
-
- rv = app->Normalize();
- if (NS_FAILED(rv)) {
- return false;
- }
- app->GetNativePath(aAppPath);
-
- return true;
-}
-
-#if defined(DEBUG)
-// Given a path to a file, return the directory which contains it.
-nsAutoCString
-nsMacUtilsImpl::GetDirectoryPath(const char *aPath)
-{
- nsCOMPtr<nsIFile> file = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
- if (!file ||
- NS_FAILED(file->InitWithNativePath(nsDependentCString(aPath)))) {
- MOZ_CRASH("Failed to create or init an nsIFile");
- }
- nsCOMPtr<nsIFile> directoryFile;
- if (NS_FAILED(file->GetParent(getter_AddRefs(directoryFile))) ||
- !directoryFile) {
- MOZ_CRASH("Failed to get parent for an nsIFile");
- }
- directoryFile->Normalize();
- nsAutoCString directoryPath;
- if (NS_FAILED(directoryFile->GetNativePath(directoryPath))) {
- MOZ_CRASH("Failed to get path for an nsIFile");
- }
- return directoryPath;
-}
-#endif /* DEBUG */
-#endif /* MOZ_CONTENT_SANDBOX */
--- a/xpcom/base/nsMacUtilsImpl.h
+++ b/xpcom/base/nsMacUtilsImpl.h
@@ -16,24 +16,16 @@ class nsMacUtilsImpl final : public nsIM
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIMACUTILS
nsMacUtilsImpl()
{
}
-#if defined(MOZ_CONTENT_SANDBOX)
- static bool GetAppPath(nsCString &aAppPath);
-
-#ifdef DEBUG
- static nsAutoCString GetDirectoryPath(const char *aPath);
-#endif /* DEBUG */
-#endif /* MOZ_CONTENT_SANDBOX */
-
private:
~nsMacUtilsImpl()
{
}
nsresult GetArchString(nsAString& aArchString);
// A string containing a "-" delimited list of architectures