diff options
| author | Ron Yorston <rmy@pobox.com> | 2021-03-05 12:48:06 +0000 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2021-03-05 12:48:06 +0000 |
| commit | dfa16f84deb0bf0d1f1cc8d223f695b2f971fc40 (patch) | |
| tree | 4aaa042a72fe85c0722763fccc1cb5e3347c5025 | |
| parent | b4506956a5703ae2df062ec307d76ac935be0258 (diff) | |
| download | busybox-w32-dfa16f84deb0bf0d1f1cc8d223f695b2f971fc40.tar.gz busybox-w32-dfa16f84deb0bf0d1f1cc8d223f695b2f971fc40.tar.bz2 busybox-w32-dfa16f84deb0bf0d1f1cc8d223f695b2f971fc40.zip | |
winansi: fix ansi emulation
The following commands (reported in GitHub issue #201):
printf "\033[38;2;255;0;0mX\033[m\n"
printf "\033[38;2;255;0;0m;\033[m\n"
produce different results. The first correctly displays a red 'X'
while the second incorrectly displays a white ';'.
The problem is that process_24bit() overruns the extent of the
escape sequence. As a result the loop in process_escape() which
handles 'ESC[...m' sequences sees the ';' in the text as a
continuation of the escape sequence.
Fix this by:
- reworking process_24bit() so that the overrun is avoided;
- changing the test in the loop in process_escape() so that even
if an overrun happens it stops processing at the end of the escape
sequence.
Also, save a few bytes by replacing '++str' with 'str + 1' in a
few places.
| -rw-r--r-- | win32/winansi.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/win32/winansi.c b/win32/winansi.c index 971702f18..68b568b81 100644 --- a/win32/winansi.c +++ b/win32/winansi.c | |||
| @@ -375,17 +375,18 @@ static WORD rgb_to_console(int *rgb) | |||
| 375 | /* 24-bit colour */ | 375 | /* 24-bit colour */ |
| 376 | static char *process_24bit(char *str, WORD *attr) | 376 | static char *process_24bit(char *str, WORD *attr) |
| 377 | { | 377 | { |
| 378 | int count = 0; | 378 | int count; |
| 379 | int rgb[3] = {0, 0, 0}; | 379 | int rgb[3]; |
| 380 | 380 | ||
| 381 | do { | 381 | for (count = 0; count < 3; ++count) { |
| 382 | rgb[count++] = strtol(str, (char **)&str, 10); | 382 | rgb[count] = strtol(str, (char **)&str, 10); |
| 383 | ++str; | 383 | if (*str == ';') |
| 384 | } while (*(str-1) == ';' && count < 3); | 384 | ++str; |
| 385 | } | ||
| 385 | 386 | ||
| 386 | *attr = rgb_to_console(rgb); | 387 | *attr = rgb_to_console(rgb); |
| 387 | 388 | ||
| 388 | return str; | 389 | return *(str - 1) == ';' ? str - 1 : str; |
| 389 | } | 390 | } |
| 390 | 391 | ||
| 391 | /* 8-bit colour */ | 392 | /* 8-bit colour */ |
| @@ -435,10 +436,10 @@ static char *process_colour(char *str, WORD *attr) | |||
| 435 | *attr = -1; /* error return */ | 436 | *attr = -1; /* error return */ |
| 436 | switch (val) { | 437 | switch (val) { |
| 437 | case 2: | 438 | case 2: |
| 438 | str = process_24bit(++str, attr); | 439 | str = process_24bit(str + 1, attr); |
| 439 | break; | 440 | break; |
| 440 | case 5: | 441 | case 5: |
| 441 | str = process_8bit(++str, attr); | 442 | str = process_8bit(str + 1, attr); |
| 442 | break; | 443 | break; |
| 443 | default: | 444 | default: |
| 444 | break; | 445 | break; |
| @@ -541,7 +542,7 @@ static char *process_escape(char *pos) | |||
| 541 | attr |= colour_1bit[val - 30]; | 542 | attr |= colour_1bit[val - 30]; |
| 542 | break; | 543 | break; |
| 543 | case 38: /* 8/24 bit */ | 544 | case 38: /* 8/24 bit */ |
| 544 | str = process_colour(++str, &t); | 545 | str = process_colour(str + 1, &t); |
| 545 | if (t != -1) { | 546 | if (t != -1) { |
| 546 | attr &= ~(FOREGROUND_ALL|FOREGROUND_INTENSITY); | 547 | attr &= ~(FOREGROUND_ALL|FOREGROUND_INTENSITY); |
| 547 | attr |= t; | 548 | attr |= t; |
| @@ -565,7 +566,7 @@ static char *process_escape(char *pos) | |||
| 565 | attr |= colour_1bit[val - 40] << 4; | 566 | attr |= colour_1bit[val - 40] << 4; |
| 566 | break; | 567 | break; |
| 567 | case 48: /* 8/24 bit */ | 568 | case 48: /* 8/24 bit */ |
| 568 | str = process_colour(++str, &t); | 569 | str = process_colour(str + 1, &t); |
| 569 | if (t != -1) { | 570 | if (t != -1) { |
| 570 | attr &= ~(BACKGROUND_ALL|BACKGROUND_INTENSITY); | 571 | attr &= ~(BACKGROUND_ALL|BACKGROUND_INTENSITY); |
| 571 | attr |= t << 4; | 572 | attr |= t << 4; |
| @@ -581,7 +582,7 @@ static char *process_escape(char *pos) | |||
| 581 | return pos; | 582 | return pos; |
| 582 | } | 583 | } |
| 583 | str++; | 584 | str++; |
| 584 | } while (*(str-1) == ';'); | 585 | } while (str < func); |
| 585 | 586 | ||
| 586 | current_attr = attr; | 587 | current_attr = attr; |
| 587 | if (reverse) | 588 | if (reverse) |
