From a8aea3ddb7ae930d7d0ebc9e9ec7c9faca80236b Mon Sep 17 00:00:00 2001 From: James Holderness Date: Sun, 15 Nov 2020 15:54:00 +0000 Subject: [PATCH 1/4] Remove incorrect noexcept specifier from IsCursorDoubleWidth. --- src/host/renderData.cpp | 2 +- src/host/renderData.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/host/renderData.cpp b/src/host/renderData.cpp index 41d41d4d035..a84b95ac5e5 100644 --- a/src/host/renderData.cpp +++ b/src/host/renderData.cpp @@ -276,7 +276,7 @@ const std::vector RenderData::GetOver // - // Return Value: // - true if the cursor should be drawn twice as wide as usual -bool RenderData::IsCursorDoubleWidth() const noexcept +bool RenderData::IsCursorDoubleWidth() const { const CONSOLE_INFORMATION& gci = ServiceLocator::LocateGlobals().getConsoleInformation(); return gci.GetActiveOutputBuffer().CursorIsDoubleWidth(); diff --git a/src/host/renderData.hpp b/src/host/renderData.hpp index 26f291477d0..17172aba435 100644 --- a/src/host/renderData.hpp +++ b/src/host/renderData.hpp @@ -46,7 +46,7 @@ class RenderData final : CursorType GetCursorStyle() const noexcept override; ULONG GetCursorPixelWidth() const noexcept override; COLORREF GetCursorColor() const noexcept override; - bool IsCursorDoubleWidth() const noexcept override; + bool IsCursorDoubleWidth() const override; bool IsScreenReversed() const noexcept override; From fd97a4ca1680cf057b64a1f20199178d3518c9b0 Mon Sep 17 00:00:00 2001 From: James Holderness Date: Sun, 15 Nov 2020 16:00:18 +0000 Subject: [PATCH 2/4] Correct off-by-one error in SetViewport coordinate checks. --- src/host/screenInfo.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/host/screenInfo.cpp b/src/host/screenInfo.cpp index 57edb1058e9..41b1a818c9a 100644 --- a/src/host/screenInfo.cpp +++ b/src/host/screenInfo.cpp @@ -2146,7 +2146,7 @@ void SCREEN_INFORMATION::SetViewport(const Viewport& newViewport, } // do adjustments on a copy that's easily manipulated. - SMALL_RECT srCorrected = newViewport.ToInclusive(); + SMALL_RECT srCorrected = newViewport.ToExclusive(); if (srCorrected.Left < 0) { @@ -2160,16 +2160,16 @@ void SCREEN_INFORMATION::SetViewport(const Viewport& newViewport, } const COORD coordScreenBufferSize = GetBufferSize().Dimensions(); - if (srCorrected.Right >= coordScreenBufferSize.X) + if (srCorrected.Right > coordScreenBufferSize.X) { srCorrected.Right = coordScreenBufferSize.X; } - if (srCorrected.Bottom >= coordScreenBufferSize.Y) + if (srCorrected.Bottom > coordScreenBufferSize.Y) { srCorrected.Bottom = coordScreenBufferSize.Y; } - _viewport = Viewport::FromInclusive(srCorrected); + _viewport = Viewport::FromExclusive(srCorrected); if (updateBottom) { UpdateBottom(); From 706ce4e786d782590e6b33dad296fd70813503dd Mon Sep 17 00:00:00 2001 From: James Holderness Date: Sun, 15 Nov 2020 16:15:59 +0000 Subject: [PATCH 3/4] Make sure viewport doesn't overflow buffer after resize. --- src/host/getset.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/host/getset.cpp b/src/host/getset.cpp index 7a088afb638..39923d109da 100644 --- a/src/host/getset.cpp +++ b/src/host/getset.cpp @@ -524,7 +524,15 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont COORD const coordScreenBufferSize = screenInfo.GetBufferSize().Dimensions(); if (size.X != coordScreenBufferSize.X || size.Y != coordScreenBufferSize.Y) { - RETURN_NTSTATUS(screenInfo.ResizeScreenBuffer(size, TRUE)); + RETURN_IF_NTSTATUS_FAILED(screenInfo.ResizeScreenBuffer(size, TRUE)); + } + + // Make sure the viewport doesn't now overflow the buffer dimensions. + auto overflow = screenInfo.GetViewport().EndExclusive() - screenInfo.GetBufferSize().Dimensions(); + if (overflow.X > 0 || overflow.Y > 0) + { + overflow = { std::max(overflow.X, 0), std::max(overflow.Y, 0) }; + RETURN_IF_NTSTATUS_FAILED(screenInfo.SetViewportOrigin(false, -overflow, false)); } return S_OK; @@ -620,6 +628,14 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont // (see https://msdn.microsoft.com/en-us/library/windows/desktop/ms686125(v=vs.85).aspx and DoSrvSetConsoleWindowInfo) // Note that it also doesn't set cursor position. + // However, we do need to make sure the viewport doesn't now overflow the buffer dimensions. + auto overflow = context.GetViewport().EndExclusive() - context.GetBufferSize().Dimensions(); + if (overflow.X > 0 || overflow.Y > 0) + { + overflow = { std::max(overflow.X, 0), std::max(overflow.Y, 0) }; + RETURN_IF_NTSTATUS_FAILED(context.SetViewportOrigin(false, -overflow, false)); + } + return S_OK; } CATCH_RETURN(); From a1e9fa885cbe0b59618b22b15febf9b8f3f9c899 Mon Sep 17 00:00:00 2001 From: James Holderness Date: Mon, 16 Nov 2020 01:07:49 +0000 Subject: [PATCH 4/4] Make sure cursor position doesn't overflow buffer after resize. --- src/host/getset.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/host/getset.cpp b/src/host/getset.cpp index 39923d109da..53a112d3fee 100644 --- a/src/host/getset.cpp +++ b/src/host/getset.cpp @@ -535,6 +535,15 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont RETURN_IF_NTSTATUS_FAILED(screenInfo.SetViewportOrigin(false, -overflow, false)); } + // And also that the cursor position is clamped within the buffer boundaries. + auto& cursor = screenInfo.GetTextBuffer().GetCursor(); + auto clampedCursorPosition = cursor.GetPosition(); + screenInfo.GetBufferSize().Clamp(clampedCursorPosition); + if (clampedCursorPosition != cursor.GetPosition()) + { + cursor.SetPosition(clampedCursorPosition); + } + return S_OK; } CATCH_RETURN(); @@ -636,6 +645,15 @@ void ApiRoutines::GetLargestConsoleWindowSizeImpl(const SCREEN_INFORMATION& cont RETURN_IF_NTSTATUS_FAILED(context.SetViewportOrigin(false, -overflow, false)); } + // And also that the cursor position is clamped within the buffer boundaries. + auto& cursor = context.GetTextBuffer().GetCursor(); + auto clampedCursorPosition = cursor.GetPosition(); + context.GetBufferSize().Clamp(clampedCursorPosition); + if (clampedCursorPosition != cursor.GetPosition()) + { + cursor.SetPosition(clampedCursorPosition); + } + return S_OK; } CATCH_RETURN();