From e8c21a8b51631df57713bfd1b6bf97ba376b1adb Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 8 Jan 2026 08:39:58 +0800 Subject: [PATCH] fix(langmap): assert failure on mapping to char >= 256 (#37291) Usually 'langmap' is used to map keyboard characters to ASCII motions or mappings. It's not entirely clear what the purpose of mapping to Unicode characters is, but since there is no error for mapping between two chars both >= 256, only give a warning that this will not work properly when mapping from a char < 256 to a char >= 256. (cherry picked from commit 16c133439958acc0656204d7127b815d268e51d4) --- src/nvim/mapping.c | 11 ++++++++--- test/functional/editor/langmap_spec.lua | 12 ++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/nvim/mapping.c b/src/nvim/mapping.c index fd97bfc18b..a28bb2473b 100644 --- a/src/nvim/mapping.c +++ b/src/nvim/mapping.c @@ -2578,21 +2578,23 @@ const char *did_set_langmap(optset_T *args) p++; } int from = utf_ptr2char(p); + const char *const from_ptr = p; int to = NUL; + const char *to_ptr = ""; if (p2 == NULL) { MB_PTR_ADV(p); if (p[0] != ',') { if (p[0] == '\\') { p++; } - to = utf_ptr2char(p); + to = utf_ptr2char(to_ptr = p); } } else { if (p2[0] != ',') { if (p2[0] == '\\') { p2++; } - to = utf_ptr2char(p2); + to = utf_ptr2char(to_ptr = p2); } } if (to == NUL) { @@ -2605,7 +2607,10 @@ const char *did_set_langmap(optset_T *args) if (from >= 256) { langmap_set_entry(from, to); } else { - assert(to <= UCHAR_MAX); + if (to > UCHAR_MAX) { + swmsg(true, "'langmap': mapping from %.*s to %.*s will not work properly", + utf_ptr2len(from_ptr), from_ptr, utf_ptr2len(to_ptr), to_ptr); + } langmap_mapchar[from & 255] = (uint8_t)to; } diff --git a/test/functional/editor/langmap_spec.lua b/test/functional/editor/langmap_spec.lua index e50e19a468..3ea67b76e2 100644 --- a/test/functional/editor/langmap_spec.lua +++ b/test/functional/editor/langmap_spec.lua @@ -266,6 +266,18 @@ describe("'langmap'", function() command('nnoremap ï ix') testrecording('x', 'xhello', local_setup) end) + it('does not crash when mapping char < 256 to char >= 256', function() + -- Note: this warning should be removed when the pending tests above are fixed. + local wmsg = table.concat({ + "'langmap': mapping from e to ε will not work properly", + "'langmap': mapping from ü to μ will not work properly", + }, '\n') + -- ä ë ï ö ü ÿ < 256, β γ ε μ >= 256 + command('set langmap=iw,wi,äë,ëä,ïx,xï,βγ,γβ,eε,εe,üμ,μü,ÿy,yÿ') + eq(wmsg, n.exec_capture('messages')) + command('messages clear | set langmap=iwäëïxβγeεüμÿy;wiëäxïγβεeμüyÿ') + eq(wmsg, n.exec_capture('messages')) + end) -- This test is to ensure the behaviour doesn't change from what's already -- around. I (hardenedapple) personally think this behaviour should be -- changed.