diff --git a/src/host/inputBuffer.cpp b/src/host/inputBuffer.cpp index 019378adb1..8893e3987d 100644 --- a/src/host/inputBuffer.cpp +++ b/src/host/inputBuffer.cpp @@ -410,6 +410,13 @@ void InputBuffer::_ReadBuffer(_Out_ std::deque>& ou } } + // GH #8663: Before we read this key from the buffer, check that there's + // space for it. If we're calling Read without unidoce being set, then I + // believe we're also going to try and break this key event into one key + // for each OEM character. Problem is though, one unicode codepoint can + // be more than two chars long. So don't just use IsGlyphFullWidth, + // actually check with the codepoint how wide this key should be. + size_t sizeOfThisKey = 1; const auto& keyToRead{ _storage.front() }; if (!unicode) { @@ -420,13 +427,17 @@ void InputBuffer::_ReadBuffer(_Out_ std::deque>& ou // convert from wchar to char std::wstring wstr{ pKeyEvent->GetCharData() }; const auto str = ConvertToA(codepage, wstr); - const auto sizeOfThisKey{ str.size() }; + sizeOfThisKey = str.size(); if (virtualReadCount + sizeOfThisKey > readCount) { break; } } } + // TODO!: If we do this, then readers who come asking for 4 events might + // only get 3 back, under the implication that they know they need to + // expand the events themselves. Who are all the InputBuffer::Read + // callers? Are they all expanding (in the case of !unicode) in post? if (performNormalRead) { @@ -434,32 +445,7 @@ void InputBuffer::_ReadBuffer(_Out_ std::deque>& ou _storage.pop_front(); } - ++virtualReadCount; - if (!unicode) - { - if (readEvents.back()->EventType() == InputEventType::KeyEvent) - { - const KeyEvent* const pKeyEvent = static_cast(readEvents.back().get()); - - if (!unicode) - { - // convert from wchar to char - std::wstring wstr{ pKeyEvent->GetCharData() }; - const auto str = ConvertToA(codepage, wstr); - if (str.size() > 1) - { - virtualReadCount += (str.size() - 1); - } - } - else - { - if (IsGlyphFullWidth(pKeyEvent->GetCharData())) - { - ++virtualReadCount; - } - } - } - } + virtualReadCount += sizeOfThisKey; } // the amount of events that were actually read diff --git a/src/host/ut_host/InputBufferTests.cpp b/src/host/ut_host/InputBufferTests.cpp index 950180918b..141f982240 100644 --- a/src/host/ut_host/InputBufferTests.cpp +++ b/src/host/ut_host/InputBufferTests.cpp @@ -441,6 +441,10 @@ class InputBufferTests resetWaitEvent, false, false); + + // TODO! I broke this test. This test expects 4 events to get read back, regardless of the fact that one would get expanded by ConvertToA. + // This might be okay, the test probably shouldn't be calling the private method directly. + // the dbcs record should have counted for two elements in // the array, making it so that we get less events read VERIFY_ARE_EQUAL(eventsRead, recordInsertCount - 1);