Skip to content

Commit

Permalink
Harden against resizing down to 0 columns/rows (#14467)
Browse files Browse the repository at this point in the history
This changeset includes various guards against resizing the terminal down to 0
columns/rows: The 2 `TextBuffer` locations that accept new sizes, as well as
the `HwndTerminal::Refresh` which was the entrypoint causing the issue.

Closes #14404

(cherry picked from commit c5d417f)
Service-Card-Id: 87020511
Service-Version: 1.16
  • Loading branch information
lhecker authored and DHowett committed Dec 12, 2022
1 parent a23423a commit 0d130a7
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 7 deletions.
12 changes: 9 additions & 3 deletions src/buffer/out/textBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ using PointTree = interval_tree::IntervalTree<til::point, size_t>;
// Return Value:
// - constructed object
// Note: may throw exception
TextBuffer::TextBuffer(const til::size screenBufferSize,
TextBuffer::TextBuffer(til::size screenBufferSize,
const TextAttribute defaultAttributes,
const UINT cursorSize,
const bool isActiveBuffer,
Expand All @@ -46,6 +46,10 @@ TextBuffer::TextBuffer(const til::size screenBufferSize,
_currentHyperlinkId{ 1 },
_currentPatternId{ 0 }
{
// Guard against resizing the text buffer to 0 columns/rows, which would break being able to insert text.
screenBufferSize.width = std::max(screenBufferSize.width, 1);
screenBufferSize.height = std::max(screenBufferSize.height, 1);

// initialize ROWs
_storage.reserve(gsl::narrow<size_t>(screenBufferSize.Y));
for (til::CoordType i = 0; i < screenBufferSize.Y; ++i)
Expand Down Expand Up @@ -896,9 +900,11 @@ void TextBuffer::Reset()
// - newSize - new size of screen.
// Return Value:
// - Success if successful. Invalid parameter if screen buffer size is unexpected. No memory if allocation failed.
[[nodiscard]] NTSTATUS TextBuffer::ResizeTraditional(const til::size newSize) noexcept
[[nodiscard]] NTSTATUS TextBuffer::ResizeTraditional(til::size newSize) noexcept
{
RETURN_HR_IF(E_INVALIDARG, newSize.X < 0 || newSize.Y < 0);
// Guard against resizing the text buffer to 0 columns/rows, which would break being able to insert text.
newSize.width = std::max(newSize.width, 1);
newSize.height = std::max(newSize.height, 1);

try
{
Expand Down
13 changes: 9 additions & 4 deletions src/cascadia/PublicTerminalCore/HwndTerminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,15 +365,20 @@ HRESULT HwndTerminal::Refresh(const til::size windowSize, _Out_ til::size* dimen
const auto viewInPixels = Viewport::FromDimensions(windowSize);
const auto vp = _renderEngine->GetViewportInCharacters(viewInPixels);

// Guard against resizing the window to 0 columns/rows, which the text buffer classes don't really support.
auto size = vp.Dimensions();
size.width = std::max(size.width, 1);
size.height = std::max(size.height, 1);

// If this function succeeds with S_FALSE, then the terminal didn't
// actually change size. No need to notify the connection of this
// no-op.
// TODO: MSFT:20642295 Resizing the buffer will corrupt it
// I believe we'll need support for CSI 2J, and additionally I think
// we're resetting the viewport to the top
RETURN_IF_FAILED(_terminal->UserResize({ vp.Width(), vp.Height() }));
dimensions->X = vp.Width();
dimensions->Y = vp.Height();
RETURN_IF_FAILED(_terminal->UserResize(size));
dimensions->width = size.width;
dimensions->height = size.height;

return S_OK;
}
Expand Down Expand Up @@ -473,7 +478,7 @@ HRESULT _stdcall TerminalCalculateResize(_In_ void* terminal, _In_ til::CoordTyp
{
const auto publicTerminal = static_cast<const HwndTerminal*>(terminal);

const auto viewInPixels = Viewport::FromDimensions({ 0, 0 }, { width, height });
const auto viewInPixels = Viewport::FromDimensions({ width, height });
const auto viewInCharacters = publicTerminal->_renderEngine->GetViewportInCharacters(viewInPixels);

dimensions->X = viewInCharacters.Width();
Expand Down

0 comments on commit 0d130a7

Please sign in to comment.