summaryrefslogtreecommitdiff
path: root/src/hook_manager.cc
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2017-02-19 12:08:13 +0000
committerMaxime Coste <mawww@kakoune.org>2017-02-19 12:08:13 +0000
commit889a2144d44218e8c03a25f8de8ee423e904b318 (patch)
treeb253c980379e70b7142a3ff539bdfe531529805e /src/hook_manager.cc
parent38102595efcf34b1c5ab4eabd961afa8b858cd01 (diff)
Copy the list of hooks to run before iterating on them and running them
Running hooks could result in the hook list getting mutated, leading to potential crashes. Fixes #1222
Diffstat (limited to 'src/hook_manager.cc')
-rw-r--r--src/hook_manager.cc17
1 files changed, 10 insertions, 7 deletions
diff --git a/src/hook_manager.cc b/src/hook_manager.cc
index 067b35ae..6c336af2 100644
--- a/src/hook_manager.cc
+++ b/src/hook_manager.cc
@@ -68,25 +68,28 @@ void HookManager::run_hook(StringView hook_name,
auto start_time = profile ? Clock::now() : TimePoint{};
auto& disabled_hooks = context.options()["disabled_hooks"].get<Regex>();
- bool hook_error = false;
+ Vector<std::pair<String, HookFunc>> hooks_to_run;
for (auto& hook : hook_list_it->value)
{
- if (not hook.key.empty() and not disabled_hooks.empty() and
+ if (hook.key.empty() or disabled_hooks.empty() or
regex_match(hook.key.begin(), hook.key.end(), disabled_hooks))
- continue;
+ hooks_to_run.push_back({hook.key, hook.value});
+ }
+ bool hook_error = false;
+ for (auto& hook : hooks_to_run)
+ {
try
{
if (debug_flags & DebugFlags::Hooks)
- write_to_debug_buffer(format("hook {}/{}", hook_name, hook.key));
-
- hook.value(param, context);
+ write_to_debug_buffer(format("hook {}/{}", hook_name, hook.first));
+ hook.second(param, context);
}
catch (runtime_error& err)
{
hook_error = true;
write_to_debug_buffer(format("error running hook {}({})/{}: {}",
- hook_name, param, hook.key, err.what()));
+ hook_name, param, hook.first, err.what()));
}
}