WriteCharsLegacy: Accumulated bugs #14708

Closed
opened 2026-01-31 04:17:26 +00:00 by claunia · 2 comments
Owner

Originally created by @DHowett on GitHub (Jul 27, 2021).

Originally assigned to: @DHowett, @lhecker on GitHub.

Inserting a tab character that would put us at the right edge of the buffer inserts two tabs (one to get us to the right edge of the buffer, one more after we wrap)

Code and example
#include <windows.h>
int main() {
        CONSOLE_SCREEN_BUFFER_INFOEX csbiex{};
        csbiex.cbSize = sizeof(csbiex);
        GetConsoleScreenBufferInfoEx(GetStdHandle(STD_OUTPUT_HANDLE), &csbiex);
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), COORD{(SHORT)(csbiex.dwSize.X - 9), csbiex.dwCursorPosition.Y});
        WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"|\t|\n", 4, nullptr, nullptr);
        return 0;
}

image

Inserting a printable control character at the right edge of the screen (ala ^A) when only the ^ would fit emits a ^ and a space.

Example

image
(here, ^D)

Inserting a printable control character (^D) at the right edge of the screen when both ^ and D fit and then backspacing it deletes the ^, not the D:

Example

image

Originally created by @DHowett on GitHub (Jul 27, 2021). Originally assigned to: @DHowett, @lhecker on GitHub. Inserting a tab character that would put us at the right edge of the buffer inserts two tabs (one to get us to the right edge of the buffer, one more after we wrap) <details> <summary>Code and example</summary> ```c++ #include <windows.h> int main() { CONSOLE_SCREEN_BUFFER_INFOEX csbiex{}; csbiex.cbSize = sizeof(csbiex); GetConsoleScreenBufferInfoEx(GetStdHandle(STD_OUTPUT_HANDLE), &csbiex); SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), COORD{(SHORT)(csbiex.dwSize.X - 9), csbiex.dwCursorPosition.Y}); WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), L"|\t|\n", 4, nullptr, nullptr); return 0; } ``` ![image](https://user-images.githubusercontent.com/189190/127206696-16a6dd41-37f7-43d7-892a-621856b57b57.png) </details> Inserting a printable control character at the right edge of the screen (ala `^A`) when only the `^` would fit emits a `^` and a space. <details> <summary>Example</summary> ![image](https://user-images.githubusercontent.com/189190/127206882-e0d6bd1b-b866-4e85-abf6-60f6ea0bf81f.png) (here, `^D`) </details> Inserting a printable control character (`^D`) at the right edge of the screen when both `^` and `D` fit and then backspacing it deletes the `^`, not the `D`: <details> <summary>Example</summary> ![image](https://user-images.githubusercontent.com/189190/127206980-661c5abe-d1ce-4e46-b134-7a8191506507.png) </details>
claunia added the Product-ConhostArea-OutputIssue-BugIn-PRImpact-Correctness labels 2026-01-31 04:17:27 +00:00
Author
Owner

@DHowett commented on GitHub (Jul 27, 2021):

Tab bug: the measurer "eats" the space before it decides that the Tab does not fit. The bulk text inserter then uses the estimated position (which was consumed by the tab we aborted inserting) to move the cursor. Then when WCL loops back around to insert the tab on the next line it measures back out at 8 characters and inserts it again.

@DHowett commented on GitHub (Jul 27, 2021): Tab bug: the measurer "eats" the space before it decides that the Tab does not fit. The bulk text inserter then uses the _estimated_ position (which was consumed by the tab we aborted inserting) to move the cursor. Then when WCL loops back around to insert the tab on the next line it measures back out at 8 characters and inserts it again.
Author
Owner

@DHowett commented on GitHub (Jul 27, 2021):

Control char bug 1: WCL does not consider a printable control char to take up 2 spaces when it is trying to fit it up against the edge of the screen. Correct behavior: treat ^D as two characters and push the whole sequence down to the next line, or print ^ and D on separate lines and be sure to delete them both.

@DHowett commented on GitHub (Jul 27, 2021): Control char bug 1: WCL does not consider a printable control char to take up 2 spaces when it is trying to fit it up against the edge of the screen. Correct behavior: treat `^D` as two characters and push the whole sequence down to the next line, or print `^` and `D` on separate lines and be sure to delete them both.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/terminal#14708