From 35ba97cbdf52027e3d2f76f24ab4ac034685f098 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Wed, 30 Jul 2014 11:32:24 -0700 Subject: [PATCH] Fix up OSC / iTerm2 escape code parsing as part of #1565 --- fish_tests.cpp | 10 ++++---- screen.cpp | 63 ++++++++++---------------------------------------- 2 files changed, 16 insertions(+), 57 deletions(-) diff --git a/fish_tests.cpp b/fish_tests.cpp index 4e26cb85b..08ab8477c 100644 --- a/fish_tests.cpp +++ b/fish_tests.cpp @@ -1211,12 +1211,10 @@ static void test_escape_sequences(void) if (escape_code_length(L"\x1b@") != 2) err(L"test_escape_sequences failed on line %d\n", __LINE__); // iTerm2 escape sequences - if (escape_code_length(L"\x1b]50;CurrentDir=/tmp/foo\x07NOT_PART_OF_SEQUENCE") != 24) err(L"test_escape_sequences failed on line %d\n", __LINE__); - if (escape_code_length(L"\x1b]50;SetMark\x07NOT_PART_OF_SEQUENCE") != 12) err(L"test_escape_sequences failed on line %d\n", __LINE__); - if (escape_code_length(L"\x1b" L"]6;1;bg;red;brightness;255\x07NOT_PART_OF_SEQUENCE") != 27) err(L"test_escape_sequences failed on line %d\n", __LINE__); - if (escape_code_length(L"\x1b]Pg4040ff\x1b\\NOT_PART_OF_SEQUENCE") != 10) err(L"test_escape_sequences failed on line %d\n", __LINE__); - - // OSC codes + if (escape_code_length(L"\x1b]50;CurrentDir=/tmp/foo\x07NOT_PART_OF_SEQUENCE") != 25) err(L"test_escape_sequences failed on line %d\n", __LINE__); + if (escape_code_length(L"\x1b]50;SetMark\x07NOT_PART_OF_SEQUENCE") != 13) err(L"test_escape_sequences failed on line %d\n", __LINE__); + if (escape_code_length(L"\x1b" L"]6;1;bg;red;brightness;255\x07NOT_PART_OF_SEQUENCE") != 28) err(L"test_escape_sequences failed on line %d\n", __LINE__); + if (escape_code_length(L"\x1b]Pg4040ff\x1b\\NOT_PART_OF_SEQUENCE") != 12) err(L"test_escape_sequences failed on line %d\n", __LINE__); if (escape_code_length(L"\x1b]blahblahblah\x1b\\") != 16) err(L"test_escape_sequences failed on line %d\n", __LINE__); if (escape_code_length(L"\x1b]blahblahblah\x07") != 15) err(L"test_escape_sequences failed on line %d\n", __LINE__); } diff --git a/screen.cpp b/screen.cpp index d7bbae5c0..9f1cc6e4d 100644 --- a/screen.cpp +++ b/screen.cpp @@ -255,26 +255,23 @@ size_t escape_code_length(const wchar_t *code) if (! found) { - /* iTerm2 escape codes: CSI followed by ], terminated by either BEL or - see https://code.google.com/p/iterm2/wiki/ProprietaryEscapeCodes */ + /* iTerm2 escape codes: CSI followed by ], terminated by either BEL or escape + backslash. See https://code.google.com/p/iterm2/wiki/ProprietaryEscapeCodes */ if (code[1] == ']') { - /* A sequence of characters terminated by either 'ESC backslash' or BEL */ - const wchar_t * const end1_sentinel = L"\x1b\\"; - const wchar_t * const end2_sentinel = L"\a"; - const wchar_t *end1 = wcsstr(&code[2], end1_sentinel); - const wchar_t *end2 = wcsstr(&code[2], end2_sentinel); - - // Use the non-null end, or if both are null, use the earlier end - const wchar_t *end = end1; - if (end == NULL || (end2 != NULL && end2 < end)) + // Start at 2 to skip over ] + size_t cursor = 2; + for (; code[cursor] != L'\0'; cursor++) { - end = end2; + /* Consume a sequence of characters up to \ or */ + if (code[cursor] == '\x07' || (code[cursor] == '\\' && code[cursor - 1] == '\x1b')) + { + found = true; + break; + } } - if (end != NULL) + if (found) { - assert(end > code); - resulting_length = (end - code); - found = true; + resulting_length = cursor + 1; } } } @@ -318,42 +315,6 @@ size_t escape_code_length(const wchar_t *code) } } if (! found) - { - /* OSC code, terminated by \ or */ - if (code[1] == L']') - { - // Start at 2 to skip over ] - size_t cursor = 2; - bool backslash_ends = false; - for (; code[cursor] != L'\0'; cursor++) - { - /* Consume a sequence of characters up to \ or */ - wchar_t c = code[cursor]; - if (c == L'\x1b') { - backslash_ends = true; - } - else if (c == L'\\' && backslash_ends) - { - found = true; - break; - } - else - { - backslash_ends = false; - } - - if (c == L'\x07') { - found = true; - break; - } - } - if (found) - { - resulting_length = cursor + 1; - } - } - } - if (! found) { /* Generic VT100 two byte sequence: followed by something in the range @ through _ */ if (code[1] >= L'@' && code[1] <= L'_')