Bug 1534370 part 1. Annotate doCommandWithParams as MOZ_CAN_RUN_SCRIPT. r=masayuki
authorBoris Zbarsky <bzbarsky@mit.edu>
Wed, 13 Mar 2019 00:43:48 +0000
changeset 524629 dcaf8c29a1eef3bf5eb76a77a3ae1a188ba5b0b3
parent 524628 88c9c5b8d99ca97c8afdb0a62d5787849129a7db
child 524630 1289a49488fa7cf67e0bfbb9ed81afc43196e3bf
push id2032
push userffxbld-merge
push dateMon, 13 May 2019 09:36:57 +0000
treeherdermozilla-release@455c1065dcbe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki
bugs1534370
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1534370 part 1. Annotate doCommandWithParams as MOZ_CAN_RUN_SCRIPT. r=masayuki Differential Revision: https://phabricator.services.mozilla.com/D23036
docshell/base/nsIDocShell.idl
dom/commandhandler/nsBaseCommandController.cpp
dom/commandhandler/nsICommandManager.idl
dom/commandhandler/nsIControllerCommand.idl
dom/commandhandler/nsIControllerCommandTable.idl
dom/events/EventStateManager.h
dom/html/nsHTMLDocument.cpp
dom/html/nsHTMLDocument.h
dom/ipc/TabChild.h
dom/xul/nsIController.idl
layout/base/PresShell.cpp
--- a/docshell/base/nsIDocShell.idl
+++ b/docshell/base/nsIDocShell.idl
@@ -907,16 +907,17 @@ interface nsIDocShell : nsIDocShellTreeI
 
   /**
     * Cherry picked parts of nsIController.
     * They are here, because we want to call these functions
     * from JS.
     */
   boolean isCommandEnabled(in string command);
   void doCommand(in string command);
+  [can_run_script]
   void doCommandWithParams(in string command, in nsICommandParams aParams);
 
   /**
    * Invisible DocShell are dummy construct to simulate DOM windows
    * without any actual visual representation. They have to be marked
    * at construction time, to avoid any painting activity.
    */
   [noscript, notxpcom] bool IsInvisible();
--- a/dom/commandhandler/nsBaseCommandController.cpp
+++ b/dom/commandhandler/nsBaseCommandController.cpp
@@ -124,23 +124,22 @@ nsBaseCommandController::DoCommand(const
 }
 
 NS_IMETHODIMP
 nsBaseCommandController::DoCommandWithParams(const char* aCommand,
                                              nsICommandParams* aParams) {
   NS_ENSURE_ARG_POINTER(aCommand);
   NS_ENSURE_STATE(mCommandTable);
 
-  nsISupports* context = mCommandContextRawPtr;
-  nsCOMPtr<nsISupports> weak;
+  nsCOMPtr<nsISupports> context = mCommandContextRawPtr;
   if (!context) {
-    weak = do_QueryReferent(mCommandContextWeakPtr);
-    context = weak;
+    context = do_QueryReferent(mCommandContextWeakPtr);
   }
-  return mCommandTable->DoCommandParams(aCommand, aParams, context);
+  nsCOMPtr<nsIControllerCommandTable> commandTable(mCommandTable);
+  return commandTable->DoCommandParams(aCommand, aParams, context);
 }
 
 NS_IMETHODIMP
 nsBaseCommandController::GetCommandStateWithParams(const char* aCommand,
                                                    nsICommandParams* aParams) {
   NS_ENSURE_ARG_POINTER(aCommand);
   NS_ENSURE_STATE(mCommandTable);
 
--- a/dom/commandhandler/nsICommandManager.idl
+++ b/dom/commandhandler/nsICommandManager.idl
@@ -83,16 +83,17 @@ interface nsICommandManager : nsISupport
    * Execute the specified command.
    * The command will be executed in aTargetWindow if it is specified.
    * If aTargetWindow is null, it will go to the focused window.
    *
    * param: aCommandParams, a list of name-value pairs of command parameters,
    * may be null for parameter-less commands.
    *
    */
+  [can_run_script]
   void        doCommand(in string aCommandName,
                         in nsICommandParams aCommandParams,
                         in mozIDOMWindowProxy aTargetWindow);
 
 };
 
 
 /*
--- a/dom/commandhandler/nsIControllerCommand.idl
+++ b/dom/commandhandler/nsIControllerCommand.idl
@@ -40,12 +40,13 @@ interface nsIControllerCommand : nsISupp
    * @param aCommandName  the name of the command to execute.
    * 
    * @param aCommandContext    a cookie held by the nsIControllerCommandTable,
    *                  allowing the command to get some context information.
    *                  The contents of this cookie are implementation-defined.
    */
   void    doCommand(in string aCommandName, in nsISupports aCommandContext);
 
