Skip to content

Crash in TextBufferCellIterator::TextBufferCellIterator() when moving cursor #2986

@pingzing

Description

@pingzing

Environment

Windows 10.0.18362.0,
Windows Terminal running in Debug mode, off commit 1caece7

Any other software?

The micro terminal text editor, with a few custom keybinds, as follows:

{
        "CtrlRight": "WordRight",
        "CtrlLeft": "WordLeft",
        "CtrlShiftRight": "SelectWordRight",
        "CtrlShiftLeft": "SelectWordLeft"
}

Steps to reproduce

I can easily reproduce this in micro, but I've had crashes from what miiiight be this issue in non-interactive-mode apps as well. The steps that tend to trigger this are as follows:

  1. Open micro. The shell doesn't seem to matter.
  2. Type at least one word.
  3. Move the cursor to the end of the line.
  4. With the above keybinds in place, press Ctrl+Shift+LeftArrow.
  5. Crash!

Expected behavior

The text is highlighted one word to the left. Old Conhost seems to be able to handle this.

Actual behavior

Crashiness.

Additional Information

I ran this in Visual Studio to capture some debug output. Here's the stack trace:

ucrtbased.dll!__threadid() + 101 bytes	Unknown
ucrtbased.dll!__threadid() + 515 bytes	Unknown
ucrtbased.dll!abort() + 29 bytes	Unknown
ucrtbased.dll!terminate() + 54 bytes	Unknown
vcruntime140_1d.dll!00007fff96842174()	Unknown
vcruntime140_1d.dll!00007fff96842e72()	Unknown
vcruntime140_1d.dll!__CxxFrameHandler4() + 251 bytes	Unknown
TerminalControl.dll!__GSHandlerCheck_EH4(_EXCEPTION_RECORD * ExceptionRecord, void * EstablisherFrame, _CONTEXT * ContextRecord, _DISPATCHER_CONTEXT * DispatcherContext) Line 73	C++
ntdll.dll!__chkstk() + 287 bytes	Unknown
ntdll.dll!RtlRaiseException() + 921 bytes	Unknown
ntdll.dll!KiUserExceptionDispatcher() + 46 bytes	Unknown
KernelBase.dll!RaiseException() + 105 bytes	Unknown
vcruntime140d.dll!_CxxThrowException() + 311 bytes	Unknown
TerminalControl.dll!wil::details::ThrowResultExceptionInternal(const wil::FailureInfo & failure) Line 2787	C++
TerminalControl.dll!wil::ThrowResultException(const wil::FailureInfo & failure) Line 2449	C++
TerminalControl.dll!wil::details::ReportFailure(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, void * returnAddress, wil::FailureType type, HRESULT hr, const wchar_t * message, wil::details::ReportFailureOptions options) Line 3390	C++
TerminalControl.dll!wil::details::ReportFailure_Hr(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, void * returnAddress, wil::FailureType type, HRESULT hr) Line 3451	C++
TerminalControl.dll!wil::details::in1diag5::_Throw_Hr(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, HRESULT hr) Line 4970	C++
TerminalControl.dll!wil::details::in1diag5::Throw_HrIf(void * callerReturnAddress, unsigned int lineNumber, const char * fileName, const char * functionName, const char * code, HRESULT hr, bool condition) Line 5074	C++
--> TerminalControl.dll!TextBufferCellIterator::TextBufferCellIterator(const TextBuffer & buffer, _COORD pos, const Microsoft::Console::Types::Viewport limits) Line 48	C++
TerminalControl.dll!TextBufferCellIterator::TextBufferCellIterator(const TextBuffer & buffer, _COORD pos) Line 25	C++
TerminalControl.dll!Microsoft::Terminal::Core::Terminal::IsCursorDoubleWidth() Line 96	C++
TerminalControl.dll!Microsoft::Console::Render::Renderer::_PaintCursor(Microsoft::Console::Render::IRenderEngine * const pEngine) Line 749	C++
TerminalControl.dll!Microsoft::Console::Render::Renderer::_PaintFrameForEngine(Microsoft::Console::Render::IRenderEngine * const pEngine) Line 137	C++
TerminalControl.dll!Microsoft::Console::Render::Renderer::PaintFrame() Line 70	C++
TerminalControl.dll!Microsoft::Console::Render::RenderThread::_ThreadProc() Line 165	C++
TerminalControl.dll!Microsoft::Console::Render::RenderThread::s_ThreadProc(void * lpParameter) Line 148	C++
[External Code]	

At the time of this particular crash, TextBufferCellIterator::TextBufferCellIterator() received a pos argument with with dimensions 120x26, and a limits arg with an LT of 0,0 and a RB of 119, 9028, so altogether a [120x9029]-sized viewport.

Judging by the failure object up in WIL's ThrowExceptionInternal, the issue seems to be line 46 of textBufferCellIterator.cpp, THROW_HR_IF(E_INVALIDARG, !limits.IsInBounds(pos));.

Some further digging reveals that Viewport::IsInBounds(const COORD& pos) is violating the "pos.X < RightExclusive()" constraint. pos.X is _exactly 120, while RightExclusive() also returns exactly 120.

Just Ctrl+Arrowing around in Micro doesn't usually trigger this, although I can occasionally get crashes to occur when I'm at the extreme left edge of a line while navigating leftward. Ctrl+Shift+Arrow is extremely reliable at triggering crashes, however.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Area-RenderingText rendering, emoji, complex glyph & font-fallback issuesIssue-BugIt either shouldn't be doing this or needs an investigation.Needs-Tag-FixDoesn't match tag requirementsProduct-TerminalThe new Windows Terminal.Resolution-Fix-CommittedFix is checked in, but it might be 3-4 weeks until a release.Severity-CrashCrashes are real bad news.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions