diff options
author | Ron Yorston <rmy@pobox.com> | 2019-03-19 11:15:13 +0000 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2019-03-19 11:15:13 +0000 |
commit | 8da63be147dd193420f29d864afc5806500f92e7 (patch) | |
tree | 25f38c55a5b8dcd23b99a71ba76a4f74fe4f3b6b | |
parent | d8043af0769250a480e324b51687fb2a994e3496 (diff) | |
download | busybox-w32-8da63be147dd193420f29d864afc5806500f92e7.tar.gz busybox-w32-8da63be147dd193420f29d864afc5806500f92e7.tar.bz2 busybox-w32-8da63be147dd193420f29d864afc5806500f92e7.zip |
winansi: more robust handling of invalid escape sequences
Commit 399b1dd64 (winansi: support escape sequence to set window
title) failed to handle some invalid escape sequences correctly.
Make the code more robust.
Fixes GitHub issue #153.
-rw-r--r-- | win32/winansi.c | 80 |
1 files changed, 46 insertions, 34 deletions
diff --git a/win32/winansi.c b/win32/winansi.c index 018b05c76..098b57c5d 100644 --- a/win32/winansi.c +++ b/win32/winansi.c | |||
@@ -213,12 +213,36 @@ static void move_cursor(int x, int y) | |||
213 | SetConsoleCursorPosition(console, pos); | 213 | SetConsoleCursorPosition(console, pos); |
214 | } | 214 | } |
215 | 215 | ||
216 | static const char *set_attr(const char *str) | 216 | /* On input pos points to the start of a suspected escape sequence. |
217 | * If a valid sequence is found return a pointer to the character | ||
218 | * following it, otherwise return the original pointer. */ | ||
219 | static char *process_escape(char *pos) | ||
217 | { | 220 | { |
218 | const char *func; | 221 | const char *str, *func; |
219 | size_t len = strspn(str, "0123456789;"); | 222 | char *bel; |
220 | func = str + len; | 223 | size_t len; |
224 | |||
225 | switch (pos[1]) { | ||
226 | case '[': | ||
227 | /* go ahead and process "\033[" sequence */ | ||
228 | break; | ||
229 | case ']': | ||
230 | if ((pos[2] == '0' || pos[2] == '2') && pos[3] == ';' && | ||
231 | (bel=strchr(pos+4, '\007')) && bel - pos < 260) { | ||
232 | /* set console title */ | ||
233 | *bel++ = '\0'; | ||
234 | CharToOem(pos+4, pos+4); | ||
235 | SetConsoleTitle(pos+4); | ||
236 | return bel; | ||
237 | } | ||
238 | /* invalid "\033]" sequence, fall through */ | ||
239 | default: | ||
240 | return pos; | ||
241 | } | ||
221 | 242 | ||
243 | str = pos + 2; | ||
244 | len = strspn(str, "0123456789;"); | ||
245 | func = str + len; | ||
222 | switch (*func) { | 246 | switch (*func) { |
223 | case 'm': | 247 | case 'm': |
224 | do { | 248 | do { |
@@ -344,7 +368,7 @@ static const char *set_attr(const char *str) | |||
344 | break; | 368 | break; |
345 | default: | 369 | default: |
346 | /* Unsupported code */ | 370 | /* Unsupported code */ |
347 | break; | 371 | return pos; |
348 | } | 372 | } |
349 | str++; | 373 | str++; |
350 | } while (*(str-1) == ';'); | 374 | } while (*(str-1) == ';'); |
@@ -391,10 +415,10 @@ static const char *set_attr(const char *str) | |||
391 | break; | 415 | break; |
392 | default: | 416 | default: |
393 | /* Unsupported code */ | 417 | /* Unsupported code */ |
394 | break; | 418 | return pos; |
395 | } | 419 | } |
396 | 420 | ||
397 | return func + 1; | 421 | return (char *)func + 1; |
398 | } | 422 | } |
399 | 423 | ||
400 | #if ENABLE_FEATURE_EURO | 424 | #if ENABLE_FEATURE_EURO |
@@ -465,28 +489,6 @@ static BOOL winansi_OemToCharBuff(LPCSTR s, LPSTR d, DWORD len) | |||
465 | # define OemToCharBuff winansi_OemToCharBuff | 489 | # define OemToCharBuff winansi_OemToCharBuff |
466 | #endif | 490 | #endif |
467 | 491 | ||
468 | static char *check_escapes(char *pos) | ||
469 | { | ||
470 | char *str = pos+1; | ||
471 | |||
472 | switch (pos[1]) { | ||
473 | case '[': | ||
474 | str = (char *)set_attr(pos+2); | ||
475 | break; | ||
476 | case ']': | ||
477 | if ((pos[2] == '0' || pos[2] == '2') && pos[3] == ';' && | ||
478 | (str=strchr(pos, '\007')) && str - pos < 260) { | ||
479 | *str = '\0'; | ||
480 | CharToOem(pos+4, pos+4); | ||
481 | SetConsoleTitle(pos+4); | ||
482 | ++str; | ||
483 | } | ||
484 | break; | ||
485 | } | ||
486 | |||
487 | return str; | ||
488 | } | ||
489 | |||
490 | static int ansi_emulate(const char *s, FILE *stream) | 492 | static int ansi_emulate(const char *s, FILE *stream) |
491 | { | 493 | { |
492 | int rv = 0; | 494 | int rv = 0; |
@@ -529,7 +531,7 @@ static int ansi_emulate(const char *s, FILE *stream) | |||
529 | size_t len = pos - str; | 531 | size_t len = pos - str; |
530 | 532 | ||
531 | if (len) { | 533 | if (len) { |
532 | *pos = '\0'; | 534 | *pos = '\0'; /* NB, '\033' has been overwritten */ |
533 | CharToOem(str, str); | 535 | CharToOem(str, str); |
534 | if (fputs(str, stream) == EOF) | 536 | if (fputs(str, stream) == EOF) |
535 | return EOF; | 537 | return EOF; |
@@ -539,8 +541,13 @@ static int ansi_emulate(const char *s, FILE *stream) | |||
539 | if (fflush(stream) == EOF) | 541 | if (fflush(stream) == EOF) |
540 | return EOF; | 542 | return EOF; |
541 | 543 | ||
542 | str = check_escapes(pos); | 544 | str = process_escape(pos); |
543 | rv += pos - str; | 545 | if (str == pos) { |
546 | if (fputc('\033', stream) == EOF) | ||
547 | return EOF; | ||
548 | ++str; | ||
549 | } | ||
550 | rv += str - pos; | ||
544 | pos = str; | 551 | pos = str; |
545 | 552 | ||
546 | if (fflush(stream) == EOF) | 553 | if (fflush(stream) == EOF) |
@@ -785,8 +792,13 @@ static int ansi_emulate_write(int fd, const void *buf, size_t count) | |||
785 | rv += out_len; | 792 | rv += out_len; |
786 | } | 793 | } |
787 | 794 | ||
788 | str = check_escapes(pos); | 795 | str = process_escape(pos); |
789 | rv += pos - str; | 796 | if (str == pos) { |
797 | if (write(fd, pos, 1) == -1) | ||
798 | return -1; | ||
799 | ++str; | ||
800 | } | ||
801 | rv += str - pos; | ||
790 | pos = str; | 802 | pos = str; |
791 | } else { | 803 | } else { |
792 | len = strlen(str); | 804 | len = strlen(str); |