diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js index 664b93530633..d811a90b6b22 100644 --- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -959,11 +959,6 @@ pref("layout.accessiblecaret.bar.enabled", true); // Hide the caret in cursor mode after 3 seconds. pref("layout.accessiblecaret.timeout_ms", 3000); -// APZ on real devices supports long tap events. -#ifdef MOZ_WIDGET_GONK -pref("layout.accessiblecaret.use_long_tap_injector", false); -#endif - // Hide carets and text selection dialog during scrolling. pref("layout.accessiblecaret.always_show_when_scrolling", false); diff --git a/b2g/app/nsBrowserApp.cpp b/b2g/app/nsBrowserApp.cpp index 33199224af87..967b54b764bf 100644 --- a/b2g/app/nsBrowserApp.cpp +++ b/b2g/app/nsBrowserApp.cpp @@ -41,6 +41,7 @@ # include #endif +#include "mozilla/Sprintf.h" #include "mozilla/Telemetry.h" #include "mozilla/WindowsDllBlocklist.h" @@ -123,7 +124,7 @@ static int do_main(int argc, char* argv[]) } char appEnv[MAXPATHLEN]; - snprintf(appEnv, MAXPATHLEN, "XUL_APP_FILE=%s", argv[2]); + SprintfLiteral(appEnv, "XUL_APP_FILE=%s", argv[2]); if (putenv(strdup(appEnv))) { Output("Couldn't set %s.\n", appEnv); return 255; diff --git a/browser/app/nsBrowserApp.cpp b/browser/app/nsBrowserApp.cpp index 335b32354daa..981e2f14cfd7 100644 --- a/browser/app/nsBrowserApp.cpp +++ b/browser/app/nsBrowserApp.cpp @@ -39,6 +39,7 @@ #include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL +#include "mozilla/Sprintf.h" #include "mozilla/Telemetry.h" #include "mozilla/WindowsDllBlocklist.h" @@ -192,7 +193,7 @@ static int do_main(int argc, char* argv[], char* envp[], nsIFile *xreDirectory) } char appEnv[MAXPATHLEN]; - snprintf(appEnv, MAXPATHLEN, "XUL_APP_FILE=%s", argv[2]); + SprintfLiteral(appEnv, "XUL_APP_FILE=%s", argv[2]); if (putenv(strdup(appEnv))) { Output("Couldn't set %s.\n", appEnv); return 255; diff --git a/browser/locales/en-US/chrome/browser/preferences/preferences.properties b/browser/locales/en-US/chrome/browser/preferences/preferences.properties index c4ae0a948e52..bf9ac602bcb0 100644 --- a/browser/locales/en-US/chrome/browser/preferences/preferences.properties +++ b/browser/locales/en-US/chrome/browser/preferences/preferences.properties @@ -183,7 +183,7 @@ disableContainersAlertTitle=Close All Container Tabs? # LOCALIZATION NOTE (disableContainersMsg): Semi-colon list of plural forms. # See: http://developer.mozilla.org/en/docs/Localization_and_Plurals # #S is the number of container tabs -disableContainersMsg=If you disable Container Tabs now, #S container tab will be closed. Are you sure you want to disable Container Tabs?;If you disable Containers Tabs now, #S container tabs will be closed. Are you sure you want to disable Containers Tabs? +disableContainersMsg=If you disable Container Tabs now, #S container tab will be closed. Are you sure you want to disable Container Tabs?;If you disable Container Tabs now, #S container tabs will be closed. Are you sure you want to disable Container Tabs? # LOCALIZATION NOTE (disableContainersOkButton): Semi-colon list of plural forms. # See: http://developer.mozilla.org/en/docs/Localization_and_Plurals diff --git a/build/autoconf/clang-plugin.m4 b/build/autoconf/clang-plugin.m4 index cbdc7874a6fe..22a48976ddb1 100644 --- a/build/autoconf/clang-plugin.m4 +++ b/build/autoconf/clang-plugin.m4 @@ -121,6 +121,35 @@ if test -n "$ENABLE_CLANG_PLUGIN"; then LLVM_CXXFLAGS="$LLVM_CXXFLAGS -DHAVE_NEW_ASTMATCHER_NAMES" fi + dnl Check if we can compile has(ignoringParenImpCasts()) because + dnl before 3.9 that ignoringParenImpCasts was done internally by "has". + dnl See https://www.mail-archive.com/cfe-commits@lists.llvm.org/msg25234.html + AC_CACHE_CHECK(for has with ignoringParenImpCasts, + ac_cv_has_accepts_ignoringParenImpCasts, + [ + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + _SAVE_CXXFLAGS="$CXXFLAGS" + _SAVE_CXX="$CXX" + _SAVE_MACOSX_DEPLOYMENT_TARGET="$MACOSX_DEPLOYMENT_TARGET" + unset MACOSX_DEPLOYMENT_TARGET + CXXFLAGS="${LLVM_CXXFLAGS}" + CXX="${HOST_CXX}" + AC_TRY_COMPILE([#include "clang/ASTMatchers/ASTMatchers.h"], + [using namespace clang::ast_matchers; + expr(has(ignoringParenImpCasts(declRefExpr()))); + ], + ac_cv_has_accepts_ignoringParenImpCasts="yes", + ac_cv_has_accepts_ignoringParenImpCasts="no") + CXX="$_SAVE_CXX" + CXXFLAGS="$_SAVE_CXXFLAGS" + export MACOSX_DEPLOYMENT_TARGET="$_SAVE_MACOSX_DEPLOYMENT_TARGET" + AC_LANG_RESTORE + ]) + if test "$ac_cv_has_accepts_ignoringParenImpCasts" = "yes"; then + LLVM_CXXFLAGS="$LLVM_CXXFLAGS -DHAS_ACCEPTS_IGNORINGPARENIMPCASTS" + fi + AC_DEFINE(MOZ_CLANG_PLUGIN) fi diff --git a/build/clang-plugin/clang-plugin.cpp b/build/clang-plugin/clang-plugin.cpp index 97ca70c7cffd..44ca9c997b40 100644 --- a/build/clang-plugin/clang-plugin.cpp +++ b/build/clang-plugin/clang-plugin.cpp @@ -42,6 +42,14 @@ typedef ASTConsumer *ASTConsumerPtr; #define cxxRecordDecl recordDecl #endif +#ifndef HAS_ACCEPTS_IGNORINGPARENIMPCASTS +#define hasIgnoringParenImpCasts(x) has(x) +#else +// Before clang 3.9 "has" would behave like has(ignoringParenImpCasts(x)), +// however doing that explicitly would not compile. +#define hasIgnoringParenImpCasts(x) has(ignoringParenImpCasts(x)) +#endif + // Check if the given expression contains an assignment expression. // This can either take the form of a Binary Operator or a // Overloaded Operator Call. @@ -163,6 +171,11 @@ private: virtual void run(const MatchFinder::MatchResult &Result); }; + class SprintfLiteralChecker : public MatchFinder::MatchCallback { + public: + virtual void run(const MatchFinder::MatchResult &Result); + }; + ScopeChecker Scope; ArithmeticArgChecker ArithmeticArg; TrivialCtorDtorChecker TrivialCtorDtor; @@ -180,6 +193,7 @@ private: RefCountedCopyConstructorChecker RefCountedCopyConstructor; AssertAssignmentChecker AssertAttribution; KungFuDeathGripChecker KungFuDeathGrip; + SprintfLiteralChecker SprintfLiteral; MatchFinder AstMatcher; }; @@ -284,6 +298,35 @@ bool isIgnoredPathForImplicitConversion(const Decl *Declaration) { return false; } +bool isIgnoredPathForSprintfLiteral(const CallExpr *Call, const SourceManager &SM) { + SourceLocation Loc = Call->getLocStart(); + SmallString<1024> FileName = SM.getFilename(Loc); + llvm::sys::fs::make_absolute(FileName); + llvm::sys::path::reverse_iterator Begin = llvm::sys::path::rbegin(FileName), + End = llvm::sys::path::rend(FileName); + for (; Begin != End; ++Begin) { + if (Begin->compare_lower(StringRef("angle")) == 0 || + Begin->compare_lower(StringRef("chromium")) == 0 || + Begin->compare_lower(StringRef("crashreporter")) == 0 || + Begin->compare_lower(StringRef("google-breakpad")) == 0 || + Begin->compare_lower(StringRef("harfbuzz")) == 0 || + Begin->compare_lower(StringRef("libstagefright")) == 0 || + Begin->compare_lower(StringRef("mtransport")) == 0 || + Begin->compare_lower(StringRef("protobuf")) == 0 || + Begin->compare_lower(StringRef("skia")) == 0 || + // Gtest uses snprintf as GTEST_SNPRINTF_ with sizeof + Begin->compare_lower(StringRef("testing")) == 0) { + return true; + } + if (Begin->compare_lower(StringRef("webrtc")) == 0) { + // Ignore trunk/webrtc, but not media/webrtc + ++Begin; + return Begin != End && Begin->compare_lower(StringRef("trunk")) == 0; + } + } + return false; +} + bool isInterestingDeclForImplicitConversion(const Decl *Declaration) { return !isInIgnoredNamespaceForImplicitConversion(Declaration) && !isIgnoredPathForImplicitConversion(Declaration); @@ -861,6 +904,23 @@ AST_MATCHER(CallExpr, isAssertAssignmentTestFunc) { && Method->getName() == AssertName; } +AST_MATCHER(CallExpr, isSnprintfLikeFunc) { + static const std::string Snprintf = "snprintf"; + static const std::string Vsnprintf = "vsnprintf"; + const FunctionDecl *Func = Node.getDirectCallee(); + + if (!Func || isa(Func)) { + return false; + } + + StringRef Name = getNameChecked(Func); + if (Name != Snprintf && Name != Vsnprintf) { + return false; + } + + return !isIgnoredPathForSprintfLiteral(&Node, Finder->getASTContext().getSourceManager()); +} + AST_MATCHER(CXXRecordDecl, isLambdaDecl) { return Node.isLambda(); } @@ -1091,9 +1151,9 @@ DiagnosticsMatcher::DiagnosticsMatcher() { AstMatcher.addMatcher( binaryOperator( allOf(binaryEqualityOperator(), - hasLHS(has( + hasLHS(hasIgnoringParenImpCasts( declRefExpr(hasType(qualType((isFloat())))).bind("lhs"))), - hasRHS(has( + hasRHS(hasIgnoringParenImpCasts( declRefExpr(hasType(qualType((isFloat())))).bind("rhs"))), unless(anyOf(isInSystemHeader(), isInSkScalarDotH())))) .bind("node"), @@ -1195,6 +1255,17 @@ DiagnosticsMatcher::DiagnosticsMatcher() { AstMatcher.addMatcher(varDecl(hasType(isRefPtr())).bind("decl"), &KungFuDeathGrip); + + AstMatcher.addMatcher( + callExpr(isSnprintfLikeFunc(), + allOf(hasArgument(0, ignoringParenImpCasts(declRefExpr().bind("buffer"))), + anyOf(hasArgument(1, sizeOfExpr(hasIgnoringParenImpCasts(declRefExpr().bind("size")))), + hasArgument(1, integerLiteral().bind("immediate")), + hasArgument(1, declRefExpr(to(varDecl(hasType(isConstQualified()), + hasInitializer(integerLiteral().bind("constant"))))))))) + .bind("funcCall"), + &SprintfLiteral + ); } // These enum variants determine whether an allocation has occured in the code. @@ -1834,6 +1905,61 @@ void DiagnosticsMatcher::KungFuDeathGripChecker::run( Diag.Report(E->getLocStart(), NoteID) << NoteThing << getNameChecked(D); } +void DiagnosticsMatcher::SprintfLiteralChecker::run( + const MatchFinder::MatchResult &Result) { + if (!Result.Context->getLangOpts().CPlusPlus) { + // SprintfLiteral is not usable in C, so there is no point in issuing these + // warnings. + return; + } + + DiagnosticsEngine &Diag = Result.Context->getDiagnostics(); + unsigned ErrorID = Diag.getDiagnosticIDs()->getCustomDiagID( + DiagnosticIDs::Error, "Use %1 instead of %0 when writing into a character array."); + unsigned NoteID = Diag.getDiagnosticIDs()->getCustomDiagID( + DiagnosticIDs::Note, "This will prevent passing in the wrong size to %0 accidentally."); + + const CallExpr *D = Result.Nodes.getNodeAs("funcCall"); + + StringRef Name = D->getDirectCallee()->getName(); + const char *Replacement; + if (Name == "snprintf") { + Replacement = "SprintfLiteral"; + } else { + assert(Name == "vsnprintf"); + Replacement = "VsprintfLiteral"; + } + + const DeclRefExpr *Buffer = Result.Nodes.getNodeAs("buffer"); + const DeclRefExpr *Size = Result.Nodes.getNodeAs("size"); + if (Size) { + // Match calls like snprintf(x, sizeof(x), ...). + if (Buffer->getFoundDecl() != Size->getFoundDecl()) { + return; + } + + Diag.Report(D->getLocStart(), ErrorID) << Name << Replacement; + Diag.Report(D->getLocStart(), NoteID) << Name; + return; + } + + const QualType QType = Buffer->getType(); + const ConstantArrayType *Type = dyn_cast(QType.getTypePtrOrNull()); + if (Type) { + // Match calls like snprintf(x, 100, ...), where x is int[100]; + const IntegerLiteral *Literal = Result.Nodes.getNodeAs("immediate"); + if (!Literal) { + // Match calls like: const int y = 100; snprintf(x, y, ...); + Literal = Result.Nodes.getNodeAs("constant"); + } + + if (Type->getSize().ule(Literal->getValue())) { + Diag.Report(D->getLocStart(), ErrorID) << Name << Replacement; + Diag.Report(D->getLocStart(), NoteID) << Name; + } + } +} + class MozCheckAction : public PluginASTAction { public: ASTConsumerPtr CreateASTConsumer(CompilerInstance &CI, diff --git a/build/clang-plugin/tests/TestSprintfLiteral.cpp b/build/clang-plugin/tests/TestSprintfLiteral.cpp new file mode 100644 index 000000000000..9b76754336e3 --- /dev/null +++ b/build/clang-plugin/tests/TestSprintfLiteral.cpp @@ -0,0 +1,47 @@ +#include + +void bad() { + char x[100]; + snprintf(x, sizeof(x), "bar"); // expected-error {{Use SprintfLiteral instead of snprintf when writing into a character array.}} expected-note {{This will prevent passing in the wrong size to snprintf accidentally.}} + snprintf(x, 100, "bar"); // expected-error {{Use SprintfLiteral instead of snprintf when writing into a character array.}} expected-note {{This will prevent passing in the wrong size to snprintf accidentally.}} + snprintf(x, 101, "bar"); // expected-error {{Use SprintfLiteral instead of snprintf when writing into a character array.}} expected-note {{This will prevent passing in the wrong size to snprintf accidentally.}} + const int hundred = 100; + snprintf(x, hundred, "bar"); // expected-error {{Use SprintfLiteral instead of snprintf when writing into a character array.}} expected-note {{This will prevent passing in the wrong size to snprintf accidentally.}} + const int hundredandone = 101; + snprintf(x, hundredandone, "bar"); // expected-error {{Use SprintfLiteral instead of snprintf when writing into a character array.}} expected-note {{This will prevent passing in the wrong size to snprintf accidentally.}} +} + +void ok() { + char x[100]; + int y; + snprintf(x, sizeof(y), "what"); + + snprintf(x, 50, "what"); + + int nothundred = 100; + nothundred = 99; + snprintf(x, nothundred, "what"); +} + +void vargs_bad(va_list args) { + char x[100]; + vsnprintf(x, sizeof(x), "bar", args); // expected-error {{Use VsprintfLiteral instead of vsnprintf when writing into a character array.}} expected-note {{This will prevent passing in the wrong size to vsnprintf accidentally.}} + vsnprintf(x, 100, "bar", args); // expected-error {{Use VsprintfLiteral instead of vsnprintf when writing into a character array.}} expected-note {{This will prevent passing in the wrong size to vsnprintf accidentally.}} + vsnprintf(x, 101, "bar", args); // expected-error {{Use VsprintfLiteral instead of vsnprintf when writing into a character array.}} expected-note {{This will prevent passing in the wrong size to vsnprintf accidentally.}} + const int hundred = 100; + vsnprintf(x, hundred, "bar", args); // expected-error {{Use VsprintfLiteral instead of vsnprintf when writing into a character array.}} expected-note {{This will prevent passing in the wrong size to vsnprintf accidentally.}} + const int hundredandone = 101; + vsnprintf(x, hundredandone, "bar", args); // expected-error {{Use VsprintfLiteral instead of vsnprintf when writing into a character array.}} expected-note {{This will prevent passing in the wrong size to vsnprintf accidentally.}} +} + +void vargs_good(va_list args) { + char x[100]; + int y; + vsnprintf(x, sizeof(y), "what", args); + + vsnprintf(x, 50, "what", args); + + int nothundred = 100; + nothundred = 99; + vsnprintf(x, nothundred, "what", args); +} diff --git a/build/clang-plugin/tests/moz.build b/build/clang-plugin/tests/moz.build index 7925a77c629e..6c3bb5e94ecd 100644 --- a/build/clang-plugin/tests/moz.build +++ b/build/clang-plugin/tests/moz.build @@ -33,6 +33,7 @@ SOURCES += [ 'TestNonTemporaryClass.cpp', 'TestNoRefcountedInsideLambdas.cpp', 'TestRefCountedCopyConstructor.cpp', + 'TestSprintfLiteral.cpp', 'TestStackClass.cpp', 'TestTrivialCtorDtor.cpp', ] diff --git a/build/moz.configure/toolchain.configure b/build/moz.configure/toolchain.configure index 2e37f6056bb3..8aaf2fd14a71 100644 --- a/build/moz.configure/toolchain.configure +++ b/build/moz.configure/toolchain.configure @@ -345,16 +345,20 @@ def check_compiler(compiler, language, target): # Note: MSVC, while supporting C++11, still reports 199711L for __cplusplus. # Note: this is a strict version check because we used to always add # -std=gnu++11. - if info.language == 'C++' and info.language_version != 201103: - if info.type in ('clang-cl', 'clang', 'gcc'): + if info.language == 'C++': + if info.type in ('clang', 'gcc') and info.language_version != 201103: append_flag('-std=gnu++11') + # MSVC 2015 headers include C++14 features, but don't guard them + # with appropriate checks. + if info.type == 'clang-cl' and info.language_version != 201402: + append_flag('-std=c++14') - # We force clang-cl to emulate Visual C++ 2013 Update 3 with fallback to + # We force clang-cl to emulate Visual C++ 2015 Update 2 with fallback to # cl.exe. - if info.type == 'clang-cl' and info.version != '18.00.30723': + if info.type == 'clang-cl' and info.version != '19.00.23918': # Those flags are direct clang-cl flags that don't need -Xclang, add # them directly. - flags.append('-fms-compatibility-version=18.00.30723') + flags.append('-fms-compatibility-version=19.00.23918') flags.append('-fallback') # Check compiler target diff --git a/dom/base/nsHostObjectProtocolHandler.cpp b/dom/base/nsHostObjectProtocolHandler.cpp index 440633e35d75..3aab90c56b8a 100644 --- a/dom/base/nsHostObjectProtocolHandler.cpp +++ b/dom/base/nsHostObjectProtocolHandler.cpp @@ -134,11 +134,6 @@ BroadcastBlobURLRegistration(const nsACString& aURI, return; } - // We don't need to broadcast Blob URL if we have just 1 content process. - if (Preferences::GetInt("dom.ipc.processCount", 0) <= 1) { - return; - } - ContentChild* cc = ContentChild::GetSingleton(); BlobChild* actor = cc->GetOrCreateActorForBlobImpl(aBlobImpl); if (NS_WARN_IF(!actor)) { diff --git a/dom/ipc/Blob.cpp b/dom/ipc/Blob.cpp index cbb089f9ae78..d9fc95cc68c1 100644 --- a/dom/ipc/Blob.cpp +++ b/dom/ipc/Blob.cpp @@ -912,7 +912,8 @@ CreateBlobImpl(const ParentBlobConstructorParams& aParams, template void BlobDataFromBlobImpl(ChildManagerType* aManager, BlobImpl* aBlobImpl, - BlobData& aBlobData) + BlobData& aBlobData, + nsTArray>& aIPCStreams) { MOZ_ASSERT(gProcessType != GeckoProcessType_Default); MOZ_ASSERT(aBlobImpl); @@ -931,7 +932,7 @@ BlobDataFromBlobImpl(ChildManagerType* aManager, BlobImpl* aBlobImpl, index < count; index++) { BlobDataFromBlobImpl(aManager, subBlobs->ElementAt(index), - subBlobDatas[index]); + subBlobDatas[index], aIPCStreams); } return; @@ -951,9 +952,11 @@ BlobDataFromBlobImpl(ChildManagerType* aManager, BlobImpl* aBlobImpl, aBlobImpl->GetInternalStream(getter_AddRefs(inputStream), rv); MOZ_ALWAYS_TRUE(!rv.Failed()); - AutoIPCStream autoStream; - autoStream.Serialize(inputStream, aManager); - aBlobData = autoStream.TakeValue(); + UniquePtr autoStream(new AutoIPCStream()); + autoStream->Serialize(inputStream, aManager); + aBlobData = autoStream->TakeValue(); + + aIPCStreams.AppendElement(Move(autoStream)); } RemoteInputStream::RemoteInputStream(BlobImpl* aBlobImpl, @@ -3347,6 +3350,7 @@ BlobChild::GetOrCreateFromImpl(ChildManagerType* aManager, MOZ_ASSERT(!aBlobImpl->IsDateUnknown()); AnyBlobConstructorParams blobParams; + nsTArray> autoIPCStreams; if (gProcessType == GeckoProcessType_Default) { RefPtr sameProcessImpl = aBlobImpl; @@ -3358,7 +3362,7 @@ BlobChild::GetOrCreateFromImpl(ChildManagerType* aManager, // BlobData is going to be populate here and it _must_ be send via IPC in // order to avoid leaks. BlobData blobData; - BlobDataFromBlobImpl(aManager, aBlobImpl, blobData); + BlobDataFromBlobImpl(aManager, aBlobImpl, blobData, autoIPCStreams); nsString contentType; aBlobImpl->GetType(contentType); @@ -3393,6 +3397,7 @@ BlobChild::GetOrCreateFromImpl(ChildManagerType* aManager, return nullptr; } + autoIPCStreams.Clear(); return actor; } diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index 1bad3d422221..2f17a01787f0 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -3450,5 +3450,26 @@ ContentChild::RecvGetFilesResponse(const nsID& aUUID, return true; } +/* static */ void +ContentChild::FatalErrorIfNotUsingGPUProcess(const char* const aProtocolName, + const char* const aErrorMsg, + base::ProcessId aOtherPid) +{ + // If we're communicating with the same process or the UI process then we + // want to crash normally. Otherwise we want to just warn as the other end + // must be the GPU process and it crashing shouldn't be fatal for us. + if (aOtherPid == base::GetCurrentProcId() || + (GetSingleton() && GetSingleton()->OtherPid() == aOtherPid)) { + mozilla::ipc::FatalError(aProtocolName, aErrorMsg, false); + } else { + nsAutoCString formattedMessage("IPDL error ["); + formattedMessage.AppendASCII(aProtocolName); + formattedMessage.AppendLiteral("]: \""); + formattedMessage.AppendASCII(aErrorMsg); + formattedMessage.AppendLiteral("\"."); + NS_WARNING(formattedMessage.get()); + } +} + } // namespace dom } // namespace mozilla diff --git a/dom/ipc/ContentChild.h b/dom/ipc/ContentChild.h index 055fd01b1990..092a4b1923bd 100644 --- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -671,6 +671,16 @@ public: virtual bool RecvBlobURLUnregistration(const nsCString& aURI) override; + /** + * Helper function for protocols that use the GPU process when available. + * Overrides FatalError to just be a warning when communicating with the + * GPU process since we don't want to crash the content process when the + * GPU process crashes. + */ + static void FatalErrorIfNotUsingGPUProcess(const char* const aProtocolName, + const char* const aErrorMsg, + base::ProcessId aOtherPid); + private: static void ForceKillTimerCallback(nsITimer* aTimer, void* aClosure); void StartForceKillTimer(); diff --git a/dom/media/VideoUtils.cpp b/dom/media/VideoUtils.cpp index ef7cdda857cf..57b7a94811df 100644 --- a/dom/media/VideoUtils.cpp +++ b/dom/media/VideoUtils.cpp @@ -29,6 +29,10 @@ namespace mozilla { +NS_NAMED_LITERAL_CSTRING(kEMEKeySystemClearkey, "org.w3.clearkey"); +NS_NAMED_LITERAL_CSTRING(kEMEKeySystemWidevine, "com.widevine.alpha"); +NS_NAMED_LITERAL_CSTRING(kEMEKeySystemPrimetime, "com.adobe.primetime"); + using layers::PlanarYCbCrImage; CheckedInt64 SaferMultDiv(int64_t aValue, uint32_t aMul, uint32_t aDiv) { diff --git a/dom/media/VideoUtils.h b/dom/media/VideoUtils.h index c9179d9d3e78..a297a6f54662 100644 --- a/dom/media/VideoUtils.h +++ b/dom/media/VideoUtils.h @@ -40,9 +40,9 @@ using mozilla::CheckedUint32; namespace mozilla { // EME Key System String. -static NS_NAMED_LITERAL_CSTRING(kEMEKeySystemClearkey, "org.w3.clearkey"); -static NS_NAMED_LITERAL_CSTRING(kEMEKeySystemWidevine, "com.widevine.alpha"); -static NS_NAMED_LITERAL_CSTRING(kEMEKeySystemPrimetime, "com.adobe.primetime"); +extern const nsLiteralCString kEMEKeySystemClearkey; +extern const nsLiteralCString kEMEKeySystemWidevine; +extern const nsLiteralCString kEMEKeySystemPrimetime; /** * ReentrantMonitorConditionallyEnter diff --git a/dom/media/ipc/VideoDecoderManagerChild.cpp b/dom/media/ipc/VideoDecoderManagerChild.cpp index 0d0f0b8e0459..565493e345b1 100644 --- a/dom/media/ipc/VideoDecoderManagerChild.cpp +++ b/dom/media/ipc/VideoDecoderManagerChild.cpp @@ -145,5 +145,11 @@ VideoDecoderManagerChild::DeallocateSurfaceDescriptorGPUVideo(const SurfaceDescr }), NS_DISPATCH_NORMAL); } +void +VideoDecoderManagerChild::FatalError(const char* const aName, const char* const aMsg) const +{ + dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aName, aMsg, OtherPid()); +} + } // namespace dom } // namespace mozilla diff --git a/dom/media/ipc/VideoDecoderManagerChild.h b/dom/media/ipc/VideoDecoderManagerChild.h index dc594ce7f5a4..267fa162cdfe 100644 --- a/dom/media/ipc/VideoDecoderManagerChild.h +++ b/dom/media/ipc/VideoDecoderManagerChild.h @@ -26,6 +26,8 @@ public: void DeallocPVideoDecoderManagerChild() override; + void FatalError(const char* const aName, const char* const aMsg) const override; + // Main thread only static void Initialize(); static void Shutdown(); diff --git a/dom/plugins/ipc/PluginModuleChild.cpp b/dom/plugins/ipc/PluginModuleChild.cpp index fe4e98069fb7..abf190768ac8 100644 --- a/dom/plugins/ipc/PluginModuleChild.cpp +++ b/dom/plugins/ipc/PluginModuleChild.cpp @@ -32,6 +32,7 @@ #include "mozilla/plugins/BrowserStreamChild.h" #include "mozilla/plugins/PluginStreamChild.h" #include "mozilla/dom/CrashReporterChild.h" +#include "mozilla/Sprintf.h" #include "mozilla/Unused.h" #include "nsNPAPIPlugin.h" @@ -265,7 +266,7 @@ PluginModuleChild::InitForChrome(const std::string& aPluginFilename, #if defined(XP_MACOSX) const char* namePrefix = "Plugin Content"; char nameBuffer[80]; - snprintf(nameBuffer, sizeof(nameBuffer), "%s (%s)", namePrefix, info.fName); + SprintfLiteral(nameBuffer, "%s (%s)", namePrefix, info.fName); mozilla::plugins::PluginUtilsOSX::SetProcessName(nameBuffer); #endif pluginFile.FreePluginInfo(info); diff --git a/dom/plugins/ipc/PluginUtilsOSX.mm b/dom/plugins/ipc/PluginUtilsOSX.mm index a4448f8f685f..2a920f7f6112 100644 --- a/dom/plugins/ipc/PluginUtilsOSX.mm +++ b/dom/plugins/ipc/PluginUtilsOSX.mm @@ -15,6 +15,8 @@ #include "nsDebug.h" +#include "mozilla/Sprintf.h" + @interface CALayer (ContentsScale) - (double)contentsScale; - (void)setContentsScale:(double)scale; @@ -222,12 +224,11 @@ bool mozilla::plugins::PluginUtilsOSX::SetProcessName(const char* aProcessName) return false; } - NSString *currentName = [[[NSBundle mainBundle] localizedInfoDictionary] + NSString *currentName = [[[NSBundle mainBundle] localizedInfoDictionary] objectForKey:(NSString *)kCFBundleNameKey]; char formattedName[1024]; - snprintf(formattedName, sizeof(formattedName), - "%s %s", [currentName UTF8String], aProcessName); + SprintfLiteral(formattedName, "%s %s", [currentName UTF8String], aProcessName); aProcessName = formattedName; diff --git a/dom/presentation/PresentationRequest.cpp b/dom/presentation/PresentationRequest.cpp index 6e5f8081f1bb..28e062435e2e 100644 --- a/dom/presentation/PresentationRequest.cpp +++ b/dom/presentation/PresentationRequest.cpp @@ -206,6 +206,7 @@ PresentationRequest::StartWithDevice(const nsAString& aDeviceId, // process. nsCOMPtr handler = do_QueryInterface(GetOwner()->GetChromeEventHandler()); + nsCOMPtr principal = doc->NodePrincipal(); nsCOMPtr callback = new PresentationRequesterCallback(this, id, promise); nsCOMPtr constructor = @@ -216,6 +217,7 @@ PresentationRequest::StartWithDevice(const nsAString& aDeviceId, aDeviceId, GetOwner()->WindowID(), handler, + principal, callback, constructor); if (NS_WARN_IF(NS_FAILED(rv))) { diff --git a/dom/presentation/PresentationService.cpp b/dom/presentation/PresentationService.cpp index fea969a68c8e..a60013648935 100644 --- a/dom/presentation/PresentationService.cpp +++ b/dom/presentation/PresentationService.cpp @@ -113,6 +113,7 @@ public: const nsAString& aOrigin, uint64_t aWindowId, nsIDOMEventTarget* aEventTarget, + nsIPrincipal* aPrincipal, nsIPresentationServiceCallback* aCallback, nsIPresentationTransportBuilderConstructor* aBuilderConstructor); @@ -126,6 +127,7 @@ private: nsString mOrigin; uint64_t mWindowId; nsWeakPtr mChromeEventHandler; + nsCOMPtr mPrincipal; nsCOMPtr mCallback; nsCOMPtr mBuilderConstructor; }; @@ -143,6 +145,7 @@ PresentationDeviceRequest::PresentationDeviceRequest( const nsAString& aOrigin, uint64_t aWindowId, nsIDOMEventTarget* aEventTarget, + nsIPrincipal* aPrincipal, nsIPresentationServiceCallback* aCallback, nsIPresentationTransportBuilderConstructor* aBuilderConstructor) : mRequestUrls(aUrls) @@ -150,6 +153,7 @@ PresentationDeviceRequest::PresentationDeviceRequest( , mOrigin(aOrigin) , mWindowId(aWindowId) , mChromeEventHandler(do_GetWeakReference(aEventTarget)) + , mPrincipal(aPrincipal) , mCallback(aCallback) , mBuilderConstructor(aBuilderConstructor) { @@ -181,6 +185,14 @@ PresentationDeviceRequest::GetChromeEventHandler(nsIDOMEventTarget** aChromeEven return NS_OK; } +NS_IMETHODIMP +PresentationDeviceRequest::GetPrincipal(nsIPrincipal** aPrincipal) +{ + nsCOMPtr principal(mPrincipal); + principal.forget(aPrincipal); + return NS_OK; +} + NS_IMETHODIMP PresentationDeviceRequest::Select(nsIPresentationDevice* aDevice) { @@ -655,6 +667,7 @@ PresentationService::StartSession( const nsAString& aDeviceId, uint64_t aWindowId, nsIDOMEventTarget* aEventTarget, + nsIPrincipal* aPrincipal, nsIPresentationServiceCallback* aCallback, nsIPresentationTransportBuilderConstructor* aBuilderConstructor) { @@ -671,6 +684,7 @@ PresentationService::StartSession( aOrigin, aWindowId, aEventTarget, + aPrincipal, aCallback, aBuilderConstructor); diff --git a/dom/presentation/interfaces/nsIPresentationDevicePrompt.idl b/dom/presentation/interfaces/nsIPresentationDevicePrompt.idl index b6afe765f167..2900eb59cb11 100644 --- a/dom/presentation/interfaces/nsIPresentationDevicePrompt.idl +++ b/dom/presentation/interfaces/nsIPresentationDevicePrompt.idl @@ -7,6 +7,7 @@ interface nsIArray; interface nsIDOMEventTarget; interface nsIPresentationDevice; +interface nsIPrincipal; %{C++ #define PRESENTATION_DEVICE_PROMPT_CONTRACTID "@mozilla.org/presentation-device/prompt;1" @@ -27,6 +28,9 @@ interface nsIPresentationDeviceRequest : nsISupports // The XUL browser element that the request was originated in. readonly attribute nsIDOMEventTarget chromeEventHandler; + // The principal of the request. + readonly attribute nsIPrincipal principal; + /* * Callback after selecting a device * @param device The selected device. diff --git a/dom/presentation/interfaces/nsIPresentationService.idl b/dom/presentation/interfaces/nsIPresentationService.idl index 493c555b046f..071d387454d3 100644 --- a/dom/presentation/interfaces/nsIPresentationService.idl +++ b/dom/presentation/interfaces/nsIPresentationService.idl @@ -11,6 +11,7 @@ interface nsIPresentationAvailabilityListener; interface nsIPresentationRespondingListener; interface nsIPresentationSessionListener; interface nsIPresentationTransportBuilderConstructor; +interface nsIPrincipal; %{C++ #define PRESENTATION_SERVICE_CID \ @@ -70,6 +71,7 @@ interface nsIPresentationService : nsISupports * @param eventTarget: The chrome event handler, in particular XUL browser * element in parent process, that the request was * originated in. + * @param principal: The principal that initiated the session. * @param callback: Invoke the callback when the operation is completed. * NotifySuccess() is called with |id| if a session is * established successfully with the selected device. @@ -82,6 +84,7 @@ interface nsIPresentationService : nsISupports in DOMString deviceId, in unsigned long long windowId, in nsIDOMEventTarget eventTarget, + in nsIPrincipal principal, in nsIPresentationServiceCallback callback, in nsIPresentationTransportBuilderConstructor constructor); diff --git a/dom/presentation/ipc/PPresentation.ipdl b/dom/presentation/ipc/PPresentation.ipdl index 98c79b449d83..3020e203c12d 100644 --- a/dom/presentation/ipc/PPresentation.ipdl +++ b/dom/presentation/ipc/PPresentation.ipdl @@ -10,6 +10,7 @@ include protocol PPresentationBuilder; include InputStreamParams; +using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h"; using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h"; namespace mozilla { @@ -23,6 +24,7 @@ struct StartSessionRequest nsString deviceId; uint64_t windowId; TabId tabId; + Principal principal; }; struct SendSessionMessageRequest diff --git a/dom/presentation/ipc/PresentationIPCService.cpp b/dom/presentation/ipc/PresentationIPCService.cpp index 4355fc13b126..03abe15c7239 100644 --- a/dom/presentation/ipc/PresentationIPCService.cpp +++ b/dom/presentation/ipc/PresentationIPCService.cpp @@ -5,6 +5,7 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/dom/ContentChild.h" +#include "mozilla/dom/PermissionMessageUtils.h" #include "mozilla/dom/PPresentation.h" #include "mozilla/dom/TabParent.h" #include "mozilla/ipc/InputStreamUtils.h" @@ -60,6 +61,7 @@ PresentationIPCService::StartSession( const nsAString& aDeviceId, uint64_t aWindowId, nsIDOMEventTarget* aEventTarget, + nsIPrincipal* aPrincipal, nsIPresentationServiceCallback* aCallback, nsIPresentationTransportBuilderConstructor* aBuilderConstructor) { @@ -78,7 +80,8 @@ PresentationIPCService::StartSession( nsString(aOrigin), nsString(aDeviceId), aWindowId, - tabId)); + tabId, + IPC::Principal(aPrincipal))); } NS_IMETHODIMP diff --git a/dom/presentation/ipc/PresentationParent.cpp b/dom/presentation/ipc/PresentationParent.cpp index 656369876039..255367a7e89c 100644 --- a/dom/presentation/ipc/PresentationParent.cpp +++ b/dom/presentation/ipc/PresentationParent.cpp @@ -403,7 +403,8 @@ PresentationRequestParent::DoRequest(const StartSessionRequest& aRequest) new PresentationTransportBuilderConstructorIPC(parent); return mService->StartSession(aRequest.urls(), aRequest.sessionId(), aRequest.origin(), aRequest.deviceId(), - aRequest.windowId(), eventTarget, this, constructor); + aRequest.windowId(), eventTarget, + aRequest.principal(), this, constructor); } nsresult diff --git a/dom/security/test/sri/iframe_require-sri-for_main.html b/dom/security/test/sri/iframe_require-sri-for_main.html index 8a51ba69f512..467c699c7a58 100644 --- a/dom/security/test/sri/iframe_require-sri-for_main.html +++ b/dom/security/test/sri/iframe_require-sri-for_main.html @@ -34,7 +34,14 @@

