From 7a4025cac1d0d29b086e30a7d5f7a98ffe3e9df5 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Mon, 1 Oct 2018 19:52:14 +0100 Subject: [PATCH] gutf8: Add a g_utf8_validate_len() function This is a variant of g_utf8_validate() which requires the length to be specified, thereby allowing string lengths up to G_MAXSIZE rather than just G_MAXSSIZE. Signed-off-by: Philip Withnall --- docs/reference/glib/glib-sections.txt | 1 + glib/gunicode.h | 4 +++ glib/gutf8.c | 44 +++++++++++++++++++++++---- glib/tests/utf8-validate.c | 15 ++++++--- 4 files changed, 54 insertions(+), 10 deletions(-) diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt index f88d6b53b..d875f9a3a 100644 --- a/docs/reference/glib/glib-sections.txt +++ b/docs/reference/glib/glib-sections.txt @@ -2964,6 +2964,7 @@ g_utf8_strrchr g_utf8_strreverse g_utf8_substring g_utf8_validate +g_utf8_validate_len g_utf8_make_valid diff --git a/glib/gunicode.h b/glib/gunicode.h index 481bc5212..36f841b9d 100644 --- a/glib/gunicode.h +++ b/glib/gunicode.h @@ -847,6 +847,10 @@ GLIB_AVAILABLE_IN_ALL gboolean g_utf8_validate (const gchar *str, gssize max_len, const gchar **end); +GLIB_AVAILABLE_IN_2_60 +gboolean g_utf8_validate_len (const gchar *str, + gsize max_len, + const gchar **end); GLIB_AVAILABLE_IN_ALL gchar *g_utf8_strup (const gchar *str, diff --git a/glib/gutf8.c b/glib/gutf8.c index a0fb16370..291534fc8 100644 --- a/glib/gutf8.c +++ b/glib/gutf8.c @@ -1669,16 +1669,48 @@ g_utf8_validate (const char *str, { const gchar *p; - if (max_len < 0) - p = fast_validate (str); - else - p = fast_validate_len (str, max_len); + if (max_len >= 0) + return g_utf8_validate_len (str, max_len, end); + + p = fast_validate (str); if (end) *end = p; - if ((max_len >= 0 && p != str + max_len) || - (max_len < 0 && *p != '\0')) + if (*p != '\0') + return FALSE; + else + return TRUE; +} + +/** + * g_utf8_validate_len: + * @str: (array length=max_len) (element-type guint8): a pointer to character data + * @max_len: max bytes to validate + * @end: (out) (optional) (transfer none): return location for end of valid data + * + * Validates UTF-8 encoded text. + * + * As with g_utf8_validate(), but @max_len must be set, and hence this function + * will always return %FALSE if any of the bytes of @str are nul. + * + * Returns: %TRUE if the text was valid UTF-8 + * Since: 2.60 + */ +gboolean +g_utf8_validate_len (const char *str, + gsize max_len, + const gchar **end) + +{ + const gchar *p; + + p = fast_validate_len (str, max_len); + + if (end) + *end = p; + + if (p != str + max_len) return FALSE; else return TRUE; diff --git a/glib/tests/utf8-validate.c b/glib/tests/utf8-validate.c index 1609bde34..5806b29a0 100644 --- a/glib/tests/utf8-validate.c +++ b/glib/tests/utf8-validate.c @@ -280,15 +280,22 @@ do_test (gconstpointer d) result = g_utf8_validate (test->text, test->max_len, &end); - g_assert (result == test->valid); - g_assert (end - test->text == test->offset); + g_assert_true (result == test->valid); + g_assert_cmpint (end - test->text, ==, test->offset); if (test->max_len < 0) { result = g_utf8_validate (test->text, strlen (test->text), &end); - g_assert (result == test->valid); - g_assert (end - test->text == test->offset); + g_assert_true (result == test->valid); + g_assert_cmpint (end - test->text, ==, test->offset); + } + else + { + result = g_utf8_validate_len (test->text, test->max_len, &end); + + g_assert_true (result == test->valid); + g_assert_cmpint (end - test->text, ==, test->offset); } }