[epiphany/pgriffis/web-extension/manifest-parsing: 3/3] WebExtensions: Restrict all icon loading to bundled resources




commit 4a0ebf6521fd1c1250c9ea45c86652828246b156
Author: Patrick Griffis <pgriffis igalia com>
Date:   Sun Jun 26 12:13:31 2022 -0500

    WebExtensions: Restrict all icon loading to bundled resources

 src/webextension/api/pageaction.c     | 14 ++++--
 src/webextension/ephy-web-extension.c | 92 ++++++++++++++++-------------------
 src/webextension/ephy-web-extension.h |  3 +-
 3 files changed, 53 insertions(+), 56 deletions(-)
---
diff --git a/src/webextension/api/pageaction.c b/src/webextension/api/pageaction.c
index dc5d01e46..76ee0bb3a 100644
--- a/src/webextension/api/pageaction.c
+++ b/src/webextension/api/pageaction.c
@@ -61,7 +61,8 @@ pageaction_handler_seticon (EphyWebExtension  *self,
                             GError           **error)
 {
   GtkWidget *action;
-  g_autoptr (JSCValue) path = NULL;
+  g_autofree char *path_str = NULL;
+  g_autoptr (JSCValue) path_value = NULL;
   g_autoptr (GdkPixbuf) pixbuf = NULL;
   g_autoptr (JSCValue) value = jsc_value_object_get_property_at_index (args, 0);
 
@@ -71,11 +72,16 @@ pageaction_handler_seticon (EphyWebExtension  *self,
     return NULL;
   }
 
-  path = jsc_value_object_get_property (value, "path");
-  pixbuf = ephy_web_extension_load_pixbuf (self, jsc_value_to_string (path));
+  path_value = jsc_value_object_get_property (value, "path");
+  if (jsc_value_is_string (path_value)) {
+    path_str = jsc_value_to_string (path_value);
+    pixbuf = ephy_web_extension_load_pixbuf (self, path_str, -1);
+  } else {
+    g_set_error_literal (error, WEB_EXTENSION_ERROR, WEB_EXTENSION_ERROR_INVALID_ARGUMENT, 
"pageAction.setIcon(): Currently only single path strings are supported.");
+    return NULL;
+  }
 
   gtk_image_set_from_pixbuf (GTK_IMAGE (gtk_bin_get_child (GTK_BIN (action))), pixbuf);
-
   return NULL;
 }
 
diff --git a/src/webextension/ephy-web-extension.c b/src/webextension/ephy-web-extension.c
index 463b7aa29..da364676e 100644
--- a/src/webextension/ephy-web-extension.c
+++ b/src/webextension/ephy-web-extension.c
@@ -42,7 +42,6 @@
 
 typedef struct {
   gint64 size;
-  char *file;
   GdkPixbuf *pixbuf;
 } WebExtensionIcon;
 
