From d8c51656d7d391f5cec0c1c920fe9bf39b798333 Mon Sep 17 00:00:00 2001 From: Martin Stein Date: Fri, 30 Jun 2023 11:48:16 +0200 Subject: [PATCH] depot_autopilot: forward tabs and color sequences The Depot Autopilot used to filter out tabs and color sequences before forwarding the test log to the own log. This commit prevents this and further cleans up the string-filters code. Ref #4922 --- repos/gems/src/app/depot_autopilot/child.cc | 166 ++++++++++---------- repos/gems/src/app/depot_autopilot/main.cc | 2 + 2 files changed, 89 insertions(+), 79 deletions(-) diff --git a/repos/gems/src/app/depot_autopilot/child.cc b/repos/gems/src/app/depot_autopilot/child.cc index 60a5039a46..721436fcb7 100644 --- a/repos/gems/src/app/depot_autopilot/child.cc +++ b/repos/gems/src/app/depot_autopilot/child.cc @@ -53,65 +53,76 @@ template struct Filters { Filter array[NR_OF_FILTERS]; + + Filter const *filter_to_apply(char const *curr, + char const *end) + { + for (Filter const &flt : array) { + char const *keyword_end { curr + flt.keyword_size() }; + if (keyword_end < curr || keyword_end > end) { + continue; + } + if (memcmp(curr, flt.keyword(), flt.keyword_size()) != 0) { + continue; + } + return &flt; + } + return nullptr; + } + + size_t apply_to(char *const base, + size_t size) + { + struct Bad_filter : Exception { }; + char const *end { base + size }; + for (char *curr { base }; curr < end; ) { + Filter const *flt { filter_to_apply(curr, end) }; + if (!flt) { + curr++; + continue; + } + if (flt->replacement_size() > flt->keyword_size()) { + throw Bad_filter(); + } + memcpy(curr, flt->replacement(), flt->replacement_size()); + if (flt->replacement_size() < flt->keyword_size()) { + char *const replacement_end { curr + flt->replacement_size() }; + char const *const keyword_end { curr + flt->keyword_size() }; + memmove(replacement_end, keyword_end, (size_t)(end - keyword_end)); + } + curr += flt->replacement_size(); + size -= flt->keyword_size() - flt->replacement_size(); + end = base + size; + } + return size; + } }; -template -static Filter const *filter_to_apply(FILTERS const &filters, - char const *curr, - char const *end) +static Filters<6> pattern_filters { - for (Filter const &flt : filters.array) { - char const *keyword_end { curr + flt.keyword_size() }; - if (keyword_end < curr || keyword_end > end) { - continue; - } - if (memcmp(curr, flt.keyword(), flt.keyword_size()) != 0) { - continue; - } - return &flt; - } - return 0; -} - - -static size_t sanitize_pattern(char *const base, - size_t size) -{ - static Filters<6> pattern_filters { - { - { "\x9", "" }, - { "\xa", "" }, - { "<", "<" }, - { "&", "&" }, - { "*", "*" }, - { """, "\"" } - } - }; - struct Bad_filter : Exception { }; - char const *end { base + size }; - for (char *curr { base }; curr < end; ) { - Filter const *flt { filter_to_apply(pattern_filters, curr, end) }; - if (!flt) { - curr++; - continue; - } - if (flt->replacement_size() > flt->keyword_size()) { - throw Bad_filter(); - } - memcpy(curr, flt->replacement(), flt->replacement_size()); - if (flt->replacement_size() < flt->keyword_size()) { - char *const replacement_end { curr + flt->replacement_size() }; - char const *const keyword_end { curr + flt->keyword_size() }; - memmove(replacement_end, keyword_end, (size_t)(end - keyword_end)); - } - curr += flt->replacement_size(); - size -= flt->keyword_size() - flt->replacement_size(); - end = base + size; + { "\x9", "" }, + { "\xa", "" }, + { "<", "<" }, + { "&", "&" }, + { "*", "*" }, + { """, "\"" } } - return size; -} +}; + + +static Filters<6> log_matching_filters +{ + { + { "\x9", "" }, + { "\x1b[0m", "" }, + { "\x1b[31m", "" }, + { "\x1b[32m", "" }, + { "\x1b[33m", "" }, + { "\x1b[34m", "" } + } +}; static void forward_to_log(uint64_t const sec, @@ -157,21 +168,15 @@ static void c_string_append(char * &dst, } -static size_t sanitize_log(char *dst, - size_t const dst_sz, - Log_session::String const &str, - Session_label const &label) +static size_t sanitize_log_for_output(char *dst, + size_t const dst_sz, + Log_session::String const &str, + Session_label const &label) { - static Filters<7> log_filters + static Filters<1> filters { { - { "\x9", "" }, - { "\xa", "" }, - { "\x1b[0m", "" }, - { "\x1b[31m", "" }, - { "\x1b[32m", "" }, - { "\x1b[33m", "" }, - { "\x1b[34m", "" } + { "\xa", "" } } }; /* first, write the label prefix to the buffer */ @@ -186,7 +191,7 @@ static size_t sanitize_log(char *dst, char const *src_copied { str.string() }; char const *src_end { str.string() + str.size() }; for (; src_curr < src_end; ) { - Filter const *const flt { filter_to_apply(log_filters, src_curr, src_end) }; + Filter const *const flt { filters.filter_to_apply(src_curr, src_end) }; if (!flt) { src_curr++; continue; @@ -630,9 +635,20 @@ size_t Child::log_session_write(Log_session::String const &str, /* max log string size + max label size + size of label framing "[ ]" */ enum { LOG_BUF_SZ = Log_session::MAX_STRING_LEN + 160 + 3 }; - char log_buf[LOG_BUF_SZ]; - size_t const log_len { sanitize_log(log_buf, LOG_BUF_SZ, str, label) }; - Log_event const *matching_event { nullptr }; + char log_buf[LOG_BUF_SZ]; + size_t log_len { sanitize_log_for_output(log_buf, LOG_BUF_SZ, str, label) }; + + /* calculate timestamp */ + uint64_t const time_us { _timer.curr_time().trunc_to_plain_us().value - init_time_us }; + uint64_t time_ms { time_us / 1000UL }; + uint64_t const time_sec { time_ms / 1000UL }; + time_ms = time_ms - time_sec * 1000UL; + + /* forward timestamp and sanitized string to back-end log session */ + forward_to_log(time_sec, time_ms, log_buf, log_buf + log_len); + + log_len = log_matching_filters.apply_to(log_buf, log_len); + Log_event const *matching_event { nullptr }; _log.append(log_buf, log_len); _log_events.for_each([&] (Log_event &log_event) { @@ -643,14 +659,6 @@ size_t Child::log_session_write(Log_session::String const &str, matching_event = &log_event; } }); - /* calculate timestamp */ - uint64_t const time_us { _timer.curr_time().trunc_to_plain_us().value - init_time_us }; - uint64_t time_ms { time_us / 1000UL }; - uint64_t const time_sec { time_ms / 1000UL }; - time_ms = time_ms - time_sec * 1000UL; - - /* forward timestamp and sanitized string to back-end log session */ - forward_to_log(time_sec, time_ms, log_buf, log_buf + log_len); /* handle a matching log event */ if (matching_event) { @@ -1093,7 +1101,7 @@ Log_event::Plain_string::Plain_string(Allocator &alloc, _size { size } { memcpy(_base, base, size); - _size = sanitize_pattern(_base, _size); + _size = pattern_filters.apply_to(_base, _size); } @@ -1123,7 +1131,7 @@ Log_prefix Log_event::_init_log_prefix(Xml_node const &xml) size_t const cpy_size = min(src_size, sizeof(buf) - 1); memcpy(buf, src_ptr, cpy_size); buf[cpy_size] = 0; - buf_str_size = sanitize_pattern(buf, cpy_size + 1); + buf_str_size = pattern_filters.apply_to(buf, cpy_size + 1); }); return Cstring { buf, buf_str_size }; } diff --git a/repos/gems/src/app/depot_autopilot/main.cc b/repos/gems/src/app/depot_autopilot/main.cc index 33da2bd625..9b0faf15c3 100644 --- a/repos/gems/src/app/depot_autopilot/main.cc +++ b/repos/gems/src/app/depot_autopilot/main.cc @@ -242,6 +242,8 @@ struct Depot_deploy::Main void Component::construct(Genode::Env &env) { + /* see log_*_filters and pattern_filters in child.cc */ + env.exec_static_constructors(); static Depot_deploy::Main main(env); }