[epiphany/mcatanzaro/user-style: 5/5] embed-prefs: improve safety of style sheet monitor



commit 0e89be789b4787e691cf84eea6ad4e2303c8a1e4
Author: Michael Catanzaro <mcatanzaro gnome org>
Date:   Mon Dec 16 19:52:29 2019 -0600

    embed-prefs: improve safety of style sheet monitor
    
    The style sheet monitoring code doesn't seem to be prepared for the user
    to remove the user style. When the style is removed, we should stop
    monitoring the file and un-apply the style on all views.
    
    Also, there is a refcounting error in user_style_sheet_read_cb():
    output_stream is unreffed immediately after starting an async function
    call, but it needs to be kept alive until after the call is completed.
    This is bad because it could cause crashes.
    
    Finally, and of least importance, webkit_pref_callback_user_stylesheet()
    is currently designed to assert if called to enable the setting twice in
    a row. Although that should probably never happen -- if the setting is
    currently enabled, then if changed it should be switched to disabled,
    not called again to enable -- it's simple to rearraneg the code to be
    robust to this possibility.
    
    Noticed in #1026.

 embed/ephy-embed-prefs.c | 65 ++++++++++++++++++++++--------------------------
 1 file changed, 30 insertions(+), 35 deletions(-)
---
diff --git a/embed/ephy-embed-prefs.c b/embed/ephy-embed-prefs.c
index a7bf7b80d..ae509b25c 100644
--- a/embed/ephy-embed-prefs.c
+++ b/embed/ephy-embed-prefs.c
@@ -53,10 +53,9 @@ update_user_style_on_all_ucm (void)
   for (list = ucm_list; list != NULL; list = list->next) {
     WebKitUserContentManager *ucm = list->data;
 
+    webkit_user_content_manager_remove_all_style_sheets (ucm);
     if (style_sheet)
       webkit_user_content_manager_add_style_sheet (ucm, style_sheet);
-    else
-      webkit_user_content_manager_remove_all_style_sheets (ucm);
   }
 }
 
@@ -67,16 +66,18 @@ user_style_sheet_output_stream_splice_cb (GOutputStream *output_stream,
 {
   gssize bytes;
 
+  g_clear_pointer (&style_sheet, webkit_user_style_sheet_unref);
+
   bytes = g_output_stream_splice_finish (output_stream, result, NULL);
   if (bytes > 0) {
-    g_clear_pointer (&style_sheet, webkit_user_style_sheet_unref);
-
     style_sheet = webkit_user_style_sheet_new (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM 
(output_stream)),
                                                WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES, 
WEBKIT_USER_STYLE_LEVEL_USER,
                                                NULL, NULL);
-
-    update_user_style_on_all_ucm ();
   }
+
+  update_user_style_on_all_ucm ();
+
+  g_object_unref (output_stream);
 }
 
 static void
@@ -84,23 +85,21 @@ user_style_sheet_read_cb (GFile        *file,
                           GAsyncResult *result,
                           gpointer      user_data)
 {
-  GFileInputStream *input_stream;
-  GOutputStream *output_stream;
+  g_autoptr (GFileInputStream) input_stream = NULL;
+  g_autoptr (GOutputStream) output_stream = NULL;
 
   input_stream = g_file_read_finish (file, result, NULL);
   if (!input_stream)
     return;
 
   output_stream = g_memory_output_stream_new_resizable ();
-  g_output_stream_splice_async (output_stream, G_INPUT_STREAM (input_stream),
-                                G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE |
-                                G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
+  g_output_stream_splice_async (g_steal_pointer (&output_stream),
+                                G_INPUT_STREAM (input_stream),
+                                G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE | G_OUTPUT_STREAM_SPLICE_CLOSE_TARGET,
                                 G_PRIORITY_DEFAULT,
                                 NULL,
                                 (GAsyncReadyCallback)user_style_sheet_output_stream_splice_cb,
                                 NULL);
-  g_object_unref (input_stream);
-  g_object_unref (output_stream);
 }
 
 static void
@@ -121,37 +120,33 @@ webkit_pref_callback_user_stylesheet (GSettings  *settings,
                                       const char *key,
                                       gpointer    data)
 {
+  g_autoptr (GFile) file = NULL;
+  g_autofree char *filename = NULL;
   gboolean value;
+  GError *error = NULL;
 
   value = g_settings_get_boolean (settings, key);
 
-  if (!value) {
-    g_clear_object (&user_style_sheet_monitor);
-    g_clear_pointer (&style_sheet, webkit_user_style_sheet_unref);
+  g_clear_object (&user_style_sheet_monitor);
+  g_clear_pointer (&style_sheet, webkit_user_style_sheet_unref);
 
+  if (!value) {
     update_user_style_on_all_ucm ();
-  } else {
-    GFile *file;
-    GError *error = NULL;
-    char *filename;
+    return;
+  }
 
-    filename = g_build_filename (ephy_profile_dir (), USER_STYLESHEET_FILENAME, NULL);
-    file = g_file_new_for_path (filename);
-    g_free (filename);
+  filename = g_build_filename (ephy_profile_dir (), USER_STYLESHEET_FILENAME, NULL);
+  file = g_file_new_for_path (filename);
 
-    g_file_read_async (file, G_PRIORITY_DEFAULT, NULL,
-                       (GAsyncReadyCallback)user_style_sheet_read_cb, NULL);
-
-    g_assert (user_style_sheet_monitor == NULL);
-    user_style_sheet_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error);
-    if (user_style_sheet_monitor == NULL) {
-      g_warning ("Could not create a file monitor for %s: %s\n", g_file_get_uri (file), error->message);
-      g_error_free (error);
-    } else {
-      g_signal_connect (user_style_sheet_monitor, "changed", G_CALLBACK (user_style_sheet_file_changed), 
NULL);
-    }
+  g_file_read_async (file, G_PRIORITY_DEFAULT, NULL,
+                     (GAsyncReadyCallback)user_style_sheet_read_cb, NULL);
 
-    g_object_unref (file);
+  user_style_sheet_monitor = g_file_monitor_file (file, G_FILE_MONITOR_NONE, NULL, &error);
+  if (user_style_sheet_monitor == NULL) {
+    g_warning ("Could not create a file monitor for %s: %s\n", g_file_get_uri (file), error->message);
+    g_error_free (error);
+  } else {
+    g_signal_connect (user_style_sheet_monitor, "changed", G_CALLBACK (user_style_sheet_file_changed), NULL);
   }
 }
 


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