diff options
author | Karen Arutyunov <karen@codesynthesis.com> | 2019-09-17 16:00:20 +0300 |
---|---|---|
committer | Karen Arutyunov <karen@codesynthesis.com> | 2019-09-19 17:46:46 +0300 |
commit | 6e84c0f9c5e4d7d98d2a352eec6bc19de0d75d28 (patch) | |
tree | aa022efe5a906e6f0272b823c7829cdfe3e39eb8 /libbuild2/test/script/parser.cxx | |
parent | 8c30c59de2d304a416dfd4fcb821e0b227e5db96 (diff) |
Fix crashing on testscript command redirect overrides
Diffstat (limited to 'libbuild2/test/script/parser.cxx')
-rw-r--r-- | libbuild2/test/script/parser.cxx | 47 |
1 files changed, 44 insertions, 3 deletions
diff --git a/libbuild2/test/script/parser.cxx b/libbuild2/test/script/parser.cxx index 8b8f705..bc06ce8 100644 --- a/libbuild2/test/script/parser.cxx +++ b/libbuild2/test/script/parser.cxx @@ -1657,7 +1657,7 @@ namespace build2 // Parse the redirect operator. // auto parse_redirect = - [&c, &expr, &p, &mod, this] (token& t, const location& l) + [&c, &expr, &p, &mod, &hd, this] (token& t, const location& l) { // Our semantics is the last redirect seen takes effect. // @@ -1774,6 +1774,8 @@ namespace build2 } redirect& r (fd == 0 ? c.in : fd == 1 ? c.out : c.err); + redirect_type overriden (r.type); + r = redirect (rt); // Don't move as still may be used for pending here-document end @@ -1848,6 +1850,37 @@ namespace build2 case redirect_type::here_doc_ref: assert (false); break; } + + // If we are overriding a here-document, then remove the reference + // to this command redirect from the corresponding here_doc object. + // + if (!pre_parse_ && + (overriden == redirect_type::here_doc_literal || + overriden == redirect_type::here_doc_regex)) + { + size_t e (expr.size () - 1); + size_t p (expr.back ().pipe.size ()); + int f (static_cast<int> (fd)); + + for (here_doc& d: hd) + { + small_vector<here_redirect, 2>& rs (d.redirects); + + auto i (find_if (rs.begin (), rs.end (), + [e, p, f] (const here_redirect& r) + { + return r.expr == e && + r.pipe == p && + r.fd == f; + })); + + if (i != rs.end ()) + { + rs.erase (i); + break; + } + } + } }; // Set pending cleanup type. @@ -2483,9 +2516,11 @@ namespace build2 parsed_doc v ( parse_here_document (t, tt, h.end, h.modifiers, h.regex)); - if (!pre_parse_) + // If all the here-document redirects are overridden, then we just + // drop the fragment. + // + if (!pre_parse_ && !h.redirects.empty ()) { - assert (!h.redirects.empty ()); auto i (h.redirects.cbegin ()); command& c (p.first[i->expr].pipe[i->pipe]); @@ -2493,11 +2528,17 @@ namespace build2 if (v.re) { + assert (r.type == redirect_type::here_doc_regex); + r.regex = move (v.regex); r.regex.flags = move (h.regex_flags); } else + { + assert (r.type == redirect_type::here_doc_literal); + r.str = move (v.str); + } r.end = move (h.end); r.end_line = v.end_line; |