[leak] fix leak of pcrepp object

This commit is contained in:
Tim Stack 2022-08-29 22:07:05 -07:00
parent 7a1ade581a
commit 1f24ab3074
4 changed files with 36 additions and 41 deletions

View File

@ -507,27 +507,21 @@ filter_sub_source::rl_perform(readline_curses* rc)
switch (tf->get_lang()) {
case filter_lang_t::NONE:
case filter_lang_t::REGEX: {
auto_mem<pcre> code;
const char* errptr;
int eoff;
auto compile_res = pcrepp::shared_from_str(
new_value, PCRE_CASELESS | PCRE_UTF8);
if ((code = pcre_compile(new_value.c_str(),
PCRE_CASELESS | PCRE_UTF8,
&errptr,
&eoff,
nullptr))
== nullptr)
{
if (compile_res.isErr()) {
auto ce = compile_res.unwrapErr();
auto um = lnav::console::user_message::error(
"invalid regular expression")
.with_reason(errptr)
.with_reason(ce.ce_msg)
.with_snippet(lnav::console::snippet::from(
INPUT_SRC, new_value));
um.um_snippets.back()
.s_content.append("\n")
.append(eoff, ' ')
.append(ce.ce_offset, ' ')
.append("^ "_comment)
.append(lnav::roles::comment(errptr));
.append(lnav::roles::comment(ce.ce_msg));
lnav_data.ld_exec_context.ec_error_callback_stack.back()(
um);
this->rl_abort(rc);
@ -535,10 +529,11 @@ filter_sub_source::rl_perform(readline_curses* rc)
tf->lf_deleted = true;
tss->text_filters_changed();
auto pf = std::make_shared<pcre_filter>(tf->get_type(),
new_value,
tf->get_index(),
code.release());
auto pf
= std::make_shared<pcre_filter>(tf->get_type(),
new_value,
tf->get_index(),
compile_res.unwrap());
*iter = pf;
tss->text_filters_changed();

View File

@ -1814,7 +1814,7 @@ com_filter(exec_context& ec,
return ec.make_error("too many filters");
}
auto pf = std::make_shared<pcre_filter>(
lt, args[1], *filter_index, compile_res.unwrap()->release());
lt, args[1], *filter_index, compile_res.unwrap());
log_debug("%s [%d] %s",
args[0].c_str(),

View File

@ -82,7 +82,10 @@ public:
class pcre_filter : public text_filter {
public:
pcre_filter(type_t type, const std::string& id, size_t index, pcre* code)
pcre_filter(type_t type,
const std::string& id,
size_t index,
std::shared_ptr<pcrepp> code)
: text_filter(type, filter_lang_t::REGEX, id, index), pf_pcre(code)
{
}
@ -96,7 +99,7 @@ public:
pcre_context_static<30> pc;
pcre_input pi(line.get_data(), 0, line.length());
return this->pf_pcre.match(pc, pi);
return this->pf_pcre->match(pc, pi);
}
std::string to_command() const override
@ -107,7 +110,7 @@ public:
}
protected:
pcrepp pf_pcre;
std::shared_ptr<pcrepp> pf_pcre;
};
class sql_filter : public text_filter {

View File

@ -97,30 +97,29 @@ struct from_sqlite<filter_lang_t> {
};
template<>
struct from_sqlite<std::pair<std::string, auto_mem<pcre>>> {
inline std::pair<std::string, auto_mem<pcre>> operator()(
int argc, sqlite3_value** val, int argi)
struct from_sqlite<std::shared_ptr<pcrepp>> {
inline std::shared_ptr<pcrepp> operator()(int argc,
sqlite3_value** val,
int argi)
{
const char* pattern = (const char*) sqlite3_value_text(val[argi]);
const char* errptr;
auto_mem<pcre> code;
int eoff;
if (pattern == nullptr || pattern[0] == '\0') {
throw sqlite_func_error("Expecting a non-empty pattern value");
}
code = pcre_compile(
pattern, PCRE_CASELESS | PCRE_UTF8, &errptr, &eoff, nullptr);
auto compile_res
= pcrepp::shared_from_str(pattern, PCRE_CASELESS | PCRE_UTF8);
if (code == nullptr) {
if (compile_res.isErr()) {
auto ce = compile_res.unwrapErr();
throw sqlite_func_error(
"Invalid regular expression for pattern: {} at offset {}",
errptr,
eoff);
ce.ce_msg,
ce.ce_offset);
}
return std::make_pair(std::string(pattern), std::move(code));
return compile_res.unwrap();
}
};
@ -684,14 +683,13 @@ CREATE TABLE lnav_view_filters (
std::shared_ptr<text_filter> tf;
switch (lang.value_or(filter_lang_t::REGEX)) {
case filter_lang_t::REGEX: {
auto pattern
= from_sqlite<std::pair<std::string, auto_mem<pcre>>>()(
1, &pattern_str, 0);
auto pattern = from_sqlite<std::shared_ptr<pcrepp>>()(
1, &pattern_str, 0);
auto pf = std::make_shared<pcre_filter>(
type.value_or(text_filter::type_t::EXCLUDE),
pattern.first,
pattern->get_pattern(),
*filter_index,
pattern.second.release());
pattern);
auto new_cmd = pf->to_command();
for (auto& filter : fs) {
if (filter->to_command() == new_cmd) {
@ -877,10 +875,9 @@ CREATE TABLE lnav_view_filters (
tss->text_filters_changed();
auto pattern
= from_sqlite<std::pair<std::string, auto_mem<pcre>>>()(
1, &pattern_val, 0);
= from_sqlite<std::shared_ptr<pcrepp>>()(1, &pattern_val, 0);
auto pf = std::make_shared<pcre_filter>(
type, pattern.first, tf->get_index(), pattern.second.release());
type, pattern->get_pattern(), tf->get_index(), pattern);
auto conflict_mode = sqlite3_vtab_on_conflict(mod_vt->v_db);
auto new_cmd = pf->to_command();
for (auto& filter : fs) {