From c390b6164871b59bc1520dd7838889c45a569dec Mon Sep 17 00:00:00 2001 From: Carlos Zamora Date: Mon, 20 Jul 2020 16:10:55 -0700 Subject: [PATCH] UIA: use full buffer comparison in rects and endpoint setter (#6447) In UiaTextRange, `_getBufferSize` returns an optimized version of the size of the buffer to be the origin and the last character in the buffer. This is to improve performance on search or checking if you are currently on the last word/line. When setting the endpoint and drawing the bounding rectangles, we should be retrieving the true buffer size. This is because it is still possible to create UiaTextRanges that are outside of this optimized size. The main source of this is `ExpandToEnclosingUnit()` when the unit is `Document`. The end _should_ be the last visible character, but it isn't because that would break our tests. This is an incomplete solution. #6986 is a follow up to completely test and implement the solution. The crash in #6402 was caused by getting the document range (a range of the full text buffer), then moving the end by one character. When we get the document range, we get the optimized size of the buffer (the position of the last character). Moving by one character is valid because the buffer still has more to explore. We then crash from checking if the new position is valid on the **optimized size**, not the **real size**. REFERENCES #6986 - follow up to properly handle/test this "end of buffer" problem Closes #6402 --- src/types/UiaTextRangeBase.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/types/UiaTextRangeBase.cpp b/src/types/UiaTextRangeBase.cpp index 3245620e369..7d12fb42762 100644 --- a/src/types/UiaTextRangeBase.cpp +++ b/src/types/UiaTextRangeBase.cpp @@ -145,7 +145,9 @@ const COORD UiaTextRangeBase::GetEndpoint(TextPatternRangeEndpoint endpoint) con // - true if range is degenerate, false otherwise. bool UiaTextRangeBase::SetEndpoint(TextPatternRangeEndpoint endpoint, const COORD val) noexcept { - const auto bufferSize = _getBufferSize(); + // GH#6402: Get the actual buffer size here, instead of the one + // constrained by the virtual bottom. + const auto bufferSize = _pData->GetTextBuffer().GetSize(); switch (endpoint) { case TextPatternRangeEndpoint_End: @@ -284,6 +286,8 @@ IFACEMETHODIMP UiaTextRangeBase::ExpandToEnclosingUnit(_In_ TextUnit unit) noexc } else { + // TODO GH#6986: properly handle "end of buffer" as last character + // instead of last cell // expand to document _start = bufferSize.Origin(); _end = bufferSize.EndExclusive(); @@ -393,7 +397,9 @@ IFACEMETHODIMP UiaTextRangeBase::GetBoundingRectangles(_Outptr_result_maybenull_ // set of coords. std::vector coords; - const auto bufferSize = _getBufferSize(); + // GH#6402: Get the actual buffer size here, instead of the one + // constrained by the virtual bottom. + const auto bufferSize = _pData->GetTextBuffer().GetSize(); // these viewport vars are converted to the buffer coordinate space const auto viewport = bufferSize.ConvertToOrigin(_pData->GetViewport());