From 7f660c27866c0f93d5deb884178af6adc83a9794 Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Tue, 8 Feb 2022 15:55:27 -0800 Subject: [PATCH] Validate cursor position in UIA UTR ctor (#12436) This adds some validation in the `UiaTextRange` ctor for the cursor position. #8730 was caused by creating a `UiaTextRange` at the cursor position when it was in a delayed state (meaning it's purposefully hanging off of the right edge of the buffer). Normally, `Cursor` maintains a flag to keep track of when that occurs, but Windows Terminal isn't maintaining that properly in `Terminal::WriteBuffer`. The _correct_ approach would be to fix `WriteBuffer` then leverage that flag for validation in `UiaTextRange`. However, messing with `WriteBuffer` is a little too risky for our comfort right now. So we'll do the second half of that by checking if the cursor position is valid. Since the cursor is really only expected to be out of bounds when it's in that delayed state, we get the same result (just maybe a tad slower than simply checking a flag). Closes #8730 Filed #12440 to track changes in `Terminal::_WriteBuffer` for delayed EOL wrap. ## Validation Steps Performed While using magnifier, input/delete wrapped text in input buffer. (cherry picked from commit 5dcf5262b46a1dbdf11bc536fe88439df437e211) --- src/types/UiaTextRangeBase.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/types/UiaTextRangeBase.cpp b/src/types/UiaTextRangeBase.cpp index 6571d2ea13f..1658e6d2b16 100644 --- a/src/types/UiaTextRangeBase.cpp +++ b/src/types/UiaTextRangeBase.cpp @@ -42,9 +42,15 @@ HRESULT UiaTextRangeBase::RuntimeClassInitialize(_In_ IUiaData* pData, _In_ std::wstring_view wordDelimiters) noexcept try { + RETURN_HR_IF_NULL(E_INVALIDARG, pData); RETURN_IF_FAILED(RuntimeClassInitialize(pData, pProvider, wordDelimiters)); + // GH#8730: The cursor position may be in a delayed state, resulting in it being out of bounds. + // If that's the case, clamp it to be within bounds. + // TODO GH#12440: We should be able to just check some fields off of the Cursor object, + // but Windows Terminal isn't updating those flags properly. _start = cursor.GetPosition(); + pData->GetTextBuffer().GetSize().Clamp(_start); _end = _start; UiaTracing::TextRange::Constructor(*this);