Compare commits

...

2 Commits

Author SHA1 Message Date
Michael Niksa
b0954c07de Try to try/catch it and make a macro to deal with the MB2WC's badness. 2020-02-04 14:20:09 -08:00
Michael Niksa
f31a3c1f74 Adapt the test. 2020-02-04 13:34:28 -08:00
4 changed files with 42 additions and 2 deletions

View File

@@ -303,6 +303,7 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
const size_t lengthToWrite,
const COORD startingCoordinate,
size_t& cellsModified) noexcept
try
{
const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
@@ -313,3 +314,4 @@ void WriteToScreen(SCREEN_INFORMATION& screenInfo, const Viewport& region)
return FillConsoleOutputCharacterWImpl(OutContext, wchs.at(0), lengthToWrite, startingCoordinate, cellsModified);
}
CATCH_RETURN()

View File

@@ -10,6 +10,24 @@ class FillOutputTests
BEGIN_TEST_CLASS(FillOutputTests)
END_TEST_CLASS()
// Adapted from repro in GH#4258
TEST_METHOD(FillWithInvalidCharacterA)
{
VERIFY_WIN32_BOOL_SUCCEEDED(SetConsoleOutputCP(50220));
auto handle = GetStdOutputHandle();
const COORD pos{ 0, 0 };
DWORD written = 0;
const char originalCh = 14;
VERIFY_WIN32_BOOL_SUCCEEDED(FillConsoleOutputCharacterA(handle, originalCh, 1, pos, &written));
VERIFY_ARE_EQUAL(1u, written);
char readCh = 42; // don't use null (the expected) or 14 (the actual) to ensure that it is read out.
DWORD read = 0;
VERIFY_WIN32_BOOL_SUCCEEDED(ReadConsoleOutputCharacterA(handle, &readCh, 1, pos, &read));
VERIFY_ARE_EQUAL(1u, read);
VERIFY_ARE_EQUAL(0, readCh, L"Null should be read back as the conversion from the invalid original character.");
}
TEST_METHOD(WriteNarrowGlyphAscii)
{
HANDLE hConsole = GetStdOutputHandle();

View File

@@ -34,3 +34,23 @@ namespace til // Terminal Implementation Library. Also: "Today I Learned"
LOG_CAUGHT_EXCEPTION(); \
return false; \
}
// MultiByteToWideChar has a bug in it where it can return 0 and then not set last error.
// WIL has a fit if the last error is 0 when a bool false is returned.
// This macro doesn't have a fit. It just reports E_UNEXPECTED instead.
#define THROW_LAST_ERROR_IF_AND_IGNORE_BAD_GLE(condition) \
do \
{ \
if (condition) \
{ \
const auto gle = ::GetLastError(); \
if (gle) \
{ \
THROW_WIN32(gle); \
} \
else \
{ \
THROW_HR(E_UNEXPECTED); \
} \
} \
} while (0, 0) \

View File

@@ -39,7 +39,7 @@ static const WORD leftShiftScanCode = 0x2A;
// Ask how much space we will need.
int const iTarget = MultiByteToWideChar(codePage, 0, source.data(), iSource, nullptr, 0);
THROW_LAST_ERROR_IF(0 == iTarget);
THROW_LAST_ERROR_IF_AND_IGNORE_BAD_GLE(0 == iTarget);
size_t cchNeeded;
THROW_IF_FAILED(IntToSizeT(iTarget, &cchNeeded));
@@ -49,7 +49,7 @@ static const WORD leftShiftScanCode = 0x2A;
out.resize(cchNeeded);
// Attempt conversion for real.
THROW_LAST_ERROR_IF(0 == MultiByteToWideChar(codePage, 0, source.data(), iSource, out.data(), iTarget));
THROW_LAST_ERROR_IF_AND_IGNORE_BAD_GLE(0 == MultiByteToWideChar(codePage, 0, source.data(), iSource, out.data(), iTarget));
// Return as a string
return out;