@@ -156,35 +155,17 @@ ephy_web_extension_get_resource_as_string (EphyWebExtension *self,
 
 static WebExtensionIcon *
 web_extension_icon_new (EphyWebExtension *self,
-                        const char       *file,
+                        const char       *resource_path,
                         gint64            size)
 {
   WebExtensionIcon *icon = NULL;
-  g_autoptr (GInputStream) stream = NULL;
-  g_autoptr (GError) error = NULL;
   g_autoptr (GdkPixbuf) pixbuf = NULL;
-  const unsigned char *data = NULL;
-  gsize length;
-
-  data = ephy_web_extension_get_resource (self, file, &length);
-  if (!data) {
-    if (!self->xpi) {
-      g_autofree char *path = NULL;
-      path = g_build_filename (self->base_location, file, NULL);
-      pixbuf = gdk_pixbuf_new_from_file (path, &error);
-    }
-  } else {
-    stream = g_memory_input_stream_new_from_data (data, length, NULL);
-    pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, &error);
-  }
 
-  if (!pixbuf) {
-    g_warning ("Could not read web_extension icon: %s", error ? error->message : "");
+  pixbuf = ephy_web_extension_load_pixbuf (self, resource_path, size);
+  if (!pixbuf)
     return NULL;
-  }
 
-  icon = g_malloc0 (sizeof (WebExtensionIcon));
-  icon->file = g_strdup (file);
+  icon = g_new (WebExtensionIcon, 1);
   icon->size = size;
   icon->pixbuf = g_steal_pointer (&pixbuf);
 
@@ -194,7 +175,6 @@ web_extension_icon_new (EphyWebExtension *self,
 static void
 web_extension_icon_free (WebExtensionIcon *icon)
 {
-  g_clear_pointer (&icon->file, g_free);
   g_clear_object (&icon->pixbuf);
   g_free (icon);
 }
@@ -249,22 +229,22 @@ web_extension_add_icon (JsonObject *object,
 {
   EphyWebExtension *self = EPHY_WEB_EXTENSION (user_data);
   WebExtensionIcon *icon;
-  const char *file;
+  const char *path;
   gint64 size;
 
-  file = ephy_json_node_to_string (member_node);
-  if (!file) {
+  path = ephy_json_node_to_string (member_node);
+  if (!path) {
     LOG ("Skipping icon as value is invalid");
     return;
   }
 
   size = g_ascii_strtoll (member_name, NULL, 0);
   if (size == 0) {
-    LOG ("Skipping %s as web extension icon as size is 0", file);
+    LOG ("Skipping %s as web extension icon as size is 0", path);
     return;
   }
 
-  icon = web_extension_icon_new (self, file, size);
+  icon = web_extension_icon_new (self, path, size);
   if (icon)
     self->icons = g_list_append (self->icons, icon);
 }
@@ -307,7 +287,7 @@ ephy_web_extension_get_icon (EphyWebExtension *self,
     WebExtensionIcon *icon = list->data;
 
     if (icon->size == size)
-      return gdk_pixbuf_scale_simple (icon->pixbuf, size, size, GDK_INTERP_BILINEAR);
+      return gdk_pixbuf_copy (icon->pixbuf);
 
     if (!icon_fallback || icon->size > icon_fallback->size)
       icon_fallback = icon;
@@ -566,32 +546,23 @@ web_extension_parse_page_action (EphyWebExtension *self,
                                  JsonObject       *object)
 {
   const char *default_icon = ephy_json_object_get_string (object, "default_icon");
-  g_autofree char *path = NULL;
-  WebExtensionPageAction *page_action;
+  g_autoptr (GdkPixbuf) pixbuf = NULL;
   WebExtensionIcon *icon;
-  g_autoptr (GFile) base = NULL;
-  g_autoptr (GFile) icon_file = NULL;
 
   if (!default_icon) {
     LOG ("We only support page_action's default_icon as a string currently.");
     return;
   }
-  base = g_file_new_for_path (self->base_location);
-  icon_file = g_file_resolve_relative_path (base, default_icon);
 
-  if (!g_file_has_prefix (icon_file, base)) {
-    LOG ("page_action's default_icon is outside of the extension");
+  pixbuf = ephy_web_extension_load_pixbuf (self, default_icon, -1);
+  if (!pixbuf)
     return;
-  }
-
-  page_action = g_malloc0 (sizeof (WebExtensionPageAction));
-  self->page_action = page_action;
 
-  icon = g_malloc (sizeof (WebExtensionIcon));
+  icon = g_new (WebExtensionIcon, 1);
   icon->size = -1;
-  icon->file = g_strdup (default_icon);
-  icon->pixbuf = gdk_pixbuf_new_from_file (g_file_peek_path (icon_file), NULL);
+  icon->pixbuf = g_steal_pointer (&pixbuf);
 
+  self->page_action = g_new0 (WebExtensionPageAction, 1);
   self->page_action->default_icons = g_list_append (self->page_action->default_icons, icon);
 }
 
@@ -692,8 +663,8 @@ web_extension_parse_browser_action (EphyWebExtension *self,
     } else if (JSON_NODE_HOLDS_VALUE (icon_node) && json_node_get_value_type (icon_node) == G_TYPE_STRING) {
       const char *default_icon = json_object_get_string_member (object, "default_icon");
       WebExtensionIcon *icon = web_extension_icon_new (self, default_icon, -1);
-
-      self->browser_action->default_icons = g_list_append (self->browser_action->default_icons, icon);
+      if (icon)
+        self->browser_action->default_icons = g_list_append (self->browser_action->default_icons, icon);
     } else {
       LOG ("browser_action's default_icon is invalid");
     }
@@ -1128,13 +1099,32 @@ ephy_web_extension_load_async (GFile               *target,
 
 GdkPixbuf *
 ephy_web_extension_load_pixbuf (EphyWebExtension *self,
-                                char             *file)
+                                const char       *resource_path,
+                                int               size)
 {
-  g_autofree gchar *path = NULL;
+  g_autoptr (GInputStream) stream = NULL;
+  g_autoptr (GError) error = NULL;
+  GdkPixbuf *pixbuf;
+  const unsigned char *data = NULL;
+  gsize length;
 
-  path = g_build_filename (self->base_location, file, NULL);
+  if (*resource_path == '/')
+    resource_path++;
+
+  data = ephy_web_extension_get_resource (self, resource_path, &length);
+  if (!data) {
+    g_warning ("Failed to find web extension icon %s", resource_path);
+    return NULL;
+  }
+
+  stream = g_memory_input_stream_new_from_data (data, length, NULL);
+  pixbuf = gdk_pixbuf_new_from_stream_at_scale (stream, size, size, TRUE, NULL, &error);
+  if (!pixbuf) {
+    g_warning ("Could not load web extension icon: %s", error->message);
+    return NULL;
+  }
 
-  return gdk_pixbuf_new_from_file (path, NULL);
+  return pixbuf;
 }
 
 void
diff --git a/src/webextension/ephy-web-extension.h b/src/webextension/ephy-web-extension.h
index a0601e804..5155ef3b0 100644
--- a/src/webextension/ephy-web-extension.h
+++ b/src/webextension/ephy-web-extension.h
@@ -94,7 +94,8 @@ EphyWebExtension      *ephy_web_extension_load_finished                   (GObje
                                                                            GError       **error);
 
 GdkPixbuf             *ephy_web_extension_load_pixbuf                     (EphyWebExtension *self,
-                                                                           char             *file);
+                                                                           const char       *resource_path,
+                                                                           int               size);
 
 gboolean               ephy_web_extension_has_page_action                 (EphyWebExtension *self);
 


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