Bug 1549270 - part 3: Mark EditorBase::SetAttributeWithTransaction() as MOZ_CAN_RUN_SCRIPT r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 08 May 2019 06:26:25 +0000
changeset 531824 8b9baadda0a72a67b359b2cbfad5de61565a4517
parent 531823 7755efc24f6d991b81598fca36a126f0fb1f565d
child 531825 8bde97e9f598f2bea1c0182de7d0b7f52126c933
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1549270
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 1549270 - part 3: Mark EditorBase::SetAttributeWithTransaction() as MOZ_CAN_RUN_SCRIPT r=m_kato Differential Revision: https://phabricator.services.mozilla.com/D30047
editor/libeditor/EditorBase.h
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditor.h
editor/libeditor/HTMLStyleEditor.cpp
editor/libeditor/HTMLTableEditor.cpp
editor/libeditor/TextEditRules.cpp
editor/libeditor/TextEditor.h
editor/nsIEditor.idl
--- a/editor/libeditor/EditorBase.h
+++ b/editor/libeditor/EditorBase.h
@@ -1200,16 +1200,17 @@ class EditorBase : public nsIEditor,
 
   /**
    * SetAttributeWithTransaction() sets aAttribute of aElement to aValue.
    *
    * @param aElement        Element node which will have aAttribute.
    * @param aAttribute      Attribute name to be set.
    * @param aValue          Attribute value be set to aAttribute.
    */
