summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Withnall <withnall@endlessm.com>2018-07-05 12:01:48 +0100
committerPhilip Withnall <withnall@endlessm.com>2018-07-05 12:03:10 +0100
commitab87af17340ff56a2000f0704c15f2dc4c98ed72 (patch)
tree690a4201fc99781a5424dadfdb78971ce8d8a095
parentf62d7c1e2a38006a6ad1d735135f222ce5ceb726 (diff)
downloadglib-ab87af17340ff56a2000f0704c15f2dc4c98ed72.tar.gz
gresource: Fix potential array overflow if using empty paths
Adds tests to cover this case and similar cases for various GResource methods in future. Signed-off-by: Philip Withnall <withnall@endlessm.com> https://gitlab.gnome.org/GNOME/glib/issues/927
-rw-r--r--gio/gresource.c3
-rw-r--r--gio/tests/resources.c66
2 files changed, 54 insertions, 15 deletions
diff --git a/gio/gresource.c b/gio/gresource.c
index 18383d9b6..bf54f1d78 100644
--- a/gio/gresource.c
+++ b/gio/gresource.c
@@ -606,8 +606,9 @@ do_lookup (GResource *resource,
gboolean res = FALSE;
GVariant *value;
+ /* Drop any trailing slash. */
path_len = strlen (path);
- if (path[path_len-1] == '/')
+ if (path_len >= 1 && path[path_len-1] == '/')
{
path = free_path = g_strdup (path);
free_path[path_len-1] = 0;
diff --git a/gio/tests/resources.c b/gio/tests/resources.c
index 5d2e27474..6ae8e7d64 100644
--- a/gio/tests/resources.c
+++ b/gio/tests/resources.c
@@ -32,14 +32,24 @@ test_resource (GResource *resource)
char **children;
GInputStream *in;
char buffer[128];
+ const gchar *not_found_paths[] =
+ {
+ "/not/there",
+ "/",
+ "",
+ };
+ gsize i;
- found = g_resource_get_info (resource,
- "/not/there",
- G_RESOURCE_LOOKUP_FLAGS_NONE,
- &size, &flags, &error);
- g_assert (!found);
- g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
- g_clear_error (&error);
+ for (i = 0; i < G_N_ELEMENTS (not_found_paths); i++)
+ {
+ found = g_resource_get_info (resource,
+ not_found_paths[i],
+ G_RESOURCE_LOOKUP_FLAGS_NONE,
+ &size, &flags, &error);
+ g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
+ g_clear_error (&error);
+ g_assert_false (found);
+ }
found = g_resource_get_info (resource,
"/test1.txt",
@@ -68,6 +78,17 @@ test_resource (GResource *resource)
g_assert_cmpint (size, ==, 6);
g_assert_cmpuint (flags, ==, 0);
+ for (i = 0; i < G_N_ELEMENTS (not_found_paths); i++)
+ {
+ data = g_resource_lookup_data (resource,
+ not_found_paths[i],
+ G_RESOURCE_LOOKUP_FLAGS_NONE,
+ &error);
+ g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
+ g_clear_error (&error);
+ g_assert_null (data);
+ }
+
data = g_resource_lookup_data (resource,
"/test1.txt",
G_RESOURCE_LOOKUP_FLAGS_NONE,
@@ -76,6 +97,17 @@ test_resource (GResource *resource)
g_assert_no_error (error);
g_bytes_unref (data);
+ for (i = 0; i < G_N_ELEMENTS (not_found_paths); i++)
+ {
+ in = g_resource_open_stream (resource,
+ not_found_paths[i],
+ G_RESOURCE_LOOKUP_FLAGS_NONE,
+ &error);
+ g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
+ g_clear_error (&error);
+ g_assert_null (in);
+ }
+
in = g_resource_open_stream (resource,
"/test1.txt",
G_RESOURCE_LOOKUP_FLAGS_NONE,
@@ -118,13 +150,19 @@ test_resource (GResource *resource)
g_assert_cmpstr (g_bytes_get_data (data, NULL), ==, "test2\n");
g_bytes_unref (data);
- children = g_resource_enumerate_children (resource,
- "/not/here",
- G_RESOURCE_LOOKUP_FLAGS_NONE,
- &error);
- g_assert (children == NULL);
- g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
- g_clear_error (&error);
+ for (i = 0; i < G_N_ELEMENTS (not_found_paths); i++)
+ {
+ if (g_str_equal (not_found_paths[i], "/"))
+ continue;
+
+ children = g_resource_enumerate_children (resource,
+ not_found_paths[i],
+ G_RESOURCE_LOOKUP_FLAGS_NONE,
+ &error);
+ g_assert_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_NOT_FOUND);
+ g_clear_error (&error);
+ g_assert_null (children);
+ }
children = g_resource_enumerate_children (resource,
"/a_prefix",