diff options
Diffstat (limited to 'debian/patches/Replace-the-icon-validator-with-the-one-from-Flatpak-1.8..patch')
-rw-r--r-- | debian/patches/Replace-the-icon-validator-with-the-one-from-Flatpak-1.8..patch | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/debian/patches/Replace-the-icon-validator-with-the-one-from-Flatpak-1.8..patch b/debian/patches/Replace-the-icon-validator-with-the-one-from-Flatpak-1.8..patch new file mode 100644 index 0000000..bc59814 --- /dev/null +++ b/debian/patches/Replace-the-icon-validator-with-the-one-from-Flatpak-1.8..patch @@ -0,0 +1,311 @@ +From: Simon McVittie <smcv@debian.org> +Date: Fri, 25 Jan 2019 19:13:33 +0000 +Subject: Replace the icon validator with the one from Flatpak 1.8.1 + +We avoid relying on Flatpak here, since that dependency would be quite +circular. + +Signed-off-by: Simon McVittie <smcv@debian.org> +--- + src/notification.c | 14 +--- + src/validate-icon.c | 212 ++++++++++++++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 207 insertions(+), 19 deletions(-) + +diff --git a/src/notification.c b/src/notification.c +index 5412609..35c779c 100644 +--- a/src/notification.c ++++ b/src/notification.c +@@ -366,7 +366,7 @@ validate_icon_more (GVariant *v) + int status; + g_autofree char *err = NULL; + g_autoptr(GError) error = NULL; +- const char *icon_validator = LIBEXECDIR "/flatpak-validate-icon"; ++ const char *icon_validator = LIBEXECDIR "/xdg-desktop-portal-validate-icon"; + const char *args[6]; + + if (G_IS_THEMED_ICON (icon)) +@@ -382,12 +382,6 @@ validate_icon_more (GVariant *v) + return FALSE; + } + +- if (!g_file_test (icon_validator, G_FILE_TEST_EXISTS)) +- { +- g_debug ("Icon validation: %s not found, accepting icon without further validation.", icon_validator); +- return TRUE; +- } +- + bytes = g_bytes_icon_get_bytes (G_BYTES_ICON (icon)); + fd = g_file_open_tmp ("iconXXXXXX", &name, &error); + if (fd == -1) +@@ -420,14 +414,12 @@ validate_icon_more (GVariant *v) + if (!g_spawn_sync (NULL, (char **)args, NULL, 0, NULL, NULL, NULL, &err, &status, &error)) + { + g_debug ("Icon validation: %s", error->message); +- + return FALSE; + } + +- if (!g_spawn_check_exit_status (status, &error)) ++ if (!g_spawn_check_exit_status (status, NULL)) + { +- g_debug ("Icon validation: %s", error->message); +- ++ g_debug ("Icon validation: %s", err); + return FALSE; + } + +diff --git a/src/validate-icon.c b/src/validate-icon.c +index 2bab74f..2c28527 100644 +--- a/src/validate-icon.c ++++ b/src/validate-icon.c +@@ -1,9 +1,35 @@ ++/* ++ * Copyright © 2018 Red Hat, Inc ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library. If not, see <http://www.gnu.org/licenses/>. ++ * ++ * Authors: ++ * Matthias Clasen <mclasen@redhat.com> ++ */ ++ + #include <gdk-pixbuf/gdk-pixbuf.h> ++#include <glib/gstdio.h> ++#include <errno.h> ++#include <unistd.h> + + static int +-validate_icon (const char *filename) ++validate_icon (const char *arg_width, ++ const char *arg_height, ++ const char *filename) + { + GdkPixbufFormat *format; ++ int max_width, max_height; + int width, height; + const char *name; + const char *allowed_formats[] = { "png", "jpeg", "svg", NULL }; +@@ -11,7 +37,7 @@ validate_icon (const char *filename) + g_autoptr(GError) error = NULL; + + format = gdk_pixbuf_get_file_info (filename, &width, &height); +- if (format == NULL) ++ if (format == NULL) + { + g_printerr ("Format not recognized\n"); + return 1; +@@ -20,13 +46,35 @@ validate_icon (const char *filename) + name = gdk_pixbuf_format_get_name (format); + if (!g_strv_contains (allowed_formats, name)) + { +- g_printerr ("Format %s not allowed\n", name); ++ g_printerr ("Format %s not accepted\n", name); + return 1; + } + +- if (width > 256 || height > 256) ++ if (!g_str_equal (name, "svg")) ++ { ++ max_width = g_ascii_strtoll (arg_width, NULL, 10); ++ if (max_width < 16 || max_width > 4096) ++ { ++ g_printerr ("Bad width limit: %s\n", arg_width); ++ return 1; ++ } ++ ++ max_height = g_ascii_strtoll (arg_height, NULL, 10); ++ if (max_height < 16 || max_height > 4096) ++ { ++ g_printerr ("Bad height limit: %s\n", arg_height); ++ return 1; ++ } ++ } ++ else ++ { ++ /* Sanity check for vector files */ ++ max_height = max_width = 4096; ++ } ++ ++ if (width > max_width || height > max_height) + { +- g_printerr ("Image too large (%dx%d)\n", width, height); ++ g_printerr ("Image too large (%dx%d). Max. size %dx%d\n", width, height, max_width, max_height); + return 1; + } + +@@ -40,14 +88,162 @@ validate_icon (const char *filename) + return 0; + } + ++G_GNUC_NULL_TERMINATED ++static void ++add_args (GPtrArray *argv_array, ...) ++{ ++ va_list args; ++ const char *arg; ++ ++ va_start (args, argv_array); ++ while ((arg = va_arg (args, const gchar *))) ++ g_ptr_array_add (argv_array, g_strdup (arg)); ++ va_end (args); ++} ++ ++const char * ++flatpak_get_bwrap (void) ++{ ++ const char *e = g_getenv ("FLATPAK_BWRAP"); ++ ++ if (e != NULL) ++ return e; ++ return HELPER; ++} ++ ++ ++static gboolean ++path_is_usrmerged (const char *dir) ++{ ++ /* does /dir point to /usr/dir? */ ++ g_autofree char *target = NULL; ++ GStatBuf stat_buf_src, stat_buf_target; ++ ++ if (g_stat (dir, &stat_buf_src) < 0) ++ return FALSE; ++ ++ target = g_strdup_printf ("/usr/%s", dir); ++ ++ if (g_stat (target, &stat_buf_target) < 0) ++ return FALSE; ++ ++ return (stat_buf_src.st_dev == stat_buf_target.st_dev) && ++ (stat_buf_src.st_ino == stat_buf_target.st_ino); ++} ++ ++static int ++rerun_in_sandbox (const char *arg_width, ++ const char *arg_height, ++ const char *filename) ++{ ++ const char * const usrmerged_dirs[] = { "bin", "lib32", "lib64", "lib", "sbin" }; ++ int i; ++ g_autoptr(GPtrArray) args = g_ptr_array_new_with_free_func (g_free); ++ char validate_icon[PATH_MAX + 1]; ++ ssize_t symlink_size; ++ ++ symlink_size = readlink ("/proc/self/exe", validate_icon, sizeof (validate_icon) - 1); ++ if (symlink_size < 0 || (size_t) symlink_size >= sizeof (validate_icon)) ++ { ++ g_printerr ("Error: failed to read /proc/self/exe\n"); ++ return 1; ++ } ++ ++ validate_icon[symlink_size] = 0; ++ ++ add_args (args, ++ flatpak_get_bwrap (), ++ "--unshare-ipc", ++ "--unshare-net", ++ "--unshare-pid", ++ "--ro-bind", "/usr", "/usr", ++ "--ro-bind", "/etc/ld.so.cache", "/etc/ld.so.cache", ++ "--ro-bind", validate_icon, validate_icon, ++ NULL); ++ ++ /* These directories might be symlinks into /usr/... */ ++ for (i = 0; i < G_N_ELEMENTS (usrmerged_dirs); i++) ++ { ++ g_autofree char *absolute_dir = g_strdup_printf ("/%s", usrmerged_dirs[i]); ++ ++ if (!g_file_test (absolute_dir, G_FILE_TEST_EXISTS)) ++ continue; ++ ++ if (path_is_usrmerged (absolute_dir)) ++ { ++ g_autofree char *symlink_target = g_strdup_printf ("/usr/%s", absolute_dir); ++ ++ add_args (args, ++ "--symlink", symlink_target, absolute_dir, ++ NULL); ++ } ++ else ++ { ++ add_args (args, ++ "--ro-bind", absolute_dir, absolute_dir, ++ NULL); ++ } ++ } ++ ++ add_args (args, ++ "--tmpfs", "/tmp", ++ "--proc", "/proc", ++ "--dev", "/dev", ++ "--chdir", "/", ++ "--setenv", "GIO_USE_VFS", "local", ++ "--unsetenv", "TMPDIR", ++ "--die-with-parent", ++ "--ro-bind", filename, filename, ++ NULL); ++ ++ if (g_getenv ("G_MESSAGES_DEBUG")) ++ add_args (args, "--setenv", "G_MESSAGES_DEBUG", g_getenv ("G_MESSAGES_DEBUG"), NULL); ++ if (g_getenv ("G_MESSAGES_PREFIXED")) ++ add_args (args, "--setenv", "G_MESSAGES_PREFIXED", g_getenv ("G_MESSAGES_PREFIXED"), NULL); ++ ++ add_args (args, validate_icon, arg_width, arg_height, filename, NULL); ++ g_ptr_array_add (args, NULL); ++ ++ { ++ g_autofree char *cmdline = g_strjoinv (" ", (char **) args->pdata); ++ g_debug ("Icon validation: Spawning %s", cmdline); ++ } ++ ++ execvpe (flatpak_get_bwrap (), (char **) args->pdata, NULL); ++ /* If we get here, then execvpe() failed. */ ++ g_printerr ("Icon validation: execvpe %s: %s\n", flatpak_get_bwrap (), g_strerror (errno)); ++ return 1; ++} ++ ++static gboolean opt_sandbox; ++ ++static GOptionEntry entries[] = { ++ { "sandbox", 0, 0, G_OPTION_ARG_NONE, &opt_sandbox, "Run in a sandbox", NULL }, ++ { NULL } ++}; ++ + int + main (int argc, char *argv[]) + { +- if (argc != 2) ++ GOptionContext *context; ++ GError *error = NULL; ++ ++ context = g_option_context_new ("WIDTH HEIGHT PATH"); ++ g_option_context_add_main_entries (context, entries, NULL); ++ if (!g_option_context_parse (context, &argc, &argv, &error)) ++ { ++ g_printerr ("Error: %s\n", error->message); ++ return 1; ++ } ++ ++ if (argc != 4) + { +- g_error ("Expect a single path"); ++ g_printerr ("Usage: %s [OPTION…] WIDTH HEIGHT PATH\n", argv[0]); + return 1; + } + +- return validate_icon (argv[1]); ++ if (opt_sandbox) ++ return rerun_in_sandbox (argv[1], argv[2], argv[3]); ++ else ++ return validate_icon (argv[1], argv[2], argv[3]); + } |