From 7b1b706f80d3cded9c7a1ba7ff8ce7197e112962 Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Sat, 14 Nov 2020 13:35:13 +0100 Subject: [PATCH] decomposed: Add flatpak_decomposed_id_is_subref_of() This checks if e.g. `org.app.App.Locale` is a subref of `org.app.App`. --- common/flatpak-ref-utils-private.h | 2 ++ common/flatpak-ref-utils.c | 46 ++++++++++++++++++++++++++++ tests/testcommon.c | 48 ++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) diff --git a/common/flatpak-ref-utils-private.h b/common/flatpak-ref-utils-private.h index 32f9f898..64d93b54 100644 --- a/common/flatpak-ref-utils-private.h +++ b/common/flatpak-ref-utils-private.h @@ -113,6 +113,8 @@ gboolean flatpak_decomposed_id_has_prefix (FlatpakDecomposed gboolean flatpak_decomposed_is_id_fuzzy (FlatpakDecomposed *ref, const char *id); gboolean flatpak_decomposed_id_is_subref (FlatpakDecomposed *ref); +gboolean flatpak_decomposed_id_is_subref_of (FlatpakDecomposed *ref, + FlatpakDecomposed *parent_ref); const char * flatpak_decomposed_peek_arch (FlatpakDecomposed *ref, gsize *out_len); char * flatpak_decomposed_dup_arch (FlatpakDecomposed *ref); diff --git a/common/flatpak-ref-utils.c b/common/flatpak-ref-utils.c index 69ceef31..65b6f34c 100644 --- a/common/flatpak-ref-utils.c +++ b/common/flatpak-ref-utils.c @@ -1353,9 +1353,55 @@ flatpak_decomposed_id_is_subref (FlatpakDecomposed *ref) gsize ref_id_len; const char *ref_id = flatpak_decomposed_peek_id (ref, &ref_id_len); + if (!flatpak_decomposed_is_runtime (ref)) + return FALSE; + return flatpak_id_has_subref_suffix (ref_id, ref_id_len); } +gboolean +flatpak_decomposed_id_is_subref_of (FlatpakDecomposed *ref, + FlatpakDecomposed *parent_ref) +{ + gsize ref_id_len; + const char *ref_id = flatpak_decomposed_peek_id (ref, &ref_id_len); + gsize parent_id_len; + const char *parent_id = flatpak_decomposed_peek_id (parent_ref, &parent_id_len); + + /* All subrefs are runtimes, even for apps */ + if (!flatpak_decomposed_is_runtime (ref)) + return FALSE; + + if (!flatpak_id_has_subref_suffix (ref_id, ref_id_len)) + return FALSE; + + /* Guaranteed to have a dot in it from the above check, so strip last element */ + while (ref_id[ref_id_len-1] != '.') + ref_id_len--; + ref_id_len--; /* And strip dot */ + + /* Any dashes in the last element of parent_id got converted to + underscores to make it a valid prefix, so custom compare here. */ + + if (ref_id_len != parent_id_len) + return FALSE; + + for (int i = 0; i < ref_id_len; i++) + { + char c = parent_id[i]; + if (c == '-') + c = '_'; + + if (c != ref_id[i]) + return FALSE; + } + + /* Check the rest of the ref */ + return strcmp (flatpak_decomposed_peek_arch (ref, NULL), + flatpak_decomposed_peek_arch (parent_ref, NULL)) == 0; +} + + const char * flatpak_decomposed_peek_arch (FlatpakDecomposed *ref, gsize *out_len) diff --git a/tests/testcommon.c b/tests/testcommon.c index 76bd7efb..1d217c07 100644 --- a/tests/testcommon.c +++ b/tests/testcommon.c @@ -431,6 +431,54 @@ test_decompose (void) branch = flatpak_decomposed_dup_branch (pref); g_assert_cmpstr (branch, ==, "master"); } + + + { + g_autoptr(FlatpakDecomposed) a = flatpak_decomposed_new_from_ref ("app/org.app.A/x86_64/master", NULL); + g_autoptr(FlatpakDecomposed) a_l = flatpak_decomposed_new_from_ref ("runtime/org.app.A.Locale/x86_64/master", NULL); + g_autoptr(FlatpakDecomposed) b = flatpak_decomposed_new_from_ref ("app/org.app.B/x86_64/master", NULL); + g_autoptr(FlatpakDecomposed) b_l = flatpak_decomposed_new_from_ref ("runtime/org.app.B.Locale/x86_64/master", NULL); + g_autoptr(FlatpakDecomposed) c = flatpak_decomposed_new_from_ref ("app/org.app.A/i386/master", NULL); + g_autoptr(FlatpakDecomposed) c_l = flatpak_decomposed_new_from_ref ("runtime/org.app.A.Locale/i386/master", NULL); + g_autoptr(FlatpakDecomposed) d = flatpak_decomposed_new_from_ref ("app/org.app.A/x86_64/beta", NULL); + g_autoptr(FlatpakDecomposed) d_l = flatpak_decomposed_new_from_ref ("runtime/org.app.A.Locale/x86_64/beta", NULL); + + g_assert (flatpak_decomposed_id_is_subref_of (a_l, a)); + g_assert (!flatpak_decomposed_id_is_subref_of (b_l, a)); + g_assert (!flatpak_decomposed_id_is_subref_of (c_l, a)); + g_assert (!flatpak_decomposed_id_is_subref_of (d_l, a)); + g_assert (!flatpak_decomposed_id_is_subref_of (a, a)); + g_assert (!flatpak_decomposed_id_is_subref_of (b, a)); + g_assert (!flatpak_decomposed_id_is_subref_of (c, a)); + g_assert (!flatpak_decomposed_id_is_subref_of (d, a)); + + g_assert (!flatpak_decomposed_id_is_subref_of (a_l, b)); + g_assert (flatpak_decomposed_id_is_subref_of (b_l, b)); + g_assert (!flatpak_decomposed_id_is_subref_of (c_l, b)); + g_assert (!flatpak_decomposed_id_is_subref_of (d_l, b)); + g_assert (!flatpak_decomposed_id_is_subref_of (a, b)); + g_assert (!flatpak_decomposed_id_is_subref_of (b, b)); + g_assert (!flatpak_decomposed_id_is_subref_of (c, b)); + g_assert (!flatpak_decomposed_id_is_subref_of (d, b)); + + g_assert (!flatpak_decomposed_id_is_subref_of (a_l, c)); + g_assert (!flatpak_decomposed_id_is_subref_of (b_l, c)); + g_assert (flatpak_decomposed_id_is_subref_of (c_l, c)); + g_assert (!flatpak_decomposed_id_is_subref_of (d_l, c)); + g_assert (!flatpak_decomposed_id_is_subref_of (a, c)); + g_assert (!flatpak_decomposed_id_is_subref_of (b, c)); + g_assert (!flatpak_decomposed_id_is_subref_of (c, c)); + g_assert (!flatpak_decomposed_id_is_subref_of (d, c)); + + g_assert (!flatpak_decomposed_id_is_subref_of (a_l, d)); + g_assert (!flatpak_decomposed_id_is_subref_of (b_l, d)); + g_assert (!flatpak_decomposed_id_is_subref_of (c_l, d)); + g_assert (flatpak_decomposed_id_is_subref_of (d_l, d)); + g_assert (!flatpak_decomposed_id_is_subref_of (a, d)); + g_assert (!flatpak_decomposed_id_is_subref_of (b, d)); + g_assert (!flatpak_decomposed_id_is_subref_of (c, d)); + g_assert (!flatpak_decomposed_id_is_subref_of (d, d)); + } }