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
This commit is contained in:
Carlos Zamora 2020-07-20 16:10:55 -07:00 committed by GitHub
parent 04f5ee7ebf
commit c390b61648
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -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<double> 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());