Improve getSafeNodeName / sanitizeString code.

This commit is contained in:
Jason P
2025-11-04 07:27:56 -06:00
parent ef5016aa12
commit ccdb27d377

View File

@@ -55,51 +55,54 @@ static int scrollIndex = 0;
const char *getSafeNodeName(OLEDDisplay *display, meshtastic_NodeInfoLite *node) const char *getSafeNodeName(OLEDDisplay *display, meshtastic_NodeInfoLite *node)
{ {
const char *name = NULL; static char nodeName[16]; // single static buffer we return
static char nodeName[16] = "?"; nodeName[0] = '\0';
if (config.display.use_long_node_name == true) {
if (node->has_user && strlen(node->user.long_name) > 0) { auto writeFallbackId = [&] {
name = node->user.long_name; std::snprintf(nodeName, sizeof(nodeName), "(%04X)", static_cast<uint16_t>(node ? (node->num & 0xFFFF) : 0));
} else { };
snprintf(nodeName, sizeof(nodeName), "(%04X)", (uint16_t)(node->num & 0xFFFF));
} // 1) Choose target candidate (long vs short) only if present
} else { const char *raw = nullptr;
if (node->has_user && strlen(node->user.short_name) > 0) { if (node && node->has_user) {
name = node->user.short_name; raw = config.display.use_long_node_name ? node->user.long_name : node->user.short_name;
} else {
snprintf(nodeName, sizeof(nodeName), "(%04X)", (uint16_t)(node->num & 0xFFFF));
}
} }
// Use sanitizeString() function and copy directly into nodeName // 2) Sanitize (empty if raw is null/empty)
std::string sanitized_name = sanitizeString(name ? name : ""); std::string s = (raw && *raw) ? sanitizeString(raw) : std::string{};
if (!sanitized_name.empty()) { // 3) Fallback if sanitize yields empty; otherwise copy safely (truncate if needed)
strncpy(nodeName, sanitized_name.c_str(), sizeof(nodeName) - 1); if (s.empty()) {
nodeName[sizeof(nodeName) - 1] = '\0'; writeFallbackId();
} else { } else {
snprintf(nodeName, sizeof(nodeName), "(%04X)", (uint16_t)(node->num & 0xFFFF)); // %.*s ensures null-termination and safe truncation to buffer size - 1
std::snprintf(nodeName, sizeof(nodeName), "%.*s", static_cast<int>(sizeof(nodeName) - 1), s.c_str());
} }
if (config.display.use_long_node_name == true) { // 4) Width-based truncation + ellipsis (long-name mode only)
if (config.display.use_long_node_name && display) {
int availWidth = (SCREEN_WIDTH / 2) - 65; int availWidth = (SCREEN_WIDTH / 2) - 65;
if (availWidth < 0) if (availWidth < 0)
availWidth = 0; availWidth = 0;
size_t origLen = strlen(nodeName); const size_t beforeLen = std::strlen(nodeName);
while (nodeName[0] && display->getStringWidth(nodeName) > availWidth) {
nodeName[strlen(nodeName) - 1] = '\0'; // Trim from the end until it fits or is empty
size_t len = beforeLen;
while (len && display->getStringWidth(nodeName) > availWidth) {
nodeName[--len] = '\0';
} }
// If we actually truncated, append "..." (ensure space remains in buffer) // If truncated, append "..." (respect buffer size)
if (strlen(nodeName) < origLen) { if (len < beforeLen) {
size_t len = strlen(nodeName); // Make sure there's room for "..." and '\0'
size_t maxLen = sizeof(nodeName) - 4; // 3 for "..." and 1 for '\0' const size_t capForText = sizeof(nodeName) - 1; // leaving space for '\0'
if (len > maxLen) { const size_t needed = 3; // "..."
nodeName[maxLen] = '\0'; if (len > capForText - needed) {
len = maxLen; len = capForText - needed;
nodeName[len] = '\0';
} }
strcat(nodeName, "..."); std::strcat(nodeName, "...");
} }
} }