IL esape sequence doesn't work correctly in non-active buffer #16430

Closed
opened 2026-01-31 05:10:31 +00:00 by claunia · 1 comment
Owner

Originally created by @j4james on GitHub (Jan 18, 2022).

Windows Terminal version

1.12.3472.0

Windows build number

10.0.19041.1415

Other Software

No response

Steps to reproduce

Run the following C++ test case in Windows Terminal or conhost.

#include <windows.h>
#include <conio.h>
#include <string>

int main() {
  // Get the handle of the main buffer, and also create a second buffer.
  HANDLE buff1 = GetStdHandle(STD_OUTPUT_HANDLE);
  HANDLE buff2 = CreateConsoleScreenBuffer(GENERIC_READ|GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);

  // Enable VT processing.
  DWORD dwMode = 0;
  GetConsoleMode(buff1, &dwMode);
  dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
  SetConsoleMode(buff1, dwMode);

  DWORD written;
  std::wstring s;

  // Write some content in the main buffer.
  s = L"\033[2J\033[HMain Buffer";
  WriteConsoleW(buff1, s.data(), s.length(), &written, NULL);
  getch();

  // Write some content in the second buffer and then make it the active buffer.
  s = L"\033[2J\033[HSecond Buffer";
  WriteConsoleW(buff2, s.data(), s.length(), &written, NULL);
  SetConsoleActiveScreenBuffer(buff2);
  getch();

  // Insert 10 lines at the top of the main buffer.
  s = L"\033[H\033[10L";
  WriteConsoleW(buff1, s.data(), s.length(), &written, NULL);
  getch();

  // Close the second buffer so the main buffer is active again.
  CloseHandle(buff2);

  return 0;
}

Expected Behavior

The sample above opens two screen buffers, and while the second one is active, sends an IL escape sequence to the handle of the first buffer. This should have no effect on the second buffer, but you should see 10 lines inserted at the top of the page when you switch back to the main buffer.

Actual Behavior

The 10 lines are inserted at the top of the second buffer, and no change is visible in the main buffer.

The source of the bug is the DoSrvPrivateModifyLinesImpl implementation, which handles both the IL and DL escape sequences:
62c95b5017/src/host/getset.cpp (L1857-L1859)

Note that it's obtaining the screenInfo from the global console information, and thus has no knowledge of the handle that initiated the operation.

I'm currently working on some refactoring of the conhost code which will fix this, but I just wanted to make a note of the issue in case I end up abandoning that work.

Originally created by @j4james on GitHub (Jan 18, 2022). ### Windows Terminal version 1.12.3472.0 ### Windows build number 10.0.19041.1415 ### Other Software _No response_ ### Steps to reproduce Run the following C++ test case in Windows Terminal or conhost. ```cpp #include <windows.h> #include <conio.h> #include <string> int main() { // Get the handle of the main buffer, and also create a second buffer. HANDLE buff1 = GetStdHandle(STD_OUTPUT_HANDLE); HANDLE buff2 = CreateConsoleScreenBuffer(GENERIC_READ|GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); // Enable VT processing. DWORD dwMode = 0; GetConsoleMode(buff1, &dwMode); dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; SetConsoleMode(buff1, dwMode); DWORD written; std::wstring s; // Write some content in the main buffer. s = L"\033[2J\033[HMain Buffer"; WriteConsoleW(buff1, s.data(), s.length(), &written, NULL); getch(); // Write some content in the second buffer and then make it the active buffer. s = L"\033[2J\033[HSecond Buffer"; WriteConsoleW(buff2, s.data(), s.length(), &written, NULL); SetConsoleActiveScreenBuffer(buff2); getch(); // Insert 10 lines at the top of the main buffer. s = L"\033[H\033[10L"; WriteConsoleW(buff1, s.data(), s.length(), &written, NULL); getch(); // Close the second buffer so the main buffer is active again. CloseHandle(buff2); return 0; } ``` ### Expected Behavior The sample above opens two screen buffers, and while the second one is active, sends an `IL` escape sequence to the handle of the first buffer. This should have no effect on the second buffer, but you should see 10 lines inserted at the top of the page when you switch back to the main buffer. ### Actual Behavior The 10 lines are inserted at the top of the second buffer, and no change is visible in the main buffer. The source of the bug is the `DoSrvPrivateModifyLinesImpl` implementation, which handles both the `IL` and `DL` escape sequences: https://github.com/microsoft/terminal/blob/62c95b5017e92a780cdc43008e30b4e43d2edc9b/src/host/getset.cpp#L1857-L1859 Note that it's obtaining the `screenInfo` from the global console information, and thus has no knowledge of the handle that initiated the operation. I'm currently working on some refactoring of the conhost code which will fix this, but I just wanted to make a note of the issue in case I end up abandoning that work.
Author
Owner

@ghost commented on GitHub (May 24, 2022):

:tada:This issue was addressed in #12247, which has now been successfully released as Windows Terminal Preview v1.14.143.🎉

Handy links:

@ghost commented on GitHub (May 24, 2022): :tada:This issue was addressed in #12247, which has now been successfully released as `Windows Terminal Preview v1.14.143`.:tada: Handy links: * [Release Notes](https://github.com/microsoft/terminal/releases/tag/v1.14.143) * [Store Download](https://www.microsoft.com/store/apps/9n8g5rfz9xk3?cid=storebadge&ocid=badge)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#16430