This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch master
in repository terminology.
View the commit online.
commit 544da9e23cef6002c42d2b688c1fb56211954643
Author: Boris Faure <[email protected]>
AuthorDate: Sat Sep 12 16:06:50 2026 +0200
termptyesc: fix XTMODKEYS argument order
CSI > Pp ; Pv m takes the resource from Pp and the value from Pv; they
were read the other way round, so nvim's CSI > 4 ; 2 m set xmod[2] = 4.
---
src/bin/termpty.c | 40 ++++++++++++++++++++++
src/bin/termpty.h | 3 +-
src/bin/termptyesc.c | 97 +++++++++++++++++++++++++---------------------------
src/bin/tytest.c | 1 +
src/bin/unit_tests.h | 1 +
5 files changed, 90 insertions(+), 52 deletions(-)
diff --git a/src/bin/termpty.c b/src/bin/termpty.c
index 8c915da8..11eac4a9 100644
--- a/src/bin/termpty.c
+++ b/src/bin/termpty.c
@@ -2232,4 +2232,44 @@ tytest_sync_change_cb_altscreen(void)
return 0;
}
+/* XTMODKEYS: CSI > Pp ; Pv m, Pp selects the resource, Pv is the value. */
+int
+tytest_xmodkeys_set(void)
+{
+ Termpty ty;
+
+ _ty_test_init(&ty, 80, 24);
+
+ _ty_feed(&ty, "\x1b[>4;2m");
+ assert(ty.termstate.xmod[XMOD_OTHER] == 2);
+ assert(ty.termstate.xmod[XMOD_FUNCTIONS] == 0);
+
+ _ty_feed(&ty, "\x1b[>1;3m");
+ assert(ty.termstate.xmod[XMOD_CURSOR] == 3);
+ assert(ty.termstate.xmod[XMOD_OTHER] == 2);
+
+ /* Pv omitted: back to the initial value. */
+ _ty_feed(&ty, "\x1b[>4m");
+ assert(ty.termstate.xmod[XMOD_OTHER] == 0);
+
+ /* No parameter at all: every resource is reset. */
+ _ty_feed(&ty, "\x1b[>4;2m");
+ _ty_feed(&ty, "\x1b[>m");
+ assert(ty.termstate.xmod[XMOD_CURSOR] == 0);
+ assert(ty.termstate.xmod[XMOD_OTHER] == 0);
+
+ /* CSI > Pp n resets a single resource. */
+ _ty_feed(&ty, "\x1b[>4;2m");
+ _ty_feed(&ty, "\x1b[>4n");
+ assert(ty.termstate.xmod[XMOD_OTHER] == 0);
+
+ /* An out of range resource changes nothing. */
+ _ty_feed(&ty, "\x1b[>4;2m");
+ _ty_feed(&ty, "\x1b[>9;1m");
+ assert(ty.termstate.xmod[XMOD_OTHER] == 2);
+
+ _ty_test_shutdown(&ty);
+ return 0;
+}
+
#endif /* BINARY_TYFUZZ || BINARY_TYTEST */
diff --git a/src/bin/termpty.h b/src/bin/termpty.h
index 9f26de2e..1890e9fc 100644
--- a/src/bin/termpty.h
+++ b/src/bin/termpty.h
@@ -106,6 +106,7 @@ typedef enum exmod {
XMOD_KEYPAD = 3,
XMOD_OTHER = 4,
XMOD_STRING = 5,
+ XMOD_LAST = 6,
} XMod;
typedef struct tag_Term_State {
@@ -134,7 +135,7 @@ typedef struct tag_Term_State {
unsigned int sace_rectangular : 1;
unsigned int esc_keycode : 1;
unsigned int alternate_esc : 1;
- int xmod[6];
+ int xmod[XMOD_LAST];
} Term_State;
typedef struct tag_Term_Cursor {
diff --git a/src/bin/termptyesc.c b/src/bin/termptyesc.c
index 2348e43e..c45e7ca3 100644
--- a/src/bin/termptyesc.c
+++ b/src/bin/termptyesc.c
@@ -3453,6 +3453,29 @@ _handle_window_manipulation(Termpty *ty, Eina_Unicode **ptr)
}
+static Eina_Bool
+_xmod_resource_is_valid(int resource)
+{
+ switch (resource)
+ {
+ case XMOD_KEYBOARD:
+ EINA_FALLTHROUGH;
+ case XMOD_CURSOR:
+ EINA_FALLTHROUGH;
+ case XMOD_FUNCTIONS:
+ EINA_FALLTHROUGH;
+ case XMOD_KEYPAD:
+ EINA_FALLTHROUGH;
+ case XMOD_OTHER:
+ EINA_FALLTHROUGH;
+ case XMOD_STRING:
+ return EINA_TRUE;
+ default:
+ return EINA_FALSE;
+ }
+}
+
+/* XTMODKEYS: CSI > Pp ; Pv m and CSI > Pp n */
static void
_handle_xmodkeys(Termpty *ty,
Eina_Unicode cmd, Eina_Unicode **ptr)
@@ -3462,7 +3485,7 @@ _handle_xmodkeys(Termpty *ty,
Eina_Unicode param = *b;
b++;
if (param == '?')
- return; // Not actually supported by xterm
+ return;
if (param != '>')
{
ERR("XMODKEYS: Invalid sequence");
@@ -3471,69 +3494,41 @@ _handle_xmodkeys(Termpty *ty,
}
if (set)
{
- int arg1 = _csi_arg_get(ty, &b);
- int arg2 = _csi_arg_get(ty, &b);
- int v, mod;
- if (arg1 == -ESC_ARG_ERROR)
+ int resource = _csi_arg_get(ty, &b);
+ int v = _csi_arg_get(ty, &b);
+
+ if (resource == -ESC_ARG_ERROR)
{
ERR("XMODKEYS set: Invalid sequence");
ty->decoding_error = EINA_TRUE;
return;
}
- if (arg2 == -ESC_ARG_NO_VALUE)
- {
- mod = arg1;
- v = 0;
+ if (resource == -ESC_ARG_NO_VALUE)
+ { /* reset all */
+ memset(ty->termstate.xmod, 0, sizeof(ty->termstate.xmod));
+ return;
}
- else
+ if (!_xmod_resource_is_valid(resource))
{
- mod = arg2;
- v = arg1;
+ ERR("XMODKEYS set: Invalid sequence");
+ ty->decoding_error = EINA_TRUE;
+ return;
}
- switch (mod)
- {
- case XMOD_KEYBOARD:
- EINA_FALLTHROUGH;
- case XMOD_CURSOR:
- EINA_FALLTHROUGH;
- case XMOD_FUNCTIONS:
- EINA_FALLTHROUGH;
- case XMOD_KEYPAD:
- EINA_FALLTHROUGH;
- case XMOD_OTHER:
- EINA_FALLTHROUGH;
- case XMOD_STRING:
- break;
- default:
- ERR("XMODKEYS set: Invalid sequence");
- ty->decoding_error = EINA_TRUE;
- return;
- }
- ty->termstate.xmod[mod] = v;
+ if (v < 0)
+ v = 0;
+ ty->termstate.xmod[resource] = v;
}
else
{ /* reset */
- int arg = _csi_arg_get(ty, &b);
- switch (arg)
+ int resource = _csi_arg_get(ty, &b);
+
+ if (!_xmod_resource_is_valid(resource))
{
- case XMOD_KEYBOARD:
- EINA_FALLTHROUGH;
- case XMOD_CURSOR:
- EINA_FALLTHROUGH;
- case XMOD_FUNCTIONS:
- EINA_FALLTHROUGH;
- case XMOD_KEYPAD:
- EINA_FALLTHROUGH;
- case XMOD_OTHER:
- EINA_FALLTHROUGH;
- case XMOD_STRING:
- break;
- default:
- ERR("XMODKEYS reset: Invalid sequence");
- ty->decoding_error = EINA_TRUE;
- return;
+ ERR("XMODKEYS reset: Invalid sequence");
+ ty->decoding_error = EINA_TRUE;
+ return;
}
- ty->termstate.xmod[arg] = 0;
+ ty->termstate.xmod[resource] = 0;
}
}
static int
diff --git a/src/bin/tytest.c b/src/bin/tytest.c
index 338fe3d0..a5cb7ed9 100644
--- a/src/bin/tytest.c
+++ b/src/bin/tytest.c
@@ -56,6 +56,7 @@ static struct {
{ "sync_change_cb_watchdog", tytest_sync_change_cb_watchdog},
{ "sync_change_cb_altscreen", tytest_sync_change_cb_altscreen},
{ "percent_decode", tytest_percent_decode},
+ { "xmodkeys_set", tytest_xmodkeys_set},
{ NULL, NULL},
};
diff --git a/src/bin/unit_tests.h b/src/bin/unit_tests.h
index b5deeb24..afa2fd42 100644
--- a/src/bin/unit_tests.h
+++ b/src/bin/unit_tests.h
@@ -30,5 +30,6 @@ int tytest_sync_change_cb_coalesced(void);
int tytest_sync_change_cb_watchdog(void);
int tytest_sync_change_cb_altscreen(void);
int tytest_percent_decode(void);
+int tytest_xmodkeys_set(void);
#endif
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.