From 0c111b1c6bacf952f08e7de388f1a8a81c29efea Mon Sep 17 00:00:00 2001 From: Mahmoud Al-Qudsi Date: Wed, 16 Nov 2022 14:10:01 -0600 Subject: [PATCH] Add comments to brace expansion --- src/common.cpp | 5 +++-- src/expand.cpp | 8 +++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/common.cpp b/src/common.cpp index 3cd4e6a94..baee97a62 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -1449,8 +1449,9 @@ static bool unescape_string_internal(const wchar_t *const input, const size_t in brace_count--; to_append_or_none = BRACE_END; if (!braces.empty()) { - // If we didn't have a var or separator since the last '{', - // put the literal back. + // HACK: To reduce accidental use of brace expansion, treat a brace + // with zero or one items as literal input. See #4632. (The hack is + // doing it here and like this.) if (vars_or_seps.empty() || vars_or_seps.back() < braces.back()) { result[braces.back()] = L'{'; // We also need to turn all spaces back. diff --git a/src/expand.cpp b/src/expand.cpp index a71a8b65a..02ceda44e 100644 --- a/src/expand.cpp +++ b/src/expand.cpp @@ -172,7 +172,7 @@ enum class parse_slice_error_t { static size_t parse_slice(const wchar_t *const in, wchar_t **const end_ptr, std::vector &idx, size_t array_size, parse_slice_error_t *const error) { const long size = static_cast(array_size); - size_t pos = 1; // skip past the opening square brace + size_t pos = 1; // skip past the opening square bracket *error = parse_slice_error_t::none; @@ -557,6 +557,7 @@ static expand_result_t expand_braces(wcstring &&instr, expand_flags_t flags, } if (brace_begin == nullptr) { + // No more brace expansions left; we can return the value as-is. if (!out->add(std::move(instr))) { return expand_result_t::error; } @@ -579,6 +580,11 @@ static expand_result_t expand_braces(wcstring &&instr, expand_flags_t flags, } } + // `whole_item` is a whitespace- and brace-stripped member of a single pass of brace + // expansion, e.g. in `{ alpha , b,{c, d }}`, `alpha`, `b`, and `c, d` will, in the + // first round of expansion, each in turn be a `whole_item` (with recursive commas + // replaced by special placeholders). + // We recursively call `expand_braces` with each item until it's been fully expanded. wcstring whole_item; whole_item.reserve(tot_len + item_len + 2); whole_item.append(in, length_preceding_braces);