--- a/widget/ContentCache.cpp
+++ b/widget/ContentCache.cpp
@@ -64,16 +64,44 @@ public:
Assign("Vertical (LTR)");
return;
}
Assign("Vertical (RTL)");
}
virtual ~GetWritingModeName() {}
};
+class GetEscapedUTF8String final : public NS_ConvertUTF16toUTF8
+{
+public:
+ explicit GetEscapedUTF8String(const nsAString& aString)
+ : NS_ConvertUTF16toUTF8(aString)
+ {
+ Escape();
+ }
+ explicit GetEscapedUTF8String(const char16ptr_t aString)
+ : NS_ConvertUTF16toUTF8(aString)
+ {
+ Escape();
+ }
+ GetEscapedUTF8String(const char16ptr_t aString, uint32_t aLength)
+ : NS_ConvertUTF16toUTF8(aString, aLength)
+ {
+ Escape();
+ }
+
+private:
+ void Escape()
+ {
+ ReplaceSubstring("\r", "\\r");
+ ReplaceSubstring("\n", "\\n");
+ ReplaceSubstring("\t", "\\t");
+ }
+};
+
/*****************************************************************************
* mozilla::ContentCache
*****************************************************************************/
LazyLogModule sContentCacheLog("ContentCacheWidgets");
ContentCache::ContentCache()
: mCompositionStart(UINT32_MAX)
@@ -644,17 +672,17 @@ ContentCacheInParent::HandleQueryContent
aEvent.mReply.mReversed = mSelection.Reversed();
aEvent.mReply.mHasSelection = true;
aEvent.mReply.mWritingMode = mSelection.mWritingMode;
MOZ_LOG(sContentCacheLog, LogLevel::Info,
("0x%p HandleQueryContentEvent(), "
"Succeeded, aEvent={ mReply={ mOffset=%u, mString=\"%s\", "
"mReversed=%s, mHasSelection=%s, mWritingMode=%s } }",
this, aEvent.mReply.mOffset,
- NS_ConvertUTF16toUTF8(aEvent.mReply.mString).get(),
+ GetEscapedUTF8String(aEvent.mReply.mString).get(),
GetBoolName(aEvent.mReply.mReversed),
GetBoolName(aEvent.mReply.mHasSelection),
GetWritingModeName(aEvent.mReply.mWritingMode).get()));
break;
case eQueryTextContent: {
MOZ_LOG(sContentCacheLog, LogLevel::Info,
("0x%p HandleQueryContentEvent("
"aEvent={ mMessage=eQueryTextContent, mInput={ mOffset=%u, "
@@ -732,17 +760,17 @@ ContentCacheInParent::HandleQueryContent
aEvent.mReply.mOffset = aEvent.mInput.mOffset;
// XXX This may be wrong if storing range isn't in the selection range.
aEvent.mReply.mWritingMode = mSelection.mWritingMode;
MOZ_LOG(sContentCacheLog, LogLevel::Info,
("0x%p HandleQueryContentEvent(), "
"Succeeded, aEvent={ mReply={ mOffset=%u, mString=\"%s\", "
"mWritingMode=%s, mRect=%s } }",
this, aEvent.mReply.mOffset,
- NS_ConvertUTF16toUTF8(aEvent.mReply.mString).get(),
+ GetEscapedUTF8String(aEvent.mReply.mString).get(),
GetWritingModeName(aEvent.mReply.mWritingMode).get(),
GetRectText(aEvent.mReply.mRect).get()));
break;
case eQueryCaretRect:
MOZ_LOG(sContentCacheLog, LogLevel::Info,
("0x%p HandleQueryContentEvent("
"aEvent={ mMessage=eQueryCaretRect, mInput={ mOffset=%u } }, "
"aWidget=0x%p), mText.Length()=%u",
@@ -1018,17 +1046,17 @@ bool
ContentCacheInParent::OnCompositionEvent(const WidgetCompositionEvent& aEvent)
{
MOZ_LOG(sContentCacheLog, LogLevel::Info,
("0x%p OnCompositionEvent(aEvent={ "
"mMessage=%s, mData=\"%s\" (Length()=%u), mRanges->Length()=%u }), "
"mPendingEventsNeedingAck=%u, mIsComposing=%s, "
"mCommitStringByRequest=0x%p",
this, ToChar(aEvent.mMessage),
- NS_ConvertUTF16toUTF8(aEvent.mData).get(), aEvent.mData.Length(),
+ GetEscapedUTF8String(aEvent.mData).get(), aEvent.mData.Length(),
aEvent.mRanges ? aEvent.mRanges->Length() : 0, mPendingEventsNeedingAck,
GetBoolName(mIsComposing), mCommitStringByRequest));
// We must be able to simulate the selection because
// we might not receive selection updates in time
if (!mIsComposing) {
if (aEvent.mWidget && aEvent.mWidget->PluginHasFocus()) {
// If focus is on plugin, we cannot get selection range
--- a/widget/windows/TSFTextStore.cpp
+++ b/widget/windows/TSFTextStore.cpp
@@ -658,16 +658,44 @@ public:
AssignLiteral("Vertical (LR)");
return;
}
AssignLiteral("Vertical (RL)");
}
virtual ~GetWritingModeName() {}
};
+class GetEscapedUTF8String final : public NS_ConvertUTF16toUTF8
+{
+public:
+ explicit GetEscapedUTF8String(const nsAString& aString)
+ : NS_ConvertUTF16toUTF8(aString)
+ {
+ Escape();
+ }
+ explicit GetEscapedUTF8String(const char16ptr_t aString)
+ : NS_ConvertUTF16toUTF8(aString)
+ {
+ Escape();
+ }
+ GetEscapedUTF8String(const char16ptr_t aString, uint32_t aLength)
+ : NS_ConvertUTF16toUTF8(aString, aLength)
+ {
+ Escape();
+ }
+
+private:
+ void Escape()
+ {
+ ReplaceSubstring("\r", "\\r");
+ ReplaceSubstring("\n", "\\n");
+ ReplaceSubstring("\t", "\\t");
+ }
+};
+
/******************************************************************/
/* InputScopeImpl */
/******************************************************************/
class InputScopeImpl final : public ITfInputScope
{
~InputScopeImpl() {}
@@ -1685,17 +1713,17 @@ TSFTextStore::FlushPendingActions()
}
break;
}
case PendingAction::COMPOSITION_UPDATE: {
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
("0x%p TSFTextStore::FlushPendingActions() "
"flushing COMPOSITION_UPDATE={ mData=\"%s\", "
"mRanges=0x%p, mRanges->Length()=%d }",
- this, NS_ConvertUTF16toUTF8(action.mData).get(),
+ this, GetEscapedUTF8String(action.mData).get(),
action.mRanges.get(),
action.mRanges ? action.mRanges->Length() : 0));
// eCompositionChange causes a DOM text event, the IME will be notified
// of NOTIFY_IME_OF_COMPOSITION_EVENT_HANDLED. In this case, we
// should not clear mContentForTSF until we notify the IME of the
// composition update.
mDeferClearingContentForTSF = true;
@@ -1727,17 +1755,17 @@ TSFTextStore::FlushPendingActions()
// Be aware, the mWidget might already have been destroyed.
}
break;
}
case PendingAction::COMPOSITION_END: {
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
("0x%p TSFTextStore::FlushPendingActions() "
"flushing COMPOSITION_END={ mData=\"%s\" }",
- this, NS_ConvertUTF16toUTF8(action.mData).get()));
+ this, GetEscapedUTF8String(action.mData).get()));
// Dispatching eCompositionCommit causes a DOM text event, then,
// the IME will be notified of NOTIFY_IME_OF_COMPOSITION_EVENT_HANDLED.
// In this case, we should not clear mContentForTSFuntil we notify
// the IME of the composition update.
mDeferClearingContentForTSF = true;
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
@@ -2051,20 +2079,20 @@ TSFTextStore::ContentForTSFRef()
mDeferClearingContentForTSF = false;
}
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
("0x%p TSFTextStore::ContentForTSFRef(): "
"mContentForTSF={ mText=\"%s\" (Length()=%u), "
"mLastCompositionString=\"%s\" (Length()=%u), "
"mMinTextModifiedOffset=%u }",
- this, mContentForTSF.Text().Length() <= 20 ?
- NS_ConvertUTF16toUTF8(mContentForTSF.Text()).get() : "<omitted>",
+ this, mContentForTSF.Text().Length() <= 40 ?
+ GetEscapedUTF8String(mContentForTSF.Text()).get() : "<omitted>",
mContentForTSF.Text().Length(),
- NS_ConvertUTF16toUTF8(mContentForTSF.LastCompositionString()).get(),
+ GetEscapedUTF8String(mContentForTSF.LastCompositionString()).get(),
mContentForTSF.LastCompositionString().Length(),
mContentForTSF.MinTextModifiedOffset()));
return mContentForTSF;
}
bool
TSFTextStore::CanAccessActualContentDirectly() const
@@ -2473,17 +2501,17 @@ GetLineStyle(TF_DA_LINESTYLE aTSFLineSty
HRESULT
TSFTextStore::RecordCompositionUpdateAction()
{
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
("0x%p TSFTextStore::RecordCompositionUpdateAction(), "
"mComposition={ mView=0x%p, mStart=%d, mString=\"%s\" "
"(Length()=%d) }",
this, mComposition.mView.get(), mComposition.mStart,
- NS_ConvertUTF16toUTF8(mComposition.mString).get(),
+ GetEscapedUTF8String(mComposition.mString).get(),
mComposition.mString.Length()));
if (!mComposition.IsComposing()) {
MOZ_LOG(sTextStoreLog, LogLevel::Error,
("0x%p TSFTextStore::RecordCompositionUpdateAction() FAILED "
"due to no composition view", this));
return E_FAIL;
}
@@ -2949,17 +2977,17 @@ TSFTextStore::SetText(DWORD dwFlags,
MOZ_LOG(sTextStoreLog, LogLevel::Info,
("0x%p TSFTextStore::SetText(dwFlags=%s, acpStart=%ld, "
"acpEnd=%ld, pchText=0x%p \"%s\", cch=%lu, pChange=0x%p), "
"mComposition.IsComposing()=%s",
this, dwFlags == TS_ST_CORRECTION ? "TS_ST_CORRECTION" :
"not-specified",
acpStart, acpEnd, pchText,
pchText && cch ?
- NS_ConvertUTF16toUTF8(pchText, cch).get() : "",
+ GetEscapedUTF8String(pchText, cch).get() : "",
cch, pChange, GetBoolName(mComposition.IsComposing())));
// Per SDK documentation, and since we don't have better
// ways to do this, this method acts as a helper to
// call SetSelection followed by InsertTextAtSelection
if (!IsReadWriteLocked()) {
MOZ_LOG(sTextStoreLog, LogLevel::Error,
("0x%p TSFTextStore::SetText() FAILED due to "
@@ -3919,17 +3947,17 @@ TSFTextStore::InsertTextAtSelection(DWOR
MOZ_LOG(sTextStoreLog, LogLevel::Info,
("0x%p TSFTextStore::InsertTextAtSelection(dwFlags=%s, "
"pchText=0x%p \"%s\", cch=%lu, pacpStart=0x%p, pacpEnd=0x%p, "
"pChange=0x%p), IsComposing()=%s",
this, dwFlags == 0 ? "0" :
dwFlags == TF_IAS_NOQUERY ? "TF_IAS_NOQUERY" :
dwFlags == TF_IAS_QUERYONLY ? "TF_IAS_QUERYONLY" : "Unknown",
pchText,
- pchText && cch ? NS_ConvertUTF16toUTF8(pchText, cch).get() : "",
+ pchText && cch ? GetEscapedUTF8String(pchText, cch).get() : "",
cch, pacpStart, pacpEnd, pChange,
GetBoolName(mComposition.IsComposing())));
if (cch && !pchText) {
MOZ_LOG(sTextStoreLog, LogLevel::Error,
("0x%p TSFTextStore::InsertTextAtSelection() FAILED due to "
"null pchText", this));
return E_INVALIDARG;
@@ -4015,17 +4043,17 @@ TSFTextStore::InsertTextAtSelection(DWOR
bool
TSFTextStore::InsertTextAtSelectionInternal(const nsAString& aInsertStr,
TS_TEXTCHANGE* aTextChange)
{
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
("0x%p TSFTextStore::InsertTextAtSelectionInternal("
"aInsertStr=\"%s\", aTextChange=0x%p), IsComposing=%s",
- this, NS_ConvertUTF16toUTF8(aInsertStr).get(), aTextChange,
+ this, GetEscapedUTF8String(aInsertStr).get(), aTextChange,
GetBoolName(mComposition.IsComposing())));
Content& contentForTSF = ContentForTSFRef();
if (!contentForTSF.IsInitialized()) {
MOZ_LOG(sTextStoreLog, LogLevel::Error,
("0x%p TSFTextStore::InsertTextAtSelectionInternal() failed "
"due to ContentForTSFRef() failure()", this));
return false;
@@ -4048,17 +4076,17 @@ TSFTextStore::InsertTextAtSelectionInter
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
("0x%p TSFTextStore::InsertTextAtSelectionInternal() "
"appending pending compositionstart and compositionend... "
"PendingCompositionStart={ mSelectionStart=%d, "
"mSelectionLength=%d }, PendingCompositionEnd={ mData=\"%s\" "
"(Length()=%u) }",
this, compositionStart->mSelectionStart,
compositionStart->mSelectionLength,
- NS_ConvertUTF16toUTF8(compositionEnd->mData).get(),
+ GetEscapedUTF8String(compositionEnd->mData).get(),
compositionEnd->mData.Length()));
}
contentForTSF.ReplaceSelectedTextWith(aInsertStr);
if (aTextChange) {
aTextChange->acpStart = oldSelection.acpStart;
aTextChange->acpOldEnd = oldSelection.acpEnd;
@@ -4208,17 +4236,17 @@ TSFTextStore::RecordCompositionStartActi
HRESULT
TSFTextStore::RecordCompositionEndAction()
{
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
("0x%p TSFTextStore::RecordCompositionEndAction(), "
"mComposition={ mView=0x%p, mString=\"%s\" }",
this, mComposition.mView.get(),
- NS_ConvertUTF16toUTF8(mComposition.mString).get()));
+ GetEscapedUTF8String(mComposition.mString).get()));
MOZ_ASSERT(mComposition.IsComposing());
CompleteLastActionIfStillIncomplete();
PendingAction* action = mPendingActions.AppendElement();
action->mType = PendingAction::COMPOSITION_END;
action->mData = mComposition.mString;
@@ -4371,31 +4399,31 @@ TSFTextStore::OnUpdateComposition(ITfCom
"SelectionForTSFRef() failure", this));
return E_FAIL;
}
MOZ_LOG(sTextStoreLog, LogLevel::Info,
("0x%p TSFTextStore::OnUpdateComposition() succeeded: "
"mComposition={ mStart=%ld, mString=\"%s\" }, "
"SelectionForTSFRef()={ acpStart=%ld, acpEnd=%ld, style.ase=%s }",
this, mComposition.mStart,
- NS_ConvertUTF16toUTF8(mComposition.mString).get(),
+ GetEscapedUTF8String(mComposition.mString).get(),
selectionForTSF.StartOffset(), selectionForTSF.EndOffset(),
GetActiveSelEndName(selectionForTSF.ActiveSelEnd())));
}
return S_OK;
}
STDMETHODIMP
TSFTextStore::OnEndComposition(ITfCompositionView* pComposition)
{
MOZ_LOG(sTextStoreLog, LogLevel::Info,
("0x%p TSFTextStore::OnEndComposition(pComposition=0x%p), "
"mComposition={ mView=0x%p, mString=\"%s\" }",
this, pComposition, mComposition.mView.get(),
- NS_ConvertUTF16toUTF8(mComposition.mString).get()));
+ GetEscapedUTF8String(mComposition.mString).get()));
AutoPendingActionAndContentFlusher flusher(this);
if (!mComposition.IsComposing()) {
MOZ_LOG(sTextStoreLog, LogLevel::Error,
("0x%p TSFTextStore::OnEndComposition() FAILED due to "
"no active composition", this));
return E_UNEXPECTED;
@@ -5235,17 +5263,17 @@ void
TSFTextStore::CommitCompositionInternal(bool aDiscard)
{
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
("0x%p TSFTextStore::CommitCompositionInternal(aDiscard=%s), "
"mSink=0x%p, mContext=0x%p, mComposition.mView=0x%p, "
"mComposition.mString=\"%s\"",
this, GetBoolName(aDiscard), mSink.get(), mContext.get(),
mComposition.mView.get(),
- NS_ConvertUTF16toUTF8(mComposition.mString).get()));
+ GetEscapedUTF8String(mComposition.mString).get()));
// If the document is locked, TSF will fail to commit composition since
// TSF needs another document lock. So, let's put off the request.
// Note that TextComposition will commit composition in the focused editor
// with the latest composition string for web apps and waits asynchronous
// committing messages. Therefore, we can and need to perform this
// asynchronously.
if (IsReadLocked()) {
@@ -5860,19 +5888,19 @@ TSFTextStore::Content::ReplaceTextWith(L
mMinTextModifiedOffset = firstDifferentOffset =
mComposition.EndOffset();
}
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
("0x%p TSFTextStore::Content::ReplaceTextWith(aStart=%d, "
"aLength=%d, aReplaceString=\"%s\"), mComposition={ mStart=%d, "
"mString=\"%s\" }, mLastCompositionString=\"%s\", "
"mMinTextModifiedOffset=%u, firstDifferentOffset=%u",
- this, aStart, aLength, NS_ConvertUTF16toUTF8(aReplaceString).get(),
- mComposition.mStart, NS_ConvertUTF16toUTF8(mComposition.mString).get(),
- NS_ConvertUTF16toUTF8(mLastCompositionString).get(),
+ this, aStart, aLength, GetEscapedUTF8String(aReplaceString).get(),
+ mComposition.mStart, GetEscapedUTF8String(mComposition.mString).get(),
+ GetEscapedUTF8String(mLastCompositionString).get(),
mMinTextModifiedOffset, firstDifferentOffset));
} else {
firstDifferentOffset =
static_cast<uint32_t>(aStart) +
FirstDifferentCharOffset(aReplaceString, replacedString);
}
mMinTextModifiedOffset =
std::min(mMinTextModifiedOffset, firstDifferentOffset);