summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gio/gactiongroup.c25
-rw-r--r--gio/gactiongroup.h2
-rw-r--r--glib/gunidecomp.c39
-rw-r--r--glib/tests/unicode-normalize.c38
4 files changed, 87 insertions, 17 deletions
diff --git a/gio/gactiongroup.c b/gio/gactiongroup.c
index 73f8faf5f..a327195cc 100644
--- a/gio/gactiongroup.c
+++ b/gio/gactiongroup.c
@@ -133,9 +133,10 @@ static gboolean
g_action_group_real_get_action_enabled (GActionGroup *action_group,
const gchar *action_name)
{
- gboolean enabled = FALSE;
+ gboolean enabled;
- g_action_group_query_action (action_group, action_name, &enabled, NULL, NULL, NULL, NULL);
+ if (!g_action_group_query_action (action_group, action_name, &enabled, NULL, NULL, NULL, NULL))
+ return FALSE;
return enabled;
}
@@ -144,9 +145,10 @@ static const GVariantType *
g_action_group_real_get_action_parameter_type (GActionGroup *action_group,
const gchar *action_name)
{
- const GVariantType *type = NULL;
+ const GVariantType *type;
- g_action_group_query_action (action_group, action_name, NULL, &type, NULL, NULL, NULL);
+ if (!g_action_group_query_action (action_group, action_name, NULL, &type, NULL, NULL, NULL))
+ return NULL;
return type;
}
@@ -155,9 +157,10 @@ static const GVariantType *
g_action_group_real_get_action_state_type (GActionGroup *action_group,
const gchar *action_name)
{
- const GVariantType *type = NULL;
+ const GVariantType *type;
- g_action_group_query_action (action_group, action_name, NULL, NULL, &type, NULL, NULL);
+ if (!g_action_group_query_action (action_group, action_name, NULL, NULL, &type, NULL, NULL))
+ return NULL;
return type;
}
@@ -166,9 +169,10 @@ static GVariant *
g_action_group_real_get_action_state_hint (GActionGroup *action_group,
const gchar *action_name)
{
- GVariant *hint = NULL;
+ GVariant *hint;
- g_action_group_query_action (action_group, action_name, NULL, NULL, NULL, &hint, NULL);
+ if (!g_action_group_query_action (action_group, action_name, NULL, NULL, NULL, &hint, NULL))
+ return NULL;
return hint;
}
@@ -177,9 +181,10 @@ static GVariant *
g_action_group_real_get_action_state (GActionGroup *action_group,
const gchar *action_name)
{
- GVariant *state = NULL;
+ GVariant *state;
- g_action_group_query_action (action_group, action_name, NULL, NULL, NULL, NULL, &state);
+ if (!g_action_group_query_action (action_group, action_name, NULL, NULL, NULL, NULL, &state))
+ return NULL;
return state;
}
diff --git a/gio/gactiongroup.h b/gio/gactiongroup.h
index f8d20ae69..06213df8a 100644
--- a/gio/gactiongroup.h
+++ b/gio/gactiongroup.h
@@ -156,7 +156,7 @@ gboolean g_action_group_query_action (GAction
const GVariantType **parameter_type,
const GVariantType **state_type,
GVariant **state_hint,
- GVariant **state);
+ GVariant **state) G_GNUC_WARN_UNUSED_RESULT;
G_END_DECLS
diff --git a/glib/gunidecomp.c b/glib/gunidecomp.c
index 07bc3cb22..f14944397 100644
--- a/glib/gunidecomp.c
+++ b/glib/gunidecomp.c
@@ -388,9 +388,33 @@ _g_utf8_normalize_wc (const gchar *str,
while ((max_len < 0 || p < str + max_len) && *p)
{
const gchar *decomp;
- gunichar wc = g_utf8_get_char (p);
+ const char *next, *between;
+ gunichar wc;
- if (wc >= SBase && wc < SBase + SCount)
+ next = g_utf8_next_char (p);
+ /* Avoid reading truncated multibyte characters
+ which run past the end of the buffer */
+ if (max_len < 0)
+ {
+ /* Does the character contain a NUL terminator? */
+ for (between = &p[1]; between < next; between++)
+ {
+ if (G_UNLIKELY (!*between))
+ return NULL;
+ }
+ }
+ else
+ {
+ if (G_UNLIKELY (next > str + max_len))
+ return NULL;
+ }
+ wc = g_utf8_get_char (p);
+
+ if (G_UNLIKELY (wc == (gunichar) -1))
+ {
+ return NULL;
+ }
+ else if (wc >= SBase && wc < SBase + SCount)
{
gsize result_len;
decompose_hangul (wc, NULL, &result_len);
@@ -406,7 +430,7 @@ _g_utf8_normalize_wc (const gchar *str,
n_wc++;
}
- p = g_utf8_next_char (p);
+ p = next;
}
wc_buffer = g_new (gunichar, n_wc + 1);
@@ -548,10 +572,13 @@ g_utf8_normalize (const gchar *str,
GNormalizeMode mode)
{
gunichar *result_wc = _g_utf8_normalize_wc (str, len, mode);
- gchar *result;
+ gchar *result = NULL;
- result = g_ucs4_to_utf8 (result_wc, -1, NULL, NULL, NULL);
- g_free (result_wc);
+ if (G_LIKELY (result_wc != NULL))
+ {
+ result = g_ucs4_to_utf8 (result_wc, -1, NULL, NULL, NULL);
+ g_free (result_wc);
+ }
return result;
}
diff --git a/glib/tests/unicode-normalize.c b/glib/tests/unicode-normalize.c
index 451c03f34..191e5bb98 100644
--- a/glib/tests/unicode-normalize.c
+++ b/glib/tests/unicode-normalize.c
@@ -146,12 +146,50 @@ test_unicode_normalize (void)
g_string_free (buffer, TRUE);
}
+static void
+test_unicode_normalize_invalid (void)
+{
+ /* g_utf8_normalize() should return NULL for all of these invalid inputs */
+ const struct
+ {
+ gssize max_len;
+ const gchar *str;
+ } test_vectors[] = {
+ /* input ending with truncated multibyte encoding */
+ { -1, "\xC0" },
+ { 1, "\xC0\x80" },
+ { -1, "\xE0\x80" },
+ { 2, "\xE0\x80\x80" },
+ { -1, "\xF0\x80\x80" },
+ { 3, "\xF0\x80\x80\x80" },
+ { -1, "\xF8\x80\x80\x80" },
+ { 4, "\xF8\x80\x80\x80\x80" },
+ { 3, "\x20\xE2\x84\xAA" },
+ { -1, "\x20\xE2\x00\xAA" },
+ { -1, "\xC0\x80\xE0\x80" },
+ { 4, "\xC0\x80\xE0\x80\x80" },
+ /* input containing invalid multibyte encoding */
+ { -1, "\xED\x85\x9C\xED\x15\x9C\xED\x85\x9C" },
+ };
+ gsize i;
+
+ for (i = 0; i < G_N_ELEMENTS (test_vectors); i++)
+ {
+ g_test_message ("Invalid UTF-8 vector %" G_GSIZE_FORMAT, i);
+ g_assert_null (g_utf8_normalize (test_vectors[i].str,
+ test_vectors[i].max_len,
+ G_NORMALIZE_ALL));
+ }
+}
+
int
main (int argc, char **argv)
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/unicode/normalize", test_unicode_normalize);
+ g_test_add_func ("/unicode/normalize-invalid",
+ test_unicode_normalize_invalid);
return g_test_run ();
}