1
0
mirror of https://github.com/profanity-im/profanity.git synced 2024-11-03 19:37:16 -05:00

Fix multibyte chars in prof_occurrences

issue #901
This commit is contained in:
James Booth 2017-01-26 00:52:13 +00:00
parent b712820c99
commit 6679b890a0
3 changed files with 48 additions and 8 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -6,6 +6,7 @@
#include <setjmp.h>
#include <cmocka.h>
#include <sys/stat.h>
#include <locale.h>
#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),