From 6679b890a052ccda92e086d94a9f253403b24a13 Mon Sep 17 00:00:00 2001 From: James Booth Date: Thu, 26 Jan 2017 00:52:13 +0000 Subject: [PATCH 1/2] Fix multibyte chars in prof_occurrences issue #901 --- src/common.c | 22 ++++++++++++++-------- tests/unittests/test_common.c | 32 ++++++++++++++++++++++++++++++++ tests/unittests/unittests.c | 2 ++ 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/src/common.c b/src/common.c index d3f09a56..9544ab73 100644 --- a/src/common.c +++ b/src/common.c @@ -509,13 +509,18 @@ prof_occurrences(const char *const needle, const char *const haystack, int offse return *result; } - if (g_str_has_prefix(&haystack[offset], needle)) { + gchar *haystack_curr = g_utf8_offset_to_pointer(haystack, offset); + if (g_str_has_prefix(haystack_curr, needle)) { if (whole_word) { - char *prev = g_utf8_prev_char(&haystack[offset]); - char *next = g_utf8_next_char(&haystack[offset] + strlen(needle) - 1); - gunichar prevu = g_utf8_get_char(prev); - gunichar nextu = g_utf8_get_char(next); - if (!g_unichar_isalnum(prevu) && !g_unichar_isalnum(nextu)) { + gchar *needle_last_ch = g_utf8_offset_to_pointer(needle, g_utf8_strlen(needle, -1)- 1); + int needle_last_ch_len = mblen(needle_last_ch, MB_CUR_MAX); + + gchar *haystack_before_ch = g_utf8_prev_char(haystack_curr); + gchar *haystack_after_ch = g_utf8_next_char(haystack_curr + strlen(needle) - needle_last_ch_len); + + gunichar before = g_utf8_get_char(haystack_before_ch); + gunichar after = g_utf8_get_char(haystack_after_ch); + if (!g_unichar_isalnum(before) && !g_unichar_isalnum(after)) { *result = g_slist_append(*result, GINT_TO_POINTER(offset)); } } else { @@ -523,8 +528,9 @@ prof_occurrences(const char *const needle, const char *const haystack, int offse } } - if (haystack[offset+1] != '\0') { - *result = prof_occurrences(needle, haystack, offset+1, whole_word, result); + offset++; + if (g_strcmp0(g_utf8_offset_to_pointer(haystack, offset), "\0") != 0) { + *result = prof_occurrences(needle, haystack, offset, whole_word, result); } return *result; diff --git a/tests/unittests/test_common.c b/tests/unittests/test_common.c index d03f2123..75eed6e2 100644 --- a/tests/unittests/test_common.c +++ b/tests/unittests/test_common.c @@ -444,12 +444,25 @@ void prof_whole_occurrences_tests(void **state) assert_true(_lists_equal(prof_occurrences("boothj5", "boothj5, hi", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; g_slist_free(expected); expected = NULL; + expected = g_slist_append(expected, GINT_TO_POINTER(0)); + assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "我能吞下玻璃而", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; + assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "我能吞下玻璃而 hi", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; + assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "我能吞下玻璃而: hi", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; + assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "我能吞下玻璃而, hi", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; + g_slist_free(expected); expected = NULL; + expected = g_slist_append(expected, GINT_TO_POINTER(6)); assert_true(_lists_equal(prof_occurrences("boothj5", "hello boothj5", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; assert_true(_lists_equal(prof_occurrences("boothj5", "hello boothj5 there", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; assert_true(_lists_equal(prof_occurrences("boothj5", "heyy @boothj5, there", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; g_slist_free(expected); expected = NULL; + expected = g_slist_append(expected, GINT_TO_POINTER(6)); + assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "hello 我能吞下玻璃而", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; + assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "hello 我能吞下玻璃而 there", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; + assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "heyy @我能吞下玻璃而, there", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; + g_slist_free(expected); expected = NULL; + expected = g_slist_append(expected, GINT_TO_POINTER(6)); expected = g_slist_append(expected, GINT_TO_POINTER(26)); assert_true(_lists_equal(prof_occurrences("boothj5", "hello boothj5 some more a boothj5 stuff", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; @@ -457,6 +470,13 @@ void prof_whole_occurrences_tests(void **state) assert_true(_lists_equal(prof_occurrences("boothj5", "heyy @boothj5, there hows boothj5?", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; g_slist_free(expected); expected = NULL; + expected = g_slist_append(expected, GINT_TO_POINTER(6)); + expected = g_slist_append(expected, GINT_TO_POINTER(26)); + assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "hello 我能吞下玻璃而 some more a 我能吞下玻璃而 stuff", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; + assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "hello 我能吞下玻璃而 there ands #我能吞下玻璃而", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; + assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "heyy @我能吞下玻璃而, there hows 我能吞下玻璃而?", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; + g_slist_free(expected); expected = NULL; + expected = g_slist_append(expected, GINT_TO_POINTER(6)); assert_true(_lists_equal(prof_occurrences("p", "ppppp p", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; g_slist_free(expected); expected = NULL; @@ -488,4 +508,16 @@ void prof_whole_occurrences_tests(void **state) assert_true(_lists_equal(prof_occurrences("k", "kk", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; assert_true(_lists_equal(prof_occurrences("k", "kkkkkkk", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; g_slist_free(expected); expected = NULL; + + expected = NULL; + assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "我能吞下玻璃而hello", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; + assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "hey我能吞下玻璃而", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; + assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "hey我能吞下玻璃而hithere", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; + assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "hey 我能吞下玻璃而hithere", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; + assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "hey @我能吞下玻璃而hithere", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; + assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "hey我能吞下玻璃而 hithere", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; + assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "hey我能吞下玻璃而, hithere", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; + assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "我能吞下玻璃而我能吞下玻璃而", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; + assert_true(_lists_equal(prof_occurrences("我能吞下玻璃而", "我能吞下玻璃而fill我能吞下玻璃而", 0, TRUE, &actual), expected)); g_slist_free(actual); actual = NULL; + g_slist_free(expected); expected = NULL; } diff --git a/tests/unittests/unittests.c b/tests/unittests/unittests.c index e0a5dd34..71bdf1b1 100644 --- a/tests/unittests/unittests.c +++ b/tests/unittests/unittests.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "config.h" #include "xmpp/chat_session.h" @@ -37,6 +38,7 @@ #include "test_plugins_disco.h" int main(int argc, char* argv[]) { + setlocale(LC_ALL, ""); const UnitTest all_tests[] = { unit_test(replace_one_substr), From 8978f809f2923f2db742a656545ae3564e307e31 Mon Sep 17 00:00:00 2001 From: James Booth Date: Sat, 28 Jan 2017 16:38:43 +0000 Subject: [PATCH 2/2] Fix alias help fixes #899 --- src/command/cmd_defs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index 33ae1a76..bf648e93 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -1580,7 +1580,7 @@ static struct cmd_t command_defs[] = CMD_EXAMPLES( "/alias add friends /who online friends", "/alias add /q /quit", - "/alias a /away \"I'm in a meeting.\"", + "/alias add a /away \"I'm in a meeting.\"", "/alias remove q", "/alias list") },