From 6d8891894ebdfdadab6b6878dac604aacf6b0df9 Mon Sep 17 00:00:00 2001 From: shdown Date: Wed, 25 Mar 2015 21:30:38 +0300 Subject: [PATCH 1/2] Allow escaping backslashes Fixes #1577. --- i3bar/src/xcb.c | 4 ++-- src/commands_parser.c | 13 +++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/i3bar/src/xcb.c b/i3bar/src/xcb.c index 3360485a..c9f8e6cb 100644 --- a/i3bar/src/xcb.c +++ b/i3bar/src/xcb.c @@ -489,7 +489,7 @@ void handle_button(xcb_button_press_event_t *event) { size_t namelen = 0; const char *utf8_name = cur_ws->canonical_name; for (const char *walk = utf8_name; *walk != '\0'; walk++) { - if (*walk == '"') + if (*walk == '"' || *walk == '\\') num_quotes++; /* While we’re looping through the name anyway, we can save one * strlen(). */ @@ -503,7 +503,7 @@ void handle_button(xcb_button_press_event_t *event) { for (inpos = 0, outpos = strlen("workspace \""); inpos < namelen; inpos++, outpos++) { - if (utf8_name[inpos] == '"') { + if (utf8_name[inpos] == '"' || utf8_name[inpos] == '\\') { buffer[outpos] = '\\'; outpos++; } diff --git a/src/commands_parser.c b/src/commands_parser.c index f325a048..fa4c2360 100644 --- a/src/commands_parser.c +++ b/src/commands_parser.c @@ -216,8 +216,9 @@ char *parse_string(const char **walk, bool as_word) { if (**walk == '"') { beginning++; (*walk)++; - while (**walk != '\0' && (**walk != '"' || *(*walk - 1) == '\\')) - (*walk)++; + for (; **walk != '\0' && **walk != '"'; (*walk)++) + if (**walk == '\\' && *(*walk + 1) != '\0') + (*walk)++; } else { if (!as_word) { /* For a string (starting with 's'), the delimiters are @@ -248,10 +249,10 @@ char *parse_string(const char **walk, bool as_word) { for (inpos = 0, outpos = 0; inpos < (*walk - beginning); inpos++, outpos++) { - /* We only handle escaped double quotes to not break - * backwards compatibility with people using \w in - * regular expressions etc. */ - if (beginning[inpos] == '\\' && beginning[inpos + 1] == '"') + /* We only handle escaped double quotes and backslashes to not break + * backwards compatibility with people using \w in regular expressions + * etc. */ + if (beginning[inpos] == '\\' && (beginning[inpos + 1] == '"' || beginning[inpos + 1] == '\\')) inpos++; str[outpos] = beginning[inpos]; } From 4e871c75f9b3ed4fd91cf534bac218a339f313ea Mon Sep 17 00:00:00 2001 From: shdown Date: Wed, 25 Mar 2015 22:55:26 +0300 Subject: [PATCH 2/2] Add tests for backslash unescaping --- testcases/t/187-commands-parser.t | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/testcases/t/187-commands-parser.t b/testcases/t/187-commands-parser.t index 5ee94f87..6d67731a 100644 --- a/testcases/t/187-commands-parser.t +++ b/testcases/t/187-commands-parser.t @@ -156,7 +156,7 @@ is(parser_calls('move something to somewhere'), 'error for unknown literal ok'); ################################################################################ -# 3: Verify that escaping of double quotes works correctly +# 3: Verify that escaping works correctly ################################################################################ is(parser_calls('workspace "foo"'), @@ -171,6 +171,18 @@ is(parser_calls('workspace "foo \"bar"'), 'cmd_workspace_name(foo "bar)', 'Command with escaped double quotes ok'); +is(parser_calls('workspace "foo \\'), + 'cmd_workspace_name(foo \\)', + 'Command with single backslash in the end ok'); + +is(parser_calls('workspace "foo\\\\bar"'), + 'cmd_workspace_name(foo\\bar)', + 'Command with escaped backslashes ok'); + +is(parser_calls('workspace "foo\\\\\\"bar"'), + 'cmd_workspace_name(foo\\"bar)', + 'Command with escaped double quotes after escaped backslashes ok'); + ################################################################################ # 4: Verify that resize commands with a "px or ppt"-construction are parsed # correctly