Skip to content

Commit 084e352

Browse files
committed
[log_format] check that a format value name does not match one of the predefined names
1 parent e3a4454 commit 084e352

File tree

8 files changed

+98
-31
lines changed

8 files changed

+98
-31
lines changed

src/log_format.cc

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ const intern_string_t log_format::LOG_TIME_STR
7777
const intern_string_t log_format::LOG_LEVEL_STR
7878
= intern_string::lookup("log_level");
7979

80-
static const uint32_t DATE_TIME_SET_FLAGS = ETF_YEAR_SET | ETF_MONTH_SET
80+
static constexpr uint32_t DATE_TIME_SET_FLAGS = ETF_YEAR_SET | ETF_MONTH_SET
8181
| ETF_DAY_SET | ETF_HOUR_SET | ETF_MINUTE_SET | ETF_SECOND_SET;
8282

8383
log_level_stats&
@@ -1830,10 +1830,10 @@ external_log_format::annotate(logfile* lf,
18301830
logline_value_vector& values,
18311831
bool annotate_module) const
18321832
{
1833-
static thread_local auto md = lnav::pcre2pp::match_data::unitialized();
1833+
thread_local auto md = lnav::pcre2pp::match_data::unitialized();
18341834

18351835
auto& line = values.lvv_sbr;
1836-
struct line_range lr;
1836+
line_range lr;
18371837

18381838
line.erase_ansi();
18391839
if (this->elf_type != elf_type_t::ELF_TYPE_TEXT) {
@@ -1873,7 +1873,7 @@ external_log_format::annotate(logfile* lf,
18731873
values.lvv_values.reserve(this->elf_value_defs.size());
18741874

18751875
int pat_index = this->pattern_index_for_line(line_number);
1876-
auto& pat = *this->elf_pattern_order[pat_index];
1876+
const auto& pat = *this->elf_pattern_order[pat_index];
18771877

18781878
sa.reserve(pat.p_pcre.pp_value->get_capture_count());
18791879
auto match_res
@@ -1926,7 +1926,7 @@ external_log_format::annotate(logfile* lf,
19261926

19271927
for (size_t lpc = 0; lpc < pat.p_value_by_index.size(); lpc++) {
19281928
const indexed_value_def& ivd = pat.p_value_by_index[lpc];
1929-
const struct scaling_factor* scaling = nullptr;
1929+
const scaling_factor* scaling = nullptr;
19301930
auto cap = md[ivd.ivd_index];
19311931
const auto& vd = *ivd.ivd_value_def;
19321932

@@ -1938,7 +1938,7 @@ external_log_format::annotate(logfile* lf,
19381938
= intern_string::lookup(unit_cap.value());
19391939
auto unit_iter = vd.vd_unit_scaling.find(unit_val);
19401940
if (unit_iter != vd.vd_unit_scaling.end()) {
1941-
const struct scaling_factor& sf = unit_iter->second;
1941+
const auto& sf = unit_iter->second;
19421942

19431943
scaling = &sf;
19441944
}
@@ -3144,6 +3144,25 @@ external_log_format::build(std::vector<lnav::console::user_message>& errors)
31443144
for (auto& vd : this->elf_value_def_order) {
31453145
std::vector<std::string>::iterator act_iter;
31463146

3147+
if (log_vtab_impl::RESERVED_COLUMNS.count(
3148+
vd->vd_meta.lvm_name.to_string_fragment()))
3149+
{
3150+
auto um = lnav::console::user_message::error(
3151+
attr_line_t("value name ")
3152+
.append_quoted(lnav::roles::symbol(
3153+
fmt::format(FMT_STRING("/{}/value/{}"),
3154+
this->elf_name,
3155+
vd->vd_meta.lvm_name)))
3156+
.append(" is reserved and cannot be used"))
3157+
.with_reason(
3158+
"lnav automatically defines several columns in "
3159+
"the log virtual table")
3160+
.with_snippets(this->get_snippets())
3161+
.with_help("Choose another name")
3162+
.move();
3163+
errors.emplace_back(um);
3164+
}
3165+
31473166
vd->vd_meta.lvm_format = this;
31483167
if (!vd->vd_internal
31493168
&& !vd->vd_meta.lvm_column.is<logline_value_meta::table_column>())

src/log_vtab_impl.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,32 @@ static log_cursor log_cursor_latest;
5555

5656
thread_local _log_vtab_data log_vtab_data;
5757

58+
const std::unordered_set<string_fragment, frag_hasher>
59+
log_vtab_impl::RESERVED_COLUMNS = {
60+
string_fragment::from_const("log_line"),
61+
string_fragment::from_const("log_time"),
62+
string_fragment::from_const("log_level"),
63+
string_fragment::from_const("log_part"),
64+
string_fragment::from_const("log_actual_time"),
65+
string_fragment::from_const("log_idle_msecs"),
66+
string_fragment::from_const("log_mark"),
67+
string_fragment::from_const("log_comment"),
68+
string_fragment::from_const("log_tags"),
69+
string_fragment::from_const("log_annotations"),
70+
string_fragment::from_const("log_filters"),
71+
string_fragment::from_const("log_opid"),
72+
string_fragment::from_const("log_user_opid"),
73+
string_fragment::from_const("log_format"),
74+
string_fragment::from_const("log_format_regex"),
75+
string_fragment::from_const("log_time_msecs"),
76+
string_fragment::from_const("log_path"),
77+
string_fragment::from_const("log_unique_path"),
78+
string_fragment::from_const("log_text"),
79+
string_fragment::from_const("log_body"),
80+
string_fragment::from_const("log_raw_text"),
81+
string_fragment::from_const("log_line_hash"),
82+
};
83+
5884
static const char* LOG_COLUMNS = R"( (
5985
log_line INTEGER, -- The line number for the log message
6086
log_time DATETIME, -- The adjusted timestamp for the log message

src/log_vtab_impl.hh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <deque>
3434
#include <map>
3535
#include <string>
36+
#include <unordered_set>
3637
#include <vector>
3738

3839
#include <sqlite3.h>
@@ -258,6 +259,9 @@ const std::string LOG_TIME = "log_time";
258259

259260
class log_vtab_impl {
260261
public:
262+
static const std::unordered_set<string_fragment, frag_hasher>
263+
RESERVED_COLUMNS;
264+
261265
struct vtab_column {
262266
vtab_column(const std::string name = "",
263267
int type = SQLITE3_TEXT,

src/mapbox/variant.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,9 @@ struct variant_helper<T, Types...>
247247
{
248248
if (type_index == sizeof...(Types))
249249
{
250-
reinterpret_cast<T*>(data)->~T();
250+
if constexpr (sizeof(T) > 0) {
251+
reinterpret_cast<T*>(data)->~T();
252+
}
251253
}
252254
else
253255
{

src/string-extension-functions.cc

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -147,28 +147,31 @@ mapbox::util::
147147
throw std::runtime_error(err.get_message());
148148
}
149149

150-
yajlpp_gen gen;
151-
yajl_gen_config(gen, yajl_gen_beautify, false);
152-
153150
if (extractor.get_capture_count() == 1) {
154151
auto cap = md[1];
155152

156153
if (!cap) {
157154
return static_cast<const char*>(nullptr);
158155
}
159156

160-
auto scan_int_res = scn::scan_value<int64_t>(cap->to_string_view());
161-
if (scan_int_res && scan_int_res->range().empty()) {
162-
return scan_int_res->value();
163-
}
164-
165-
auto scan_float_res = scn::scan_value<double>(cap->to_string_view());
166-
if (scan_float_res && scan_float_res->range().empty()) {
167-
return scan_float_res->value();
157+
auto scan_int_res = scn::scan_int<int64_t>(cap->to_string_view());
158+
if (scan_int_res) {
159+
if (scan_int_res->range().empty()) {
160+
return scan_int_res->value();
161+
}
162+
auto scan_float_res
163+
= scn::scan_value<double>(cap->to_string_view());
164+
if (scan_float_res && scan_float_res->range().empty()) {
165+
return scan_float_res->value();
166+
}
168167
}
169168

170169
return cap.value();
171-
} else {
170+
}
171+
172+
yajlpp_gen gen;
173+
yajl_gen_config(gen, yajl_gen_beautify, false);
174+
{
172175
yajlpp_map root_map(gen);
173176

174177
for (size_t lpc = 0; lpc < extractor.get_capture_count(); lpc++) {

test/bad-config/formats/invalid-properties/format.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
"value": {
1818
"non-existent": {
1919
"kind": "string"
20+
},
21+
"log_level": {
22+
"kind": "string"
2023
}
2124
},
2225
"highlights": {

test/expected/test_format_loader.sh_5992e2695b7e6cf1f3520dbb87af8fc2b8f27088.err

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
 --> /invalid_props_log/tags/badtag3/pattern
3030
 | invalid(abc 
3131
 |  ^ missing closing parenthesis
32-
 --> {test_dir}/bad-config/formats/invalid-properties/format.json:36
32+
 --> {test_dir}/bad-config/formats/invalid-properties/format.json:39
3333
 |  "pattern": "invalid(abc"
3434
 = help: Property Synopsis
3535
/invalid_props_log/tags/badtag3/pattern <regex>
@@ -42,7 +42,7 @@
4242
 --> /invalid_props_log/search-table/bad_table_regex/pattern
4343
 | abc(def 
4444
 |  ^ missing closing parenthesis 
45-
 --> {test_dir}/bad-config/formats/invalid-properties/format.json:41
45+
 --> {test_dir}/bad-config/formats/invalid-properties/format.json:44
4646
 |  "pattern": "abc(def" 
4747
 = help: Property Synopsis
4848
/invalid_props_log/search-table/bad_table_regex/pattern <regex>
@@ -176,6 +176,16 @@
176176
 = note: the following captures are available:
177177
body, pid, timestamp
178178
 = help: values are populated from captures in patterns, so at least one pattern must have a capture with this value name
179+
✘ error: value name “/invalid_props_log/value/log_level” is reserved and cannot be used
180+
reason: lnav automatically defines several columns in the log virtual table
181+
 --> {test_dir}/bad-config/formats/invalid-properties/format.json:3
182+
 = help: Choose another name
183+
⚠ warning: invalid value “/invalid_props_log/value/log_level”
184+
reason: no patterns have a capture named “log_level”
185+
 --> {test_dir}/bad-config/formats/invalid-properties/format.json:3
186+
 = note: the following captures are available:
187+
body, pid, timestamp
188+
 = help: values are populated from captures in patterns, so at least one pattern must have a capture with this value name
179189
✘ error: invalid tag definition “/invalid_props_log/tags/badtag”
180190
reason: tag definitions must have a non-empty pattern
181191
 --> {test_dir}/bad-config/formats/invalid-properties/format.json:3
@@ -195,10 +205,10 @@
195205
body, pid, timestamp
196206
✘ error: “not a color” is not a valid color value for property “/invalid_props_log/highlights/hl1/color”
197207
reason: Unknown color: 'not a color'. See https://jonasjacek.github.io/colors/ for a list of supported color names
198-
 --> {test_dir}/bad-config/formats/invalid-properties/format.json:24
208+
 --> {test_dir}/bad-config/formats/invalid-properties/format.json:27
199209
✘ error: “also not a color” is not a valid color value for property “/invalid_props_log/highlights/hl1/background-color”
200210
reason: Unknown color: 'also not a color'. See https://jonasjacek.github.io/colors/ for a list of supported color names
201-
 --> {test_dir}/bad-config/formats/invalid-properties/format.json:25
211+
 --> {test_dir}/bad-config/formats/invalid-properties/format.json:28
202212
✘ error: “no_regexes_log” is not a valid log format
203213
reason: no regexes specified
204214
 --> {test_dir}/bad-config/formats/no-regexes/format.json:3
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
2013-06-06T19:13:20.123+00:00 I t0 log_vtab_impl.cc:576 vt_next at EOF (1000:1000:1), scanned rows 1
2-
2013-06-06T19:13:20.123+00:00 I t0 log_vtab_impl.cc:576 vt_next at EOF (996:996:1), scanned rows 1
3-
2013-06-06T19:13:20.123+00:00 I t0 log_vtab_impl.cc:576 vt_next at EOF (662:662:1), scanned rows 1
4-
2013-06-06T19:13:20.123+00:00 I t0 log_vtab_impl.cc:576 vt_next at EOF (-1:-1:-1), scanned rows 661
5-
2013-06-06T19:13:20.123+00:00 I t0 log_vtab_impl.cc:576 vt_next at EOF (999:999:1), scanned rows 1
6-
2013-06-06T19:13:20.123+00:00 I t0 log_vtab_impl.cc:576 vt_next at EOF (998:998:1), scanned rows 1
7-
2013-06-06T19:13:20.123+00:00 I t0 log_vtab_impl.cc:576 vt_next at EOF (997:997:1), scanned rows 1
8-
2013-06-06T19:13:20.123+00:00 I t0 log_vtab_impl.cc:576 vt_next at EOF (1000:1000:1), scanned rows 59
1+
2013-06-06T19:13:20.123+00:00 I t0 log_vtab_impl.cc:602 vt_next at EOF (1000:1000:1), scanned rows 1
2+
2013-06-06T19:13:20.123+00:00 I t0 log_vtab_impl.cc:602 vt_next at EOF (996:996:1), scanned rows 1
3+
2013-06-06T19:13:20.123+00:00 I t0 log_vtab_impl.cc:602 vt_next at EOF (662:662:1), scanned rows 1
4+
2013-06-06T19:13:20.123+00:00 I t0 log_vtab_impl.cc:602 vt_next at EOF (-1:-1:-1), scanned rows 661
5+
2013-06-06T19:13:20.123+00:00 I t0 log_vtab_impl.cc:602 vt_next at EOF (999:999:1), scanned rows 1
6+
2013-06-06T19:13:20.123+00:00 I t0 log_vtab_impl.cc:602 vt_next at EOF (998:998:1), scanned rows 1
7+
2013-06-06T19:13:20.123+00:00 I t0 log_vtab_impl.cc:602 vt_next at EOF (997:997:1), scanned rows 1
8+
2013-06-06T19:13:20.123+00:00 I t0 log_vtab_impl.cc:602 vt_next at EOF (1000:1000:1), scanned rows 59

0 commit comments

Comments
 (0)