From 92d4fbc5ff4a4bb5f05fecd88873ad3732faee35 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 29 Apr 2026 12:48:03 +0700 Subject: [PATCH] popup: UTF-8-aware SSID truncation %.*s cuts at byte index, splitting multi-byte sequences and producing broken glyphs followed by the ellipsis. Walk codepoints instead and truncate at a codepoint boundary. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/e_mod_popup.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/e_mod_popup.c b/src/e_mod_popup.c index 3bd28bc..5417b47 100644 --- a/src/e_mod_popup.c +++ b/src/e_mod_popup.c @@ -231,13 +231,23 @@ _rebuild_list(Popup *p) evas_object_size_hint_align_set(row, EVAS_HINT_FILL, 0); Evas_Object *btn = elm_button_add(row); - /* Truncate long SSIDs so the row never forces horizontal scrolling. */ + /* Truncate long SSIDs so the row never forces horizontal scrolling. + * Count codepoints, not bytes — SSIDs may contain UTF-8 and naive + * byte truncation would split a multi-byte sequence. */ const char *raw_ssid = n->ssid ? n->ssid : "(hidden)"; - char ssid_buf[32]; - const int max_ssid = 22; - if ((int)strlen(raw_ssid) > max_ssid) + char ssid_buf[64]; + const int max_chars = 21; + int iindex = 0, prev = 0, chars = 0; + while (chars < max_chars + && eina_unicode_utf8_next_get(raw_ssid, &iindex)) + { prev = iindex; chars++; } + if (eina_unicode_utf8_next_get(raw_ssid, &iindex)) { - snprintf(ssid_buf, sizeof(ssid_buf), "%.*s…", max_ssid - 1, raw_ssid); + /* more remains — truncate at `prev` and append U+2026 */ + int copy = prev < (int)sizeof(ssid_buf) - 4 + ? prev : (int)sizeof(ssid_buf) - 4; + memcpy(ssid_buf, raw_ssid, copy); + memcpy(ssid_buf + copy, "\xe2\x80\xa6", 4); /* "…" + NUL */ raw_ssid = ssid_buf; } char label[256];