From b5305ce3d3a460559d85f19914588604ad40b02b Mon Sep 17 00:00:00 2001 From: Fabian Homborg Date: Fri, 5 Feb 2021 22:00:31 +0100 Subject: [PATCH] Handle backslashes properly in locate_brackets_of_type This needs to be rewritten, I'm pretty sure we have like 6 of these kinds of ad-hoc "is this quoted" things lying around. But for now, at least don't just check if the *previous* character was a backslash. Fixes #7685. --- src/parse_util.cpp | 10 +++++++--- tests/checks/basic.fish | 4 ++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/parse_util.cpp b/src/parse_util.cpp index 32ad194f9..e3d085a8b 100644 --- a/src/parse_util.cpp +++ b/src/parse_util.cpp @@ -109,7 +109,7 @@ static int parse_util_locate_brackets_of_type(const wchar_t *in, wchar_t **begin wchar_t close_type) { // open_type is typically ( or [, and close type is the corresponding value. wchar_t *pos; - wchar_t prev = 0; + bool escaped = false; bool syntax_error = false; int paran_count = 0; @@ -118,7 +118,7 @@ static int parse_util_locate_brackets_of_type(const wchar_t *in, wchar_t **begin assert(in && "null parameter"); for (pos = const_cast(in); *pos; pos++) { - if (prev != '\\') { + if (!escaped) { if (std::wcschr(L"\'\"", *pos)) { wchar_t *q_end = quote_end(pos); if (q_end && *q_end) { @@ -148,7 +148,11 @@ static int parse_util_locate_brackets_of_type(const wchar_t *in, wchar_t **begin } } } - prev = *pos; + if (*pos == '\\') { + escaped = !escaped; + } else { + escaped = false; + } } syntax_error |= (paran_count < 0); diff --git a/tests/checks/basic.fish b/tests/checks/basic.fish index c16ab5d7e..6f8170701 100644 --- a/tests/checks/basic.fish +++ b/tests/checks/basic.fish @@ -484,3 +484,7 @@ echo '-n art' echo banana # CHECK: -n art # CHECK: banana + +# This used to be a parse error - #7685. +echo (echo hello\\) +# CHECK: hello\