Bug 1538732 - Don't let inspector change random content state. r=smaug
authorEmilio Cobos Álvarez <emilio@crisal.io>
Fri, 29 Mar 2019 17:20:39 +0000
changeset 466881 67aebff0be25e1d3a647b33358d191464f3bef8e
parent 466880 7d058f3174e5b7b6558e944137558ad501ec4a17
child 466882 f99c446d23b189936aacc1a8664915219618b8f6
push id112603
push usernerli@mozilla.com
push dateSat, 30 Mar 2019 09:35:57 +0000
treeherdermozilla-inbound@7c3183c56eb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1538732
milestone68.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 1538732 - Don't let inspector change random content state. r=smaug Differential Revision: https://phabricator.services.mozilla.com/D25417
dom/events/EventStateManager.cpp
dom/events/EventStateManager.h
layout/inspector/InspectorUtils.cpp
layout/inspector/tests/test_bug462787.html
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -5238,23 +5238,17 @@ void EventStateManager::UpdateAncestorSt
         DoStateChange(labelTarget, aState, true);
       }
     }
   }
 }
 
 bool EventStateManager::SetContentState(nsIContent* aContent,
                                         EventStates aState) {
-  // We manage 4 states here: ACTIVE, HOVER, DRAGOVER, URLTARGET
-  // The input must be exactly one of them.
-  MOZ_ASSERT(aState == NS_EVENT_STATE_ACTIVE ||
-                 aState == NS_EVENT_STATE_HOVER ||
-                 aState == NS_EVENT_STATE_DRAGOVER ||
-                 aState == NS_EVENT_STATE_URLTARGET,
-             "Unexpected state");
+  MOZ_ASSERT(ManagesState(aState), "Unexpected state");
 
   nsCOMPtr<nsIContent> notifyContent1;
   nsCOMPtr<nsIContent> notifyContent2;
   bool updateAncestors;
 
   if (aState == NS_EVENT_STATE_HOVER || aState == NS_EVENT_STATE_ACTIVE) {
     // Hover and active are hierarchical
     updateAncestors = true;
--- a/dom/events/EventStateManager.h
+++ b/dom/events/EventStateManager.h
@@ -126,16 +126,24 @@ class EventStateManager : public nsSuppo
 
   void NotifyDestroyPresContext(nsPresContext* aPresContext);
   void SetPresContext(nsPresContext* aPresContext);
   void ClearFrameRefs(nsIFrame* aFrame);
 
   nsIFrame* GetEventTarget();
   already_AddRefed<nsIContent> GetEventTargetContent(WidgetEvent* aEvent);
 
+  // We manage 4 states here: ACTIVE, HOVER, DRAGOVER, URLTARGET
+  static bool ManagesState(EventStates aState) {
+    return aState == NS_EVENT_STATE_ACTIVE ||
+           aState == NS_EVENT_STATE_HOVER ||
+           aState == NS_EVENT_STATE_DRAGOVER ||
+           aState == NS_EVENT_STATE_URLTARGET;
+  }
+
   /**
    * Notify that the given NS_EVENT_STATE_* bit has changed for this content.
    * @param aContent Content which has changed states
    * @param aState   Corresponding state flags such as NS_EVENT_STATE_FOCUS
    * @return  Whether the content was able to change all states. Returns false
    *                  if a resulting DOM event causes the content node passed in
    *                  to not change states. Note, the frame for the content may
    *                  change as a result of the content state change, because of
--- a/layout/inspector/InspectorUtils.cpp
+++ b/layout/inspector/InspectorUtils.cpp
@@ -542,22 +542,22 @@ void InspectorUtils::GetBindingURLs(Glob
 }
 
 /* static */
 bool InspectorUtils::SetContentState(GlobalObject& aGlobalObject,
                                      Element& aElement, uint64_t aState,
                                      ErrorResult& aRv) {
   RefPtr<EventStateManager> esm =
       inLayoutUtils::GetEventStateManagerFor(aElement);
-  if (!esm) {
+  EventStates state(aState);
+  if (!esm || !EventStateManager::ManagesState(state)) {
     aRv.Throw(NS_ERROR_INVALID_ARG);
     return false;
   }
-
-  return esm->SetContentState(&aElement, EventStates(aState));
+  return esm->SetContentState(&aElement, state);
 }
 
 /* static */
 bool InspectorUtils::RemoveContentState(GlobalObject& aGlobalObject,
                                         Element& aElement, uint64_t aState,
                                         bool aClearActiveDocument,
                                         ErrorResult& aRv) {
   RefPtr<EventStateManager> esm =
--- a/layout/inspector/tests/test_bug462787.html
+++ b/layout/inspector/tests/test_bug462787.html
@@ -73,16 +73,24 @@ function do_test() {
   try {
     InspectorUtils.setContentState(null, false); 
     ok(false, "expected an exception"); 
   }
   catch(e) {
     is(e.name, "TypeError", "got the expected exception");
   }
 
+  try {
+    InspectorUtils.setContentState(document.documentElement, 3);
+    ok(false, "expected an exception");
+  }
+  catch(e) {
+    ok(true, "Threw");
+  }
+
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 addLoadEvent(do_test);
 
 
 </script>