From 46f2f08e76f749fbafa460a1958f98daa6ced441 Mon Sep 17 00:00:00 2001 From: Karl Fleischmann Date: Tue, 19 May 2026 16:24:04 +0200 Subject: [PATCH] daemon, gui: Consolidate keyname length in project This commit fixes incorrect behavior of the 'w' key which was linked to the "ctrlwheelcw" event, because the keyname was read in 10 character chunks. Create a consolidated macro, with a large enough limit to allow all currently relevant keys. Replace all custom keyname lengths with this macro. Ensure that relevant sscanf() calls use an appropriate string version of this length (minus one for the trailing '\0'). CKB_KEYNAME_MAX in animation.h still needs to be kept in sync manually due to it being a standalone header. --- src/ckbnextconfig.h.in | 9 +++++++++ src/daemon/command.c | 4 ++-- src/daemon/input.c | 13 +++++++------ src/daemon/led.c | 4 ++-- src/gui/animscript.cpp | 4 ++-- src/libs/ckb-next/include/ckb-next/animation.h | 2 +- 6 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/ckbnextconfig.h.in b/src/ckbnextconfig.h.in index 3d9590ed..ee93356f 100644 --- a/src/ckbnextconfig.h.in +++ b/src/ckbnextconfig.h.in @@ -18,3 +18,12 @@ #define CKB_NEXT_COPYRIGHT_YEAR "${ckb-next_COPYRIGHT_YEAR}" #cmakedefine ckb_next_VERSION_IS_RELEASE #define CKB_NEXT_DESCRIPTION "Open Source Driver for Corsair devices." + +#include +// Number of characters allowed for key names. +#define N_KEYNAME_LENGTH 40 +#define N_KEYNAME_STRLEN 39 +#define N_KEYNAME_STR_REAL(x) #x +#define N_KEYNAME_STR(x) N_KEYNAME_STR_REAL(x) +#define N_SCANF_KEYNAME N_KEYNAME_STR(N_KEYNAME_STRLEN) +static_assert((N_KEYNAME_LENGTH == N_KEYNAME_STRLEN + 1), "N_KEYNAME_LENGTH must be 1 greater than N_KEYNAME_STRLEN"); diff --git a/src/daemon/command.c b/src/daemon/command.c index 193fec92..8eebf56f 100644 --- a/src/daemon/command.c +++ b/src/daemon/command.c @@ -332,8 +332,8 @@ int readcmd(usbdevice* kb, char* line){ } // Scan the left side for key names and run the requested command int position = 0, field = 0; - char keyname[11] = { 0 }; - while(position < left && sscanf(word + position, "%10[^:,]%n", keyname, &field) == 1){ + char keyname[N_KEYNAME_LENGTH] = { 0 }; + while(position < left && sscanf(word + position, "%"N_SCANF_KEYNAME"[^:,]%n", keyname, &field) == 1){ uint keycode; if(!strcmp(keyname, "all")){ // Set all keys diff --git a/src/daemon/input.c b/src/daemon/input.c index 1c3e9820..2b12f9c3 100644 --- a/src/daemon/input.c +++ b/src/daemon/input.c @@ -645,8 +645,8 @@ static void _cmd_macro(usbmode* mode, const char* keys, const char* assignment, int empty = 1; int left = strlen(keys), right = strlen(assignment); int position = 0, field = 0; - char keyname[40]; - while(position < left && sscanf(keys + position, "%10[^+]%n", keyname, &field) == 1){ + char keyname[N_KEYNAME_LENGTH]; + while(position < left && sscanf(keys + position, "%"N_SCANF_KEYNAME"[^+]%n", keyname, &field) == 1){ // Find this key in the keymap for(unsigned i = 0; i < N_KEYS_INPUT; i++){ if(kb->keymap[i].name && !strcmp(keyname, kb->keymap[i].name)){ @@ -673,7 +673,7 @@ static void _cmd_macro(usbmode* mode, const char* keys, const char* assignment, position = 0; field = 0; // max action = old 11 chars plus 12 chars which is the max 32-bit unsigned int 4294967295 size * 2 + 1 for range underscore - while(position < right && sscanf(assignment + position, "%36[^,]%n", keyname, &field) == 1){ + while(position < right && sscanf(assignment + position, "%"N_SCANF_KEYNAME"[^,]%n", keyname, &field) == 1){ if(!strcmp(keyname, "clear")) break; @@ -682,12 +682,13 @@ static void _cmd_macro(usbmode* mode, const char* keys, const char* assignment, int64_t long_delay_range = 0; uint32_t delay = UINT32_MAX; // computed delay value. UINT32_MAX means use the default value. uint32_t delay_range = 0; - char real_keyname[12]; // temp to hold the left side (key) of the = - int scan_matches = sscanf(keyname, "%11[^=]=%"SCNd64"_%"SCNd64, real_keyname, &long_delay, &long_delay_range); + char real_keyname[N_KEYNAME_LENGTH]; // temp to hold the left side (key) of the = + int scan_matches = sscanf(keyname, "%"N_SCANF_KEYNAME"[^=]=%"SCNd64"_%"SCNd64, real_keyname, &long_delay, &long_delay_range); if (scan_matches == 2 || scan_matches == 3) { if (0 <= long_delay && long_delay < UINT32_MAX) { delay = (uint32_t)long_delay; - strcpy(keyname, real_keyname); // keyname[40], real_keyname[12] + static_assert(sizeof(keyname) >= sizeof(real_keyname), ""); + strcpy(keyname, real_keyname); if(0 < long_delay_range && long_delay_range < UINT32_MAX && long_delay_range > long_delay) { delay_range = (uint32_t)long_delay_range; diff --git a/src/daemon/led.c b/src/daemon/led.c index 4ece826c..30196b77 100644 --- a/src/daemon/led.c +++ b/src/daemon/led.c @@ -157,13 +157,13 @@ char* printrgb(const lighting* light, const usbdevice* kb){ b[i] = mb[k]; } // Make a buffer to track key names and to filter out duplicates - char names[N_KEYS_EXTENDED][11]; + char names[N_KEYS_EXTENDED][N_KEYNAME_LENGTH]; for(int i = 0; i < N_KEYS_EXTENDED; i++){ const char* name = kb->keymap[i].name; if(kb->keymap[i].led < 0 || !has_key(name, kb)) names[i][0] = 0; else - strncpy(names[i], name, 11); + strncpy(names[i], name, N_KEYNAME_LENGTH); } // Check to make sure these aren't all the same color int same = 1; diff --git a/src/gui/animscript.cpp b/src/gui/animscript.cpp index 52fa106f..0198001d 100644 --- a/src/gui/animscript.cpp +++ b/src/gui/animscript.cpp @@ -447,9 +447,9 @@ void AnimScript::readProcess(){ } if(line.startsWith("argb ")){ // Add a color to the buffer - char keyName[31]; + char keyName[N_KEYNAME_LENGTH]; QRgb keyColor = 0; - if(sscanf(line, "argb %30s %x", keyName, &keyColor) != 2) + if(sscanf(line, "argb %" N_SCANF_KEYNAME "s %x", keyName, &keyColor) != 2) continue; QRgb* inMap = _colorBuffer.colorForName(keyName); if(!inMap) diff --git a/src/libs/ckb-next/include/ckb-next/animation.h b/src/libs/ckb-next/include/ckb-next/animation.h index ee51b39c..92acc903 100644 --- a/src/libs/ckb-next/include/ckb-next/animation.h +++ b/src/libs/ckb-next/include/ckb-next/animation.h @@ -127,7 +127,7 @@ #define CKB_REAL_ANGLE(angle) fmod((-(angle) + 90.) * M_PI / 180. + M_PI * 2., M_PI * 2.) // Key definition -#define CKB_KEYNAME_MAX 12 +#define CKB_KEYNAME_MAX 40 typedef struct { char name[CKB_KEYNAME_MAX+1]; int x, y;