+  [can_run_script]
   void    doCommandParams(in string aCommandName, in nsICommandParams aParams, in nsISupports aCommandContext);
   
 };
 
--- a/dom/commandhandler/nsIControllerCommandTable.idl
+++ b/dom/commandhandler/nsIControllerCommandTable.idl
@@ -74,16 +74,17 @@ interface nsIControllerCommandTable : ns
   /**
    * Execute the named command.
    *
    * @param aCommandName    the name of the command to execute
    * @param aCommandRefCon  the command context data
    */
 	void    doCommand(in string aCommandName, in nsISupports aCommandRefCon);
 
+  [can_run_script]
 	void    doCommandParams(in string aCommandName, in nsICommandParams aParam, in nsISupports aCommandRefCon);
 
 	void    getCommandState(in string aCommandName, in nsICommandParams aParam, in nsISupports aCommandRefCon);
 
   void getSupportedCommands(out unsigned long count,
                             [array, size_is(count), retval] out string commands);
 };
 
--- a/dom/events/EventStateManager.h
+++ b/dom/events/EventStateManager.h
@@ -92,27 +92,28 @@ class EventStateManager : public nsSuppo
    * be conditional based on either DOM or frame processing should occur in
    * PostHandleEvent.  Any centralized event processing which must occur before
    * DOM or frame event handling should occur here as well.
    *
    * aOverrideClickTarget can be used to indicate which element should be
    * used as the *up target when deciding whether to send click event.
    * This is used when releasing pointer capture. Otherwise null.
    */
+  MOZ_CAN_RUN_SCRIPT
   nsresult PreHandleEvent(nsPresContext* aPresContext, WidgetEvent* aEvent,
                           nsIFrame* aTargetFrame, nsIContent* aTargetContent,
                           nsEventStatus* aStatus,
                           nsIContent* aOverrideClickTarget);
 
   /* The PostHandleEvent method should contain all system processing which
    * should occur conditionally based on DOM or frame processing.  It should
    * also contain any centralized event processing which must occur after
    * DOM and frame processing.
    */
-  MOZ_CAN_RUN_SCRIPT_BOUNDARY
+  MOZ_CAN_RUN_SCRIPT
   nsresult PostHandleEvent(nsPresContext* aPresContext, WidgetEvent* aEvent,
                            nsIFrame* aTargetFrame, nsEventStatus* aStatus,
                            nsIContent* aOverrideClickTarget);
 
   void PostHandleKeyboardEvent(WidgetKeyboardEvent* aKeyboardEvent,
                                nsIFrame* aTargetFrame, nsEventStatus& aStatus);
 
   /**
@@ -1094,16 +1095,17 @@ class EventStateManager : public nsSuppo
   /**
    * Set the fields of aEvent to reflect the mouse position and modifier keys
    * that were set when the user first pressed the mouse button (stored by
    * BeginTrackingDragGesture). aEvent->mWidget must be
    * mCurrentTarget->GetNearestWidget().
    */
   void FillInEventFromGestureDown(WidgetMouseEvent* aEvent);
 
