Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp
Warning:line 593, column 12
Value stored to 'rv' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_editor_libeditor2.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/editor/libeditor -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/editor/libeditor -resource-dir /usr/lib/llvm-20/lib/clang/20 -include /var/lib/jenkins/workspace/firefox-scan-build/config/gcc_hidden.h -include /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D _GLIBCXX_ASSERTIONS -D DEBUG=1 -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/editor/libeditor -I /var/lib/jenkins/workspace/firefox-scan-build/dom/base -I /var/lib/jenkins/workspace/firefox-scan-build/dom/html -I /var/lib/jenkins/workspace/firefox-scan-build/extensions/spellcheck/src -I /var/lib/jenkins/workspace/firefox-scan-build/layout/generic -I /var/lib/jenkins/workspace/firefox-scan-build/layout/style -I /var/lib/jenkins/workspace/firefox-scan-build/layout/tables -I /var/lib/jenkins/workspace/firefox-scan-build/layout/xul -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /var/lib/jenkins/workspace/firefox-scan-build/ipc/chromium/src -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-20/lib/clang/20/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2025-01-20-090804-167946-1 -x c++ Unified_cpp_editor_libeditor2.cpp
1/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6#include "TextEditor.h"
7
8#include <algorithm>
9
10#include "EditAction.h"
11#include "EditAggregateTransaction.h"
12#include "EditorDOMPoint.h"
13#include "HTMLEditor.h"
14#include "HTMLEditUtils.h"
15#include "InternetCiter.h"
16#include "PlaceholderTransaction.h"
17#include "gfxFontUtils.h"
18
19#include "mozilla/dom/DocumentInlines.h"
20#include "mozilla/Assertions.h"
21#include "mozilla/ContentIterator.h"
22#include "mozilla/IMEStateManager.h"
23#include "mozilla/LookAndFeel.h"
24#include "mozilla/mozalloc.h"
25#include "mozilla/Preferences.h"
26#include "mozilla/PresShell.h"
27#include "mozilla/StaticPrefs_dom.h"
28#include "mozilla/StaticPrefs_editor.h"
29#include "mozilla/TextComposition.h"
30#include "mozilla/TextEvents.h"
31#include "mozilla/TextServicesDocument.h"
32#include "mozilla/Try.h"
33#include "mozilla/dom/Event.h"
34#include "mozilla/dom/Element.h"
35#include "mozilla/dom/Selection.h"
36#include "mozilla/dom/StaticRange.h"
37
38#include "nsAString.h"
39#include "nsCRT.h"
40#include "nsCaret.h"
41#include "nsCharTraits.h"
42#include "nsComponentManagerUtils.h"
43#include "nsContentList.h"
44#include "nsDebug.h"
45#include "nsDependentSubstring.h"
46#include "nsError.h"
47#include "nsFocusManager.h"
48#include "nsGkAtoms.h"
49#include "nsIContent.h"
50#include "nsINode.h"
51#include "nsIPrincipal.h"
52#include "nsISelectionController.h"
53#include "nsISupportsPrimitives.h"
54#include "nsITransferable.h"
55#include "nsIWeakReferenceUtils.h"
56#include "nsNameSpaceManager.h"
57#include "nsLiteralString.h"
58#include "nsPresContext.h"
59#include "nsReadableUtils.h"
60#include "nsServiceManagerUtils.h"
61#include "nsString.h"
62#include "nsStringFwd.h"
63#include "nsTextFragment.h"
64#include "nsTextNode.h"
65#include "nsUnicharUtils.h"
66#include "nsXPCOM.h"
67
68class nsIOutputStream;
69class nsISupports;
70
71namespace mozilla {
72
73using namespace dom;
74
75using LeafNodeType = HTMLEditUtils::LeafNodeType;
76using LeafNodeTypes = HTMLEditUtils::LeafNodeTypes;
77
78template EditorDOMPoint TextEditor::FindBetterInsertionPoint(
79 const EditorDOMPoint& aPoint) const;
80template EditorRawDOMPoint TextEditor::FindBetterInsertionPoint(
81 const EditorRawDOMPoint& aPoint) const;
82
83TextEditor::TextEditor() : EditorBase(EditorBase::EditorType::Text) {
84 // printf("Size of TextEditor: %zu\n", sizeof(TextEditor));
85 static_assert(
86 sizeof(TextEditor) <= 512,
87 "TextEditor instance should be allocatable in the quantum class bins");
88}
89
90TextEditor::~TextEditor() {
91 // Remove event listeners. Note that if we had an HTML editor,
92 // it installed its own instead of these
93 RemoveEventListeners();
94}
95
96NS_IMPL_CYCLE_COLLECTION_CLASS(TextEditor)TextEditor::cycleCollection TextEditor::_cycleCollectorGlobal
;
97
98NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(TextEditor, EditorBase)void TextEditor::cycleCollection::Unlink(void* p) { TextEditor
* tmp = DowncastCCParticipant<TextEditor>(p); nsISupports
* s = static_cast<nsISupports*>(p); EditorBase::cycleCollection
::Unlink(s);
99 if (tmp->mPasswordMaskData) {
100 tmp->mPasswordMaskData->CancelTimer(PasswordMaskData::ReleaseTimer::No);
101 NS_IMPL_CYCLE_COLLECTION_UNLINK(mPasswordMaskData->mTimer)ImplCycleCollectionUnlink(tmp->mPasswordMaskData->mTimer
);
102 }
103NS_IMPL_CYCLE_COLLECTION_UNLINK_END(void)tmp; }
104
105NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(TextEditor, EditorBase)nsresult TextEditor::cycleCollection::TraverseNative( void* p
, nsCycleCollectionTraversalCallback& cb) { TextEditor* tmp
= DowncastCCParticipant<TextEditor>(p); nsISupports* s
= static_cast<nsISupports*>(p); if (EditorBase::cycleCollection
::TraverseNative(s, cb) == NS_SUCCESS_INTERRUPTED_TRAVERSE) {
return NS_SUCCESS_INTERRUPTED_TRAVERSE; }
106 if (tmp->mPasswordMaskData) {
107 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPasswordMaskData->mTimer)ImplCycleCollectionTraverse(cb, tmp->mPasswordMaskData->
mTimer, "mPasswordMaskData->mTimer", 0);
108 }
109NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END(void)tmp; return NS_OK; }
110
111NS_IMPL_ADDREF_INHERITED(TextEditor, EditorBase)MozExternalRefCountType TextEditor::AddRef(void) { static_assert
(!std::is_destructible_v<TextEditor>, "Reference-counted class "
"TextEditor" " should not have a public destructor. " "Make this class's destructor non-public"
); nsrefcnt r = EditorBase::AddRef(); if constexpr (::mozilla
::detail::ShouldLogInheritedRefcnt<TextEditor>) { NS_LogAddRef
((this), (r), ("TextEditor"), (uint32_t)(sizeof(*this))); } return
r; }
112NS_IMPL_RELEASE_INHERITED(TextEditor, EditorBase)MozExternalRefCountType TextEditor::Release(void) { nsrefcnt r
= EditorBase::Release(); if constexpr (::mozilla::detail::ShouldLogInheritedRefcnt
<TextEditor>) { NS_LogRelease((this), (r), ("TextEditor"
)); } return r; }
113
114NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TextEditor)nsresult TextEditor::QueryInterface(const nsIID& aIID, void
** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak(
NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 114); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
; if (TopThreeWordsEquals( aIID, (nsXPCOMCycleCollectionParticipant
::COMTypeInfo<nsXPCOMCycleCollectionParticipant, void>::
kIID), (nsCycleCollectionISupports::COMTypeInfo<nsCycleCollectionISupports
, void>::kIID)) && (LowWordEquals(aIID, (nsXPCOMCycleCollectionParticipant
::COMTypeInfo<nsXPCOMCycleCollectionParticipant, void>::
kIID)) || LowWordEquals(aIID, (nsCycleCollectionISupports::COMTypeInfo
<nsCycleCollectionISupports, void>::kIID)))) { if (LowWordEquals
(aIID, (nsXPCOMCycleCollectionParticipant::COMTypeInfo<nsXPCOMCycleCollectionParticipant
, void>::kIID))) { *aInstancePtr = TextEditor::cycleCollection
::GetParticipant(); return NS_OK; } if (LowWordEquals(aIID, (
nsCycleCollectionISupports::COMTypeInfo<nsCycleCollectionISupports
, void>::kIID))) { *aInstancePtr = TextEditor::cycleCollection
::Upcast(this); return NS_OK; } foundInterface = nullptr; } else
115 NS_INTERFACE_MAP_ENTRY(nsITimerCallback)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsITimerCallback>)) foundInterface
= static_cast<nsITimerCallback*>(this); else
116 NS_INTERFACE_MAP_ENTRY(nsINamed)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsINamed>)) foundInterface = static_cast
<nsINamed*>(this); else
117NS_INTERFACE_MAP_END_INHERITING(EditorBase)foundInterface = 0; nsresult status; if (!foundInterface) status
= EditorBase::QueryInterface(aIID, (void**)&foundInterface
); else { (foundInterface)->AddRef(); status = NS_OK; } *aInstancePtr
= foundInterface; return status; }
118
119NS_IMETHODIMPnsresult TextEditor::EndOfDocument() {
120 AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
121 if (NS_WARN_IF(!editActionData.CanHandle())NS_warn_if_impl(!editActionData.CanHandle(), "!editActionData.CanHandle()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 121)
) {
122 return NS_ERROR_NOT_INITIALIZED;
123 }
124 nsresult rv = CollapseSelectionToEndOfTextNode();
125 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::CollapseSelectionToEndOfTextNode() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 126); } } while (false)
126 "TextEditor::CollapseSelectionToEndOfTextNode() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::CollapseSelectionToEndOfTextNode() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 126); } } while (false)
;
127 // This is low level API for embedders and chrome script so that we can return
128 // raw error code here.
129 return rv;
130}
131
132nsresult TextEditor::CollapseSelectionToEndOfTextNode() {
133 MOZ_ASSERT(IsEditActionDataAvailable())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsEditActionDataAvailable())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsEditActionDataAvailable())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("IsEditActionDataAvailable()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 133); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()"
")"); do { *((volatile int*)__null) = 133; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
134
135 Element* anonymousDivElement = GetRoot();
136 if (NS_WARN_IF(!anonymousDivElement)NS_warn_if_impl(!anonymousDivElement, "!anonymousDivElement",
"/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 136)
) {
137 return NS_ERROR_NULL_POINTER;
138 }
139
140 RefPtr<Text> textNode =
141 Text::FromNodeOrNull(anonymousDivElement->GetFirstChild());
142 MOZ_ASSERT(textNode)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(textNode)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(textNode))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("textNode", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 142); AnnotateMozCrashReason("MOZ_ASSERT" "(" "textNode" ")"
); do { *((volatile int*)__null) = 142; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
143 nsresult rv = CollapseSelectionToEndOf(*textNode);
144 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::CollapseSelectionToEndOf() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 145); } } while (false)
145 "EditorBase::CollapseSelectionToEndOf() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::CollapseSelectionToEndOf() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 145); } } while (false)
;
146 return rv;
147}
148
149nsresult TextEditor::Init(Document& aDocument, Element& aAnonymousDivElement,
150 nsISelectionController& aSelectionController,
151 uint32_t aFlags,
152 UniquePtr<PasswordMaskData>&& aPasswordMaskData) {
153 MOZ_ASSERT(!mInitSucceeded,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mInitSucceeded)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mInitSucceeded))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mInitSucceeded"
" (" "TextEditor::Init() called again without calling PreDestroy()?"
")", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 154); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mInitSucceeded"
") (" "TextEditor::Init() called again without calling PreDestroy()?"
")"); do { *((volatile int*)__null) = 154; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
154 "TextEditor::Init() called again without calling PreDestroy()?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mInitSucceeded)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mInitSucceeded))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mInitSucceeded"
" (" "TextEditor::Init() called again without calling PreDestroy()?"
")", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 154); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mInitSucceeded"
") (" "TextEditor::Init() called again without calling PreDestroy()?"
")"); do { *((volatile int*)__null) = 154; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
155 MOZ_ASSERT(!(aFlags & nsIEditor::eEditorPasswordMask) == !aPasswordMaskData)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!(aFlags & nsIEditor::eEditorPasswordMask) == !aPasswordMaskData
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!(aFlags & nsIEditor::eEditorPasswordMask) == !aPasswordMaskData
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!(aFlags & nsIEditor::eEditorPasswordMask) == !aPasswordMaskData"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 155); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!(aFlags & nsIEditor::eEditorPasswordMask) == !aPasswordMaskData"
")"); do { *((volatile int*)__null) = 155; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
156 mPasswordMaskData = std::move(aPasswordMaskData);
157
158 // Init the base editor
159 nsresult rv = InitInternal(aDocument, &aAnonymousDivElement,
160 aSelectionController, aFlags);
161 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
162 NS_WARNING("EditorBase::InitInternal() failed")NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::InitInternal() failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 162)
;
163 return rv;
164 }
165
166 AutoEditActionDataSetter editActionData(*this, EditAction::eInitializing);
167 if (NS_WARN_IF(!editActionData.CanHandle())NS_warn_if_impl(!editActionData.CanHandle(), "!editActionData.CanHandle()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 167)
) {
168 return NS_ERROR_FAILURE;
169 }
170
171 // We set mInitSucceeded here rather than at the end of the function,
172 // since InitEditorContentAndSelection() can perform some transactions
173 // and can warn if mInitSucceeded is still false.
174 MOZ_ASSERT(!mInitSucceeded, "TextEditor::Init() shouldn't be nested")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mInitSucceeded)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mInitSucceeded))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mInitSucceeded"
" (" "TextEditor::Init() shouldn't be nested" ")", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 174); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mInitSucceeded"
") (" "TextEditor::Init() shouldn't be nested" ")"); do { *(
(volatile int*)__null) = 174; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
175 mInitSucceeded = true;
176
177 rv = InitEditorContentAndSelection();
178 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
179 NS_WARNING("TextEditor::InitEditorContentAndSelection() failed")NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::InitEditorContentAndSelection() failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 179)
;
180 // XXX Shouldn't we expose `NS_ERROR_EDITOR_DESTROYED` even though this
181 // is a public method?
182 mInitSucceeded = false;
183 return EditorBase::ToGenericNSResult(rv);
184 }
185
186 // Throw away the old transaction manager if this is not the first time that
187 // we're initializing the editor.
188 ClearUndoRedo();
189 EnableUndoRedo();
190 return NS_OK;
191}
192
193nsresult TextEditor::InitEditorContentAndSelection() {
194 MOZ_ASSERT(IsEditActionDataAvailable())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsEditActionDataAvailable())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsEditActionDataAvailable())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("IsEditActionDataAvailable()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 194); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()"
")"); do { *((volatile int*)__null) = 194; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
195
196 MOZ_TRY(EnsureEmptyTextFirstChild())do { auto mozTryTempResult_ = ::mozilla::ToResult(EnsureEmptyTextFirstChild
()); if ((__builtin_expect(!!(mozTryTempResult_.isErr()), 0))
) { return mozTryTempResult_.propagateErr(); } } while (0)
;
197
198 // If the selection hasn't been set up yet, set it up collapsed to the end of
199 // our editable content.
200 if (!SelectionRef().RangeCount()) {
201 nsresult rv = CollapseSelectionToEndOfTextNode();
202 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
203 NS_WARNING("EditorBase::CollapseSelectionToEndOfTextNode() failed")NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::CollapseSelectionToEndOfTextNode() failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 203)
;
204 return rv;
205 }
206 }
207
208 if (!IsSingleLineEditor()) {
209 nsresult rv = EnsurePaddingBRElementInMultilineEditor();
210 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
211 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::EnsurePaddingBRElementInMultilineEditor() failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 212)
212 "EditorBase::EnsurePaddingBRElementInMultilineEditor() failed")NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::EnsurePaddingBRElementInMultilineEditor() failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 212)
;
213 return rv;
214 }
215 }
216
217 return NS_OK;
218}
219
220nsresult TextEditor::PostCreate() {
221 AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
222 if (NS_WARN_IF(!editActionData.CanHandle())NS_warn_if_impl(!editActionData.CanHandle(), "!editActionData.CanHandle()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 222)
) {
223 return NS_ERROR_NOT_INITIALIZED;
224 }
225
226 nsresult rv = PostCreateInternal();
227
228 // Restore unmasked range if there is.
229 if (IsPasswordEditor() && !IsAllMasked()) {
230 DebugOnly<nsresult> rvIgnored =
231 SetUnmaskRangeAndNotify(UnmaskedStart(), UnmaskedLength());
232 NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed to "
"restore unmasked range, but ignored", "NS_SUCCEEDED(rvIgnored)"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 234); } } while (false)
233 "TextEditor::SetUnmaskRangeAndNotify() failed to "do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed to "
"restore unmasked range, but ignored", "NS_SUCCEEDED(rvIgnored)"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 234); } } while (false)
234 "restore unmasked range, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed to "
"restore unmasked range, but ignored", "NS_SUCCEEDED(rvIgnored)"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 234); } } while (false)
;
235 }
236 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::PostCreateInternal() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 237); } } while (false)
237 "EditorBase::PostCreateInternal() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::PostCreateInternal() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 237); } } while (false)
;
238 return rv;
239}
240
241UniquePtr<PasswordMaskData> TextEditor::PreDestroy() {
242 if (mDidPreDestroy) {
243 return nullptr;
244 }
245
246 UniquePtr<PasswordMaskData> passwordMaskData = std::move(mPasswordMaskData);
247 if (passwordMaskData) {
248 // Disable auto-masking timer since nobody can catch the notification
249 // from the timer and canceling the unmasking.
250 passwordMaskData->CancelTimer(PasswordMaskData::ReleaseTimer::Yes);
251 // Similary, keeping preventing echoing password temporarily across
252 // TextEditor instances is hard. So, we should forget it.
253 passwordMaskData->mEchoingPasswordPrevented = false;
254 }
255
256 PreDestroyInternal();
257
258 return passwordMaskData;
259}
260
261nsresult TextEditor::HandleKeyPressEvent(WidgetKeyboardEvent* aKeyboardEvent) {
262 // NOTE: When you change this method, you should also change:
263 // * editor/libeditor/tests/test_texteditor_keyevent_handling.html
264 // * editor/libeditor/tests/test_htmleditor_keyevent_handling.html
265 //
266 // And also when you add new key handling, you need to change the subclass's
267 // HandleKeyPressEvent()'s switch statement.
268
269 if (NS_WARN_IF(!aKeyboardEvent)NS_warn_if_impl(!aKeyboardEvent, "!aKeyboardEvent", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 269)
) {
270 return NS_ERROR_UNEXPECTED;
271 }
272
273 if (IsReadonly()) {
274 HandleKeyPressEventInReadOnlyMode(*aKeyboardEvent);
275 return NS_OK;
276 }
277
278 MOZ_ASSERT(aKeyboardEvent->mMessage == eKeyPress,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aKeyboardEvent->mMessage == eKeyPress)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(aKeyboardEvent->mMessage == eKeyPress))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("aKeyboardEvent->mMessage == eKeyPress"
" (" "HandleKeyPressEvent gets non-keypress event" ")", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 279); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aKeyboardEvent->mMessage == eKeyPress"
") (" "HandleKeyPressEvent gets non-keypress event" ")"); do
{ *((volatile int*)__null) = 279; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
279 "HandleKeyPressEvent gets non-keypress event")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aKeyboardEvent->mMessage == eKeyPress)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(aKeyboardEvent->mMessage == eKeyPress))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("aKeyboardEvent->mMessage == eKeyPress"
" (" "HandleKeyPressEvent gets non-keypress event" ")", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 279); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aKeyboardEvent->mMessage == eKeyPress"
") (" "HandleKeyPressEvent gets non-keypress event" ")"); do
{ *((volatile int*)__null) = 279; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
280
281 switch (aKeyboardEvent->mKeyCode) {
282 case NS_VK_META:
283 case NS_VK_WIN:
284 case NS_VK_SHIFT:
285 case NS_VK_CONTROL:
286 case NS_VK_ALT:
287 // FYI: This shouldn't occur since modifier key shouldn't cause eKeyPress
288 // event.
289 aKeyboardEvent->PreventDefault();
290 return NS_OK;
291
292 case NS_VK_BACK:
293 case NS_VK_DELETE:
294 case NS_VK_TAB: {
295 nsresult rv = EditorBase::HandleKeyPressEvent(aKeyboardEvent);
296 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::HandleKeyPressEvent() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 297); } } while (false)
297 "EditorBase::HandleKeyPressEvent() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::HandleKeyPressEvent() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 297); } } while (false)
;
298 return rv;
299 }
300 case NS_VK_RETURN: {
301 if (!aKeyboardEvent->IsInputtingLineBreak()) {
302 return NS_OK;
303 }
304 if (!IsSingleLineEditor()) {
305 aKeyboardEvent->PreventDefault();
306 }
307 // We need to dispatch "beforeinput" event at least even if we're a
308 // single line text editor.
309 nsresult rv = InsertLineBreakAsAction();
310 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::InsertLineBreakAsAction() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 311); } } while (false)
311 "TextEditor::InsertLineBreakAsAction() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::InsertLineBreakAsAction() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 311); } } while (false)
;
312 return rv;
313 }
314 }
315
316 if (!aKeyboardEvent->IsInputtingText()) {
317 // we don't PreventDefault() here or keybindings like control-x won't work
318 return NS_OK;
319 }
320 aKeyboardEvent->PreventDefault();
321 // If we dispatch 2 keypress events for a surrogate pair and we set only
322 // first `.key` value to the surrogate pair, the preceding one has it and the
323 // other has empty string. In this case, we should handle only the first one
324 // with the key value.
325 if (!StaticPrefs::dom_event_keypress_dispatch_once_per_surrogate_pair() &&
326 !StaticPrefs::dom_event_keypress_key_allow_lone_surrogate() &&
327 aKeyboardEvent->mKeyValue.IsEmpty() &&
328 IS_SURROGATE(aKeyboardEvent->mCharCode)((uint32_t(aKeyboardEvent->mCharCode) & 0xFFFFF800) ==
0xD800)
) {
329 return NS_OK;
330 }
331 // Our widget shouldn't set `\r` to `mKeyValue`, but it may be synthesized
332 // keyboard event and its value may be `\r`. In such case, we should treat
333 // it as `\n` for the backward compatibility because we stopped converting
334 // `\r` and `\r\n` to `\n` at getting `HTMLInputElement.value` and
335 // `HTMLTextAreaElement.value` for the performance (i.e., we don't need to
336 // take care in `HTMLEditor`).
337 nsAutoString str(aKeyboardEvent->mKeyValue);
338 if (str.IsEmpty()) {
339 MOZ_ASSERT(aKeyboardEvent->mCharCode <= 0xFFFF,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aKeyboardEvent->mCharCode <= 0xFFFF)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(aKeyboardEvent->mCharCode <= 0xFFFF))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("aKeyboardEvent->mCharCode <= 0xFFFF"
" (" "Non-BMP character needs special handling" ")", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 340); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aKeyboardEvent->mCharCode <= 0xFFFF"
") (" "Non-BMP character needs special handling" ")"); do { *
((volatile int*)__null) = 340; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
340 "Non-BMP character needs special handling")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aKeyboardEvent->mCharCode <= 0xFFFF)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(aKeyboardEvent->mCharCode <= 0xFFFF))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("aKeyboardEvent->mCharCode <= 0xFFFF"
" (" "Non-BMP character needs special handling" ")", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 340); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aKeyboardEvent->mCharCode <= 0xFFFF"
") (" "Non-BMP character needs special handling" ")"); do { *
((volatile int*)__null) = 340; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
341 str.Assign(aKeyboardEvent->mCharCode == nsCRT::CR
342 ? static_cast<char16_t>(nsCRT::LF)
343 : static_cast<char16_t>(aKeyboardEvent->mCharCode));
344 } else {
345 MOZ_ASSERT(str.Find(u"\r\n"_ns) == kNotFound,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(str.Find(u"\r\n"_ns) == kNotFound)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(str.Find(u"\r\n"_ns) == kNotFound
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"str.Find(u\"\\r\\n\"_ns) == kNotFound" " (" "This assumes that typed text does not include CRLF"
")", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 346); AnnotateMozCrashReason("MOZ_ASSERT" "(" "str.Find(u\"\\r\\n\"_ns) == kNotFound"
") (" "This assumes that typed text does not include CRLF" ")"
); do { *((volatile int*)__null) = 346; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
346 "This assumes that typed text does not include CRLF")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(str.Find(u"\r\n"_ns) == kNotFound)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(str.Find(u"\r\n"_ns) == kNotFound
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"str.Find(u\"\\r\\n\"_ns) == kNotFound" " (" "This assumes that typed text does not include CRLF"
")", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 346); AnnotateMozCrashReason("MOZ_ASSERT" "(" "str.Find(u\"\\r\\n\"_ns) == kNotFound"
") (" "This assumes that typed text does not include CRLF" ")"
); do { *((volatile int*)__null) = 346; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
347 str.ReplaceChar('\r', '\n');
348 }
349 nsresult rv = OnInputText(str);
350 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "EditorBase::OnInputText() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::OnInputText() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 350); } } while (false)
;
351 return rv;
352}
353
354NS_IMETHODIMPnsresult TextEditor::InsertLineBreak() {
355 AutoEditActionDataSetter editActionData(*this, EditAction::eInsertLineBreak);
356 nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
357 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
358 NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak
(NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed"
, "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 359); } } while (false)
359 "CanHandleAndMaybeDispatchBeforeInputEvent() failed")do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak
(NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed"
, "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 359); } } while (false)
;
360 return EditorBase::ToGenericNSResult(rv);
361 }
362
363 if (NS_WARN_IF(IsSingleLineEditor())NS_warn_if_impl(IsSingleLineEditor(), "IsSingleLineEditor()",
"/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 363)
) {
364 return NS_ERROR_FAILURE;
365 }
366
367 AutoPlaceholderBatch treatAsOneTransaction(
368 *this, ScrollSelectionIntoView::Yes, __FUNCTION__);
369 rv = InsertLineBreakAsSubAction();
370 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::InsertLineBreakAsSubAction() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 371); } } while (false)
371 "TextEditor::InsertLineBreakAsSubAction() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::InsertLineBreakAsSubAction() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 371); } } while (false)
;
372 return EditorBase::ToGenericNSResult(rv);
373}
374
375nsresult TextEditor::InsertLineBreakAsAction(nsIPrincipal* aPrincipal) {
376 AutoEditActionDataSetter editActionData(*this, EditAction::eInsertLineBreak,
377 aPrincipal);
378 nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
379 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
380 NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak
(NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed"
, "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 381); } } while (false)
381 "CanHandleAndMaybeDispatchBeforeInputEvent() failed")do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak
(NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed"
, "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 381); } } while (false)
;
382 return EditorBase::ToGenericNSResult(rv);
383 }
384
385 if (IsSingleLineEditor()) {
386 return NS_OK;
387 }
388
389 // XXX This may be called by execCommand() with "insertParagraph".
390 // In such case, naming the transaction "TypingTxnName" is odd.
391 AutoPlaceholderBatch treatAsOneTransaction(*this, *nsGkAtoms::TypingTxnName,
392 ScrollSelectionIntoView::Yes,
393 __FUNCTION__);
394 rv = InsertLineBreakAsSubAction();
395 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::InsertLineBreakAsSubAction() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 396); } } while (false)
396 "EditorBase::InsertLineBreakAsSubAction() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::InsertLineBreakAsSubAction() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 396); } } while (false)
;
397 return EditorBase::ToGenericNSResult(rv);
398}
399
400nsresult TextEditor::SetTextAsAction(
401 const nsAString& aString,
402 AllowBeforeInputEventCancelable aAllowBeforeInputEventCancelable,
403 nsIPrincipal* aPrincipal) {
404 MOZ_ASSERT(aString.FindChar(nsCRT::CR) == kNotFound)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aString.FindChar(nsCRT::CR) == kNotFound)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(aString.FindChar(nsCRT::CR) == kNotFound))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("aString.FindChar(nsCRT::CR) == kNotFound"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 404); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aString.FindChar(nsCRT::CR) == kNotFound"
")"); do { *((volatile int*)__null) = 404; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
405
406 AutoEditActionDataSetter editActionData(*this, EditAction::eSetText,
407 aPrincipal);
408 if (aAllowBeforeInputEventCancelable == AllowBeforeInputEventCancelable::No) {
409 editActionData.MakeBeforeInputEventNonCancelable();
410 }
411 nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
412 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
413 NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak
(NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed"
, "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 414); } } while (false)
414 "CanHandleAndMaybeDispatchBeforeInputEvent() failed")do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak
(NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed"
, "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 414); } } while (false)
;
415 return EditorBase::ToGenericNSResult(rv);
416 }
417
418 AutoPlaceholderBatch treatAsOneTransaction(
419 *this, ScrollSelectionIntoView::Yes, __FUNCTION__);
420 rv = SetTextAsSubAction(aString);
421 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetTextAsSubAction() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 422); } } while (false)
422 "TextEditor::SetTextAsSubAction() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetTextAsSubAction() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 422); } } while (false)
;
423 return EditorBase::ToGenericNSResult(rv);
424}
425
426nsresult TextEditor::SetTextAsSubAction(const nsAString& aString) {
427 MOZ_ASSERT(IsEditActionDataAvailable())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsEditActionDataAvailable())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsEditActionDataAvailable())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("IsEditActionDataAvailable()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 427); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()"
")"); do { *((volatile int*)__null) = 427; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
428 MOZ_ASSERT(mPlaceholderBatch)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mPlaceholderBatch)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mPlaceholderBatch))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mPlaceholderBatch"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 428); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mPlaceholderBatch"
")"); do { *((volatile int*)__null) = 428; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
429
430 if (NS_WARN_IF(!mInitSucceeded)NS_warn_if_impl(!mInitSucceeded, "!mInitSucceeded", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 430)
) {
431 return NS_ERROR_NOT_INITIALIZED;
432 }
433
434 IgnoredErrorResult ignoredError;
435 AutoEditSubActionNotifier startToHandleEditSubAction(
436 *this, EditSubAction::eSetText, nsIEditor::eNext, ignoredError);
437 if (NS_WARN_IF(ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED))NS_warn_if_impl(ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED
), "ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 437)
) {
438 return ignoredError.StealNSResult();
439 }
440 NS_WARNING_ASSERTION(do { if (!(!ignoredError.Failed())) { NS_DebugBreak(NS_DEBUG_WARNING
, "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored"
, "!ignoredError.Failed()", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 442); } } while (false)
441 !ignoredError.Failed(),do { if (!(!ignoredError.Failed())) { NS_DebugBreak(NS_DEBUG_WARNING
, "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored"
, "!ignoredError.Failed()", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 442); } } while (false)
442 "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored")do { if (!(!ignoredError.Failed())) { NS_DebugBreak(NS_DEBUG_WARNING
, "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored"
, "!ignoredError.Failed()", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 442); } } while (false)
;
443
444 if (!IsIMEComposing() && !IsUndoRedoEnabled() &&
445 GetEditAction() != EditAction::eReplaceText && mMaxTextLength < 0) {
446 Result<EditActionResult, nsresult> result =
447 SetTextWithoutTransaction(aString);
448 if (MOZ_UNLIKELY(result.isErr())(__builtin_expect(!!(result.isErr()), 0))) {
449 NS_WARNING("TextEditor::SetTextWithoutTransaction() failed")NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetTextWithoutTransaction() failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 449)
;
450 return result.unwrapErr();
451 }
452 if (!result.inspect().Ignored()) {
453 return NS_OK;
454 }
455 }
456
457 {
458 // Note that do not notify selectionchange caused by selecting all text
459 // because it's preparation of our delete implementation so web apps
460 // shouldn't receive such selectionchange before the first mutation.
461 AutoUpdateViewBatch preventSelectionChangeEvent(*this, __FUNCTION__);
462
463 // XXX We should make ReplaceSelectionAsSubAction() take range. Then,
464 // we can saving the expensive cost of modifying `Selection` here.
465 if (NS_SUCCEEDED(SelectEntireDocument())((bool)(__builtin_expect(!!(!NS_FAILED_impl(SelectEntireDocument
())), 1)))
) {
466 DebugOnly<nsresult> rvIgnored = ReplaceSelectionAsSubAction(aString);
467 NS_WARNING_ASSERTION(do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::ReplaceSelectionAsSubAction() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 469); } } while (false)
468 NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::ReplaceSelectionAsSubAction() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 469); } } while (false)
469 "EditorBase::ReplaceSelectionAsSubAction() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::ReplaceSelectionAsSubAction() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 469); } } while (false)
;
470 }
471 }
472
473 // Destroying AutoUpdateViewBatch may cause destroying us.
474 return NS_WARN_IF(Destroyed())NS_warn_if_impl(Destroyed(), "Destroyed()", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 474)
? NS_ERROR_EDITOR_DESTROYED : NS_OK;
475}
476
477already_AddRefed<Element> TextEditor::GetInputEventTargetElement() const {
478 RefPtr<Element> target = Element::FromEventTargetOrNull(mEventTarget);
479 return target.forget();
480}
481
482bool TextEditor::IsEmpty() const {
483 // Even if there is no padding <br> element for empty editor, we should be
484 // detected as empty editor if all the children are text nodes and these
485 // have no content.
486 Element* anonymousDivElement = GetRoot();
487 if (!anonymousDivElement) {
488 return true; // Don't warn it, this is possible, e.g., 997805.html
489 }
490
491 MOZ_ASSERT(anonymousDivElement->GetFirstChild() &&do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anonymousDivElement->GetFirstChild() && anonymousDivElement
->GetFirstChild()->IsText())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anonymousDivElement->GetFirstChild
() && anonymousDivElement->GetFirstChild()->IsText
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anonymousDivElement->GetFirstChild() && anonymousDivElement->GetFirstChild()->IsText()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 492); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anonymousDivElement->GetFirstChild() && anonymousDivElement->GetFirstChild()->IsText()"
")"); do { *((volatile int*)__null) = 492; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
492 anonymousDivElement->GetFirstChild()->IsText())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anonymousDivElement->GetFirstChild() && anonymousDivElement
->GetFirstChild()->IsText())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anonymousDivElement->GetFirstChild
() && anonymousDivElement->GetFirstChild()->IsText
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anonymousDivElement->GetFirstChild() && anonymousDivElement->GetFirstChild()->IsText()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 492); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anonymousDivElement->GetFirstChild() && anonymousDivElement->GetFirstChild()->IsText()"
")"); do { *((volatile int*)__null) = 492; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
493
494 // Only when there is non-empty text node, we are not empty.
495 return !anonymousDivElement->GetFirstChild()->Length();
496}
497
498NS_IMETHODIMPnsresult TextEditor::GetTextLength(uint32_t* aCount) {
499 MOZ_ASSERT(aCount)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aCount)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(aCount))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aCount", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 499); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aCount" ")")
; do { *((volatile int*)__null) = 499; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
500
501 // initialize out params
502 *aCount = 0;
503
504 // special-case for empty document, to account for the padding <br> element
505 // for empty editor.
506 // XXX This should be overridden by `HTMLEditor` and we should return the
507 // first text node's length from `TextEditor` instead. The following
508 // code is too expensive.
509 if (IsEmpty()) {
510 return NS_OK;
511 }
512
513 Element* rootElement = GetRoot();
514 if (NS_WARN_IF(!rootElement)NS_warn_if_impl(!rootElement, "!rootElement", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 514)
) {
515 return NS_ERROR_FAILURE;
516 }
517
518 uint32_t totalLength = 0;
519 PostContentIterator postOrderIter;
520 DebugOnly<nsresult> rvIgnored = postOrderIter.Init(rootElement);
521 NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "PostContentIterator::Init() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 522); } } while (false)
522 "PostContentIterator::Init() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "PostContentIterator::Init() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 522); } } while (false)
;
523 EditorType editorType = GetEditorType();
524 for (; !postOrderIter.IsDone(); postOrderIter.Next()) {
525 nsINode* currentNode = postOrderIter.GetCurrentNode();
526 if (currentNode && currentNode->IsText() &&
527 EditorUtils::IsEditableContent(*currentNode->AsText(), editorType)) {
528 totalLength += currentNode->Length();
529 }
530 }
531
532 *aCount = totalLength;
533 return NS_OK;
534}
535
536bool TextEditor::IsCopyToClipboardAllowedInternal() const {
537 MOZ_ASSERT(IsEditActionDataAvailable())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsEditActionDataAvailable())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsEditActionDataAvailable())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("IsEditActionDataAvailable()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 537); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()"
")"); do { *((volatile int*)__null) = 537; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
538 if (!EditorBase::IsCopyToClipboardAllowedInternal()) {
539 return false;
540 }
541
542 if (!IsSingleLineEditor() || !IsPasswordEditor() ||
543 NS_WARN_IF(!mPasswordMaskData)NS_warn_if_impl(!mPasswordMaskData, "!mPasswordMaskData", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 543)
) {
544 return true;
545 }
546
547 // If we're a password editor, we should allow selected text to be copied
548 // to the clipboard only when selection range is in unmasked range.
549 if (IsAllMasked() || IsMaskingPassword() || !UnmaskedLength()) {
550 return false;
551 }
552
553 // If there are 2 or more ranges, we don't allow to copy/cut for now since
554 // we need to check whether all ranges are in unmasked range or not.
555 // Anyway, such operation in password field does not make sense.
556 if (SelectionRef().RangeCount() > 1) {
557 return false;
558 }
559
560 uint32_t selectionStart = 0, selectionEnd = 0;
561 nsContentUtils::GetSelectionInTextControl(&SelectionRef(), mRootElement,
562 selectionStart, selectionEnd);
563 return UnmaskedStart() <= selectionStart && UnmaskedEnd() >= selectionEnd;
564}
565
566nsresult TextEditor::HandlePasteAsQuotation(
567 AutoEditActionDataSetter& aEditActionData,
568 nsIClipboard::ClipboardType aClipboardType, DataTransfer* aDataTransfer) {
569 MOZ_ASSERT(aClipboardType == nsIClipboard::kGlobalClipboard ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aClipboardType == nsIClipboard::kGlobalClipboard || aClipboardType
== nsIClipboard::kSelectionClipboard)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aClipboardType == nsIClipboard
::kGlobalClipboard || aClipboardType == nsIClipboard::kSelectionClipboard
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"aClipboardType == nsIClipboard::kGlobalClipboard || aClipboardType == nsIClipboard::kSelectionClipboard"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 570); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aClipboardType == nsIClipboard::kGlobalClipboard || aClipboardType == nsIClipboard::kSelectionClipboard"
")"); do { *((volatile int*)__null) = 570; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
570 aClipboardType == nsIClipboard::kSelectionClipboard)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aClipboardType == nsIClipboard::kGlobalClipboard || aClipboardType
== nsIClipboard::kSelectionClipboard)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aClipboardType == nsIClipboard
::kGlobalClipboard || aClipboardType == nsIClipboard::kSelectionClipboard
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"aClipboardType == nsIClipboard::kGlobalClipboard || aClipboardType == nsIClipboard::kSelectionClipboard"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 570); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aClipboardType == nsIClipboard::kGlobalClipboard || aClipboardType == nsIClipboard::kSelectionClipboard"
")"); do { *((volatile int*)__null) = 570; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
571 if (NS_WARN_IF(!GetDocument())NS_warn_if_impl(!GetDocument(), "!GetDocument()", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 571)
) {
572 return NS_OK;
573 }
574
575 // XXX Why don't we dispatch ePaste event here?
576
577 // Get the nsITransferable interface for getting the data from the clipboard
578 Result<nsCOMPtr<nsITransferable>, nsresult> maybeTransferable =
579 EditorUtils::CreateTransferableForPlainText(*GetDocument());
580 if (maybeTransferable.isErr()) {
581 NS_WARNING("EditorUtils::CreateTransferableForPlainText() failed")NS_DebugBreak(NS_DEBUG_WARNING, "EditorUtils::CreateTransferableForPlainText() failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 581)
;
582 return maybeTransferable.unwrapErr();
583 }
584 nsCOMPtr<nsITransferable> trans(maybeTransferable.unwrap());
585 if (!trans) {
586 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "EditorUtils::CreateTransferableForPlainText() returned nullptr, but "
"ignored", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 588)
587 "EditorUtils::CreateTransferableForPlainText() returned nullptr, but "NS_DebugBreak(NS_DEBUG_WARNING, "EditorUtils::CreateTransferableForPlainText() returned nullptr, but "
"ignored", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 588)
588 "ignored")NS_DebugBreak(NS_DEBUG_WARNING, "EditorUtils::CreateTransferableForPlainText() returned nullptr, but "
"ignored", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 588)
;
589 return NS_OK;
590 }
591
592 // Get the Data from the clipboard
593 nsresult rv =
Value stored to 'rv' during its initialization is never read
594 GetDataFromDataTransferOrClipboard(aDataTransfer, trans, aClipboardType);
595
596 // Now we ask the transferable for the data
597 // it still owns the data, we just have a pointer to it.
598 // If it can't support a "text" output of the data the call will fail
599 nsCOMPtr<nsISupports> genericDataObj;
600 nsAutoCString flavor;
601 rv = trans->GetAnyTransferData(flavor, getter_AddRefs(genericDataObj));
602 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
603 NS_WARNING("nsITransferable::GetAnyTransferData() failed")NS_DebugBreak(NS_DEBUG_WARNING, "nsITransferable::GetAnyTransferData() failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 603)
;
604 return rv;
605 }
606
607 if (!flavor.EqualsLiteral(kTextMime"text/plain") &&
608 !flavor.EqualsLiteral(kMozTextInternal"text/x-moz-text-internal")) {
609 return NS_OK;
610 }
611
612 nsCOMPtr<nsISupportsString> text = do_QueryInterface(genericDataObj);
613 if (!text) {
614 return NS_OK;
615 }
616
617 nsString stuffToPaste;
618 DebugOnly<nsresult> rvIgnored = text->GetData(stuffToPaste);
619 NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "nsISupportsString::GetData() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 620); } } while (false)
620 "nsISupportsString::GetData() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "nsISupportsString::GetData() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 620); } } while (false)
;
621 if (stuffToPaste.IsEmpty()) {
622 return NS_OK;
623 }
624
625 aEditActionData.SetData(stuffToPaste);
626 if (!stuffToPaste.IsEmpty()) {
627 nsContentUtils::PlatformToDOMLineBreaks(stuffToPaste);
628 }
629 rv = aEditActionData.MaybeDispatchBeforeInputEvent();
630 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
631 NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak
(NS_DEBUG_WARNING, "MaybeDispatchBeforeInputEvent() failed", "rv == NS_ERROR_EDITOR_ACTION_CANCELED"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 632); } } while (false)
632 "MaybeDispatchBeforeInputEvent() failed")do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak
(NS_DEBUG_WARNING, "MaybeDispatchBeforeInputEvent() failed", "rv == NS_ERROR_EDITOR_ACTION_CANCELED"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 632); } } while (false)
;
633 return rv;
634 }
635
636 AutoPlaceholderBatch treatAsOneTransaction(
637 *this, ScrollSelectionIntoView::Yes, __FUNCTION__);
638 rv = InsertWithQuotationsAsSubAction(stuffToPaste);
639 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::InsertWithQuotationsAsSubAction() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 640); } } while (false)
640 "TextEditor::InsertWithQuotationsAsSubAction() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::InsertWithQuotationsAsSubAction() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 640); } } while (false)
;
641 return rv;
642}
643
644nsresult TextEditor::InsertWithQuotationsAsSubAction(
645 const nsAString& aQuotedText) {
646 MOZ_ASSERT(IsEditActionDataAvailable())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsEditActionDataAvailable())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsEditActionDataAvailable())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("IsEditActionDataAvailable()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 646); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()"
")"); do { *((volatile int*)__null) = 646; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
647
648 if (IsReadonly()) {
649 return NS_OK;
650 }
651
652 // Let the citer quote it for us:
653 nsString quotedStuff;
654 InternetCiter::GetCiteString(aQuotedText, quotedStuff);
655
656 // It's best to put a blank line after the quoted text so that mails
657 // written without thinking won't be so ugly.
658 if (!aQuotedText.IsEmpty() && (aQuotedText.Last() != char16_t('\n'))) {
659 quotedStuff.Append(char16_t('\n'));
660 }
661
662 IgnoredErrorResult ignoredError;
663 AutoEditSubActionNotifier startToHandleEditSubAction(
664 *this, EditSubAction::eInsertText, nsIEditor::eNext, ignoredError);
665 if (NS_WARN_IF(ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED))NS_warn_if_impl(ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED
), "ignoredError.ErrorCodeIs(NS_ERROR_EDITOR_DESTROYED)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 665)
) {
666 return ignoredError.StealNSResult();
667 }
668 NS_WARNING_ASSERTION(do { if (!(!ignoredError.Failed())) { NS_DebugBreak(NS_DEBUG_WARNING
, "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored"
, "!ignoredError.Failed()", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 670); } } while (false)
669 !ignoredError.Failed(),do { if (!(!ignoredError.Failed())) { NS_DebugBreak(NS_DEBUG_WARNING
, "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored"
, "!ignoredError.Failed()", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 670); } } while (false)
670 "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored")do { if (!(!ignoredError.Failed())) { NS_DebugBreak(NS_DEBUG_WARNING
, "TextEditor::OnStartToHandleTopLevelEditSubAction() failed, but ignored"
, "!ignoredError.Failed()", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 670); } } while (false)
;
671
672 // XXX Do we need to support paste-as-quotation in password editor (and
673 // also in single line editor)?
674 MaybeDoAutoPasswordMasking();
675
676 nsresult rv = InsertTextAsSubAction(quotedStuff, SelectionHandling::Delete);
677 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::InsertTextAsSubAction() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 678); } } while (false)
678 "EditorBase::InsertTextAsSubAction() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::InsertTextAsSubAction() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 678); } } while (false)
;
679 return rv;
680}
681
682nsresult TextEditor::SelectEntireDocument() {
683 MOZ_ASSERT(IsEditActionDataAvailable())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsEditActionDataAvailable())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsEditActionDataAvailable())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("IsEditActionDataAvailable()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 683); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()"
")"); do { *((volatile int*)__null) = 683; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
684
685 if (NS_WARN_IF(!mInitSucceeded)NS_warn_if_impl(!mInitSucceeded, "!mInitSucceeded", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 685)
) {
686 return NS_ERROR_NOT_INITIALIZED;
687 }
688
689 RefPtr<Element> anonymousDivElement = GetRoot();
690 if (NS_WARN_IF(!anonymousDivElement)NS_warn_if_impl(!anonymousDivElement, "!anonymousDivElement",
"/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 690)
) {
691 return NS_ERROR_NOT_INITIALIZED;
692 }
693
694 RefPtr<Text> text =
695 Text::FromNodeOrNull(anonymousDivElement->GetFirstChild());
696 MOZ_ASSERT(text)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(text)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(text))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("text", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 696); AnnotateMozCrashReason("MOZ_ASSERT" "(" "text" ")"); do
{ *((volatile int*)__null) = 696; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
697
698 MOZ_TRY(SelectionRef().SetStartAndEndInLimiter(do { auto mozTryTempResult_ = ::mozilla::ToResult(SelectionRef
().SetStartAndEndInLimiter( *text, 0, *text, text->TextDataLength
(), eDirNext, nsISelectionListener::SELECTALL_REASON)); if ((
__builtin_expect(!!(mozTryTempResult_.isErr()), 0))) { return
mozTryTempResult_.propagateErr(); } } while (0)
699 *text, 0, *text, text->TextDataLength(), eDirNext,do { auto mozTryTempResult_ = ::mozilla::ToResult(SelectionRef
().SetStartAndEndInLimiter( *text, 0, *text, text->TextDataLength
(), eDirNext, nsISelectionListener::SELECTALL_REASON)); if ((
__builtin_expect(!!(mozTryTempResult_.isErr()), 0))) { return
mozTryTempResult_.propagateErr(); } } while (0)
700 nsISelectionListener::SELECTALL_REASON))do { auto mozTryTempResult_ = ::mozilla::ToResult(SelectionRef
().SetStartAndEndInLimiter( *text, 0, *text, text->TextDataLength
(), eDirNext, nsISelectionListener::SELECTALL_REASON)); if ((
__builtin_expect(!!(mozTryTempResult_.isErr()), 0))) { return
mozTryTempResult_.propagateErr(); } } while (0)
;
701
702 return NS_OK;
703}
704
705EventTarget* TextEditor::GetDOMEventTarget() const { return mEventTarget; }
706
707void TextEditor::ReinitializeSelection(Element& aElement) {
708 if (NS_WARN_IF(Destroyed())NS_warn_if_impl(Destroyed(), "Destroyed()", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 708)
) {
709 return;
710 }
711
712 AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
713 if (NS_WARN_IF(!editActionData.CanHandle())NS_warn_if_impl(!editActionData.CanHandle(), "!editActionData.CanHandle()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 713)
) {
714 return;
715 }
716
717 // We don't need to flush pending notifications here and we don't need to
718 // handle spellcheck at first focus. Therefore, we don't need to call
719 // `TextEditor::OnFocus` here.
720 EditorBase::OnFocus(aElement);
721
722 // If previous focused editor turn on spellcheck and this editor doesn't
723 // turn on it, spellcheck state is mismatched. So we need to re-sync it.
724 SyncRealTimeSpell();
725}
726
727nsresult TextEditor::OnFocus(const nsINode& aOriginalEventTargetNode) {
728 RefPtr<PresShell> presShell = GetPresShell();
729 if (NS_WARN_IF(!presShell)NS_warn_if_impl(!presShell, "!presShell", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 729)
) {
730 return NS_ERROR_FAILURE;
731 }
732 // Let's update the layout information right now because there are some
733 // pending notifications and flushing them may cause destroying the editor.
734 presShell->FlushPendingNotifications(FlushType::Layout);
735 if (MOZ_UNLIKELY(!CanKeepHandlingFocusEvent(aOriginalEventTargetNode))(__builtin_expect(!!(!CanKeepHandlingFocusEvent(aOriginalEventTargetNode
)), 0))
) {
736 return NS_OK;
737 }
738
739 AutoEditActionDataSetter editActionData(*this, EditAction::eNotEditing);
740 if (NS_WARN_IF(!editActionData.CanHandle())NS_warn_if_impl(!editActionData.CanHandle(), "!editActionData.CanHandle()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 740)
) {
741 return NS_ERROR_FAILURE;
742 }
743
744 // Spell check a textarea the first time that it is focused.
745 nsresult rv = FlushPendingSpellCheck();
746 if (MOZ_UNLIKELY(rv == NS_ERROR_EDITOR_DESTROYED)(__builtin_expect(!!(rv == NS_ERROR_EDITOR_DESTROYED), 0))) {
747 NS_WARNING("EditorBase::FlushPendingSpellCheck() failed")NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::FlushPendingSpellCheck() failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 747)
;
748 return NS_ERROR_EDITOR_DESTROYED;
749 }
750 NS_WARNING_ASSERTION(do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::FlushPendingSpellCheck() failed, but ignored"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 752); } } while (false)
751 NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::FlushPendingSpellCheck() failed, but ignored"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 752); } } while (false)
752 "EditorBase::FlushPendingSpellCheck() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::FlushPendingSpellCheck() failed, but ignored"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 752); } } while (false)
;
753 if (MOZ_UNLIKELY(!CanKeepHandlingFocusEvent(aOriginalEventTargetNode))(__builtin_expect(!!(!CanKeepHandlingFocusEvent(aOriginalEventTargetNode
)), 0))
) {
754 return NS_OK;
755 }
756
757 return EditorBase::OnFocus(aOriginalEventTargetNode);
758}
759
760nsresult TextEditor::OnBlur(const EventTarget* aEventTarget) {
761 // check if something else is focused. If another element is focused, then
762 // we should not change the selection. If another element already has focus,
763 // we should not maintain the selection because we may not have the rights
764 // doing it.
765 if (nsFocusManager::GetFocusedElementStatic()) {
766 return NS_OK;
767 }
768
769 nsresult rv = FinalizeSelection();
770 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::FinalizeSelection() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 771); } } while (false)
771 "EditorBase::FinalizeSelection() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::FinalizeSelection() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 771); } } while (false)
;
772 return rv;
773}
774
775nsresult TextEditor::SetAttributeOrEquivalent(Element* aElement,
776 nsAtom* aAttribute,
777 const nsAString& aValue,
778 bool aSuppressTransaction) {
779 if (NS_WARN_IF(!aElement)NS_warn_if_impl(!aElement, "!aElement", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 779)
|| NS_WARN_IF(!aAttribute)NS_warn_if_impl(!aAttribute, "!aAttribute", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 779)
) {
780 return NS_ERROR_INVALID_ARG;
781 }
782
783 AutoEditActionDataSetter editActionData(*this, EditAction::eSetAttribute);
784 nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
785 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
786 NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak
(NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed"
, "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 787); } } while (false)
787 "CanHandleAndMaybeDispatchBeforeInputEvent() failed")do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak
(NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed"
, "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 787); } } while (false)
;
788 return EditorBase::ToGenericNSResult(rv);
789 }
790
791 rv = SetAttributeWithTransaction(*aElement, *aAttribute, aValue);
792 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::SetAttributeWithTransaction() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 793); } } while (false)
793 "EditorBase::SetAttributeWithTransaction() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::SetAttributeWithTransaction() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 793); } } while (false)
;
794 return EditorBase::ToGenericNSResult(rv);
795}
796
797nsresult TextEditor::RemoveAttributeOrEquivalent(Element* aElement,
798 nsAtom* aAttribute,
799 bool aSuppressTransaction) {
800 if (NS_WARN_IF(!aElement)NS_warn_if_impl(!aElement, "!aElement", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 800)
|| NS_WARN_IF(!aAttribute)NS_warn_if_impl(!aAttribute, "!aAttribute", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 800)
) {
801 return NS_ERROR_INVALID_ARG;
802 }
803
804 AutoEditActionDataSetter editActionData(*this, EditAction::eRemoveAttribute);
805 nsresult rv = editActionData.CanHandleAndMaybeDispatchBeforeInputEvent();
806 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
807 NS_WARNING_ASSERTION(rv == NS_ERROR_EDITOR_ACTION_CANCELED,do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak
(NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed"
, "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 808); } } while (false)
808 "CanHandleAndMaybeDispatchBeforeInputEvent() failed")do { if (!(rv == NS_ERROR_EDITOR_ACTION_CANCELED)) { NS_DebugBreak
(NS_DEBUG_WARNING, "CanHandleAndMaybeDispatchBeforeInputEvent() failed"
, "rv == NS_ERROR_EDITOR_ACTION_CANCELED", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 808); } } while (false)
;
809 return EditorBase::ToGenericNSResult(rv);
810 }
811
812 rv = RemoveAttributeWithTransaction(*aElement, *aAttribute);
813 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::RemoveAttributeWithTransaction() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 814); } } while (false)
814 "EditorBase::RemoveAttributeWithTransaction() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::RemoveAttributeWithTransaction() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 814); } } while (false)
;
815 return EditorBase::ToGenericNSResult(rv);
816}
817
818template <typename EditorDOMPointType>
819EditorDOMPointType TextEditor::FindBetterInsertionPoint(
820 const EditorDOMPointType& aPoint) const {
821 if (MOZ_UNLIKELY(NS_WARN_IF(!aPoint.IsInContentNode()))(__builtin_expect(!!(NS_warn_if_impl(!aPoint.IsInContentNode(
), "!aPoint.IsInContentNode()", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 821)), 0))
) {
822 return aPoint;
823 }
824
825 MOZ_ASSERT(aPoint.IsSetAndValid())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aPoint.IsSetAndValid())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aPoint.IsSetAndValid()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("aPoint.IsSetAndValid()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 825); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aPoint.IsSetAndValid()"
")"); do { *((volatile int*)__null) = 825; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
826
827 Element* const anonymousDivElement = GetRoot();
828 if (aPoint.GetContainer() == anonymousDivElement) {
829 // In some cases, aPoint points start of the anonymous <div>. To avoid
830 // injecting unneeded text nodes, we first look to see if we have one
831 // available. In that case, we'll just adjust node and offset accordingly.
832 if (aPoint.IsStartOfContainer()) {
833 if (aPoint.GetContainer()->HasChildren() &&
834 aPoint.GetContainer()->GetFirstChild()->IsText()) {
835 return EditorDOMPointType(aPoint.GetContainer()->GetFirstChild(), 0u);
836 }
837 }
838 // In some other cases, aPoint points the terminating padding <br> element
839 // for empty last line in the anonymous <div>. In that case, we'll adjust
840 // aInOutNode and aInOutOffset to the preceding text node, if any.
841 else {
842 nsIContent* child = aPoint.GetContainer()->GetLastChild();
843 while (child) {
844 if (child->IsText()) {
845 return EditorDOMPointType::AtEndOf(*child);
846 }
847 child = child->GetPreviousSibling();
848 }
849 }
850 }
851
852 // Sometimes, aPoint points the padding <br> element. In that case, we'll
853 // adjust the insertion point to the previous text node, if one exists, or to
854 // the parent anonymous DIV.
855 if (EditorUtils::IsPaddingBRElementForEmptyLastLine(
856 *aPoint.template ContainerAs<nsIContent>()) &&
857 aPoint.IsStartOfContainer()) {
858 nsIContent* previousSibling = aPoint.GetContainer()->GetPreviousSibling();
859 if (previousSibling && previousSibling->IsText()) {
860 return EditorDOMPointType::AtEndOf(*previousSibling);
861 }
862
863 nsINode* parentOfContainer = aPoint.GetContainerParent();
864 if (parentOfContainer && parentOfContainer == anonymousDivElement) {
865 return EditorDOMPointType(parentOfContainer,
866 aPoint.template ContainerAs<nsIContent>(), 0u);
867 }
868 }
869
870 return aPoint;
871}
872
873// static
874void TextEditor::MaskString(nsString& aString, const Text& aTextNode,
875 uint32_t aStartOffsetInString,
876 uint32_t aStartOffsetInText) {
877 MOZ_ASSERT(aTextNode.HasFlag(NS_MAYBE_MASKED))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aTextNode.HasFlag(NS_MAYBE_MASKED))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aTextNode.HasFlag(NS_MAYBE_MASKED
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("aTextNode.HasFlag(NS_MAYBE_MASKED)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 877); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aTextNode.HasFlag(NS_MAYBE_MASKED)"
")"); do { *((volatile int*)__null) = 877; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
878 MOZ_ASSERT(aStartOffsetInString == 0 || aStartOffsetInText == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aStartOffsetInString == 0 || aStartOffsetInText == 0
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(aStartOffsetInString == 0 || aStartOffsetInText == 0
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"aStartOffsetInString == 0 || aStartOffsetInText == 0", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 878); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aStartOffsetInString == 0 || aStartOffsetInText == 0"
")"); do { *((volatile int*)__null) = 878; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
879
880 uint32_t unmaskStart = UINT32_MAX(4294967295U), unmaskLength = 0;
881 TextEditor* textEditor =
882 nsContentUtils::GetTextEditorFromAnonymousNodeWithoutCreation(&aTextNode);
883 if (textEditor && textEditor->UnmaskedLength() > 0) {
884 unmaskStart = textEditor->UnmaskedStart();
885 unmaskLength = textEditor->UnmaskedLength();
886 // If text is copied from after unmasked range, we can treat this case
887 // as mask all.
888 if (aStartOffsetInText >= unmaskStart + unmaskLength) {
889 unmaskLength = 0;
890 unmaskStart = UINT32_MAX(4294967295U);
891 } else {
892 // If text is copied from middle of unmasked range, reduce the length
893 // and adjust start offset.
894 if (aStartOffsetInText > unmaskStart) {
895 unmaskLength = unmaskStart + unmaskLength - aStartOffsetInText;
896 unmaskStart = 0;
897 }
898 // If text is copied from before start of unmasked range, just adjust
899 // the start offset.
900 else {
901 unmaskStart -= aStartOffsetInText;
902 }
903 // Make the range is in the string.
904 unmaskStart += aStartOffsetInString;
905 }
906 }
907
908 const char16_t kPasswordMask = TextEditor::PasswordMask();
909 for (uint32_t i = aStartOffsetInString; i < aString.Length(); ++i) {
910 bool isSurrogatePair = NS_IS_HIGH_SURROGATE(aString.CharAt(i))((uint32_t(aString.CharAt(i)) & 0xFFFFFC00) == 0xD800) &&
911 i < aString.Length() - 1 &&
912 NS_IS_LOW_SURROGATE(aString.CharAt(i + 1))((uint32_t(aString.CharAt(i + 1)) & 0xFFFFFC00) == 0xDC00
)
;
913 if (i < unmaskStart || i >= unmaskStart + unmaskLength) {
914 if (isSurrogatePair) {
915 aString.SetCharAt(kPasswordMask, i);
916 aString.SetCharAt(kPasswordMask, i + 1);
917 } else {
918 aString.SetCharAt(kPasswordMask, i);
919 }
920 }
921
922 // Skip the following low surrogate.
923 if (isSurrogatePair) {
924 ++i;
925 }
926 }
927}
928
929nsresult TextEditor::SetUnmaskRangeInternal(uint32_t aStart, uint32_t aLength,
930 uint32_t aTimeout, bool aNotify,
931 bool aForceStartMasking) {
932 if (mPasswordMaskData) {
933 mPasswordMaskData->mIsMaskingPassword = aForceStartMasking || aTimeout != 0;
934
935 // We cannot manage multiple unmasked ranges so that shrink the previous
936 // range first.
937 if (!IsAllMasked()) {
938 mPasswordMaskData->mUnmaskedLength = 0;
939 mPasswordMaskData->CancelTimer(PasswordMaskData::ReleaseTimer::No);
940 }
941 }
942
943 // If we're not a password editor, return error since this call does not
944 // make sense.
945 if (!IsPasswordEditor() || NS_WARN_IF(!mPasswordMaskData)NS_warn_if_impl(!mPasswordMaskData, "!mPasswordMaskData", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 945)
) {
946 mPasswordMaskData->CancelTimer(PasswordMaskData::ReleaseTimer::Yes);
947 return NS_ERROR_NOT_AVAILABLE;
948 }
949
950 Element* rootElement = GetRoot();
951 if (NS_WARN_IF(!rootElement)NS_warn_if_impl(!rootElement, "!rootElement", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 951)
) {
952 return NS_ERROR_NOT_INITIALIZED;
953 }
954 Text* text = Text::FromNodeOrNull(rootElement->GetFirstChild());
955 if (!text || !text->Length()) {
956 // There is no anonymous text node in the editor.
957 return aStart > 0 && aStart != UINT32_MAX(4294967295U) ? NS_ERROR_INVALID_ARG : NS_OK;
958 }
959
960 if (aStart < UINT32_MAX(4294967295U)) {
961 uint32_t valueLength = text->Length();
962 if (aStart >= valueLength) {
963 return NS_ERROR_INVALID_ARG; // There is no character can be masked.
964 }
965 // If aStart is middle of a surrogate pair, expand it to include the
966 // preceding high surrogate because the caller may want to show a
967 // character before the character at `aStart + 1`.
968 const nsTextFragment* textFragment = text->GetText();
969 if (textFragment->IsLowSurrogateFollowingHighSurrogateAt(aStart)) {
970 mPasswordMaskData->mUnmaskedStart = aStart - 1;
971 // If caller collapses the range, keep it. Otherwise, expand the length.
972 if (aLength > 0) {
973 ++aLength;
974 }
975 } else {
976 mPasswordMaskData->mUnmaskedStart = aStart;
977 }
978 mPasswordMaskData->mUnmaskedLength =
979 std::min(valueLength - UnmaskedStart(), aLength);
980 // If unmasked end is middle of a surrogate pair, expand it to include
981 // the following low surrogate because the caller may want to show a
982 // character after the character at `aStart + aLength`.
983 if (UnmaskedEnd() < valueLength &&
984 textFragment->IsLowSurrogateFollowingHighSurrogateAt(UnmaskedEnd())) {
985 mPasswordMaskData->mUnmaskedLength++;
986 }
987 // If it's first time to mask the unmasking characters with timer, create
988 // the timer now. Then, we'll keep using it for saving the creation cost.
989 if (!HasAutoMaskingTimer() && aLength && aTimeout && UnmaskedLength()) {
990 mPasswordMaskData->mTimer = NS_NewTimer();
991 }
992 } else {
993 if (NS_WARN_IF(aLength != 0)NS_warn_if_impl(aLength != 0, "aLength != 0", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 993)
) {
994 return NS_ERROR_INVALID_ARG;
995 }
996 mPasswordMaskData->MaskAll();
997 }
998
999 // Notify nsTextFrame of this update if the caller wants this to do it.
1000 // Only in this case, script may run.
1001 if (aNotify) {
1002 MOZ_ASSERT(IsEditActionDataAvailable())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsEditActionDataAvailable())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsEditActionDataAvailable())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("IsEditActionDataAvailable()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1002); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()"
")"); do { *((volatile int*)__null) = 1002; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1003
1004 RefPtr<Document> document = GetDocument();
1005 if (NS_WARN_IF(!document)NS_warn_if_impl(!document, "!document", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1005)
) {
1006 return NS_ERROR_NOT_INITIALIZED;
1007 }
1008 // Notify nsTextFrame of masking range change.
1009 if (RefPtr<PresShell> presShell = document->GetObservingPresShell()) {
1010 nsAutoScriptBlocker blockRunningScript;
1011 uint32_t valueLength = text->Length();
1012 CharacterDataChangeInfo changeInfo = {false, 0, valueLength, valueLength,
1013 nullptr};
1014 presShell->CharacterDataChanged(text, changeInfo);
1015 }
1016
1017 // Scroll caret into the view since masking or unmasking character may
1018 // move caret to outside of the view.
1019 nsresult rv = ScrollSelectionFocusIntoView();
1020 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1021 NS_WARNING("EditorBase::ScrollSelectionFocusIntoView() failed")NS_DebugBreak(NS_DEBUG_WARNING, "EditorBase::ScrollSelectionFocusIntoView() failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1021)
;
1022 return rv;
1023 }
1024 }
1025
1026 if (!IsAllMasked() && aTimeout != 0) {
1027 // Initialize the timer to mask the range automatically.
1028 MOZ_ASSERT(HasAutoMaskingTimer())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(HasAutoMaskingTimer())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(HasAutoMaskingTimer()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("HasAutoMaskingTimer()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1028); AnnotateMozCrashReason("MOZ_ASSERT" "(" "HasAutoMaskingTimer()"
")"); do { *((volatile int*)__null) = 1028; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1029 DebugOnly<nsresult> rvIgnored = mPasswordMaskData->mTimer->InitWithCallback(
1030 this, aTimeout, nsITimer::TYPE_ONE_SHOT);
1031 NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "nsITimer::InitWithCallback() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1032); } } while (false)
1032 "nsITimer::InitWithCallback() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "nsITimer::InitWithCallback() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1032); } } while (false)
;
1033 }
1034
1035 return NS_OK;
1036}
1037
1038// static
1039char16_t TextEditor::PasswordMask() {
1040 char16_t ret = LookAndFeel::GetPasswordCharacter();
1041 if (!ret) {
1042 ret = '*';
1043 }
1044 return ret;
1045}
1046
1047MOZ_CAN_RUN_SCRIPT_BOUNDARY NS_IMETHODIMPnsresult TextEditor::Notify(nsITimer* aTimer) {
1048 // Check whether our text editor's password flag was changed before this
1049 // "hide password character" timer actually fires.
1050 if (!IsPasswordEditor() || NS_WARN_IF(!mPasswordMaskData)NS_warn_if_impl(!mPasswordMaskData, "!mPasswordMaskData", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1050)
) {
1051 return NS_OK;
1052 }
1053
1054 if (IsAllMasked()) {
1055 return NS_OK;
1056 }
1057
1058 AutoEditActionDataSetter editActionData(*this, EditAction::eHidePassword);
1059 if (NS_WARN_IF(!editActionData.CanHandle())NS_warn_if_impl(!editActionData.CanHandle(), "!editActionData.CanHandle()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1059)
) {
1060 return NS_ERROR_NOT_INITIALIZED;
1061 }
1062
1063 // Mask all characters.
1064 nsresult rv = MaskAllCharactersAndNotify();
1065 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::MaskAllCharactersAndNotify() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1066); } } while (false)
1066 "TextEditor::MaskAllCharactersAndNotify() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::MaskAllCharactersAndNotify() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1066); } } while (false)
;
1067
1068 if (StaticPrefs::editor_password_testing_mask_delay()) {
1069 if (RefPtr<Element> target = GetInputEventTargetElement()) {
1070 RefPtr<Document> document = target->OwnerDoc();
1071 DebugOnly<nsresult> rvIgnored = nsContentUtils::DispatchTrustedEvent(
1072 document, target, u"MozLastInputMasked"_ns, CanBubble::eYes,
1073 Cancelable::eNo);
1074 NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "nsContentUtils::DispatchTrustedEvent("
"MozLastInputMasked) failed, but ignored", "NS_SUCCEEDED(rvIgnored)"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1076); } } while (false)
1075 "nsContentUtils::DispatchTrustedEvent("do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "nsContentUtils::DispatchTrustedEvent("
"MozLastInputMasked) failed, but ignored", "NS_SUCCEEDED(rvIgnored)"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1076); } } while (false)
1076 "MozLastInputMasked) failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "nsContentUtils::DispatchTrustedEvent("
"MozLastInputMasked) failed, but ignored", "NS_SUCCEEDED(rvIgnored)"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1076); } } while (false)
;
1077 }
1078 }
1079
1080 return EditorBase::ToGenericNSResult(rv);
1081}
1082
1083NS_IMETHODIMPnsresult TextEditor::GetName(nsACString& aName) {
1084 aName.AssignLiteral("TextEditor");
1085 return NS_OK;
1086}
1087
1088void TextEditor::WillDeleteText(uint32_t aCurrentLength,
1089 uint32_t aRemoveStartOffset,
1090 uint32_t aRemoveLength) {
1091 MOZ_ASSERT(IsEditActionDataAvailable())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsEditActionDataAvailable())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsEditActionDataAvailable())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("IsEditActionDataAvailable()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1091); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()"
")"); do { *((volatile int*)__null) = 1091; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1092
1093 if (!IsPasswordEditor() || NS_WARN_IF(!mPasswordMaskData)NS_warn_if_impl(!mPasswordMaskData, "!mPasswordMaskData", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1093)
|| IsAllMasked()) {
1094 return;
1095 }
1096
1097 // Adjust unmasked range before deletion since DOM mutation may cause
1098 // layout referring the range in old text.
1099
1100 // If we need to mask automatically, mask all now.
1101 if (IsMaskingPassword()) {
1102 DebugOnly<nsresult> rvIgnored = MaskAllCharacters();
1103 NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::MaskAllCharacters() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1104); } } while (false)
1104 "TextEditor::MaskAllCharacters() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::MaskAllCharacters() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1104); } } while (false)
;
1105 return;
1106 }
1107
1108 if (aRemoveStartOffset < UnmaskedStart()) {
1109 // If removing range is before the unmasked range, move it.
1110 if (aRemoveStartOffset + aRemoveLength <= UnmaskedStart()) {
1111 DebugOnly<nsresult> rvIgnored =
1112 SetUnmaskRange(UnmaskedStart() - aRemoveLength, UnmaskedLength());
1113 NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRange() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1114); } } while (false)
1114 "TextEditor::SetUnmaskRange() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRange() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1114); } } while (false)
;
1115 return;
1116 }
1117
1118 // If removing range starts before unmasked range, and ends in unmasked
1119 // range, move and shrink the range.
1120 if (aRemoveStartOffset + aRemoveLength < UnmaskedEnd()) {
1121 uint32_t unmaskedLengthInRemovingRange =
1122 aRemoveStartOffset + aRemoveLength - UnmaskedStart();
1123 DebugOnly<nsresult> rvIgnored = SetUnmaskRange(
1124 aRemoveStartOffset, UnmaskedLength() - unmaskedLengthInRemovingRange);
1125 NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRange() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1126); } } while (false)
1126 "TextEditor::SetUnmaskRange() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRange() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1126); } } while (false)
;
1127 return;
1128 }
1129
1130 // If removing range includes all unmasked range, collapse it to the
1131 // remove offset.
1132 DebugOnly<nsresult> rvIgnored = SetUnmaskRange(aRemoveStartOffset, 0);
1133 NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRange() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1134); } } while (false)
1134 "TextEditor::SetUnmaskRange() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRange() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1134); } } while (false)
;
1135 return;
1136 }
1137
1138 if (aRemoveStartOffset < UnmaskedEnd()) {
1139 // If removing range is in unmasked range, shrink the range.
1140 if (aRemoveStartOffset + aRemoveLength <= UnmaskedEnd()) {
1141 DebugOnly<nsresult> rvIgnored =
1142 SetUnmaskRange(UnmaskedStart(), UnmaskedLength() - aRemoveLength);
1143 NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRange() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1144); } } while (false)
1144 "TextEditor::SetUnmaskRange() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRange() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1144); } } while (false)
;
1145 return;
1146 }
1147
1148 // If removing range starts from unmasked range, and ends after it,
1149 // shrink it.
1150 DebugOnly<nsresult> rvIgnored =
1151 SetUnmaskRange(UnmaskedStart(), aRemoveStartOffset - UnmaskedStart());
1152 NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRange() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1153); } } while (false)
1153 "TextEditor::SetUnmaskRange() failed, but ignored")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rvIgnored
)), 1))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRange() failed, but ignored"
, "NS_SUCCEEDED(rvIgnored)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1153); } } while (false)
;
1154 return;
1155 }
1156
1157 // If removing range is after the unmasked range, keep it.
1158}
1159
1160nsresult TextEditor::DidInsertText(uint32_t aNewLength,
1161 uint32_t aInsertedOffset,
1162 uint32_t aInsertedLength) {
1163 MOZ_ASSERT(IsEditActionDataAvailable())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(IsEditActionDataAvailable())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(IsEditActionDataAvailable())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("IsEditActionDataAvailable()"
, "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1163); AnnotateMozCrashReason("MOZ_ASSERT" "(" "IsEditActionDataAvailable()"
")"); do { *((volatile int*)__null) = 1163; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1164
1165 if (!IsPasswordEditor() || NS_WARN_IF(!mPasswordMaskData)NS_warn_if_impl(!mPasswordMaskData, "!mPasswordMaskData", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1165)
|| IsAllMasked()) {
1166 return NS_OK;
1167 }
1168
1169 if (IsMaskingPassword()) {
1170 // If we need to mask password, mask all right now.
1171 nsresult rv = MaskAllCharactersAndNotify();
1172 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::MaskAllCharacters() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1173); } } while (false)
1173 "TextEditor::MaskAllCharacters() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::MaskAllCharacters() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1173); } } while (false)
;
1174 return rv;
1175 }
1176
1177 if (aInsertedOffset < UnmaskedStart()) {
1178 // If insertion point is before unmasked range, expand the unmasked range
1179 // to include the new text.
1180 nsresult rv = SetUnmaskRangeAndNotify(
1181 aInsertedOffset, UnmaskedEnd() + aInsertedLength - aInsertedOffset);
1182 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1183); } } while (false)
1183 "TextEditor::SetUnmaskRangeAndNotify() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1183); } } while (false)
;
1184 return rv;
1185 }
1186
1187 if (aInsertedOffset <= UnmaskedEnd()) {
1188 // If insertion point is in unmasked range, unmask new text.
1189 nsresult rv = SetUnmaskRangeAndNotify(UnmaskedStart(),
1190 UnmaskedLength() + aInsertedLength);
1191 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1192); } } while (false)
1192 "TextEditor::SetUnmaskRangeAndNotify() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1192); } } while (false)
;
1193 return rv;
1194 }
1195
1196 // If insertion point is after unmasked range, extend the unmask range to
1197 // include the new text.
1198 nsresult rv = SetUnmaskRangeAndNotify(
1199 UnmaskedStart(), aInsertedOffset + aInsertedLength - UnmaskedStart());
1200 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1201); } } while (false)
1201 "TextEditor::SetUnmaskRangeAndNotify() failed")do { if (!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1
))))) { NS_DebugBreak(NS_DEBUG_WARNING, "TextEditor::SetUnmaskRangeAndNotify() failed"
, "NS_SUCCEEDED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/editor/libeditor/TextEditor.cpp"
, 1201); } } while (false)
;
1202 return rv;
1203}
1204
1205} // namespace mozilla