Bugfix: vertical selection out of bounds (#1317)

* Fix crash bug and acknowledge that getting cell data can cause a crash
This commit is contained in:
Carlos Zamora
2019-06-19 10:49:57 -07:00
committed by Dustin L. Howett (MSFT)
parent 50dc8d48d9
commit 871718952c
2 changed files with 18 additions and 14 deletions

View File

@@ -20,17 +20,21 @@ std::vector<SMALL_RECT> Terminal::_GetSelectionRects() const
}
// create these new anchors for comparison and rendering
COORD selectionAnchorWithOffset;
COORD endSelectionPositionWithOffset;
COORD selectionAnchorWithOffset{ _selectionAnchor };
COORD endSelectionPositionWithOffset{ _endSelectionPosition };
// Add anchor offset here to update properly on new buffer output
THROW_IF_FAILED(ShortAdd(_selectionAnchor.Y, _selectionAnchor_YOffset, &selectionAnchorWithOffset.Y));
THROW_IF_FAILED(ShortAdd(_endSelectionPosition.Y, _endSelectionPosition_YOffset, &endSelectionPositionWithOffset.Y));
THROW_IF_FAILED(ShortAdd(selectionAnchorWithOffset.Y, _selectionAnchor_YOffset, &selectionAnchorWithOffset.Y));
THROW_IF_FAILED(ShortAdd(endSelectionPositionWithOffset.Y, _endSelectionPosition_YOffset, &endSelectionPositionWithOffset.Y));
// clamp Y values to be within mutable viewport bounds
selectionAnchorWithOffset.Y = std::clamp(selectionAnchorWithOffset.Y, static_cast<SHORT>(0), _mutableViewport.BottomInclusive());
endSelectionPositionWithOffset.Y = std::clamp(endSelectionPositionWithOffset.Y, static_cast<SHORT>(0), _mutableViewport.BottomInclusive());
// clamp X values to be within buffer bounds
const auto bufferWidth = _buffer->GetSize().RightInclusive();
selectionAnchorWithOffset.X = std::clamp(_selectionAnchor.X, static_cast<SHORT>(0), bufferWidth);
endSelectionPositionWithOffset.X = std::clamp(_endSelectionPosition.X, static_cast<SHORT>(0), bufferWidth);
const auto bufferSize = _buffer->GetSize();
selectionAnchorWithOffset.X = std::clamp(_selectionAnchor.X, bufferSize.Left(), bufferSize.RightInclusive());
endSelectionPositionWithOffset.X = std::clamp(_endSelectionPosition.X, bufferSize.Left(), bufferSize.RightInclusive());
// NOTE: (0,0) is top-left so vertical comparison is inverted
const COORD& higherCoord = (selectionAnchorWithOffset.Y <= endSelectionPositionWithOffset.Y) ?
@@ -56,7 +60,7 @@ std::vector<SMALL_RECT> Terminal::_GetSelectionRects() const
else
{
selectionRow.Left = (row == higherCoord.Y) ? higherCoord.X : 0;
selectionRow.Right = (row == lowerCoord.Y) ? lowerCoord.X : bufferWidth;
selectionRow.Right = (row == lowerCoord.Y) ? lowerCoord.X : bufferSize.RightInclusive();
}
selectionRow.Left = _ExpandWideGlyphSelectionLeft(selectionRow.Left, row);
@@ -73,10 +77,10 @@ std::vector<SMALL_RECT> Terminal::_GetSelectionRects() const
// - position: the (x,y) coordinate on the visible viewport
// Return Value:
// - updated x position to encapsulate the wide glyph
const SHORT Terminal::_ExpandWideGlyphSelectionLeft(const SHORT xPos, const SHORT yPos) const noexcept
const SHORT Terminal::_ExpandWideGlyphSelectionLeft(const SHORT xPos, const SHORT yPos) const
{
// don't change the value if at/outside the boundary
if (xPos <= 0 || xPos >= _buffer->GetSize().RightInclusive())
if (xPos <= 0 || xPos > _buffer->GetSize().RightInclusive())
{
return xPos;
}
@@ -98,10 +102,10 @@ const SHORT Terminal::_ExpandWideGlyphSelectionLeft(const SHORT xPos, const SHOR
// - position: the (x,y) coordinate on the visible viewport
// Return Value:
// - updated x position to encapsulate the wide glyph
const SHORT Terminal::_ExpandWideGlyphSelectionRight(const SHORT xPos, const SHORT yPos) const noexcept
const SHORT Terminal::_ExpandWideGlyphSelectionRight(const SHORT xPos, const SHORT yPos) const
{
// don't change the value if at/outside the boundary
if (xPos <= 0 || xPos >= _buffer->GetSize().RightInclusive())
if (xPos < 0 || xPos >= _buffer->GetSize().RightInclusive())
{
return xPos;
}