black text

diff --git a/dom/security/test/sri/iframe_require-sri-for_no_csp.html b/dom/security/test/sri/iframe_require-sri-for_no_csp.html new file mode 100644 index 000000000000..435b32ea3b98 --- /dev/null +++ b/dom/security/test/sri/iframe_require-sri-for_no_csp.html @@ -0,0 +1,5 @@ + diff --git a/dom/security/test/sri/mochitest.ini b/dom/security/test/sri/mochitest.ini index e10a7771b47b..2e3ad7c61b8e 100644 --- a/dom/security/test/sri/mochitest.ini +++ b/dom/security/test/sri/mochitest.ini @@ -3,11 +3,16 @@ support-files = file_bug_1271796.css iframe_require-sri-for_main.html iframe_require-sri-for_main.html^headers^ + iframe_require-sri-for_no_csp.html iframe_script_crossdomain.html iframe_script_sameorigin.html iframe_sri_disabled.html iframe_style_crossdomain.html iframe_style_sameorigin.html + rsf_csp_worker.js + rsf_csp_worker.js^headers^ + rsf_imported.js + rsf_worker.js script_crossdomain1.js script_crossdomain1.js^headers^ script_crossdomain2.js diff --git a/dom/security/test/sri/rsf_csp_worker.js b/dom/security/test/sri/rsf_csp_worker.js new file mode 100644 index 000000000000..553fdf92b983 --- /dev/null +++ b/dom/security/test/sri/rsf_csp_worker.js @@ -0,0 +1,9 @@ +postMessage("good_worker_could_load"); +try { + importScripts('rsf_imported.js'); +} catch(e) { + postMessage("good_worker_after_importscripts"); +} +finally { + postMessage("finish"); +} diff --git a/dom/security/test/sri/rsf_csp_worker.js^headers^ b/dom/security/test/sri/rsf_csp_worker.js^headers^ new file mode 100644 index 000000000000..0a6ccba79063 --- /dev/null +++ b/dom/security/test/sri/rsf_csp_worker.js^headers^ @@ -0,0 +1 @@ +content-security-policy: require-sri-for script style diff --git a/dom/security/test/sri/rsf_imported.js b/dom/security/test/sri/rsf_imported.js new file mode 100644 index 000000000000..33f54b7a0adf --- /dev/null +++ b/dom/security/test/sri/rsf_imported.js @@ -0,0 +1 @@ +postMessage('bad_worker_could_load_via_importScripts'); diff --git a/dom/security/test/sri/rsf_spawn_CSPd_worker.js b/dom/security/test/sri/rsf_spawn_CSPd_worker.js new file mode 100644 index 000000000000..652c77100acc --- /dev/null +++ b/dom/security/test/sri/rsf_spawn_CSPd_worker.js @@ -0,0 +1,3 @@ +w = new Worker("rsf_csp_worker.js"); +// use the handler function in test_require-sri-for_csp_directive.html +w.onmessage = parent.handler; diff --git a/dom/security/test/sri/rsf_worker.js b/dom/security/test/sri/rsf_worker.js new file mode 100644 index 000000000000..553d3deee742 --- /dev/null +++ b/dom/security/test/sri/rsf_worker.js @@ -0,0 +1,2 @@ +parent.postMessage('bad_worker_could_load', '*'); +importScripts('rsf_imported.js'); diff --git a/dom/security/test/sri/test_require-sri-for_csp_directive.html b/dom/security/test/sri/test_require-sri-for_csp_directive.html index 0e2b91712bd7..ef1b3603f5f3 100644 --- a/dom/security/test/sri/test_require-sri-for_csp_directive.html +++ b/dom/security/test/sri/test_require-sri-for_csp_directive.html @@ -10,10 +10,12 @@ -Mozilla Bug 1265318 - +Mozilla Bug 1265318
+
+ diff --git a/dom/workers/RuntimeService.cpp b/dom/workers/RuntimeService.cpp index cd7c0d18d7c1..d2c4bcd10904 100644 --- a/dom/workers/RuntimeService.cpp +++ b/dom/workers/RuntimeService.cpp @@ -2365,7 +2365,7 @@ RuntimeService::SuspendWorkersForWindow(nsPIDOMWindowInner* aWindow) GetWorkersForWindow(aWindow, workers); for (uint32_t index = 0; index < workers.Length(); index++) { - workers[index]->Suspend(); + workers[index]->ParentWindowPaused(); } } @@ -2379,7 +2379,7 @@ RuntimeService::ResumeWorkersForWindow(nsPIDOMWindowInner* aWindow) GetWorkersForWindow(aWindow, workers); for (uint32_t index = 0; index < workers.Length(); index++) { - workers[index]->Resume(); + workers[index]->ParentWindowResumed(); } } diff --git a/dom/workers/ScriptLoader.cpp b/dom/workers/ScriptLoader.cpp index 83ecb3720cf8..ac4f709b258d 100644 --- a/dom/workers/ScriptLoader.cpp +++ b/dom/workers/ScriptLoader.cpp @@ -59,6 +59,7 @@ #include "mozilla/dom/PromiseNativeHandler.h" #include "mozilla/dom/Response.h" #include "mozilla/dom/ScriptSettings.h" +#include "mozilla/dom/SRILogHelper.h" #include "mozilla/UniquePtr.h" #include "Principal.h" #include "WorkerHolder.h" @@ -1110,6 +1111,25 @@ private: aLoadInfo.mURL.Assign(NS_ConvertUTF8toUTF16(filename)); } + nsCOMPtr chanLoadInfo = channel->GetLoadInfo(); + if (chanLoadInfo && chanLoadInfo->GetEnforceSRI()) { + // importScripts() and the Worker constructor do not support integrity metadata + // (or any fetch options). Until then, we can just block. + // If we ever have those data in the future, we'll have to the check to + // by using the SRICheck module + MOZ_LOG(SRILogHelper::GetSriLog(), mozilla::LogLevel::Debug, + ("Scriptloader::Load, SRI required but not supported in workers")); + nsCOMPtr wcsp; + chanLoadInfo->LoadingPrincipal()->GetCsp(getter_AddRefs(wcsp)); + MOZ_ASSERT(wcsp, "We sould have a CSP for the worker here"); + if (wcsp) { + wcsp->LogViolationDetails( + nsIContentSecurityPolicy::VIOLATION_TYPE_REQUIRE_SRI_FOR_SCRIPT, + aLoadInfo.mURL, EmptyString(), 0, EmptyString(), EmptyString()); + } + return NS_ERROR_SRI_CORRUPT; + } + // Update the principal of the worker and its base URI if we just loaded the // worker's primary script. if (IsMainWorkerScript()) { @@ -1215,7 +1235,8 @@ private: rv = csp->GetReferrerPolicy(&rp, &hasReferrerPolicy); NS_ENSURE_SUCCESS(rv, rv); - if (hasReferrerPolicy) { + + if (hasReferrerPolicy) { //FIXME bug 1307366: move RP out of CSP code mWorkerPrivate->SetReferrerPolicy(static_cast(rp)); } } diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 1635a6663fa6..85786388f325 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -760,7 +760,8 @@ private: return true; } - if (aWorkerPrivate->IsFrozen() || aWorkerPrivate->IsSuspended()) { + if (aWorkerPrivate->IsFrozen() || + aWorkerPrivate->IsParentWindowPaused()) { MOZ_ASSERT(!IsDebuggerRunnable()); aWorkerPrivate->QueueRunnable(this); return true; @@ -1159,7 +1160,8 @@ private: else { AssertIsOnMainThread(); - if (aWorkerPrivate->IsFrozen() || aWorkerPrivate->IsSuspended()) { + if (aWorkerPrivate->IsFrozen() || + aWorkerPrivate->IsParentWindowPaused()) { MOZ_ASSERT(!IsDebuggerRunnable()); aWorkerPrivate->QueueRunnable(this); return true; @@ -2179,7 +2181,7 @@ WorkerPrivateParent::WorkerPrivateParent( mParent(aParent), mScriptURL(aScriptURL), mWorkerName(aWorkerName), mLoadingWorkerScript(false), mBusyCount(0), mParentStatus(Pending), mParentFrozen(false), - mParentSuspended(false), mIsChromeWorker(aIsChromeWorker), + mParentWindowPaused(false), mIsChromeWorker(aIsChromeWorker), mMainThreadObjectsForgotten(false), mWorkerType(aWorkerType), mCreationTimeStamp(TimeStamp::Now()), mCreationTimeHighRes((double)PR_Now() / PR_USEC_PER_MSEC) @@ -2637,7 +2639,7 @@ WorkerPrivateParent::Thaw(nsPIDOMWindowInner* aWindow) // Execute queued runnables before waking up the worker, otherwise the worker // could post new messages before we run those that have been queued. - if (!IsSuspended() && !mQueuedRunnables.IsEmpty()) { + if (!IsParentWindowPaused() && !mQueuedRunnables.IsEmpty()) { AssertIsOnMainThread(); MOZ_ASSERT(IsDedicatedWorker()); @@ -2660,24 +2662,24 @@ WorkerPrivateParent::Thaw(nsPIDOMWindowInner* aWindow) template void -WorkerPrivateParent::Suspend() +WorkerPrivateParent::ParentWindowPaused() { AssertIsOnMainThread(); - MOZ_ASSERT(!mParentSuspended, "Suspended more than once!"); + MOZ_ASSERT(!mParentWindowPaused, "Suspended more than once!"); - mParentSuspended = true; + mParentWindowPaused = true; } template void -WorkerPrivateParent::Resume() +WorkerPrivateParent::ParentWindowResumed() { AssertIsOnMainThread(); - MOZ_ASSERT(mParentSuspended, "Resumed more than once!"); + MOZ_ASSERT(mParentWindowPaused, "Resumed more than once!"); - mParentSuspended = false; + mParentWindowPaused = false; { MutexAutoLock lock(mMutex); @@ -5104,6 +5106,11 @@ WorkerPrivate::FreezeInternal() NS_ASSERTION(!mFrozen, "Already frozen!"); mFrozen = true; + + for (uint32_t index = 0; index < mChildWorkers.Length(); index++) { + mChildWorkers[index]->Freeze(nullptr); + } + return true; } @@ -5114,6 +5121,10 @@ WorkerPrivate::ThawInternal() NS_ASSERTION(mFrozen, "Not yet frozen!"); + for (uint32_t index = 0; index < mChildWorkers.Length(); index++) { + mChildWorkers[index]->Thaw(nullptr); + } + mFrozen = false; return true; } diff --git a/dom/workers/WorkerPrivate.h b/dom/workers/WorkerPrivate.h index bc02913c4895..3369df59ca55 100644 --- a/dom/workers/WorkerPrivate.h +++ b/dom/workers/WorkerPrivate.h @@ -199,7 +199,7 @@ private: uint64_t mBusyCount; Status mParentStatus; bool mParentFrozen; - bool mParentSuspended; + bool mParentWindowPaused; bool mIsChromeWorker; bool mMainThreadObjectsForgotten; WorkerType mWorkerType; @@ -323,11 +323,14 @@ public: bool Thaw(nsPIDOMWindowInner* aWindow); + // When we debug a worker, we want to disconnect the window and the worker + // communication. This happens calling this method. + // Note: this method doesn't suspend the worker! Use Freeze/Thaw instead. void - Suspend(); + ParentWindowPaused(); void - Resume(); + ParentWindowResumed(); bool Terminate() @@ -425,10 +428,10 @@ public: } bool - IsSuspended() const + IsParentWindowPaused() const { AssertIsOnParentThread(); - return mParentSuspended; + return mParentWindowPaused; } bool diff --git a/dom/workers/test/mochitest.ini b/dom/workers/test/mochitest.ini index c297fc88cccb..bd52098f8309 100644 --- a/dom/workers/test/mochitest.ini +++ b/dom/workers/test/mochitest.ini @@ -105,6 +105,8 @@ support-files = worker_setTimeoutWith0.js worker_bug1301094.js script_bug1301094.js + worker_suspended.js + window_suspended.html !/dom/base/test/file_websocket_basic_wsh.py !/dom/base/test/file_websocket_hello_wsh.py !/dom/base/test/file_websocket_http_resource.txt @@ -230,3 +232,4 @@ skip-if = buildapp == 'b2g' || toolkit == 'android' #bug 982828 [test_bug1278777.html] [test_setTimeoutWith0.html] [test_bug1301094.html] +[test_subworkers_suspended.html] diff --git a/dom/workers/test/test_subworkers_suspended.html b/dom/workers/test/test_subworkers_suspended.html new file mode 100644 index 000000000000..78ce695e947b --- /dev/null +++ b/dom/workers/test/test_subworkers_suspended.html @@ -0,0 +1,135 @@ + + + + + Test for sub workers+bfcache behavior + + + + + + + + diff --git a/dom/workers/test/window_suspended.html b/dom/workers/test/window_suspended.html new file mode 100644 index 000000000000..b482cbe09b82 --- /dev/null +++ b/dom/workers/test/window_suspended.html @@ -0,0 +1,5 @@ + diff --git a/dom/workers/test/worker_suspended.js b/dom/workers/test/worker_suspended.js new file mode 100644 index 000000000000..3b53fcea2af1 --- /dev/null +++ b/dom/workers/test/worker_suspended.js @@ -0,0 +1,31 @@ +var count = 0; + +function do_magic(data) { + caches.open("test") + .then(function(cache) { + return cache.put("http://mochi.test:888/foo", new Response(data.type + "-" + count++)); + }) + .then(function() { + if (count == 1) { + postMessage("ready"); + } + + if (data.loop) { + setTimeout(function() {do_magic(data); }, 500); + } + }); +} + +onmessage = function(e) { + if (e.data.type == 'page1') { + if (e.data.count > 0) { + var a = new Worker("worker_suspended.js"); + a.postMessage({ type: "page1", count: e.data - 1 }); + a.onmessage = function() { postMessage("ready"); } + } else { + do_magic({ type: e.data.type, loop: true }); + } + } else if (e.data.type == 'page2') { + do_magic({ type: e.data.type, loop: false }); + } +} diff --git a/embedding/browser/nsWebBrowser.cpp b/embedding/browser/nsWebBrowser.cpp index 11f96deff59c..ca99cc01b538 100644 --- a/embedding/browser/nsWebBrowser.cpp +++ b/embedding/browser/nsWebBrowser.cpp @@ -245,8 +245,8 @@ nsWebBrowser::RemoveWebBrowserListener(nsIWeakReference* aListener, // iterate the array and remove the queued listener int32_t count = mListenerArray->Length(); while (count > 0) { - if (mListenerArray->ElementAt(count).Equals(aListener, aIID)) { - mListenerArray->RemoveElementAt(count); + if (mListenerArray->ElementAt(count-1).Equals(aListener, aIID)) { + mListenerArray->RemoveElementAt(count-1); break; } count--; diff --git a/gfx/ipc/VsyncBridgeChild.cpp b/gfx/ipc/VsyncBridgeChild.cpp index 799c48e36639..cb43acd0185c 100644 --- a/gfx/ipc/VsyncBridgeChild.cpp +++ b/gfx/ipc/VsyncBridgeChild.cpp @@ -5,6 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "VsyncBridgeChild.h" #include "VsyncIOThreadHolder.h" +#include "mozilla/dom/ContentChild.h" namespace mozilla { namespace gfx { @@ -138,5 +139,11 @@ VsyncBridgeChild::ProcessingError(Result aCode, const char* aReason) MOZ_RELEASE_ASSERT(aCode == MsgDropped, "Processing error in VsyncBridgeChild"); } +void +VsyncBridgeChild::FatalError(const char* const aName, const char* const aMsg) const +{ + dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aName, aMsg, OtherPid()); +} + } // namespace gfx } // namespace mozilla diff --git a/gfx/ipc/VsyncBridgeChild.h b/gfx/ipc/VsyncBridgeChild.h index 93d46878b3fb..76133ad8d104 100644 --- a/gfx/ipc/VsyncBridgeChild.h +++ b/gfx/ipc/VsyncBridgeChild.h @@ -33,6 +33,8 @@ public: void NotifyVsync(TimeStamp aTimeStamp, const uint64_t& aLayersId); + virtual void FatalError(const char* const aName, const char* const aMsg) const override; + private: VsyncBridgeChild(RefPtr, const uint64_t& aProcessToken); ~VsyncBridgeChild(); diff --git a/gfx/layers/apz/util/APZEventState.cpp b/gfx/layers/apz/util/APZEventState.cpp index 0964e2e27361..9e52d7dc46a5 100644 --- a/gfx/layers/apz/util/APZEventState.cpp +++ b/gfx/layers/apz/util/APZEventState.cpp @@ -230,17 +230,15 @@ APZEventState::FireContextmenuEvents(const nsCOMPtr& aPresShell, // If the contextmenu event was handled then we're showing a contextmenu, // and so we should remove any activation mActiveElementManager->ClearActivation(); +#ifndef XP_WIN } else { - // If no one handle context menu, fire MOZLONGTAP event - LayoutDevicePoint ldPoint = aPoint * aScale; - int time = 0; - nsEventStatus status = - APZCCallbackHelper::DispatchSynthesizedMouseEvent(eMouseLongTap, time, - ldPoint, aModifiers, - /*clickCount*/ 1, - aWidget); + // If the contextmenu wasn't consumed, fire the eMouseLongTap event. + nsEventStatus status = APZCCallbackHelper::DispatchSynthesizedMouseEvent( + eMouseLongTap, /*time*/ 0, aPoint * aScale, aModifiers, + /*clickCount*/ 1, aWidget); eventHandled = (status == nsEventStatus_eConsumeNoDefault); - APZES_LOG("MOZLONGTAP event handled: %d\n", eventHandled); + APZES_LOG("eMouseLongTap event handled: %d\n", eventHandled); +#endif } return eventHandled; @@ -266,8 +264,14 @@ APZEventState::ProcessLongTap(const nsCOMPtr& aPresShell, #ifdef XP_WIN // On Windows, we fire the contextmenu events when the user lifts their // finger, in keeping with the platform convention. This happens in the - // ProcessLongTapUp function. - bool eventHandled = false; + // ProcessLongTapUp function. However, we still fire the eMouseLongTap event + // at this time, because things like text selection or dragging may want + // to know about it. + nsEventStatus status = APZCCallbackHelper::DispatchSynthesizedMouseEvent( + eMouseLongTap, /*time*/ 0, aPoint * aScale, aModifiers, /*clickCount*/ 1, + widget); + + bool eventHandled = (status == nsEventStatus_eConsumeNoDefault); #else bool eventHandled = FireContextmenuEvents(aPresShell, aPoint, aScale, aModifiers, widget); diff --git a/gfx/layers/composite/PaintCounter.cpp b/gfx/layers/composite/PaintCounter.cpp index f9a90cd3806a..13cf7613fcf9 100644 --- a/gfx/layers/composite/PaintCounter.cpp +++ b/gfx/layers/composite/PaintCounter.cpp @@ -48,11 +48,10 @@ PaintCounter::~PaintCounter() void PaintCounter::Draw(Compositor* aCompositor, TimeDuration aPaintTime, TimeDuration aCompositeTime) { - const int buffer_size = 48; - char buffer[buffer_size]; - snprintf(buffer, buffer_size, "P: %.2f C: %.2f", - aPaintTime.ToMilliseconds(), - aCompositeTime.ToMilliseconds()); + char buffer[48]; + SprintfLiteral(buffer, "P: %.2f C: %.2f", + aPaintTime.ToMilliseconds(), + aCompositeTime.ToMilliseconds()); SkPaint paint; paint.setTextSize(32); diff --git a/gfx/layers/ipc/CompositorBridgeChild.cpp b/gfx/layers/ipc/CompositorBridgeChild.cpp index e9e6b724cc85..633b1de12bbf 100644 --- a/gfx/layers/ipc/CompositorBridgeChild.cpp +++ b/gfx/layers/ipc/CompositorBridgeChild.cpp @@ -33,6 +33,7 @@ #include "FrameLayerBuilder.h" #include "mozilla/dom/TabChild.h" #include "mozilla/dom/TabParent.h" +#include "mozilla/dom/ContentChild.h" #include "mozilla/Unused.h" #include "mozilla/DebugOnly.h" #if defined(XP_WIN) @@ -1144,6 +1145,12 @@ CompositorBridgeChild::WillEndTransaction() ResetShmemCounter(); } +void +CompositorBridgeChild::FatalError(const char* const aName, const char* const aMsg) const +{ + dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aName, aMsg, OtherPid()); +} + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/ipc/CompositorBridgeChild.h b/gfx/layers/ipc/CompositorBridgeChild.h index e95d24a7c894..18d4f733bc08 100644 --- a/gfx/layers/ipc/CompositorBridgeChild.h +++ b/gfx/layers/ipc/CompositorBridgeChild.h @@ -134,6 +134,8 @@ public: TextureFlags aFlags, uint64_t aSerial) override; + virtual void FatalError(const char* const aName, const char* const aMsg) const override; + /** * Request that the parent tell us when graphics are ready on GPU. * When we get that message, we bounce it to the TabParent via diff --git a/gfx/layers/ipc/ImageBridgeChild.cpp b/gfx/layers/ipc/ImageBridgeChild.cpp index 664b11529af5..5e75299a4b90 100644 --- a/gfx/layers/ipc/ImageBridgeChild.cpp +++ b/gfx/layers/ipc/ImageBridgeChild.cpp @@ -32,6 +32,7 @@ #include "mozilla/layers/LayersMessages.h" // for CompositableOperation #include "mozilla/layers/PCompositableChild.h" // for PCompositableChild #include "mozilla/layers/TextureClient.h" // for TextureClient +#include "mozilla/dom/ContentChild.h" #include "mozilla/mozalloc.h" // for operator new, etc #include "mtransport/runnable_utils.h" #include "nsContentUtils.h" @@ -1477,5 +1478,11 @@ ImageBridgeChild::CanSend() const return mCanSend; } +void +ImageBridgeChild::FatalError(const char* const aName, const char* const aMsg) const +{ + dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aName, aMsg, OtherPid()); +} + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/ipc/ImageBridgeChild.h b/gfx/layers/ipc/ImageBridgeChild.h index 87e577a4069b..82fba5937754 100644 --- a/gfx/layers/ipc/ImageBridgeChild.h +++ b/gfx/layers/ipc/ImageBridgeChild.h @@ -370,6 +370,8 @@ public: return InImageBridgeChildThread(); } + virtual void FatalError(const char* const aName, const char* const aMsg) const override; + protected: ImageBridgeChild(); bool DispatchAllocShmemInternal(size_t aSize, diff --git a/gfx/vr/ipc/VRManagerChild.cpp b/gfx/vr/ipc/VRManagerChild.cpp index a92fec6eb139..5567eea35f93 100644 --- a/gfx/vr/ipc/VRManagerChild.cpp +++ b/gfx/vr/ipc/VRManagerChild.cpp @@ -13,6 +13,7 @@ #include "mozilla/dom/Navigator.h" #include "mozilla/dom/VREventObserver.h" #include "mozilla/dom/WindowBinding.h" // for FrameRequestCallback +#include "mozilla/dom/ContentChild.h" #include "mozilla/layers/TextureClient.h" #include "nsContentUtils.h" @@ -566,5 +567,11 @@ VRManagerChild::RemoveListener(dom::VREventObserver* aObserver) } } +void +VRManagerChild::FatalError(const char* const aName, const char* const aMsg) const +{ + dom::ContentChild::FatalErrorIfNotUsingGPUProcess(aName, aMsg, OtherPid()); +} + } // namespace gfx } // namespace mozilla diff --git a/gfx/vr/ipc/VRManagerChild.h b/gfx/vr/ipc/VRManagerChild.h index 9f018a6223c2..841c2cd3194f 100644 --- a/gfx/vr/ipc/VRManagerChild.h +++ b/gfx/vr/ipc/VRManagerChild.h @@ -83,6 +83,8 @@ public: void FireDOMVRDisplayDisconnectEvent(); void FireDOMVRDisplayPresentChangeEvent(); + virtual void FatalError(const char* const aName, const char* const aMsg) const override; + protected: explicit VRManagerChild(); ~VRManagerChild(); diff --git a/ipc/app/macbuild/Contents/Info.plist.in b/ipc/app/macbuild/Contents/Info.plist.in index c5291160ef96..c1bbf6506e35 100644 --- a/ipc/app/macbuild/Contents/Info.plist.in +++ b/ipc/app/macbuild/Contents/Info.plist.in @@ -29,5 +29,7 @@ 1 NSSupportsAutomaticGraphicsSwitching + NSHighResolutionCapable + diff --git a/ipc/glue/ProtocolUtils.h b/ipc/glue/ProtocolUtils.h index f5d9e2f03e5f..aa10177495c8 100644 --- a/ipc/glue/ProtocolUtils.h +++ b/ipc/glue/ProtocolUtils.h @@ -185,6 +185,8 @@ public: virtual ProcessId OtherPid() const = 0; virtual MessageChannel* GetIPCChannel() = 0; + virtual void FatalError(const char* const aProtocolName, const char* const aErrorMsg) const = 0; + Maybe ReadActor(const IPC::Message* aMessage, PickleIterator* aIter, bool aNullable, const char* aActorDescription, int32_t aProtocolTypeId); }; diff --git a/ipc/ipdl/ipdl/lower.py b/ipc/ipdl/ipdl/lower.py index f095780ad134..59c80a5e82a0 100644 --- a/ipc/ipdl/ipdl/lower.py +++ b/ipc/ipdl/ipdl/lower.py @@ -395,13 +395,25 @@ def _protocolErrorBreakpoint(msg): return StmtExpr(ExprCall(ExprVar('mozilla::ipc::ProtocolErrorBreakpoint'), args=[ msg ])) -def _ipcFatalError(name, msg, isparent): +def _ipcFatalError(name, msg): if isinstance(name, str): name = ExprLiteral.String(name) if isinstance(msg, str): msg = ExprLiteral.String(msg) - return StmtExpr(ExprCall(ExprVar('mozilla::ipc::FatalError'), - args=[ name, msg, isparent ])) + return StmtExpr(ExprCall(ExprVar('FatalError'), + args=[ name, msg ])) + +def _ipcFatalErrorWithClassname(name, msg, p, isparent): + if isinstance(name, str): + name = ExprLiteral.String(name) + if isinstance(msg, str): + msg = ExprLiteral.String(msg) + if p.decl.type.isToplevel(): + return StmtExpr(ExprCall(ExprVar('mozilla::ipc::FatalError'), + args=[ name, msg, isparent ])) + else: + return StmtExpr(ExprCall(ExprSelect(p.managerVar(), '->', 'FatalError'), + [ name, msg ])) def _printWarningMessage(msg): if isinstance(msg, str): @@ -3417,7 +3429,6 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): ## FatalError() msgparam = ExprVar('aMsg') - msgvar = ExprVar('formattedMessage') actorname = _actorName(p.name, self.side) fatalerror = MethodDefn(MethodDecl( 'FatalError', @@ -3428,10 +3439,22 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor): else: isparent = ExprLiteral.FALSE fatalerror.addstmts([ - _ipcFatalError(actorname, msgparam, isparent) + _ipcFatalError(actorname, msgparam) ]) self.cls.addstmts([ fatalerror, Whitespace.NL ]) + protocolnameparam = ExprVar('aProtocolName') + + fatalerrorwithclassname = MethodDefn(MethodDecl( + 'FatalError', + params=[ Decl(Type('char', const=1, ptrconst=1), protocolnameparam.name), + Decl(Type('char', const=1, ptrconst=1), msgparam.name) ], + const=1)) + fatalerrorwithclassname.addstmts([ + _ipcFatalErrorWithClassname(protocolnameparam, msgparam, self.protocol, isparent) + ]) + self.cls.addstmts([ fatalerrorwithclassname, Whitespace.NL ]) + ## DestroySubtree(bool normal) whyvar = ExprVar('why') subtreewhyvar = ExprVar('subtreewhy') diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp index 657bda71d241..1ffde325c1f9 100644 --- a/js/src/jit/Ion.cpp +++ b/js/src/jit/Ion.cpp @@ -2361,6 +2361,13 @@ CheckScript(JSContext* cx, JSScript* script, bool osr) return false; } + if (script->nTypeSets() >= UINT16_MAX) { + // In this case multiple bytecode ops can share a single observed + // TypeSet (see bug 1303710). + TrackAndSpewIonAbort(cx, script, "too many typesets"); + return false; + } + return true; } diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 654cd97c94e2..ad5bad9145d2 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -165,6 +165,7 @@ IonBuilder::IonBuilder(JSContext* analysisContext, CompileCompartment* comp, MOZ_ASSERT(script()->hasBaselineScript() == (info->analysisMode() != Analysis_ArgumentsUsage)); MOZ_ASSERT(!!analysisContext == (info->analysisMode() == Analysis_DefiniteProperties)); + MOZ_ASSERT(script_->nTypeSets() < UINT16_MAX); if (!info->isAnalysis()) script()->baselineScript()->setIonCompiledOrInlined(); diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index 40a93890c9a8..b42587e0c0c5 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -3827,6 +3827,9 @@ GetPropertyIC::tryAttachDenseElement(JSContext* cx, HandleScript outerScript, Io if (!obj->isNative() || !idval.isInt32()) return true; + if (uint32_t(idval.toInt32()) >= obj->as().getDenseInitializedLength()) + return true; + *emitted = true; MacroAssembler masm(cx, ion, outerScript, profilerLeavePc_); diff --git a/js/src/jit/MIR.cpp b/js/src/jit/MIR.cpp index 271f742771e8..7fe6045b6e34 100644 --- a/js/src/jit/MIR.cpp +++ b/js/src/jit/MIR.cpp @@ -2736,20 +2736,6 @@ MBinaryBitwiseInstruction::foldsTo(TempAllocator& alloc) MDefinition* MBinaryBitwiseInstruction::foldUnnecessaryBitop() { - // Fold unsigned shift right operator when the second operand is zero and - // the only use is an unsigned modulo. Thus, the expression - // |(x >>> 0) % y| becomes |x % y|. - if (isUrsh() && hasOneDefUse() && getOperand(1)->isConstant()) { - MConstant* constant = getOperand(1)->toConstant(); - if (constant->type() == MIRType::Int32 && constant->toInt32() == 0) { - for (MUseDefIterator use(this); use; use++) { - if (use.def()->isMod() && use.def()->toMod()->isUnsigned()) - return getOperand(0); - break; - } - } - } - if (specialization_ != MIRType::Int32) return this; diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 951ad4835479..279a06b82298 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -7139,51 +7139,23 @@ class MDiv : public MBinaryArithInstruction class MMod : public MBinaryArithInstruction { - public: - enum class PossiblyUnsigned { - NotPossible, - LHSPossible, - RHSPossible, - BothPossible, - }; - - protected: bool unsigned_; bool canBeNegativeDividend_; bool canBePowerOfTwoDivisor_; bool canBeDivideByZero_; bool trapOnError_; - PossiblyUnsigned possiblyUnsigned_; - MMod(MDefinition* left, MDefinition* right, MIRType type) : MBinaryArithInstruction(left, right), unsigned_(false), canBeNegativeDividend_(true), canBePowerOfTwoDivisor_(true), canBeDivideByZero_(true), - trapOnError_(false), - possiblyUnsigned_(PossiblyUnsigned::NotPossible) + trapOnError_(false) { if (type != MIRType::Value) specialization_ = type; setResultType(type); - - if (left->isUrsh() && left->getOperand(1)->isConstant()) { - MConstant* constant = left->getOperand(1)->toConstant(); - if (constant->type() == MIRType::Int32 && constant->toInt32() == 0) - possiblyUnsigned_ = PossiblyUnsigned::LHSPossible; - } - - if (right->isUrsh() && right->getOperand(1)->isConstant()) { - MConstant* constant = right->getOperand(1)->toConstant(); - if (constant->type() == MIRType::Int32 && constant->toInt32() == 0) { - if (possiblyUnsigned_ == PossiblyUnsigned::NotPossible) - possiblyUnsigned_ = PossiblyUnsigned::RHSPossible; - else - possiblyUnsigned_ = PossiblyUnsigned::BothPossible; - } - } } public: diff --git a/js/src/jit/RangeAnalysis.cpp b/js/src/jit/RangeAnalysis.cpp index df1288ccff24..3921e0b9d948 100644 --- a/js/src/jit/RangeAnalysis.cpp +++ b/js/src/jit/RangeAnalysis.cpp @@ -1561,40 +1561,13 @@ MMod::computeRange(TempAllocator& alloc) // If either operand is a NaN, the result is NaN. This also conservatively // handles Infinity cases. - if ((possiblyUnsigned_ == PossiblyUnsigned::NotPossible && - !lhs.hasInt32Bounds()) || !rhs.hasInt32Bounds()) - { + if (!lhs.hasInt32Bounds() || !rhs.hasInt32Bounds()) return; - } // If RHS can be zero, the result can be NaN. if (rhs.lower() <= 0 && rhs.upper() >= 0) return; - // (x >>> 0) % y is an unsigned modulo operation but the lhs' range is not - // always >= 0. The lhs range assumes a signed integer 32 bit while the - // value is unsigned 32 bit. That breaks the assumption that range >= 0. - if (specialization() == MIRType::Int32) { - switch (possiblyUnsigned_) { - case PossiblyUnsigned::NotPossible: - break; - case PossiblyUnsigned::LHSPossible: - if (rhs.lower() > 0 && !rhs.canHaveFractionalPart()) - unsigned_ = true; - break; - case PossiblyUnsigned::RHSPossible: - if (lhs.lower() >= 0 && !lhs.canHaveFractionalPart()) - unsigned_ = true; - break; - case PossiblyUnsigned::BothPossible: - if (lhs.lower() >= 0 && !lhs.canHaveFractionalPart()) - unsigned_ = true; - else if (rhs.lower() > 0 && !rhs.canHaveFractionalPart()) - unsigned_ = true; - break; - } - } - // If both operands are non-negative integers, we can optimize this to an // unsigned mod. if (specialization() == MIRType::Int32 && lhs.lower() >= 0 && rhs.lower() > 0 && diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index ecc0a0696508..d75a977521a3 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -1860,7 +1860,11 @@ JSObject::fixupAfterMovingGC() if (is()) { NativeObject& obj = as(); if (obj.denseElementsAreCopyOnWrite()) { - NativeObject* owner = MaybeForwarded(obj.getElementsHeader()->ownerObject().get()); + NativeObject* owner = obj.getElementsHeader()->ownerObject(); + // Get the new owner pointer but don't call MaybeForwarded as we + // don't need to access the object's shape. + if (IsForwarded(owner)) + owner = Forwarded(owner); if (owner != &obj && owner->hasFixedElements()) obj.elements_ = owner->getElementsHeader()->elements(); MOZ_ASSERT(!IsForwarded(obj.getElementsHeader()->ownerObject().get())); diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index e607367a189b..52579a8040b6 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -6839,15 +6839,18 @@ ShellOpenAsmJSCacheEntryForWrite(HandleObject global, bool installed, CloseHandle(fileMapping); if (!memory) return JS::AsmJSCache_InternalError; + MOZ_ASSERT(*(uint32_t*)memory == 0); #else - memory = mmap(nullptr, serializedSize, PROT_WRITE, MAP_SHARED, fd, 0); + memory = mmap(nullptr, serializedSize, PROT_READ, MAP_SHARED, fd, 0); if (memory == MAP_FAILED) return JS::AsmJSCache_InternalError; + MOZ_ASSERT(*(uint32_t*)memory == 0); + if (mprotect(memory, serializedSize, PROT_WRITE)) + return JS::AsmJSCache_InternalError; #endif // The embedding added the cookie so strip it off of the buffer returned to // the JS engine. The asmJSCacheCookie will be written on close, below. - MOZ_ASSERT(*(uint32_t*)memory == 0); *memoryOut = (uint8_t*)memory + sizeof(uint32_t); *handleOut = fd.forget(); return JS::AsmJSCache_Success; diff --git a/js/xpconnect/src/XPCDebug.cpp b/js/xpconnect/src/XPCDebug.cpp index 0c109b241188..f8500ba10768 100644 --- a/js/xpconnect/src/XPCDebug.cpp +++ b/js/xpconnect/src/XPCDebug.cpp @@ -9,6 +9,8 @@ #include "nsThreadUtils.h" #include "nsContentUtils.h" +#include "mozilla/Sprintf.h" + #ifdef XP_WIN #include #endif @@ -20,10 +22,10 @@ static void DebugDump(const char* fmt, ...) va_start(ap, fmt); #ifdef XPWIN _vsnprintf(buffer, sizeof(buffer), fmt, ap); -#else - vsnprintf(buffer, sizeof(buffer), fmt, ap); -#endif buffer[sizeof(buffer)-1] = '\0'; +#else + VsprintfLiteral(buffer, fmt, ap); +#endif va_end(ap); #ifdef XP_WIN if (IsDebuggerPresent()) { diff --git a/js/xpconnect/src/XPCJSContext.cpp b/js/xpconnect/src/XPCJSContext.cpp index 909e54b8e028..861662028f30 100644 --- a/js/xpconnect/src/XPCJSContext.cpp +++ b/js/xpconnect/src/XPCJSContext.cpp @@ -47,6 +47,7 @@ #include "mozilla/Atomics.h" #include "mozilla/Attributes.h" #include "mozilla/ProcessHangMonitor.h" +#include "mozilla/Sprintf.h" #include "mozilla/UniquePtrExtensions.h" #include "mozilla/Unused.h" #include "AccessCheck.h" @@ -3528,7 +3529,7 @@ XPCJSContext::DescribeCustomObjects(JSObject* obj, const js::Class* clasp, return false; } - snprintf(name, sizeof(name), "JS Object (%s - %s)", clasp->name, si->GetJSClass()->name); + SprintfLiteral(name, "JS Object (%s - %s)", clasp->name, si->GetJSClass()->name); return true; } diff --git a/js/xpconnect/src/XPCWrappedJS.cpp b/js/xpconnect/src/XPCWrappedJS.cpp index 2b37379d35be..f6c0014eb342 100644 --- a/js/xpconnect/src/XPCWrappedJS.cpp +++ b/js/xpconnect/src/XPCWrappedJS.cpp @@ -9,6 +9,7 @@ #include "xpcprivate.h" #include "jsprf.h" #include "mozilla/DeferredFinalize.h" +#include "mozilla/Sprintf.h" #include "mozilla/jsipc/CrossProcessObjectWrappers.h" #include "nsCCUncollectableMarker.h" #include "nsContentUtils.h" @@ -103,9 +104,9 @@ NS_CYCLE_COLLECTION_CLASSNAME(nsXPCWrappedJS)::Traverse if (cb.WantDebugInfo()) { char name[72]; if (tmp->GetClass()) - snprintf(name, sizeof(name), "nsXPCWrappedJS (%s)", tmp->GetClass()->GetInterfaceName()); + SprintfLiteral(name, "nsXPCWrappedJS (%s)", tmp->GetClass()->GetInterfaceName()); else - snprintf(name, sizeof(name), "nsXPCWrappedJS"); + SprintfLiteral(name, "nsXPCWrappedJS"); cb.DescribeRefCountedNode(refcnt, name); } else { NS_IMPL_CYCLE_COLLECTION_DESCRIBE(nsXPCWrappedJS, refcnt) diff --git a/js/xpconnect/src/XPCWrappedNative.cpp b/js/xpconnect/src/XPCWrappedNative.cpp index 2041af6eb7aa..912d3fcbe6b3 100644 --- a/js/xpconnect/src/XPCWrappedNative.cpp +++ b/js/xpconnect/src/XPCWrappedNative.cpp @@ -23,6 +23,7 @@ #include "mozilla/DeferredFinalize.h" #include "mozilla/Likely.h" #include "mozilla/Unused.h" +#include "mozilla/Sprintf.h" #include "mozilla/dom/BindingUtils.h" #include @@ -51,9 +52,9 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(XPCWrappedNative) char name[72]; XPCNativeScriptableInfo* si = tmp->GetScriptableInfo(); if (si) - snprintf(name, sizeof(name), "XPCWrappedNative (%s)", si->GetJSClass()->name); + SprintfLiteral(name, "XPCWrappedNative (%s)", si->GetJSClass()->name); else - snprintf(name, sizeof(name), "XPCWrappedNative"); + SprintfLiteral(name, "XPCWrappedNative"); cb.DescribeRefCountedNode(tmp->mRefCnt.get(), name); } else { diff --git a/layout/base/AccessibleCaretEventHub.cpp b/layout/base/AccessibleCaretEventHub.cpp index b45eb5a4a18e..b897e4d776d8 100644 --- a/layout/base/AccessibleCaretEventHub.cpp +++ b/layout/base/AccessibleCaretEventHub.cpp @@ -382,7 +382,7 @@ MOZ_IMPL_STATE_CLASS_GETTER(ScrollState) MOZ_IMPL_STATE_CLASS_GETTER(PostScrollState) MOZ_IMPL_STATE_CLASS_GETTER(LongTapState) -bool AccessibleCaretEventHub::sUseLongTapInjector = true; +bool AccessibleCaretEventHub::sUseLongTapInjector = false; AccessibleCaretEventHub::AccessibleCaretEventHub(nsIPresShell* aPresShell) : mPresShell(aPresShell) diff --git a/layout/base/tests/marionette/test_accessiblecaret_selection_mode.py b/layout/base/tests/marionette/test_accessiblecaret_selection_mode.py index 6473e8591edf..6bd729e5cf68 100644 --- a/layout/base/tests/marionette/test_accessiblecaret_selection_mode.py +++ b/layout/base/tests/marionette/test_accessiblecaret_selection_mode.py @@ -50,7 +50,6 @@ class AccessibleCaretSelectionModeTestCase(MarionetteTestCase): self.carets_tested_pref = 'layout.accessiblecaret.enabled' self.prefs = { 'layout.word_select.eat_space_to_next_word': False, - 'layout.accessiblecaret.use_long_tap_injector': False, self.carets_tested_pref: True, } self.marionette.set_prefs(self.prefs) diff --git a/layout/style/nsCSSProps.h b/layout/style/nsCSSProps.h index 4c0fae6b3ba3..8d0d5c5f6937 100644 --- a/layout/style/nsCSSProps.h +++ b/layout/style/nsCSSProps.h @@ -340,7 +340,7 @@ public: // KTableEntry objects can be initialized either with an int16_t value // or a value of an enumeration type that can fit within an int16_t. - KTableEntry(nsCSSKeyword aKeyword, int16_t aValue) + constexpr KTableEntry(nsCSSKeyword aKeyword, int16_t aValue) : mKeyword(aKeyword) , mValue(aValue) { @@ -348,7 +348,7 @@ public: template::value>::type> - KTableEntry(nsCSSKeyword aKeyword, T aValue) + constexpr KTableEntry(nsCSSKeyword aKeyword, T aValue) : mKeyword(aKeyword) , mValue(static_cast(aValue)) { diff --git a/media/mtransport/rlogringbuffer.cpp b/media/mtransport/rlogringbuffer.cpp index 141fd24f68aa..f51da3ebcc76 100644 --- a/media/mtransport/rlogringbuffer.cpp +++ b/media/mtransport/rlogringbuffer.cpp @@ -16,6 +16,7 @@ #include "mozilla/Assertions.h" #include "mozilla/Move.h" // Pinch hitting for and std::move #include "mozilla/Mutex.h" +#include "mozilla/Sprintf.h" #include extern "C" { @@ -33,7 +34,7 @@ static int ringbuffer_vlog(int facility, // I could be evil and printf right into a std::string, but unless this // shows up in profiling, it is not worth doing. char temp[4096]; - vsnprintf(temp, sizeof(temp), format, ap); + VsprintfLiteral(temp, format, ap); mozilla::RLogRingBuffer::GetInstance()->Log(std::string(temp)); return 0; diff --git a/media/webrtc/signaling/src/common/browser_logging/CSFLog.cpp b/media/webrtc/signaling/src/common/browser_logging/CSFLog.cpp index 4ecf9512d10c..3d7e2d6dcdb1 100644 --- a/media/webrtc/signaling/src/common/browser_logging/CSFLog.cpp +++ b/media/webrtc/signaling/src/common/browser_logging/CSFLog.cpp @@ -15,6 +15,7 @@ #include "nsThreadUtils.h" #include "mozilla/Logging.h" +#include "mozilla/Sprintf.h" static PRLogModuleInfo *gLogModuleInfo = nullptr; @@ -83,7 +84,7 @@ void CSFLogV(CSFLogLevel priority, const char* sourceFile, int sourceLine, const threadName = ""; } - vsnprintf(message, MAX_MESSAGE_LENGTH, format, args); + VsprintfLiteral(message, format, args); MOZ_LOG(gLogModuleInfo, level, ("[%s|%s] %s:%d: %s", threadName, tag, sourceFile, sourceLine, message)); diff --git a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp index 4ec3d5605128..07934a86a36d 100755 --- a/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp +++ b/media/webrtc/signaling/src/media-conduit/VideoConduit.cpp @@ -726,7 +726,12 @@ WebrtcVideoConduit::ConfigureSendMediaCodec(const VideoCodecConfig* codecConfig) video_codec.width = mSendingWidth; video_codec.height = mSendingHeight; video_codec.maxFramerate = mSendingFramerate; + } else { + mSendingWidth = 0; + mSendingHeight = 0; + mSendingFramerate = video_codec.maxFramerate; } + video_codec.mode = mCodecMode; if(mPtrViECodec->SetSendCodec(mChannel, video_codec) == -1) @@ -756,10 +761,6 @@ WebrtcVideoConduit::ConfigureSendMediaCodec(const VideoCodecConfig* codecConfig) } mVideoCodecStat->Register(true); - mSendingWidth = 0; - mSendingHeight = 0; - mSendingFramerate = video_codec.maxFramerate; - // See Bug 1297058, enabling FEC when NACK is set on H.264 is problematic bool use_fec = codecConfig->RtcpFbFECIsSet(); if ((mExternalSendCodec && codecConfig->mType == mExternalSendCodec->mType) diff --git a/mfbt/Attributes.h b/mfbt/Attributes.h index f615885ad500..23e77e5e0375 100644 --- a/mfbt/Attributes.h +++ b/mfbt/Attributes.h @@ -468,6 +468,10 @@ * use `auto` in place of this type in variable declarations. This is intended to * be used with types which are intended to be implicitly constructed into other * other types before being assigned to variables. + * MOZ_REQUIRED_BASE_METHOD: Applies to virtual class method declarations. + * Sometimes derived classes override methods that need to be called by their + * overridden counterparts. This marker indicates that the marked method must + * be called by the method that it overrides. */ #ifdef MOZ_CLANG_PLUGIN # define MOZ_MUST_OVERRIDE __attribute__((annotate("moz_must_override"))) @@ -501,6 +505,8 @@ __attribute__((annotate("moz_ignore_ctor_initialization"))) # define MOZ_IS_CLASS_INIT \ __attribute__((annotate("moz_is_class_init"))) +# define MOZ_REQUIRED_BASE_METHOD \ + __attribute__((annotate("moz_required_base_method"))) /* * It turns out that clang doesn't like void func() __attribute__ {} without a * warning, so use pragmas to disable the warning. This code won't work on GCC @@ -535,6 +541,7 @@ # define MOZ_INIT_OUTSIDE_CTOR /* nothing */ # define MOZ_IS_CLASS_INIT /* nothing */ # define MOZ_NON_AUTOABLE /* nothing */ +# define MOZ_REQUIRED_BASE_METHOD /* nothing */ #endif /* MOZ_CLANG_PLUGIN */ #define MOZ_RAII MOZ_NON_TEMPORARY_CLASS MOZ_STACK_CLASS diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js index c9e47a856326..256bbc8537ee 100644 --- a/mobile/android/app/mobile.js +++ b/mobile/android/app/mobile.js @@ -848,9 +848,6 @@ pref("layout.accessiblecaret.margin-left", "-11.5"); // Android needs to show the caret when long tapping on an empty content. pref("layout.accessiblecaret.caret_shown_when_long_tapping_on_empty_content", true); -// Android generates long tap (mouse) events. -pref("layout.accessiblecaret.use_long_tap_injector", false); - // Androids carets are always tilt to match the text selection guideline. pref("layout.accessiblecaret.always_tilt", true); diff --git a/mobile/android/base/java/org/mozilla/gecko/push/PushService.java b/mobile/android/base/java/org/mozilla/gecko/push/PushService.java index b10e0fb594e8..8d3a92e480ed 100644 --- a/mobile/android/base/java/org/mozilla/gecko/push/PushService.java +++ b/mobile/android/base/java/org/mozilla/gecko/push/PushService.java @@ -14,7 +14,6 @@ import android.util.Log; import org.json.JSONException; import org.json.JSONObject; import org.mozilla.gecko.EventDispatcher; -import org.mozilla.gecko.GeckoApp; import org.mozilla.gecko.GeckoAppShell; import org.mozilla.gecko.GeckoProfile; import org.mozilla.gecko.GeckoService; @@ -246,12 +245,12 @@ public class PushService implements BundleEventListener { protected void registerGeckoEventListener() { Log.d(LOG_TAG, "Registered Gecko event listener."); - GeckoApp.getEventDispatcher().registerBackgroundThreadListener(this, GECKO_EVENTS); + EventDispatcher.getInstance().registerBackgroundThreadListener(this, GECKO_EVENTS); } protected void unregisterGeckoEventListener() { Log.d(LOG_TAG, "Unregistered Gecko event listener."); - GeckoApp.getEventDispatcher().unregisterBackgroundThreadListener(this, GECKO_EVENTS); + EventDispatcher.getInstance().unregisterBackgroundThreadListener(this, GECKO_EVENTS); } @Override diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index bdb3d0359fe7..314c597b9611 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -5238,7 +5238,7 @@ pref("layout.accessiblecaret.timeout_ms", 0); // Simulate long tap to select words on the platforms where APZ is not enabled // or long tap events does not fired by APZ. -pref("layout.accessiblecaret.use_long_tap_injector", true); +pref("layout.accessiblecaret.use_long_tap_injector", false); // By default, carets become tilt only when they are overlapping. pref("layout.accessiblecaret.always_tilt", false); diff --git a/mozglue/linker/ElfLoader.cpp b/mozglue/linker/ElfLoader.cpp index 631decb368a8..76225d1e7723 100644 --- a/mozglue/linker/ElfLoader.cpp +++ b/mozglue/linker/ElfLoader.cpp @@ -479,6 +479,7 @@ ElfLoader::GetMappableFromPath(const char *path) char *zip_path = strndup(path, subpath - path); while (*(++subpath) == '/') { } zip = ZipCollection::GetZip(zip_path); + free(zip_path); Zip::Stream s; if (zip && zip->GetStream(subpath, &s)) { /* When the MOZ_LINKER_EXTRACT environment variable is set to "1", diff --git a/netwerk/base/nsILoadInfo.idl b/netwerk/base/nsILoadInfo.idl index fa66bf3792a2..7cd412c5bede 100644 --- a/netwerk/base/nsILoadInfo.idl +++ b/netwerk/base/nsILoadInfo.idl @@ -199,6 +199,18 @@ interface nsILoadInfo : nsISupports * principal of the parent document. For top-level loads, the * LoadingPrincipal is null. For all loads except top-level loads * the LoadingPrincipal is never null. + * + * If the loadingPrincipal is the system principal, no security checks + * will be done at all. There will be no security checks on the initial + * load or any subsequent redirects. This means there will be no + * nsIContentPolicy checks or any CheckLoadURI checks. Because of + * this, never set the loadingPrincipal to the system principal when + * the URI to be loaded is controlled by a webpage. + * If the loadingPrincipal and triggeringPrincipal are both + * codebase-principals, then we will always call into + * nsIContentPolicies and CheckLoadURI. The call to nsIContentPolicies + * and CheckLoadURI happen even if the URI to be loaded is same-origin + * with the loadingPrincipal or triggeringPrincipal. */ readonly attribute nsIPrincipal loadingPrincipal; @@ -215,7 +227,7 @@ interface nsILoadInfo : nsISupports * where that's not true. * * For example for loads into an