From e3a05597ec42ed02230918fe0bcada3dbb521209 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 3 Jun 2021 12:48:56 +0300 Subject: Fix crashing on test command output regex match failure --- libbuild2/script/run.cxx | 58 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/libbuild2/script/run.cxx b/libbuild2/script/run.cxx index f36e979..46941734 100644 --- a/libbuild2/script/run.cxx +++ b/libbuild2/script/run.cxx @@ -644,33 +644,45 @@ namespace build2 } } - // Create line regex. + // Issue regex error diagnostics and fail. // - line_regex regex; - - try - { - regex = line_regex (move (rls), move (pool)); - } - catch (const regex_error& e) + auto fail_regex = [&rl, &rd, &loc, &env, &output_info, &save_regex] + (const regex_error& e, const string& what) { - // Note that line regex creation can not fail for here-string - // redirect as it doesn't have syntax line chars. That in - // particular means that end_line and end_column are meaningful. + const auto& ls (rl.lines); + + // Note that the parser treats both empty here-string (for example + // >:~'') and empty here-document redirects as an error and so there + // should be at least one line in the list. // - assert (rd.type == redirect_type::here_doc_regex); + assert (!ls.empty ()); - diag_record d (fail (loc (rd.end_line, rd.end_column))); + diag_record d (fail (rd.type == redirect_type::here_doc_regex + ? loc (rd.end_line, rd.end_column) + : loc (ls[0].line, ls[0].column))); // Print regex_error description if meaningful. // - d << "invalid " << what << " regex redirect" << e; + d << what << " regex redirect" << e; // It would be a waste to save the regex into the file just to // remove it. // if (env.temp_dir_keep) output_info (d, save_regex (), "", " regex"); + }; + + // Create line regex. + // + line_regex regex; + + try + { + regex = line_regex (move (rls), move (pool)); + } + catch (const regex_error& e) + { + fail_regex (e, string ("invalid ") + what); } // Parse the output into the literal line string. @@ -720,8 +732,22 @@ namespace build2 // Match the output with the regex. // - if (regex_match (ls, regex)) // Doesn't throw. - return true; + // Note that we don't distinguish between the line_regex and + // char_regex match failures. While it would be convenient for the + // user if we provide additional information in the latter case (regex + // line number, etc), the implementation feels too hairy for now + // (would require to pull additional information into char_regex, + // etc). Though, we may want to implement it in the future. + // + try + { + if (regex_match (ls, regex)) + return true; + } + catch (const regex_error& e) + { + fail_regex (e, string ("unable to match ") + what); + } // Output doesn't match the regex. // -- cgit v1.1