aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/script
diff options
context:
space:
mode:
authorKaren Arutyunov <karen@codesynthesis.com>2021-06-03 12:48:56 +0300
committerKaren Arutyunov <karen@codesynthesis.com>2021-06-03 14:24:25 +0300
commite3a05597ec42ed02230918fe0bcada3dbb521209 (patch)
treef4733d7c153ceb43ba4280eec9474c1bc4f70d23 /libbuild2/script
parent73a64baac30f5c478201e9f86dc4dd5ef85f0192 (diff)
Fix crashing on test command output regex match failure
Diffstat (limited to 'libbuild2/script')
-rw-r--r--libbuild2/script/run.cxx58
1 files 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.
//