tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 29812c52786cf03bd239679062e9c63954966c1a
parent de491d857f09cae95af53509792b1c05fd9e2727
Author: Masayuki Nakano <masayuki@d-toybox.com>
Date:   Wed, 17 Dec 2025 00:32:11 +0000

Bug 2006229 - Make `AutoEditActionDataSetter` log the HTML and Selection when it's created r=m_kato

When we get a bug report from the fuzzing team, which edit action is
performed within what `innerHTML` of the editing host and `Selection`
ranges are important and help us to minimize the testcase.  Therefore,
let's make `AutoEditActionDataSetter` log them when it's created for an
`HTMLEditor`.

Differential Revision: https://phabricator.services.mozilla.com/D276585

Diffstat:
Meditor/libeditor/EditAction.h | 241+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Meditor/libeditor/EditorBase.cpp | 35+++++++++++++++++++++++++++++++++++
2 files changed, 276 insertions(+), 0 deletions(-)

diff --git a/editor/libeditor/EditAction.h b/editor/libeditor/EditAction.h @@ -853,6 +853,247 @@ inline bool MayEditActionRequireLayout(const EditAction aEditAction) { } } +inline std::ostream& operator<<(std::ostream& aStream, + const EditAction& aEditAction) { + switch (aEditAction) { + case EditAction::eNone: + return aStream << "eNone"; + case EditAction::eNotEditing: + return aStream << "eNotEditing"; + case EditAction::eInitializing: + return aStream << "eInitializing"; + case EditAction::eInsertText: + return aStream << "eInsertText"; + case EditAction::eInsertParagraphSeparator: + return aStream << "eInsertParagraphSeparator"; + case EditAction::eInsertLineBreak: + return aStream << "eInsertLineBreak"; + case EditAction::eDeleteSelection: + return aStream << "eDeleteSelection"; + case EditAction::eDeleteBackward: + return aStream << "eDeleteBackward"; + case EditAction::eDeleteForward: + return aStream << "eDeleteForward"; + case EditAction::eDeleteWordBackward: + return aStream << "eDeleteWordBackward"; + case EditAction::eDeleteWordForward: + return aStream << "eDeleteWordForward"; + case EditAction::eDeleteToBeginningOfSoftLine: + return aStream << "eDeleteToBeginningOfSoftLine"; + case EditAction::eDeleteToEndOfSoftLine: + return aStream << "eDeleteToEndOfSoftLine"; + case EditAction::eDeleteByDrag: + return aStream << "eDeleteByDrag"; + case EditAction::eStartComposition: + return aStream << "eStartComposition"; + case EditAction::eUpdateComposition: + return aStream << "eUpdateComposition"; + case EditAction::eUpdateCompositionToCommit: + return aStream << "eUpdateCompositionToCommit"; + case EditAction::eCommitComposition: + return aStream << "eCommitComposition"; + case EditAction::eCancelComposition: + return aStream << "eCancelComposition"; + case EditAction::eUndo: + return aStream << "eUndo"; + case EditAction::eRedo: + return aStream << "eRedo"; + case EditAction::eSetTextDirection: + return aStream << "eSetTextDirection"; + case EditAction::eCut: + return aStream << "eCut"; + case EditAction::eCopy: + return aStream << "eCopy"; + case EditAction::ePaste: + return aStream << "ePaste"; + case EditAction::ePasteAsQuotation: + return aStream << "ePasteAsQuotation"; + case EditAction::eDrop: + return aStream << "eDrop"; + case EditAction::eIndent: + return aStream << "eIndent"; + case EditAction::eOutdent: + return aStream << "eOutdent"; + case EditAction::eReplaceText: + return aStream << "eReplaceText"; + case EditAction::eInsertTableRowElement: + return aStream << "eInsertTableRowElement"; + case EditAction::eRemoveTableRowElement: + return aStream << "eRemoveTableRowElement"; + case EditAction::eInsertTableColumn: + return aStream << "eInsertTableColumn"; + case EditAction::eRemoveTableColumn: + return aStream << "eRemoveTableColumn"; + case EditAction::eResizingElement: + return aStream << "eResizingElement"; + case EditAction::eResizeElement: + return aStream << "eResizeElement"; + case EditAction::eMovingElement: + return aStream << "eMovingElement"; + case EditAction::eMoveElement: + return aStream << "eMoveElement"; + case EditAction::eUnknown: + return aStream << "eUnknown"; + case EditAction::eSetAttribute: + return aStream << "eSetAttribute"; + case EditAction::eRemoveAttribute: + return aStream << "eRemoveAttribute"; + case EditAction::eInsertNode: + return aStream << "eInsertNode"; + case EditAction::eRemoveNode: + return aStream << "eRemoveNode"; + case EditAction::eInsertBlockElement: + return aStream << "eInsertBlockElement"; + case EditAction::eInsertHorizontalRuleElement: + return aStream << "eInsertHorizontalRuleElement"; + case EditAction::eInsertLinkElement: + return aStream << "eInsertLinkElement"; + case EditAction::eInsertUnorderedListElement: + return aStream << "eInsertUnorderedListElement"; + case EditAction::eInsertOrderedListElement: + return aStream << "eInsertOrderedListElement"; + case EditAction::eRemoveUnorderedListElement: + return aStream << "eRemoveUnorderedListElement"; + case EditAction::eRemoveOrderedListElement: + return aStream << "eRemoveOrderedListElement"; + case EditAction::eRemoveListElement: + return aStream << "eRemoveListElement"; + case EditAction::eInsertBlockquoteElement: + return aStream << "eInsertBlockquoteElement"; + case EditAction::eNormalizeTable: + return aStream << "eNormalizeTable"; + case EditAction::eRemoveTableElement: + return aStream << "eRemoveTableElement"; + case EditAction::eDeleteTableCellContents: + return aStream << "eDeleteTableCellContents"; + case EditAction::eInsertTableCellElement: + return aStream << "eInsertTableCellElement"; + case EditAction::eRemoveTableCellElement: + return aStream << "eRemoveTableCellElement"; + case EditAction::eJoinTableCellElements: + return aStream << "eJoinTableCellElements"; + case EditAction::eSplitTableCellElement: + return aStream << "eSplitTableCellElement"; + case EditAction::eSetTableCellElementType: + return aStream << "eSetTableCellElementType"; + case EditAction::eSelectTableCell: + return aStream << "eSelectTableCell"; + case EditAction::eSelectTableRow: + return aStream << "eSelectTableRow"; + case EditAction::eSelectTableColumn: + return aStream << "eSelectTableColumn"; + case EditAction::eSelectTable: + return aStream << "eSelectTable"; + case EditAction::eSelectAllTableCells: + return aStream << "eSelectAllTableCells"; + case EditAction::eGetCellIndexes: + return aStream << "eGetCellIndexes"; + case EditAction::eGetTableSize: + return aStream << "eGetTableSize"; + case EditAction::eGetCellAt: + return aStream << "eGetCellAt"; + case EditAction::eGetCellDataAt: + return aStream << "eGetCellDataAt"; + case EditAction::eGetFirstRow: + return aStream << "eGetFirstRow"; + case EditAction::eGetSelectedOrParentTableElement: + return aStream << "eGetSelectedOrParentTableElement"; + case EditAction::eGetSelectedCellsType: + return aStream << "eGetSelectedCellsType"; + case EditAction::eGetFirstSelectedCellInTable: + return aStream << "eGetFirstSelectedCellInTable"; + case EditAction::eGetSelectedCells: + return aStream << "eGetSelectedCells"; + case EditAction::eSetInlineStyleProperty: + return aStream << "eSetInlineStyleProperty"; + case EditAction::eRemoveInlineStyleProperty: + return aStream << "eRemoveInlineStyleProperty"; + case EditAction::eSetFontWeightProperty: + return aStream << "eSetFontWeightProperty"; + case EditAction::eRemoveFontWeightProperty: + return aStream << "eRemoveFontWeightProperty"; + case EditAction::eSetTextStyleProperty: + return aStream << "eSetTextStyleProperty"; + case EditAction::eRemoveTextStyleProperty: + return aStream << "eRemoveTextStyleProperty"; + case EditAction::eSetTextDecorationPropertyUnderline: + return aStream << "eSetTextDecorationPropertyUnderline"; + case EditAction::eRemoveTextDecorationPropertyUnderline: + return aStream << "eRemoveTextDecorationPropertyUnderline"; + case EditAction::eSetTextDecorationPropertyLineThrough: + return aStream << "eSetTextDecorationPropertyLineThrough"; + case EditAction::eRemoveTextDecorationPropertyLineThrough: + return aStream << "eRemoveTextDecorationPropertyLineThrough"; + case EditAction::eSetVerticalAlignPropertySuper: + return aStream << "eSetVerticalAlignPropertySuper"; + case EditAction::eRemoveVerticalAlignPropertySuper: + return aStream << "eRemoveVerticalAlignPropertySuper"; + case EditAction::eSetVerticalAlignPropertySub: + return aStream << "eSetVerticalAlignPropertySub"; + case EditAction::eRemoveVerticalAlignPropertySub: + return aStream << "eRemoveVerticalAlignPropertySub"; + case EditAction::eSetFontFamilyProperty: + return aStream << "eSetFontFamilyProperty"; + case EditAction::eRemoveFontFamilyProperty: + return aStream << "eRemoveFontFamilyProperty"; + case EditAction::eSetColorProperty: + return aStream << "eSetColorProperty"; + case EditAction::eRemoveColorProperty: + return aStream << "eRemoveColorProperty"; + case EditAction::eSetBackgroundColorPropertyInline: + return aStream << "eSetBackgroundColorPropertyInline"; + case EditAction::eRemoveBackgroundColorPropertyInline: + return aStream << "eRemoveBackgroundColorPropertyInline"; + case EditAction::eRemoveAllInlineStyleProperties: + return aStream << "eRemoveAllInlineStyleProperties"; + case EditAction::eIncrementFontSize: + return aStream << "eIncrementFontSize"; + case EditAction::eDecrementFontSize: + return aStream << "eDecrementFontSize"; + case EditAction::eSetAlignment: + return aStream << "eSetAlignment"; + case EditAction::eAlignLeft: + return aStream << "eAlignLeft"; + case EditAction::eAlignRight: + return aStream << "eAlignRight"; + case EditAction::eAlignCenter: + return aStream << "eAlignCenter"; + case EditAction::eJustify: + return aStream << "eJustify"; + case EditAction::eSetBackgroundColor: + return aStream << "eSetBackgroundColor"; + case EditAction::eSetPositionToAbsoluteOrStatic: + return aStream << "eSetPositionToAbsoluteOrStatic"; + case EditAction::eIncreaseOrDecreaseZIndex: + return aStream << "eIncreaseOrDecreaseZIndex"; + case EditAction::eEnableOrDisableCSS: + return aStream << "eEnableOrDisableCSS"; + case EditAction::eEnableOrDisableAbsolutePositionEditor: + return aStream << "eEnableOrDisableAbsolutePositionEditor"; + case EditAction::eEnableOrDisableResizer: + return aStream << "eEnableOrDisableResizer"; + case EditAction::eEnableOrDisableInlineTableEditingUI: + return aStream << "eEnableOrDisableInlineTableEditingUI"; + case EditAction::eSetCharacterSet: + return aStream << "eSetCharacterSet"; + case EditAction::eSetWrapWidth: + return aStream << "eSetWrapWidth"; + case EditAction::eRewrap: + return aStream << "eRewrap"; + case EditAction::eSetText: + return aStream << "eSetText"; + case EditAction::eInsertHTML: + return aStream << "eInsertHTML"; + case EditAction::eHidePassword: + return aStream << "eHidePassword"; + case EditAction::eCreatePaddingBRElementForEmptyEditor: + return aStream << "eCreatePaddingBRElementForEmptyEditor"; + } + MOZ_ASSERT_UNREACHABLE("Ensure no invalid EditAction!"); + return aStream << "<invalid value: " << static_cast<uint32_t>(aEditAction) + << ">"; +} + } // namespace mozilla inline bool operator!(const mozilla::EditSubAction& aEditSubAction) { diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp @@ -149,6 +149,8 @@ using LeafNodeTypes = HTMLEditUtils::LeafNodeTypes; using WalkTreeOption = HTMLEditUtils::WalkTreeOption; static LazyLogModule gEventLog("EditorEvent"); +static LazyLogModule gHTMLEditorEditActionStartLog("HTMLEditorEditActionStart"); + LazyLogModule gTextInputLog("EditorTextInput"); /***************************************************************************** @@ -6638,6 +6640,39 @@ EditorBase::AutoEditActionDataSetter::AutoEditActionDataSetter( } } mEditorBase.mEditActionData = this; + + if (aEditorBase.IsHTMLEditor() && + MOZ_LOG_TEST(gHTMLEditorEditActionStartLog, LogLevel::Info) && + aEditAction != EditAction::eNone && + aEditAction != EditAction::eNotEditing && + aEditAction != EditAction::eInitializing) { + const HTMLEditor& htmlEditor = *aEditorBase.AsHTMLEditor(); + Element* const editingHost = + htmlEditor.ComputeEditingHost(HTMLEditor::LimitInBodyElement::No); + nsAutoString innerHTML; + if (editingHost) { + editingHost->GetInnerHTML(innerHTML, IgnoreErrors()); + innerHTML.ReplaceSubstring(u"\n", u"\\n"); + innerHTML.ReplaceSubstring(u"\r", u"\\r"); + innerHTML.ReplaceSubstring(u"\t", u"\\t"); + innerHTML.ReplaceSubstring(u"\f", u"\\f"); + innerHTML.ReplaceSubstring(u"\u00A0", u"&nbsp;"); + } + MOZ_ASSERT(mSelection); + MOZ_LOG( + gHTMLEditorEditActionStartLog, LogLevel::Info, + ("%s\nediting host: %s\ninnerHTML: \"%s\"\nselection range " + "count: %u", + ToString(aEditAction).c_str(), ToString(RefPtr{editingHost}).c_str(), + NS_ConvertUTF16toUTF8(innerHTML).get(), mSelection->RangeCount())); + for (const uint32_t index : IntegerRange(mSelection->RangeCount())) { + nsRange* const range = mSelection->GetRangeAt(index); + MOZ_ASSERT(range); + EditorRawDOMRange editorRange(*range); + MOZ_LOG(gHTMLEditorEditActionStartLog, LogLevel::Info, + ("getRangeAt(%u): %s", index, ToString(editorRange).c_str())); + } + } } EditorBase::AutoEditActionDataSetter::~AutoEditActionDataSetter() {