Merge remote-tracking branch 'krobelus/fix-unmap-uaf'

This commit is contained in:
Maxime Coste 2023-05-29 20:10:50 +10:00
commit 3069b68245
9 changed files with 29 additions and 10 deletions

View File

@ -1933,10 +1933,15 @@ const CommandDesc unmap_key_cmd = {
if (key.size() != 1) if (key.size() != 1)
throw runtime_error("only a single key can be unmapped"); throw runtime_error("only a single key can be unmapped");
if (keymaps.is_mapped(key[0], keymap_mode) and if (not keymaps.is_mapped(key[0], keymap_mode))
(parser.positional_count() < 4 or return;
(keymaps.get_mapping(key[0], keymap_mode).keys == auto& mapping = keymaps.get_mapping(key[0], keymap_mode);
parse_keys(parser[3]))))
if (mapping.is_executing)
throw runtime_error("cannot unmap key that is currently executing");
if (parser.positional_count() < 4 or
(mapping.keys == parse_keys(parser[3])))
keymaps.unmap_key(key[0], keymap_mode); keymaps.unmap_key(key[0], keymap_mode);
} }
}; };
@ -2653,8 +2658,12 @@ void enter_user_mode(Context& context, String mode_name, KeymapMode mode, bool l
InputHandler::ScopedForceNormal force_normal{context.input_handler(), {}}; InputHandler::ScopedForceNormal force_normal{context.input_handler(), {}};
ScopedEdition edition(context); ScopedEdition edition(context);
{
ScopedSetBool executing_mapping{mapping.is_executing};
for (auto& key : mapping.keys) for (auto& key : mapping.keys)
context.input_handler().handle_key(key); context.input_handler().handle_key(key);
}
if (lock) if (lock)
enter_user_mode(context, std::move(mode_name), mode, true); enter_user_mode(context, std::move(mode_name), mode, true);

View File

@ -1773,7 +1773,10 @@ void InputHandler::handle_key(Key key)
if (keymaps.is_mapped(key, keymap_mode) and not m_context.keymaps_disabled()) if (keymaps.is_mapped(key, keymap_mode) and not m_context.keymaps_disabled())
{ {
ScopedSetBool disable_history{context().history_disabled()}; ScopedSetBool disable_history{context().history_disabled()};
for (auto& k : keymaps.get_mapping(key, keymap_mode).keys)
auto& mapping = keymaps.get_mapping(key, keymap_mode);
ScopedSetBool executing_mapping{mapping.is_executing};
for (auto& k : mapping.keys)
process_key(k); process_key(k);
} }
else else

View File

@ -40,8 +40,8 @@ bool KeymapManager::is_mapped(Key key, KeymapMode mode) const
(m_parent and m_parent->is_mapped(key, mode)); (m_parent and m_parent->is_mapped(key, mode));
} }
const KeymapManager::KeymapInfo& KeymapManager::KeymapInfo&
KeymapManager::get_mapping(Key key, KeymapMode mode) const KeymapManager::get_mapping(Key key, KeymapMode mode)
{ {
auto it = m_mapping.find(KeyAndMode{key, mode}); auto it = m_mapping.find(KeyAndMode{key, mode});
if (it != m_mapping.end()) if (it != m_mapping.end())

View File

@ -6,6 +6,7 @@
#include "hash.hh" #include "hash.hh"
#include "string.hh" #include "string.hh"
#include "hash_map.hh" #include "hash_map.hh"
#include "utils.hh"
#include "vector.hh" #include "vector.hh"
namespace Kakoune namespace Kakoune
@ -42,8 +43,9 @@ public:
{ {
KeyList keys; KeyList keys;
String docstring; String docstring;
NestedBool is_executing{};
}; };
const KeymapInfo& get_mapping(Key key, KeymapMode mode) const; KeymapInfo& get_mapping(Key key, KeymapMode mode);
using UserModeList = Vector<String>; using UserModeList = Vector<String>;
UserModeList& user_modes() { UserModeList& user_modes() {

View File

@ -2033,6 +2033,7 @@ void exec_user_mappings(Context& context, NormalParams params)
ScopedEdition edition(context); ScopedEdition edition(context);
ScopedSelectionEdition selection_edition{context}; ScopedSelectionEdition selection_edition{context};
ScopedSetBool executing_mapping{mapping.is_executing};
for (auto& key : mapping.keys) for (auto& key : mapping.keys)
context.input_handler().handle_key(key); context.input_handler().handle_key(key);
}, "user mapping", }, "user mapping",

View File

@ -0,0 +1 @@
<space>u

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@
123

View File

@ -0,0 +1 @@
map global user u %{i123<esc>:unmap global user u<ret>i456<esc>}