From 5e6cf2e79cfdf325b7260beeccf775aee53af0e9 Mon Sep 17 00:00:00 2001 From: Wilhelm Date: Fri, 1 Apr 2022 06:16:01 +0200 Subject: [PATCH] fix: Custom stick and switch names were being mangled internally (#1770) * followup to PR1754 * Cleanup * Formatting * Long comment --- radio/src/lua/api_general.cpp | 31 +++++++++++++++++++------------ radio/src/strhelpers.cpp | 15 +++++---------- radio/src/strhelpers.h | 33 ++++++++++++++++++++++++++++++++- 3 files changed, 56 insertions(+), 23 deletions(-) diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index 25c167ecc..a2a049f7e 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -91,6 +91,10 @@ { "EVT_"#xxx"_LONG", EVT_KEY_LONG(yyy) }, \ { "EVT_"#xxx"_REPT", EVT_KEY_REPT(yyy) } +// see strhelpers.cpp for pre-instantiation of function-template +// getSourceString() for this parametrization +static constexpr uint8_t maxSourceNameLength{16}; + // Note: // - luaRxFifo & luaReceiveData are used only for USB serial // - otherwise, the AUX serial buffer is used directly @@ -2301,22 +2305,23 @@ This function is rather time consuming, and should not be used repeatedly in a s @status current Introduced in 2.6 */ -static int luaGetSourceIndex(lua_State * L) +static int luaGetSourceIndex(lua_State* const L) { - const char * name = luaL_checkstring(L, 1); + const char* const name = luaL_checkstring(L, 1); bool found = false; mixsrc_t idx; - + for (idx = MIXSRC_NONE; idx <= MIXSRC_LAST_TELEM; idx++) { if (isSourceAvailable(idx)) { - char* s = getSourceString(idx); - if (!strncasecmp(s, name, 31)) { + char srcName[maxSourceNameLength]; + getSourceString(srcName, idx); + if (!strncasecmp(srcName, name)) { found = true; break; } } } - + if (found) lua_pushinteger(L, idx); else @@ -2341,11 +2346,12 @@ static int luaGetSourceName(lua_State * L) { mixsrc_t idx = luaL_checkinteger(L, 1); if (idx <= MIXSRC_LAST_TELEM && isSourceAvailable(idx)) { - char* name = getSourceString(idx); - lua_pushstring(L, name); - } - else + char srcName[maxSourceNameLength]; + getSourceString(srcName, idx); + lua_pushstring(L, srcName); + } else { lua_pushnil(L); + } return 1; } @@ -2368,9 +2374,10 @@ static int luaNextSource(lua_State * L) while (++idx <= last) { if (isSourceAvailable(idx)) { - char* name = getSourceString(idx); + char srcName[maxSourceNameLength]; + getSourceString(srcName, idx); lua_pushinteger(L, idx); - lua_pushstring(L, name); + lua_pushstring(L, srcName); return 2; } } diff --git a/radio/src/strhelpers.cpp b/radio/src/strhelpers.cpp index 404ff88ab..52620061f 100644 --- a/radio/src/strhelpers.cpp +++ b/radio/src/strhelpers.cpp @@ -512,9 +512,8 @@ char *getSwitchPositionName(char *dest, swsrc_t idx) else if (idx <= SWSRC_LAST_MULTIPOS_SWITCH) { div_t swinfo = div(int(idx - SWSRC_FIRST_MULTIPOS_SWITCH), XPOTS_MULTIPOS_COUNT); - char temp[LEN_ANA_NAME + 1]; + char temp[LEN_ANA_NAME + 2]; getSourceString(temp, MIXSRC_FIRST_POT + swinfo.quot); - temp[LEN_ANA_NAME] = '\0'; strAppendStringWithIndex(s, temp, swinfo.rem + 1); } #endif @@ -611,10 +610,8 @@ char *getSourceString(char (&dest)[L], mixsrc_t idx) dest[0] = CHAR_POT; #endif } - idx -= MIXSRC_Rud; - memcpy(dest + 1, g_eeGeneral.anaNames[idx], L - 1); - dest[L - 1] = '\0'; + copyToTerminated(dest, g_eeGeneral.anaNames[idx], offset_t<1>{}); } else { idx -= MIXSRC_Rud; getStringAtIndex(dest, STR_VSRCRAW, idx + 1); @@ -625,8 +622,7 @@ char *getSourceString(char (&dest)[L], mixsrc_t idx) } else if (idx <= MIXSRC_LAST_SWITCH) { idx -= MIXSRC_FIRST_SWITCH; if (g_eeGeneral.switchNames[idx][0] != '\0') { - strncpy(dest, g_eeGeneral.switchNames[idx], LEN_SWITCH_NAME); - dest[LEN_SWITCH_NAME] = '\0'; + copyToTerminated(dest, g_eeGeneral.switchNames[idx], offset_t<1>{}); } else { getStringAtIndex(dest, STR_VSRCRAW, idx + MIXSRC_FIRST_SWITCH - MIXSRC_Rud + 1); @@ -647,9 +643,8 @@ char *getSourceString(char (&dest)[L], mixsrc_t idx) MAX_GVARS); } else if (idx <= MIXSRC_LAST_TIMER) { if (g_model.timers[idx - MIXSRC_FIRST_TIMER].name[0] != '\0') { - strncpy(dest, g_model.timers[idx - MIXSRC_FIRST_TIMER].name, - L - 1); - dest[L - 1] = '\0'; + copyToTerminated(dest, g_model.timers[idx - MIXSRC_FIRST_TIMER].name, + offset_t<1>{}); } else { getStringAtIndex(dest, STR_VSRCRAW, idx - MIXSRC_Rud + 1 - MAX_LOGICAL_SWITCHES - diff --git a/radio/src/strhelpers.h b/radio/src/strhelpers.h index 22ff8a9bd..2ec059137 100644 --- a/radio/src/strhelpers.h +++ b/radio/src/strhelpers.h @@ -78,7 +78,7 @@ char *getSwitchPositionName(char *dest, swsrc_t idx); char *getSwitchName(char *dest, swsrc_t idx); template -char *getSourceString(char (&dest)[L], mixsrc_t idx); +char* getSourceString(char (&dest)[L], mixsrc_t idx); int getRawSwitchIdx(char sw); char getRawSwitchFromIdx(int sw); @@ -113,4 +113,35 @@ template void clearStruct(S& s) { memset((void*) &s, 0, sizeof(S)); } + +template +using offset_t = std::integral_constant; + +template +void copyToTerminated(char (&dest)[DL], const char (&src)[SL], + const offset_t = offset_t<0>{}) +{ + // unfortinately std::min() isn't constexpr in C++11 + // static constexpr size_t len = std::min(DL - O - 1, SL); + static constexpr size_t dl{DL - O - 1}; + static_assert(dl > 0, "wrong sizes or offset"); + static constexpr size_t len = (dl < SL) ? dl : SL; + strncpy(&dest[O], &src[0], len); + static_assert((len + O) < DL); + dest[len + O] = '\0'; +} + +template +int strncasecmp(char (&s1)[L1], const char (&s2)[L2]) +{ + static constexpr size_t len = (L1 < L2) ? L1 : L2; + return strncasecmp(s1, s2, len); +} + +template +int strncasecmp(char (&s1)[L1], const char *const s2) +{ + return strncasecmp(s1, s2, L1); +} + #endif // _STRHELPERS_H_