+  MOZ_CAN_RUN_SCRIPT
   nsresult SetAttributeWithTransaction(Element& aElement, nsAtom& aAttribute,
                                        const nsAString& aValue);
 
   MOZ_CAN_RUN_SCRIPT
   virtual nsresult SetAttributeOrEquivalent(Element* aElement,
                                             nsAtom* aAttribute,
                                             const nsAString& aValue,
                                             bool aSuppressTransaction) = 0;
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -4163,18 +4163,19 @@ nsresult HTMLEditRules::MakeList(nsAtom&
           }
         }
       }
       nsCOMPtr<Element> curElement = do_QueryInterface(curNode);
       if (NS_WARN_IF(!curElement)) {
         return NS_ERROR_FAILURE;
       }
       if (aBulletType && !aBulletType->IsEmpty()) {
-        rv = HTMLEditorRef().SetAttributeWithTransaction(
-            *curElement, *nsGkAtoms::type, *aBulletType);
+        rv = MOZ_KnownLive(HTMLEditorRef())
+                 .SetAttributeWithTransaction(*curElement, *nsGkAtoms::type,
+                                              *aBulletType);
         if (NS_WARN_IF(!CanHandleEditAction())) {
           return NS_ERROR_EDITOR_DESTROYED;
         }
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
       } else {
         rv = MOZ_KnownLive(HTMLEditorRef())
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -1886,18 +1886,18 @@ class HTMLEditor final : public TextEdit
    * DeleteTableElementAndChildren() removes aTableElement (and its children)
    * from the DOM tree with transaction.
    *
    * @param aTableElement   The <table> element which you want to remove.
    */
   MOZ_CAN_RUN_SCRIPT
   nsresult DeleteTableElementAndChildrenWithTransaction(Element& aTableElement);
 
-  nsresult SetColSpan(Element* aCell, int32_t aColSpan);
-  nsresult SetRowSpan(Element* aCell, int32_t aRowSpan);
+  MOZ_CAN_RUN_SCRIPT nsresult SetColSpan(Element* aCell, int32_t aColSpan);
+  MOZ_CAN_RUN_SCRIPT nsresult SetRowSpan(Element* aCell, int32_t aRowSpan);
 
   /**
    * Helper used to get nsTableWrapperFrame for a table.
    */
   static nsTableWrapperFrame* GetTableFrame(Element* aTable);
 
   /**
    * GetNumberOfCellsInRow() returns number of actual cell elements in the row.
@@ -1942,25 +1942,26 @@ class HTMLEditor final : public TextEdit
                                 int32_t aColIndex, int32_t aColSpanLeft,
                                 int32_t aColSpanRight, Element** aNewCell);
 
   MOZ_CAN_RUN_SCRIPT
   nsresult SplitCellIntoRows(Element* aTable, int32_t aRowIndex,
                              int32_t aColIndex, int32_t aRowSpanAbove,
                              int32_t aRowSpanBelow, Element** aNewCell);
 
-  nsresult CopyCellBackgroundColor(Element* aDestCell, Element* aSourceCell);
+  MOZ_CAN_RUN_SCRIPT nsresult CopyCellBackgroundColor(Element* aDestCell,
+                                                      Element* aSourceCell);
 
   /**
    * Reduce rowspan/colspan when cells span into nonexistent rows/columns.
    */
-  nsresult FixBadRowSpan(Element* aTable, int32_t aRowIndex,
-                         int32_t& aNewRowCount);
-  nsresult FixBadColSpan(Element* aTable, int32_t aColIndex,
-                         int32_t& aNewColCount);
+  MOZ_CAN_RUN_SCRIPT nsresult FixBadRowSpan(Element* aTable, int32_t aRowIndex,
+                                            int32_t& aNewRowCount);
+  MOZ_CAN_RUN_SCRIPT nsresult FixBadColSpan(Element* aTable, int32_t aColIndex,
+                                            int32_t& aNewColCount);
 
   /**
    * XXX NormalizeTableInternal() is broken.  If it meets a cell which has
    *     bigger or smaller rowspan or colspan than actual number of cells,
    *     this always failed to scan the table.  Therefore, this does nothing
    *     when the table should be normalized.
    *
    * @param aTableOrElementInTable  An element which is in a <table> element
--- a/editor/libeditor/HTMLStyleEditor.cpp
+++ b/editor/libeditor/HTMLStyleEditor.cpp
@@ -497,17 +497,18 @@ nsresult HTMLEditor::SetInlinePropertyOn
   }
 
   // is it already the right kind of node, but with wrong attribute?
   if (aNode.IsHTMLElement(&aProperty)) {
     if (NS_WARN_IF(!aAttribute)) {
       return NS_ERROR_FAILURE;
     }
     // Just set the attribute on it.
-    return SetAttributeWithTransaction(*aNode.AsElement(), *aAttribute, aValue);
+    return SetAttributeWithTransaction(MOZ_KnownLive(*aNode.AsElement()),
+                                       *aAttribute, aValue);
   }
 
   // ok, chuck it in its very own container
   RefPtr<Element> tmp = InsertContainerWithTransaction(
       aNode, aProperty, aAttribute ? *aAttribute : *nsGkAtoms::_empty, aValue);
   if (NS_WARN_IF(!tmp)) {
     return NS_ERROR_FAILURE;
   }
--- a/editor/libeditor/HTMLTableEditor.cpp
+++ b/editor/libeditor/HTMLTableEditor.cpp
@@ -444,17 +444,17 @@ nsresult HTMLEditor::InsertTableColumnsW
     case InsertPosition::eAfterSelectedCell:
       // Use column after current cell.
       startColIndex += cellDataAtSelection.mEffectiveColSpan;
 
       // Detect when user is adding after a colspan=0 case.
       // Assume they want to stop the "0" behavior and really add a new column.
       // Thus we set the colspan to its true value.
       if (!cellDataAtSelection.mColSpan) {
-        SetColSpan(cellDataAtSelection.mElement,
+        SetColSpan(MOZ_KnownLive(cellDataAtSelection.mElement),
                    cellDataAtSelection.mEffectiveColSpan);
       }
       break;
     default:
       MOZ_ASSERT_UNREACHABLE("Invalid InsertPosition");
   }
 
   // We control selection resetting after the insert.
@@ -492,17 +492,17 @@ nsresult HTMLEditor::InsertTableColumnsW
       }
 
       if (cellData.IsSpannedFromOtherColumn()) {
         // If we have a cell spanning this location, simply increase its
         // colspan to keep table rectangular.
         // Note: we do nothing if colsspan=0, since it should automatically
         // span the new column.
         if (cellData.mColSpan > 0) {
-          SetColSpan(cellData.mElement,
+          SetColSpan(MOZ_KnownLive(cellData.mElement),
                      cellData.mColSpan + aNumberOfColumnsToInsert);
         }
         continue;
       }
 
       // Simply set selection to the current cell. So, we can let
       // InsertTableCellsWithTransaction() do the work.  Insert a new cell
       // before current one.
@@ -631,17 +631,17 @@ nsresult HTMLEditor::InsertTableRowsWith
     case InsertPosition::eAfterSelectedCell:
       // Use row after current cell.
       startRowIndex += cellDataAtSelection.mEffectiveRowSpan;
 
       // Detect when user is adding after a rowspan=0 case.
       // Assume they want to stop the "0" behavior and really add a new row.
       // Thus we set the rowspan to its true value.
       if (!cellDataAtSelection.mRowSpan) {
-        SetRowSpan(cellDataAtSelection.mElement,
+        SetRowSpan(MOZ_KnownLive(cellDataAtSelection.mElement),
                    cellDataAtSelection.mEffectiveRowSpan);
       }
       break;
     default:
       MOZ_ASSERT_UNREACHABLE("Invalid InsertPosition");
   }
 
   // We control selection resetting after the insert.
@@ -669,17 +669,17 @@ nsresult HTMLEditor::InsertTableRowsWith
         break;
       }
 
       if (cellData.IsSpannedFromOtherRow()) {
         // We have a cell spanning this location.  Increase its rowspan.
         // Note that if rowspan is 0, we do nothing since that cell should
         // automatically extend into the new row.
         if (cellData.mRowSpan > 0) {
-          SetRowSpan(cellData.mElement,
+          SetRowSpan(MOZ_KnownLive(cellData.mElement),
                      cellData.mRowSpan + aNumberOfRowsToInsert);
         }
         continue;
       }
 
       cellsInRow += cellData.mEffectiveColSpan;
       if (!cellForRowParent) {
         // FYI: Don't use std::move() here since NextColumnIndex() needs it.
@@ -1350,17 +1350,17 @@ nsresult HTMLEditor::DeleteTableColumnWi
     MOZ_ASSERT(cellData.mColSpan >= 0);
     if (cellData.IsSpannedFromOtherColumn() || cellData.mColSpan != 1) {
       // If we have a cell spanning this location, decrease its colspan to
       // keep table rectangular, but if colspan is 0, it'll be adjusted
       // automatically.
       if (cellData.mColSpan > 0) {
         NS_WARNING_ASSERTION(cellData.mColSpan > 1,
                              "colspan should be 2 or larger");
-        SetColSpan(cellData.mElement, cellData.mColSpan - 1);
+        SetColSpan(MOZ_KnownLive(cellData.mElement), cellData.mColSpan - 1);
       }
       if (!cellData.IsSpannedFromOtherColumn()) {
         // Cell is in column to be deleted, but must have colspan > 1,
         // so delete contents of cell instead of cell itself (We must have
         // reset colspan above).
         DebugOnly<nsresult> rv =
             DeleteAllChildrenWithTransaction(MOZ_KnownLive(*cellData.mElement));
         NS_WARNING_ASSERTION(
@@ -1663,17 +1663,18 @@ nsresult HTMLEditor::DeleteTableRowWithT
     }
   }
 
   // Now we can set new rowspans for cells stored above.
   for (SpanCell& spanCell : spanCellArray) {
     if (NS_WARN_IF(!spanCell.mElement)) {
       continue;
     }
-    nsresult rv = SetRowSpan(spanCell.mElement, spanCell.mNewRowSpanValue);
+    nsresult rv =
+        SetRowSpan(MOZ_KnownLive(spanCell.mElement), spanCell.mNewRowSpanValue);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
   return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -2190,17 +2191,17 @@ nsresult HTMLEditor::SplitCellIntoColumn
 
   // We can't split!
   if (cellData.mEffectiveColSpan <= 1 ||
       aColSpanLeft + aColSpanRight > cellData.mEffectiveColSpan) {
     return NS_OK;
   }
 
   // Reduce colspan of cell to split
-  nsresult rv = SetColSpan(cellData.mElement, aColSpanLeft);
+  nsresult rv = SetColSpan(MOZ_KnownLive(cellData.mElement), aColSpanLeft);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   // Insert new cell after using the remaining span
   // and always get the new cell so we can copy the background color;
   RefPtr<Element> newCellElement;
   rv = InsertCell(MOZ_KnownLive(cellData.mElement), cellData.mEffectiveRowSpan,
@@ -2209,17 +2210,18 @@ nsresult HTMLEditor::SplitCellIntoColumn
     return rv;
   }
   if (!newCellElement) {
     return NS_OK;
   }
   if (aNewCell) {
     NS_ADDREF(*aNewCell = newCellElement.get());
   }
-  rv = CopyCellBackgroundColor(newCellElement, cellData.mElement);
+  rv =
+      CopyCellBackgroundColor(newCellElement, MOZ_KnownLive(cellData.mElement));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
   return NS_OK;
 }
 
 nsresult HTMLEditor::SplitCellIntoRows(Element* aTable, int32_t aRowIndex,
                                        int32_t aColIndex, int32_t aRowSpanAbove,
@@ -2311,17 +2313,17 @@ nsresult HTMLEditor::SplitCellIntoRows(E
     // or before because column(s) before desired column
     // and all columns after it are spanned from above.
     // We can insert after the last cell we found
     cellElementAtInsertionPoint = std::move(lastCellFound);
     insertAfter = true;  // Should always be true, but let's be sure
   }
 
   // Reduce rowspan of cell to split
-  nsresult rv = SetRowSpan(cellData.mElement, aRowSpanAbove);
+  nsresult rv = SetRowSpan(MOZ_KnownLive(cellData.mElement), aRowSpanAbove);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   // Insert new cell after using the remaining span
   // and always get the new cell so we can copy the background color;
   RefPtr<Element> newCell;
   rv = InsertCell(cellElementAtInsertionPoint, aRowSpanBelow,
@@ -2649,22 +2651,22 @@ HTMLEditor::JoinTableCells(bool aMergeNo
       if (!deletedCell) {
         SelectionRefPtr()->RemoveRange(*range, IgnoreErrors());
         rangeCount--;
         i--;
       }
     }
 
     // Set spans for the cell everything merged into
-    rv = SetRowSpan(firstSelectedCell.mElement,
+    rv = SetRowSpan(MOZ_KnownLive(firstSelectedCell.mElement),
                     lastRowIndex - firstSelectedCell.mIndexes.mRow + 1);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return EditorBase::ToGenericNSResult(rv);
     }
-    rv = SetColSpan(firstSelectedCell.mElement,
+    rv = SetColSpan(MOZ_KnownLive(firstSelectedCell.mElement),
                     lastColIndex - firstSelectedCell.mIndexes.mColumn + 1);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return EditorBase::ToGenericNSResult(rv);
     }
 
     // Fixup disturbances in table layout
     DebugOnly<nsresult> rv = NormalizeTableInternal(*table);
     NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to normalize the table");
@@ -2731,25 +2733,27 @@ HTMLEditor::JoinTableCells(bool aMergeNo
       // We could try splitting those cells, but that's REAL messy,
       // so the safest thing to do is NOT really join the cells
       return NS_OK;
     }
 
     if (spanAboveMergedCell > 0) {
       // Cell we merged started in a row above the target cell
       // Reduce rowspan to give room where target cell will extend its colspan
-      rv = SetRowSpan(rightCellData.mElement, spanAboveMergedCell);
+      rv = SetRowSpan(MOZ_KnownLive(rightCellData.mElement),
+                      spanAboveMergedCell);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return EditorBase::ToGenericNSResult(rv);
       }
     }
 
     // Reset target cell's colspan to encompass cell to the right
-    rv = SetColSpan(leftCellData.mElement, leftCellData.mEffectiveColSpan +
-                                               rightCellData.mEffectiveColSpan);
+    rv = SetColSpan(
+        MOZ_KnownLive(leftCellData.mElement),
+        leftCellData.mEffectiveColSpan + rightCellData.mEffectiveColSpan);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return EditorBase::ToGenericNSResult(rv);
     }
   }
   return NS_OK;
 }
 
 nsresult HTMLEditor::MergeCells(RefPtr<Element> aTargetCell,
@@ -2867,18 +2871,18 @@ nsresult HTMLEditor::FixBadRowSpan(Eleme
         return NS_ERROR_FAILURE;
       }
 
       // Fixup rowspans only for cells starting in current row
       // XXX So, this does not assume that CellData returns error when just
       //     not found a cell.  Fix this later.
       if (cellData.mElement && cellData.mRowSpan > 0 &&
           !cellData.IsSpannedFromOtherRowOrColumn()) {
-        nsresult rv =
-            SetRowSpan(cellData.mElement, cellData.mRowSpan - rowsReduced);
+        nsresult rv = SetRowSpan(MOZ_KnownLive(cellData.mElement),
+                                 cellData.mRowSpan - rowsReduced);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
       }
       MOZ_ASSERT(colIndex < cellData.NextColumnIndex());
     }
   }
   tableSize.Update(*this, *aTable, error);
@@ -2940,18 +2944,18 @@ nsresult HTMLEditor::FixBadColSpan(Eleme
         return NS_ERROR_FAILURE;
       }
 
       // Fixup colspans only for cells starting in current column
       // XXX So, this does not assume that CellData returns error when just
       //     not found a cell.  Fix this later.
       if (cellData.mElement && cellData.mColSpan > 0 &&
           !cellData.IsSpannedFromOtherRowOrColumn()) {
-        nsresult rv =
-            SetColSpan(cellData.mElement, cellData.mColSpan - colsReduced);
+        nsresult rv = SetColSpan(MOZ_KnownLive(cellData.mElement),
+                                 cellData.mColSpan - colsReduced);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return rv;
         }
       }
       MOZ_ASSERT(rowIndex < cellData.NextRowIndex());
     }
   }
   tableSize.Update(*this, *aTable, error);
--- a/editor/libeditor/TextEditRules.cpp
+++ b/editor/libeditor/TextEditRules.cpp
@@ -1790,18 +1790,19 @@ CreateElementResult TextEditRules::Creat
   }
 
   // give it special moz attr
   if (!aCreateMozBR) {
     return CreateElementResult(brElement.forget());
   }
 
   // XXX Why do we need to set this attribute with transaction?
-  nsresult rv = TextEditorRef().SetAttributeWithTransaction(
-      *brElement, *nsGkAtoms::type, NS_LITERAL_STRING("_moz"));
+  nsresult rv = MOZ_KnownLive(TextEditorRef())
+                    .SetAttributeWithTransaction(*brElement, *nsGkAtoms::type,
+                                                 NS_LITERAL_STRING("_moz"));
   // XXX Don't we need to remove the new <br> element from the DOM tree
   //     in these case?
   if (NS_WARN_IF(!CanHandleEditAction())) {
     return CreateElementResult(NS_ERROR_EDITOR_DESTROYED);
   }
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return CreateElementResult(NS_ERROR_FAILURE);
   }
--- a/editor/libeditor/TextEditor.h
+++ b/editor/libeditor/TextEditor.h
@@ -54,16 +54,17 @@ class TextEditor : public EditorBase, pu
 
   // Overrides of nsIEditor
   NS_IMETHOD GetDocumentIsEmpty(bool* aDocumentIsEmpty) override;
 
   MOZ_CAN_RUN_SCRIPT
   NS_IMETHOD DeleteSelection(EDirection aAction,
                              EStripWrappers aStripWrappers) override;
 
+  MOZ_CAN_RUN_SCRIPT
   NS_IMETHOD SetDocumentCharacterSet(const nsACString& characterSet) override;
 
   // If there are some good name to create non-virtual Undo()/Redo() methods,
   // we should create them and those methods should just run them.
   MOZ_CAN_RUN_SCRIPT
   NS_IMETHOD Undo(uint32_t aCount) final;
   MOZ_CAN_RUN_SCRIPT
   NS_IMETHOD Redo(uint32_t aCount) final;
@@ -517,17 +518,18 @@ class TextEditor : public EditorBase, pu
   nsresult SharedOutputString(uint32_t aFlags, bool* aIsCollapsed,
                               nsAString& aResult);
 
   enum PasswordFieldAllowed { ePasswordFieldAllowed, ePasswordFieldNotAllowed };
   bool CanCutOrCopy(PasswordFieldAllowed aPasswordFieldAllowed) const;
   bool FireClipboardEvent(EventMessage aEventMessage, int32_t aSelectionType,
                           bool* aActionTaken = nullptr);
 
-  bool UpdateMetaCharset(Document& aDocument, const nsACString& aCharacterSet);
+  MOZ_CAN_RUN_SCRIPT bool UpdateMetaCharset(Document& aDocument,
+                                            const nsACString& aCharacterSet);
 
   /**
    * EnsureComposition() should be called by composition event handlers.  This
    * tries to get the composition for the event and set it to mComposition.
    * However, this may fail because the composition may be committed before
    * the event comes to the editor.
    *
    * @return            true if there is a composition.  Otherwise, for example,
--- a/editor/nsIEditor.idl
+++ b/editor/nsIEditor.idl
@@ -110,16 +110,17 @@ interface nsIEditor  : nsISupports
 
   /** Returns true if the document has no *meaningful* content */
   readonly attribute boolean documentIsEmpty;
 
   /** Returns true if the document is modifed and needs saving */
   readonly attribute boolean documentModified;
 
   /** Sets the current 'Save' document character set */
+  [can_run_script]  // setter only
   attribute ACString documentCharacterSet;
 
   /** to be used ONLY when we need to override the doc's modification
     * state (such as when it's saved).
     */
   void resetModificationCount();
 
   /** Gets the modification count of the document we are editing.
@@ -335,16 +336,17 @@ interface nsIEditor  : nsISupports
    * setAttribute() sets the attribute of aElement.
    * No checking is done to see if aAttribute is a legal attribute of the node,
    * or if aValue is a legal value of aAttribute.
    *
    * @param aElement    the content element to operate on
    * @param aAttribute  the string representation of the attribute to set
    * @param aValue      the value to set aAttribute to
    */
+  [can_run_script]
   void setAttribute(in Element aElement, in AString attributestr,
                     in AString attvalue);
 
   /**
    * getAttributeValue() retrieves the attribute's value for aElement.
    *
    * @param aElement      the content element to operate on
    * @param aAttribute    the string representation of the attribute to get