+  MOZ_CAN_RUN_SCRIPT
   nsresult DoContentCommandEvent(WidgetContentCommandEvent* aEvent);
   nsresult DoContentCommandScrollEvent(WidgetContentCommandEvent* aEvent);
 
   dom::TabParent* GetCrossProcessTarget();
   bool IsTargetCrossProcess(WidgetGUIEvent* aEvent);
 
   /**
    * DispatchCrossProcessEvent() try to post aEvent to target remote process.
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -2112,23 +2112,24 @@ nsresult nsHTMLDocument::EditingStateCha
   if (makeWindowEditable) {
     // Set the editor to not insert br's on return when in p
     // elements by default.
     // XXX Do we only want to do this for designMode?
     // Note that it doesn't matter what CallerType we pass, because the callee
     // doesn't use it for this command.  Play it safe and pass the more
     // restricted one.
     ErrorResult errorResult;
+    nsCOMPtr<nsIPrincipal> principal = NodePrincipal();
     Unused << ExecCommand(NS_LITERAL_STRING("insertBrOnReturn"), false,
                           NS_LITERAL_STRING("false"),
                           // Principal doesn't matter here, because the
                           // insertBrOnReturn command doesn't use it.   Still
                           // it's too bad we can't easily grab a nullprincipal
                           // from somewhere without allocating one..
-                          *NodePrincipal(), errorResult);
+                          *principal, errorResult);
 
     if (errorResult.Failed()) {
       // Editor setup failed. Editing is not on after all.
       // XXX Should we reset the editable flag on nodes?
       editSession->TearDownEditorOnWindow(window);
       mEditingState = eOff;
 
       return errorResult.StealNSResult();
@@ -2535,17 +2536,17 @@ bool nsHTMLDocument::ExecCommand(const n
   // get command manager and dispatch command to our window if it's acceptable
   nsCOMPtr<nsICommandManager> cmdMgr;
   GetMidasCommandManager(getter_AddRefs(cmdMgr));
   if (!cmdMgr) {
     rv.Throw(NS_ERROR_FAILURE);
     return false;
   }
 
-  nsPIDOMWindowOuter* window = GetWindow();
+  nsCOMPtr<nsPIDOMWindowOuter> window = GetWindow();
   if (!window) {
     rv.Throw(NS_ERROR_FAILURE);
     return false;
   }
 
   if ((cmdToDispatch.EqualsLiteral("cmd_fontSize") ||
        cmdToDispatch.EqualsLiteral("cmd_insertImageNoUI") ||
        cmdToDispatch.EqualsLiteral("cmd_insertLinkNoUI") ||
@@ -2784,17 +2785,17 @@ void nsHTMLDocument::QueryCommandValue(c
   // get command manager and dispatch command to our window if it's acceptable
   nsCOMPtr<nsICommandManager> cmdMgr;
   GetMidasCommandManager(getter_AddRefs(cmdMgr));
   if (!cmdMgr) {
     rv.Throw(NS_ERROR_FAILURE);
     return;
   }
 
-  nsPIDOMWindowOuter* window = GetWindow();
+  nsCOMPtr<nsPIDOMWindowOuter> window = GetWindow();
   if (!window) {
     rv.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   // this is a special command since we are calling DoCommand rather than
   // GetCommandState like the other commands
   RefPtr<nsCommandParams> params = new nsCommandParams();
--- a/dom/html/nsHTMLDocument.h
+++ b/dom/html/nsHTMLDocument.h
@@ -164,27 +164,32 @@ class nsHTMLDocument : public mozilla::d
   void Writeln(const mozilla::dom::Sequence<nsString>& aText,
                mozilla::ErrorResult& rv);
   void GetDesignMode(nsAString& aDesignMode);
   void SetDesignMode(const nsAString& aDesignMode,
                      nsIPrincipal& aSubjectPrincipal, mozilla::ErrorResult& rv);
   void SetDesignMode(const nsAString& aDesignMode,
                      const mozilla::Maybe<nsIPrincipal*>& aSubjectPrincipal,
                      mozilla::ErrorResult& rv);
+  // MOZ_CAN_RUN_SCRIPT_BOUNDARY because I haven't figured out how to teach the
+  // analysis that a MOZ_KnownLive(NonNull<T>) being passed as T& is OK.  See
+  // bug 1534383.
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY
   bool ExecCommand(const nsAString& aCommandID, bool aDoShowUI,
                    const nsAString& aValue, nsIPrincipal& aSubjectPrincipal,
                    mozilla::ErrorResult& rv);
   bool QueryCommandEnabled(const nsAString& aCommandID,
                            nsIPrincipal& aSubjectPrincipal,
                            mozilla::ErrorResult& rv);
   bool QueryCommandIndeterm(const nsAString& aCommandID,
                             mozilla::ErrorResult& rv);
   bool QueryCommandState(const nsAString& aCommandID, mozilla::ErrorResult& rv);
   bool QueryCommandSupported(const nsAString& aCommandID,
                              mozilla::dom::CallerType aCallerType);
+  MOZ_CAN_RUN_SCRIPT
   void QueryCommandValue(const nsAString& aCommandID, nsAString& aValue,
                          mozilla::ErrorResult& rv);
   void GetFgColor(nsAString& aFgColor);
   void SetFgColor(const nsAString& aFgColor);
   void GetLinkColor(nsAString& aLinkColor);
   void SetLinkColor(const nsAString& aLinkColor);
   void GetVlinkColor(nsAString& aAvlinkColor);
   void SetVlinkColor(const nsAString& aVlinkColor);
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -390,16 +390,17 @@ class TabChild final : public TabChildBa
       const mozilla::WidgetCompositionEvent& aEvent) override;
 
   virtual mozilla::ipc::IPCResult RecvSelectionEvent(
       const mozilla::WidgetSelectionEvent& aEvent) override;
 
   virtual mozilla::ipc::IPCResult RecvNormalPrioritySelectionEvent(
       const mozilla::WidgetSelectionEvent& aEvent) override;
 
+  MOZ_CAN_RUN_SCRIPT_BOUNDARY
   virtual mozilla::ipc::IPCResult RecvPasteTransferable(
       const IPCDataTransfer& aDataTransfer, const bool& aIsPrivateData,
       const IPC::Principal& aRequestingPrincipal,
       const uint32_t& aContentPolicyType) override;
 
   virtual mozilla::ipc::IPCResult RecvActivateFrameEvent(
       const nsString& aType, const bool& aCapture) override;
 
--- a/dom/xul/nsIController.idl
+++ b/dom/xul/nsIController.idl
@@ -26,13 +26,14 @@ interface nsIController : nsISupports {
 interface nsICommandParams;
 
 [scriptable, uuid(EEC0B435-7F53-44FE-B00A-CF3EED65C01A)]
 interface nsICommandController : nsISupports
 {
   
   void        getCommandStateWithParams( in string command, in nsICommandParams aCommandParams);
     
+  [can_run_script]
   void        doCommandWithParams(in string command, in nsICommandParams aCommandParams);
 
   void getSupportedCommands(out unsigned long count,
                             [array, size_is(count), retval] out string commands);
 };
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -7720,21 +7720,25 @@ nsresult PresShell::EventHandler::Dispat
     bool aTouchIsNew, nsEventStatus* aEventStatus,
     nsIContent* aOverrideClickTarget) {
   MOZ_ASSERT(aEventStateManager);
   MOZ_ASSERT(aEvent);
   MOZ_ASSERT(aEventStatus);
 
   // 1. Give event to event manager for pre event state changes and
   //    generation of synthetic events.
-  nsresult rv = aEventStateManager->PreHandleEvent(
-      GetPresContext(), aEvent, mPresShell->mCurrentEventFrame,
-      mPresShell->mCurrentEventContent, aEventStatus, aOverrideClickTarget);
-  if (NS_FAILED(rv)) {
-    return rv;
+  {  // Scope for presContext
+    RefPtr<nsPresContext> presContext = GetPresContext();
+    nsCOMPtr<nsIContent> eventContent = mPresShell->mCurrentEventContent;
+    nsresult rv = aEventStateManager->PreHandleEvent(
+        presContext, aEvent, mPresShell->mCurrentEventFrame, eventContent,
+        aEventStatus, aOverrideClickTarget);
+    if (NS_FAILED(rv)) {
+      return rv;
+    }
   }
 
   // 2. Give event to the DOM for third party and JS use.
   bool wasHandlingKeyBoardEvent = nsContentUtils::IsHandlingKeyBoardEvent();
   if (aEvent->mClass == eKeyboardEventClass) {
     nsContentUtils::SetIsHandlingKeyBoardEvent(true);
   }
   // If EventStateManager or something wants reply from remote process and
@@ -7778,19 +7782,21 @@ nsresult PresShell::EventHandler::Dispat
   }
 
   if (mPresShell->IsDestroying()) {
     return NS_OK;
   }
 
   // 3. Give event to event manager for post event state changes and
   //    generation of synthetic events.
+  // Refetch the prescontext, in case it changed.
+  RefPtr<nsPresContext> presContext = GetPresContext();
   return aEventStateManager->PostHandleEvent(
-      GetPresContext(), aEvent, mPresShell->GetCurrentEventFrame(),
-      aEventStatus, aOverrideClickTarget);
+      presContext, aEvent, mPresShell->GetCurrentEventFrame(), aEventStatus,
+      aOverrideClickTarget);
 }
 
 bool PresShell::EventHandler::PrepareToDispatchEvent(WidgetEvent* aEvent) {
   if (!aEvent->IsTrusted()) {
     return false;
   }
 
   if (aEvent->IsUserAction()) {