Branch: refs/heads/master Author: Colomban Wendling ban@herbesfolles.org Committer: GitHub noreply@github.com Date: Sat, 20 Apr 2024 15:26:59 UTC Commit: 548c971499aecfa1021541b00ff40b0c6506cabb https://github.com/geany/geany/commit/548c971499aecfa1021541b00ff40b0c6506ca...
Log Message: ----------- Merge pull request #3846 from b4n/utils-get-initials
Fix invalid memory access and Unicode support in utils_get_initials()
Modified Paths: -------------- src/utils.c tests/test_utils.c
Modified: src/utils.c 32 lines changed, 24 insertions(+), 8 deletions(-) =================================================================== @@ -766,21 +766,37 @@ gchar *utils_get_date_time(const gchar *format, time_t *time_to_use) }
+/* Extracts initials from @p name, with basic Unicode support */ +GEANY_EXPORT_SYMBOL gchar *utils_get_initials(const gchar *name) { - gint i = 1, j = 1; - gchar *initials = g_malloc0(5); + GString *initials; + gchar *composed; + gboolean at_bound = TRUE; + + g_return_val_if_fail(name != NULL, NULL); + + composed = g_utf8_normalize(name, -1, G_NORMALIZE_ALL_COMPOSE); + g_return_val_if_fail(composed != NULL, NULL);
- initials[0] = name[0]; - while (name[i] != '\0' && j < 4) + initials = g_string_new(NULL); + for (const gchar *p = composed; *p; p = g_utf8_next_char(p)) { - if (name[i] == ' ' && name[i + 1] != ' ') + gunichar ch = g_utf8_get_char(p); + + if (g_unichar_isspace(ch)) + at_bound = TRUE; + else if (at_bound) { - initials[j++] = name[i + 1]; + const gchar *end = g_utf8_next_char(p); + g_string_append_len(initials, p, end - p); + at_bound = FALSE; } - i++; } - return initials; + + g_free(composed); + + return g_string_free(initials, FALSE); }
Modified: tests/test_utils.c 23 lines changed, 23 insertions(+), 0 deletions(-) =================================================================== @@ -408,6 +408,28 @@ void test_utils_strv_shorten_file_list(void) g_strfreev(data); }
+static void test_utils_get_initials(void) +{ +#define CHECK_INITIALS(buf, initials) \ + G_STMT_START { \ + gchar *r = utils_get_initials(buf); \ + g_assert_cmpstr(r, ==, initials); \ + g_free(r); \ + } G_STMT_END + + CHECK_INITIALS("John Doe", "JD"); + CHECK_INITIALS(" John Doe ", "JD"); + CHECK_INITIALS("John", "J"); + CHECK_INITIALS("John F. Doe", "JFD"); + CHECK_INITIALS("Gary Errol Anthony Nicholas Yales", "GEANY"); + CHECK_INITIALS("", ""); + CHECK_INITIALS("Åsa Åkesson", "ÅÅ"); /* composed */ + CHECK_INITIALS("Åsa Åkesson", "ÅÅ"); /* decomposed */ + CHECK_INITIALS("Œdipe", "Œ"); + +#undef CHECK_INITIALS +} + int main(int argc, char **argv) { g_test_init(&argc, &argv, NULL); @@ -416,6 +438,7 @@ int main(int argc, char **argv) UTIL_TEST_ADD("strv_find_common_prefix", test_utils_strv_find_common_prefix); UTIL_TEST_ADD("strv_find_lcs", test_utils_strv_find_lcs); UTIL_TEST_ADD("strv_shorten_file_list", test_utils_strv_shorten_file_list); + UTIL_TEST_ADD("get_initals", test_utils_get_initials);
return g_test_run(); }
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).