diff options
| author | Maxime Coste <mawww@kakoune.org> | 2017-02-19 12:08:13 +0000 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2017-02-19 12:08:13 +0000 |
| commit | 889a2144d44218e8c03a25f8de8ee423e904b318 (patch) | |
| tree | b253c980379e70b7142a3ff539bdfe531529805e /src | |
| parent | 38102595efcf34b1c5ab4eabd961afa8b858cd01 (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')
| -rw-r--r-- | src/hook_manager.cc | 17 |
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())); } } |
