aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2019-03-19 11:15:13 +0000
committerRon Yorston <rmy@pobox.com>2019-03-19 11:15:13 +0000
commit8da63be147dd193420f29d864afc5806500f92e7 (patch)
tree25f38c55a5b8dcd23b99a71ba76a4f74fe4f3b6b
parentd8043af0769250a480e324b51687fb2a994e3496 (diff)
downloadbusybox-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.c80
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
216static 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. */
219static 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
468static 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
490static int ansi_emulate(const char *s, FILE *stream) 492static 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);