From: Thomas Csovcsity <thc.fr13nd@gmail.com> Remove Control Sequence Introducer(CSI) commands avoids console scrambling --- dlls/kernel32/tests/console.c | 6 ++-- programs/conhost/conhost.c | 56 +++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c index c3fa141ee44..8ced7f1ad7e 100644 --- a/dlls/kernel32/tests/console.c +++ b/dlls/kernel32/tests/console.c @@ -5744,16 +5744,14 @@ static void test_ANSI_escape_sequences(void) ok(ret, "GetConsoleScreenBufferInfo failed\n"); ok(sb_info.dwCursorPosition.X == 5 + 3, "Incorrect X cursor position\n"); ok(sb_info.dwCursorPosition.Y == 0, "Incorrect X cursor position\n"); - ok(sb_info.wAttributes == (FOREGROUND_RED | FOREGROUND_INTENSITY), "Unexpected attributes got %x, expected %x\n", sb_info.wAttributes, FOREGROUND_RED | FOREGROUND_INTENSITY); + todo_wine ok(sb_info.wAttributes == (FOREGROUND_RED | FOREGROUND_INTENSITY), "Unexpected attributes got %x, expected %x\n", sb_info.wAttributes, FOREGROUND_RED | FOREGROUND_INTENSITY); ret = SetConsoleTextAttribute(hConOut, FOREGROUND_BLUE | FOREGROUND_INTENSITY); ret = WriteConsoleW(hConOut, L"BLUE\x1b[m", 4+3, &dw, NULL); ok(dw == 4+3, "Wrong count\n"); ret = GetConsoleScreenBufferInfo(hConOut, &sb_info); ok(sb_info.dwCursorPosition.X == 5 + 3 + 4, "Incorrect X cursor position\n"); ok(sb_info.dwCursorPosition.Y == 0, "Incorrect X cursor position\n"); - ok(sb_info.wAttributes == (FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN), "Unexpected attributes: got %x, expected %x\n", sb_info.wAttributes, FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN); - /* TODO should call ReadConsoleOutput to check that the colors are correct (they are visually) */ - /* could test more sequences */ + todo_wine ok(sb_info.wAttributes == (FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN), "Unexpected attributes: got %x, expected %x\n", sb_info.wAttributes, FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN); CloseHandle(hConOut); FreeConsole(); diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c index 8298743553f..c472fff9c29 100644 --- a/programs/conhost/conhost.c +++ b/programs/conhost/conhost.c @@ -2107,6 +2107,9 @@ static NTSTATUS write_console( struct screen_buffer *screen_buffer, const WCHAR { RECT update_rect; size_t i, j; + enum { + ST_START, ST_PARAM, ST_INTER, ST_FINAL + } state; TRACE( "%s\n", debugstr_wn(buffer, len) ); @@ -2143,6 +2146,59 @@ static NTSTATUS write_console( struct screen_buffer *screen_buffer, const WCHAR case '\r': screen_buffer->cursor_x = 0; continue; + case '\e': + if ((screen_buffer->mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING)) + { + if (buffer[i+1] == '[') + { + FIXME( "CSI sequences not supported fully yet, only skipping control sequences!\n" ); + state = ST_PARAM; + i+=2; + } + else + { + ERR("Invalid CSI start sequence\n"); + break; + } + /* intermediate bytes 0x30 - 0x3f (0-?) */ + for (; i<len && (state == ST_PARAM); i++) + { + if (buffer[i] >= 0x30 && buffer[i] <= 0x3b) + continue; + else if (buffer[i] >= 0x3c && buffer[i] <= 0x3f) + { + WARN( "This is a private -terminal manufacturer only- CSI sequence\n" ); + continue; + } + else + { + state = ST_INTER; + break; + } + } + /* intermediate bytes 0x20 - 0x2f*/ + for (; i<len && (state == ST_INTER || state == ST_PARAM); i++) + { + if (buffer[i] >= 0x20 && buffer[i] <= 0x2f) + continue; + else + { + state = ST_FINAL; + break; + } + } + if (state == ST_START || state == ST_FINAL) + { + if (buffer[i] >= 0x70 && buffer[i] <= 0x7e) + WARN("This is a private -terminal manufacturer only- CSI sequence\n"); + else if (!(buffer[i] >= 0x40 && buffer[i] <= 0x6f)) + ERR("This was no valid CSI sequence\n"); + } + } + else + WARN( "ENABLE_VIRTUAL_TERMINAL_PROCESSING is disabled\n" ); + + continue; } } if (screen_buffer->cursor_x == screen_buffer->width && !(screen_buffer->mode & ENABLE_WRAP_AT_EOL_OUTPUT)) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9973