Bug 1460509 - part 3: Make TextEditRules::HideLastPWInput() return NS_ERROR_EDITOR_DESTROYED when it causes destroying the editor r?m_kato
And also this patch marks it as MOZ_MUST_USE. All callers have to check if
the result is NS_ERROR_EDITOR_DESTROYED at least.
MozReview-Commit-ID: H4DfU1asPpe
--- a/editor/libeditor/TextEditRules.cpp
+++ b/editor/libeditor/TextEditRules.cpp
@@ -738,24 +738,27 @@ TextEditRules::WillInsertText(EditAction
outString->Assign(tString);
}
if (IsPasswordEditor()) {
// manage the password buffer
mPasswordText.Insert(*outString, start);
if (LookAndFeel::GetEchoPassword() && !DontEchoPassword()) {
- HideLastPWInput();
+ nsresult rv = HideLastPWInput();
mLastStart = start;
mLastLength = outString->Length();
if (mTimer) {
mTimer->Cancel();
- } else {
+ }
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ if (!mTimer) {
mTimer = NS_NewTimer();
- NS_ENSURE_TRUE(mTimer, NS_ERROR_OUT_OF_MEMORY);
}
mTimer->InitWithCallback(this, LookAndFeel::GetPasswordMaskDelay(),
nsITimer::TYPE_ONE_SHOT);
} else {
FillBufWithPWChars(outString, outString->Length());
}
}
@@ -1005,22 +1008,25 @@ TextEditRules::WillDeleteSelection(nsIEd
// manage the password buffer
uint32_t start, end;
nsContentUtils::GetSelectionInTextControl(&SelectionRef(),
TextEditorRef().GetRoot(),
start, end);
if (LookAndFeel::GetEchoPassword()) {
- HideLastPWInput();
+ rv = HideLastPWInput();
mLastStart = start;
mLastLength = 0;
if (mTimer) {
mTimer->Cancel();
}
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
}
// Collapsed selection.
if (end == start) {
// Deleting back.
if (nsIEditor::ePrevious == aCollapsedAction && start > 0) {
mPasswordText.Cut(start-1, 1);
}
@@ -1601,16 +1607,17 @@ TextEditRules::Notify(nsITimer* aTimer)
return NS_ERROR_FAILURE;
}
AutoSafeEditorData setData(*this, *mTextEditor, *selection);
// Check whether our text editor's password flag was changed before this
// "hide password character" timer actually fires.
nsresult rv = IsPasswordEditor() ? HideLastPWInput() : NS_OK;
+ NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to hide last password input");
ASSERT_PASSWORD_LENGTHS_EQUAL();
mLastLength = 0;
return rv;
}
NS_IMETHODIMP
TextEditRules::GetName(nsACString& aName)
{
@@ -1638,22 +1645,31 @@ TextEditRules::HideLastPWInput()
nsCOMPtr<nsINode> selNode = GetTextNode(&SelectionRef());
if (NS_WARN_IF(!selNode)) {
return NS_OK;
}
selNode->GetAsText()->ReplaceData(mLastStart, mLastLength, hiddenText,
IgnoreErrors());
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
// XXXbz Selection::Collapse/Extend take int32_t, but there are tons of
// callsites... Converting all that is a battle for another day.
DebugOnly<nsresult> rv = SelectionRef().Collapse(selNode, start);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to collapse selection");
if (start != end) {
rv = SelectionRef().Extend(selNode, end);
+ if (NS_WARN_IF(!CanHandleEditAction())) {
+ return NS_ERROR_EDITOR_DESTROYED;
+ }
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "Failed to extend selection");
}
return NS_OK;
}
// static
void
TextEditRules::FillBufWithPWChars(nsAString* aOutString,
--- a/editor/libeditor/TextEditRules.h
+++ b/editor/libeditor/TextEditRules.h
@@ -250,17 +250,22 @@ protected:
}
void UndefineCaretBidiLevel();
nsresult CheckBidiLevelForDeletion(const EditorRawDOMPoint& aSelectionPoint,
nsIEditor::EDirection aAction,
bool* aCancel);
- nsresult HideLastPWInput();
+ /**
+ * HideLastPWInput() replaces last password characters which have not
+ * been replaced with mask character like '*' with with the mask character.
+ * This method may cause destroying the editor.
+ */
+ MOZ_MUST_USE nsresult HideLastPWInput();
nsresult CollapseSelectionToTrailingBRIfNeeded();
bool IsPasswordEditor() const;
bool IsSingleLineEditor() const;
bool IsPlaintextEditor() const;
bool IsReadonly() const;
bool IsDisabled() const;