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;