While testing some Windows CUI app (hiew.exe from bug #54141), it appears that some console API allow to write all the possible control characters onto the console. This serie: - add tests for read/write test of these - fix 'unix' console to not send some of the control characters to the underlying tty, which would reinterpret them. This leads to unwanted display (ie hexdump of a file would insert real cr/lf when displaying dump of \r\n")
From: Eric Pouech eric.pouech@gmail.com
WriteConsole (not in processed mode) and WriteConsoleOutput* functions allow to write control characters, which can then be read back as is.
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/kernel32/tests/console.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+)
diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c index 1f285faf1e2..f8e39c164d2 100644 --- a/dlls/kernel32/tests/console.c +++ b/dlls/kernel32/tests/console.c @@ -306,6 +306,7 @@ static void testWriteNotWrappedNotProcessed(HANDLE hCon, COORD sbSize) DWORD len, mode; const char* mytest = "123"; const int mylen = strlen(mytest); + char ctrl_buf[32]; int ret; int p;
@@ -336,6 +337,17 @@ static void testWriteNotWrappedNotProcessed(HANDLE hCon, COORD sbSize) ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left-3\n");
ok(WriteConsoleA(hCon, mytest, mylen, &len, NULL) != 0 && len == mylen, "WriteConsole\n"); + + /* test how control chars are handled. */ + c.X = c.Y = 0; + ok(SetConsoleCursorPosition(hCon, c) != 0, "Cursor in upper-left-3\n"); + for (p = 0; p < 32; p++) ctrl_buf[p] = (char)p; + ok(WriteConsoleA(hCon, ctrl_buf, 32, &len, NULL) != 0 && len == 32, "WriteConsole\n"); + for (p = 0; p < 32; p++) + { + c.X = p; c.Y = 0; + okCHAR(hCon, c, (char)p, TEST_ATTRIB); + } }
static void testWriteNotWrappedProcessed(HANDLE hCon, COORD sbSize) @@ -2378,6 +2390,19 @@ static void test_WriteConsoleOutputCharacterA(HANDLE output_handle) ret = WriteConsoleOutputCharacterA(output_handle, output, 0, origin, &count); ok(ret == TRUE, "Expected WriteConsoleOutputCharacterA to return TRUE, got %d\n", ret); ok(count == 0, "Expected count to be 0, got %lu\n", count); + + for (i = 1; i < 32; i++) + { + CONSOLE_SCREEN_BUFFER_INFO csbi; + char ch = (char)i; + COORD c = {1, 2}; + + ret = WriteConsoleOutputCharacterA(output_handle, &ch, 1, c, &count); + ok(ret == TRUE, "Expected WriteConsoleOutputCharacterA to return TRUE, got %d\n", ret); + ok(count == 1, "Expected count to be 1, got %lu\n", count); + okCHAR(output_handle, c, (char)i, 7); + ret = GetConsoleScreenBufferInfo(output_handle, &csbi); + } }
static void test_WriteConsoleOutputCharacterW(HANDLE output_handle)
From: Eric Pouech eric.pouech@gmail.com
They will be reinterpreted by Unix tty, leading to wrong display.
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- programs/conhost/conhost.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c index c3a106c9321..769f998f404 100644 --- a/programs/conhost/conhost.c +++ b/programs/conhost/conhost.c @@ -358,6 +358,8 @@ static void update_output( struct screen_buffer *screen_buffer, RECT *rect ) int x, y, size, trailing_spaces; char_info_t *ch; char buf[8]; + WCHAR wch; + const unsigned int mask = (1u << '\0') | (1u << '\b') | (1u << '\t') | (1u << '\n') | (1u << '\a') | (1u << '\r');
if (!is_active( screen_buffer ) || rect->top > rect->bottom || rect->right < rect->left) return; @@ -393,9 +395,11 @@ static void update_output( struct screen_buffer *screen_buffer, RECT *rect ) tty_write( screen_buffer->console, "\x1b[K", 3 ); break; } - + wch = ch->ch; + if (screen_buffer->console->is_unix && wch < L' ' && mask & (1u << wch)) + wch = L'?'; size = WideCharToMultiByte( get_tty_cp( screen_buffer->console ), 0, - &ch->ch, 1, buf, sizeof(buf), NULL, NULL ); + &wch, 1, buf, sizeof(buf), NULL, NULL ); tty_write( screen_buffer->console, buf, size ); screen_buffer->console->tty_cursor_x++; }
FWIW, I think it's weird that it's not handled similarly by MS for pseudo-consoles, they will be broken in this case. Anyway, testing conforms that, so I guess we need to do that only for Unix consoles.
This merge request was approved by Jacek Caban.
On Tue Dec 20 14:31:28 2022 +0000, Jacek Caban wrote:
FWIW, I think it's weird that it's not handled similarly by MS for pseudo-consoles, they will be broken in this case. Anyway, testing conforms that, so I guess we need to do that only for Unix consoles.
yes for pseudo consoles, see https://github.com/microsoft/terminal/issues/4363