From 1a7e69fced4637d47b1a92817a53f942382527ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 29 Jan 2025 14:22:20 +0100 Subject: [PATCH] Fix refcount issue in stylesheet tracking Resolves: https://issues.redhat.com/browse/RHEL-62870 --- ...-theme-Reuse-stylesheets-if-possible.patch | 114 ++++++++++++++++++ gnome-shell.spec | 1 + 2 files changed, 115 insertions(+) create mode 100644 0001-st-theme-Reuse-stylesheets-if-possible.patch diff --git a/0001-st-theme-Reuse-stylesheets-if-possible.patch b/0001-st-theme-Reuse-stylesheets-if-possible.patch new file mode 100644 index 0000000..f608a92 --- /dev/null +++ b/0001-st-theme-Reuse-stylesheets-if-possible.patch @@ -0,0 +1,114 @@ +From 4ad7120d0188dcf21146da02637f82bac2ac7ad6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 29 Jan 2025 02:46:44 +0100 +Subject: [PATCH] st/theme: Reuse stylesheets if possible + +The following happens when processing an `@import()` rule: + + 1. `_st_theme_resolve_url()` to resolve file + 2. `insert_stylesheet()` to track file/sheet + a. take ownership of file/sheet (ref) + b. use file as key in `stylesheets_by_file` hash table + c. use file as value in `files_by_stylesheet` hash table + 3. release reference to file + +This leads to a refcount error when importing a file that +was already parsed before: + + 1. file start with refcount 1 + 2. `insert_stylesheet()` + a. increases refcount to 2 + b. inserting into `stylesheets_by_file` *decreases* the + passed-in key if the key already exists + c. `files_by_stylesheet` now tracks a file with recount 1 + 3. releases the last reference to file + +The file object tracked in `files_by_stylesheet` is now invalid, +and accessing it results in a crash. + +Avoid this issue by reusing existing stylesheets, so we don't insert +a stylesheet that's already tracked. + +As a side-effect, this also saves us from re-parsing the same file +unnecessarily. + +Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/7306 +--- + src/st/st-theme.c | 32 ++++++++++++++++++++++++++------ + 1 file changed, 26 insertions(+), 6 deletions(-) + +diff --git a/src/st/st-theme.c b/src/st/st-theme.c +index 9867ee1510..9ad99e2b1a 100644 +--- a/src/st/st-theme.c ++++ b/src/st/st-theme.c +@@ -244,6 +244,27 @@ insert_stylesheet (StTheme *theme, + g_hash_table_insert (theme->files_by_stylesheet, stylesheet, file); + } + ++static CRStyleSheet * ++resolve_stylesheet (StTheme *theme, ++ GFile *file, ++ GError **error) ++{ ++ CRStyleSheet *sheet; ++ ++ sheet = g_hash_table_lookup (theme->stylesheets_by_file, file); ++ if (sheet) ++ { ++ cr_stylesheet_ref (sheet); ++ return sheet; ++ } ++ ++ sheet = parse_stylesheet (file, error); ++ if (sheet) ++ insert_stylesheet (theme, file, sheet); ++ ++ return sheet; ++} ++ + /** + * st_theme_load_stylesheet: + * @theme: a #StTheme +@@ -261,13 +282,12 @@ st_theme_load_stylesheet (StTheme *theme, + { + CRStyleSheet *stylesheet; + +- stylesheet = parse_stylesheet (file, error); ++ stylesheet = resolve_stylesheet (theme, file, error); + if (!stylesheet) + return FALSE; + + stylesheet->app_data = GUINT_TO_POINTER (TRUE); + +- insert_stylesheet (theme, file, stylesheet); + cr_stylesheet_ref (stylesheet); + theme->custom_stylesheets = g_slist_prepend (theme->custom_stylesheets, stylesheet); + g_signal_emit (theme, signals[STYLESHEETS_CHANGED], 0); +@@ -884,6 +904,7 @@ add_matched_properties (StTheme *a_this, + + if (import_rule->sheet == NULL) + { ++ CRStyleSheet *sheet = NULL; + GFile *file = NULL; + + if (import_rule->url->stryng && import_rule->url->stryng->str) +@@ -891,13 +912,12 @@ add_matched_properties (StTheme *a_this, + file = _st_theme_resolve_url (a_this, + a_nodesheet, + import_rule->url->stryng->str); +- import_rule->sheet = parse_stylesheet (file, NULL); ++ sheet = resolve_stylesheet (a_this, file, NULL); + } + +- if (import_rule->sheet) ++ if (sheet) + { +- insert_stylesheet (a_this, file, import_rule->sheet); +- /* refcount of stylesheets starts off at zero, so we don't need to unref! */ ++ import_rule->sheet = sheet; + } + else + { +-- +2.48.1 + diff --git a/gnome-shell.spec b/gnome-shell.spec index be6041e..dc782a4 100644 --- a/gnome-shell.spec +++ b/gnome-shell.spec @@ -43,6 +43,7 @@ Patch: 0001-st-texture-cache-purge-on-resume.patch Patch: fix-some-js-warnings.patch Patch: 0001-data-Update-generated-stylesheets.patch Patch: 0001-theme-Welcome-Illustration.patch +Patch: 0001-st-theme-Reuse-stylesheets-if-possible.patch %define eds_version 3.45.1 %define gnome_desktop_version 44.0-7