Fix up OSC / iTerm2 escape code parsing as part of #1565

This commit is contained in:
ridiculousfish 2014-07-30 11:32:24 -07:00
parent 9f59cf1468
commit 35ba97cbdf
2 changed files with 16 additions and 57 deletions

View file

@ -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__); if (escape_code_length(L"\x1b@") != 2) err(L"test_escape_sequences failed on line %d\n", __LINE__);
// iTerm2 escape sequences // 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;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") != 12) 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") != 27) 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") != 10) 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__);
// OSC codes
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\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__); if (escape_code_length(L"\x1b]blahblahblah\x07") != 15) err(L"test_escape_sequences failed on line %d\n", __LINE__);
} }

View file

@ -255,26 +255,23 @@ size_t escape_code_length(const wchar_t *code)
if (! found) 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] == ']') if (code[1] == ']')
{ {
/* A sequence of characters terminated by either 'ESC backslash' or BEL */ // Start at 2 to skip over <esc>]
const wchar_t * const end1_sentinel = L"\x1b\\"; size_t cursor = 2;
const wchar_t * const end2_sentinel = L"\a"; for (; code[cursor] != L'\0'; cursor++)
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))
{ {
end = end2; /* Consume a sequence of characters up to <esc>\ or <bel> */
} if (code[cursor] == '\x07' || (code[cursor] == '\\' && code[cursor - 1] == '\x1b'))
if (end != NULL)
{ {
assert(end > code);
resulting_length = (end - code);
found = true; found = true;
break;
}
}
if (found)
{
resulting_length = cursor + 1;
} }
} }
} }
@ -318,42 +315,6 @@ size_t escape_code_length(const wchar_t *code)
} }
} }
if (! found) if (! found)
{
/* OSC code, terminated by <esc>\ or <bel> */
if (code[1] == L']')
{
// Start at 2 to skip over <esc>]
size_t cursor = 2;
bool backslash_ends = false;
for (; code[cursor] != L'\0'; cursor++)
{
/* Consume a sequence of characters up to <esc>\ or <bel> */
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: <esc> followed by something in the range @ through _ */ /* Generic VT100 two byte sequence: <esc> followed by something in the range @ through _ */
if (code[1] >= L'@' && code[1] <= L'_') if (code[1] >= L'@' && code[1] <= L'_')