From 50bd51c4d43931418c5b8c706841b46b67c1a947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Mon, 27 Jul 2020 16:43:41 +0200 Subject: [PATCH] tokenize: handle escaped quotes We only support escaping quotes inside a quote, and only of the same type as the enclosing quote. I.e. "double quote \"escaped double quote\"" But not "double quote \'invalid escaped single quote\'" --- CHANGELOG.md | 2 ++ tokenize.c | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4836891..764e8f46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ * [LICENSE](LICENSE), [README.md](README.md) and [CHANGELOG.md](CHANGELOG.md) are now installed to `${datadir}/doc/foot`. +* Support for escaping quotes in **pipe-visible** and + **pipe-scrollback** commands. ### Changed diff --git a/tokenize.c b/tokenize.c index 2671e23b..35d52345 100644 --- a/tokenize.c +++ b/tokenize.c @@ -38,10 +38,11 @@ tokenize_cmdline(char *cmdline, char ***argv) char delim = first_token_is_quoted ? cmdline[0] : ' '; char *p = first_token_is_quoted ? &cmdline[1] : &cmdline[0]; + char *search_start = p; size_t idx = 0; while (*p != '\0') { - char *end = strchr(p, delim); + char *end = strchr(search_start, delim); if (end == NULL) { if (delim != ' ') { LOG_ERR("unterminated %s quote", delim == '"' ? "double" : "single"); @@ -58,6 +59,15 @@ tokenize_cmdline(char *cmdline, char ***argv) return true; } + if (end > p && *(end - 1) == '\\') { + /* Escaped quote, remove one level of escaping and + * continue searching for "our" closing quote */ + memmove(end - 1, end, strlen(end)); + end[strlen(end) - 1] = '\0'; + search_start = end; + continue; + } + *end = '\0'; if (!push_argv(argv, &argv_size, p, &idx)) @@ -75,6 +85,7 @@ tokenize_cmdline(char *cmdline, char ***argv) p++; } else delim = ' '; + search_start = p; } if (!push_argv(argv, &argv_size, NULL, &idx))