266 lines
8.0 KiB
Diff
266 lines
8.0 KiB
Diff
From d9c50cac5d160798498e42d5b190ad89920a9a6a Mon Sep 17 00:00:00 2001
|
|
From: Alex Henrie <alexhenrie24@gmail.com>
|
|
Date: Sun, 19 Nov 2023 15:54:27 -0700
|
|
Subject: [PATCH 1/2] xdgmime: Handle buggy type definitions with circular
|
|
inheritance
|
|
|
|
This fixes a stack overflow reported by a user who had both the
|
|
definition of text/javascript from shared-mime-info 2.3 and the
|
|
definition of text/javascript from shared-mime-info 2.4 installed at the
|
|
same time. In 2.3, text/javascript is a subtype of
|
|
application/ecmascript, but in 2.4 application/ecmascript is a subtype
|
|
of text/javascript. Having both at the same time resulted in circular
|
|
inheritance.
|
|
|
|
The new logic keeps a list of all parents that have already been
|
|
checked, which is more comprehensive than the old workaround that was
|
|
implemented in commit 38869ece2 ("xdgmime: Prevent infinite loops from
|
|
badly-formed MIME registrations").
|
|
|
|
https://bugs.archlinux.org/task/80279
|
|
---
|
|
gio/xdgmime/xdgmime.c | 43 +++++++++++++++++++++++++++-------
|
|
gio/xdgmime/xdgmime.h | 3 ++-
|
|
gio/xdgmime/xdgmimecache.c | 47 ++++++++++++++++++++++++++++----------
|
|
gio/xdgmime/xdgmimecache.h | 3 ++-
|
|
4 files changed, 74 insertions(+), 22 deletions(-)
|
|
|
|
diff --git a/gio/xdgmime/xdgmime.c b/gio/xdgmime/xdgmime.c
|
|
index c3c11625e8..31f352ceee 100644
|
|
--- a/gio/xdgmime/xdgmime.c
|
|
+++ b/gio/xdgmime/xdgmime.c
|
|
@@ -835,13 +835,16 @@ xdg_mime_is_super_type (const char *mime)
|
|
|
|
int
|
|
_xdg_mime_mime_type_subclass (const char *mime,
|
|
- const char *base)
|
|
+ const char *base,
|
|
+ const char **seen)
|
|
{
|
|
- const char *umime, *ubase;
|
|
+ const char *umime, *ubase, *parent;
|
|
const char **parents;
|
|
|
|
+ int first_seen = 0, i, ret = 0;
|
|
+
|
|
if (_caches)
|
|
- return _xdg_mime_cache_mime_type_subclass (mime, base);
|
|
+ return _xdg_mime_cache_mime_type_subclass (mime, base, NULL);
|
|
|
|
umime = _xdg_mime_unalias_mime_type (mime);
|
|
ubase = _xdg_mime_unalias_mime_type (base);
|
|
@@ -864,15 +867,39 @@ _xdg_mime_mime_type_subclass (const char *mime,
|
|
if (strcmp (ubase, "application/octet-stream") == 0 &&
|
|
strncmp (umime, "inode/", 6) != 0)
|
|
return 1;
|
|
-
|
|
+
|
|
+ if (!seen)
|
|
+ {
|
|
+ seen = calloc (1, sizeof (char *));
|
|
+ first_seen = 1;
|
|
+ }
|
|
+
|
|
parents = _xdg_mime_parent_list_lookup (parent_list, umime);
|
|
for (; parents && *parents; parents++)
|
|
{
|
|
- if (_xdg_mime_mime_type_subclass (*parents, ubase))
|
|
- return 1;
|
|
+ parent = *parents;
|
|
+
|
|
+ /* Detect and avoid buggy circular relationships */
|
|
+ for (i = 0; seen[i] != NULL; i++)
|
|
+ if (parent == seen[i])
|
|
+ goto next_parent;
|
|
+ seen = realloc (seen, (i + 2) * sizeof (char *));
|
|
+ seen[i] = parent;
|
|
+ seen[i + 1] = NULL;
|
|
+
|
|
+ if (_xdg_mime_mime_type_subclass (parent, ubase, seen))
|
|
+ {
|
|
+ ret = 1;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ next_parent:
|
|
}
|
|
|
|
- return 0;
|
|
+done:
|
|
+ if (first_seen)
|
|
+ free (seen);
|
|
+ return ret;
|
|
}
|
|
|
|
int
|
|
@@ -881,7 +908,7 @@ xdg_mime_mime_type_subclass (const char *mime,
|
|
{
|
|
xdg_mime_init ();
|
|
|
|
- return _xdg_mime_mime_type_subclass (mime, base);
|
|
+ return _xdg_mime_mime_type_subclass (mime, base, NULL);
|
|
}
|
|
|
|
char **
|
|
diff --git a/gio/xdgmime/xdgmime.h b/gio/xdgmime/xdgmime.h
|
|
index c5909967f2..bbae1be790 100644
|
|
--- a/gio/xdgmime/xdgmime.h
|
|
+++ b/gio/xdgmime/xdgmime.h
|
|
@@ -125,7 +125,8 @@ void xdg_mime_set_dirs (const char * const *dirs);
|
|
int _xdg_mime_mime_type_equal (const char *mime_a,
|
|
const char *mime_b);
|
|
int _xdg_mime_mime_type_subclass (const char *mime,
|
|
- const char *base);
|
|
+ const char *base,
|
|
+ const char **seen);
|
|
const char *_xdg_mime_unalias_mime_type (const char *mime);
|
|
|
|
|
|
diff --git a/gio/xdgmime/xdgmimecache.c b/gio/xdgmime/xdgmimecache.c
|
|
index 234e4b4677..6b1985082f 100644
|
|
--- a/gio/xdgmime/xdgmimecache.c
|
|
+++ b/gio/xdgmime/xdgmimecache.c
|
|
@@ -751,8 +751,8 @@ cache_get_mime_type_for_data (const void *data,
|
|
/* Pick glob-result R where mime_type inherits from R */
|
|
for (n = 0; n < n_mime_types; n++)
|
|
{
|
|
- if (mime_types[n] && _xdg_mime_cache_mime_type_subclass(mime_types[n], mime_type))
|
|
- return mime_types[n];
|
|
+ if (mime_types[n] && _xdg_mime_cache_mime_type_subclass (mime_types[n], mime_type, NULL))
|
|
+ return mime_types[n];
|
|
}
|
|
if (n == 0)
|
|
{
|
|
@@ -901,13 +901,14 @@ is_super_type (const char *mime)
|
|
|
|
int
|
|
_xdg_mime_cache_mime_type_subclass (const char *mime,
|
|
- const char *base)
|
|
+ const char *base,
|
|
+ const char **seen)
|
|
{
|
|
- const char *umime, *ubase;
|
|
+ const char *umime, *ubase, *parent;
|
|
|
|
xdg_uint32_t j;
|
|
- int i, min, max, med, cmp;
|
|
-
|
|
+ int i, k, min, max, med, cmp, first_seen = 0, ret = 0;
|
|
+
|
|
umime = _xdg_mime_cache_unalias_mime_type (mime);
|
|
ubase = _xdg_mime_cache_unalias_mime_type (base);
|
|
|
|
@@ -932,7 +933,13 @@ _xdg_mime_cache_mime_type_subclass (const char *mime,
|
|
if (strcmp (ubase, "application/octet-stream") == 0 &&
|
|
strncmp (umime, "inode/", 6) != 0)
|
|
return 1;
|
|
-
|
|
+
|
|
+ if (!seen)
|
|
+ {
|
|
+ seen = calloc (1, sizeof (char *));
|
|
+ first_seen = 1;
|
|
+ }
|
|
+
|
|
for (i = 0; _caches[i]; i++)
|
|
{
|
|
XdgMimeCache *cache = _caches[i];
|
|
@@ -966,10 +973,23 @@ _xdg_mime_cache_mime_type_subclass (const char *mime,
|
|
for (j = 0; j < n_parents; j++)
|
|
{
|
|
parent_offset = GET_UINT32 (cache->buffer, offset + 4 + 4 * j);
|
|
- if (strcmp (cache->buffer + parent_offset, mime) != 0 &&
|
|
- strcmp (cache->buffer + parent_offset, umime) != 0 &&
|
|
- _xdg_mime_cache_mime_type_subclass (cache->buffer + parent_offset, ubase))
|
|
- return 1;
|
|
+ parent = cache->buffer + parent_offset;
|
|
+
|
|
+ /* Detect and avoid buggy circular relationships */
|
|
+ for (k = 0; seen[k] != NULL; k++)
|
|
+ if (parent == seen[k])
|
|
+ goto next_parent;
|
|
+ seen = realloc (seen, (k + 2) * sizeof (char *));
|
|
+ seen[k] = parent;
|
|
+ seen[k + 1] = NULL;
|
|
+
|
|
+ if (_xdg_mime_cache_mime_type_subclass (parent, ubase, seen))
|
|
+ {
|
|
+ ret = 1;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ next_parent:
|
|
}
|
|
|
|
break;
|
|
@@ -977,7 +997,10 @@ _xdg_mime_cache_mime_type_subclass (const char *mime,
|
|
}
|
|
}
|
|
|
|
- return 0;
|
|
+done:
|
|
+ if (first_seen)
|
|
+ free (seen);
|
|
+ return ret;
|
|
}
|
|
|
|
const char *
|
|
diff --git a/gio/xdgmime/xdgmimecache.h b/gio/xdgmime/xdgmimecache.h
|
|
index df25b2a576..0ac0b054fe 100644
|
|
--- a/gio/xdgmime/xdgmimecache.h
|
|
+++ b/gio/xdgmime/xdgmimecache.h
|
|
@@ -70,7 +70,8 @@ int _xdg_mime_cache_mime_type_equal (const char *mime_a,
|
|
int _xdg_mime_cache_media_type_equal (const char *mime_a,
|
|
const char *mime_b);
|
|
int _xdg_mime_cache_mime_type_subclass (const char *mime_a,
|
|
- const char *mime_b);
|
|
+ const char *mime_b,
|
|
+ const char **seen);
|
|
char **_xdg_mime_cache_list_mime_parents (const char *mime);
|
|
const char *_xdg_mime_cache_unalias_mime_type (const char *mime);
|
|
int _xdg_mime_cache_get_max_buffer_extents (void);
|
|
--
|
|
GitLab
|
|
|
|
From 77902e1b1c8ff906a560270656a51a28787b9492 Mon Sep 17 00:00:00 2001
|
|
From: Alex Henrie <alexhenrie24@gmail.com>
|
|
Date: Tue, 21 Nov 2023 11:04:50 -0700
|
|
Subject: [PATCH 2/2] xdgmime: Add continue statements after goto labels
|
|
in_xdg_mime_(cache_)mime_type_subclass
|
|
|
|
To fix the Android build.
|
|
---
|
|
gio/xdgmime/xdgmime.c | 1 +
|
|
gio/xdgmime/xdgmimecache.c | 3 ++-
|
|
2 files changed, 3 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/gio/xdgmime/xdgmime.c b/gio/xdgmime/xdgmime.c
|
|
index 31f352ceee..dce938a6f5 100644
|
|
--- a/gio/xdgmime/xdgmime.c
|
|
+++ b/gio/xdgmime/xdgmime.c
|
|
@@ -894,6 +894,7 @@ _xdg_mime_mime_type_subclass (const char *mime,
|
|
}
|
|
|
|
next_parent:
|
|
+ continue;
|
|
}
|
|
|
|
done:
|
|
diff --git a/gio/xdgmime/xdgmimecache.c b/gio/xdgmime/xdgmimecache.c
|
|
index 6b1985082f..9ea10f901d 100644
|
|
--- a/gio/xdgmime/xdgmimecache.c
|
|
+++ b/gio/xdgmime/xdgmimecache.c
|
|
@@ -989,7 +989,8 @@ _xdg_mime_cache_mime_type_subclass (const char *mime,
|
|
goto done;
|
|
}
|
|
|
|
- next_parent:
|
|
+ next_parent:
|
|
+ continue;
|
|
}
|
|
|
|
break;
|
|
--
|
|
GitLab
|
|
|