[glib: 2/3] gresource: Fix potential array overflow if using empty paths



commit ab87af17340ff56a2000f0704c15f2dc4c98ed72
Author: Philip Withnall <withnall endlessm com>
Date:   Thu Jul 5 12:01:48 2018 +0100

    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

 gio/gresource.c       |  3 ++-
 gio/tests/resources.c | 66 ++++++++++++++++++++++++++++++++++++++++-----------
 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",


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]