diff --git a/common/flatpak-dir.c b/common/flatpak-dir.c index 8fd1bf72..23c47646 100644 --- a/common/flatpak-dir.c +++ b/common/flatpak-dir.c @@ -12318,7 +12318,7 @@ find_matching_ref (GHashTable *refs, if (j != 0) g_string_append (err, ", "); - const char *branch = flatpak_decomposed_peek_branch (ref); + const char *branch = flatpak_decomposed_get_branch (ref); g_string_append (err, g_strdup_printf ("%s/%s/%s", @@ -12358,7 +12358,7 @@ decomposed_refs_to_strv (GPtrArray *decomposed) for (int i = 0; i < decomposed->len; i++) { FlatpakDecomposed *ref = g_ptr_array_index (decomposed, i); - g_ptr_array_add (res, flatpak_decomposed_get_ref (ref)); + g_ptr_array_add (res, flatpak_decomposed_dup_ref (ref)); } g_ptr_array_add (res, NULL); @@ -12505,7 +12505,7 @@ flatpak_dir_find_remote_ref (FlatpakDir *self, if (out_kind != NULL) *out_kind = flatpak_decomposed_get_kind (remote_ref); - return flatpak_decomposed_get_ref (remote_ref); + return flatpak_decomposed_dup_ref (remote_ref); } static GHashTable * @@ -12744,7 +12744,7 @@ flatpak_dir_find_installed_ref (FlatpakDir *self, if (out_kind != NULL) *out_kind = flatpak_decomposed_get_kind (local_ref); - return flatpak_decomposed_get_ref (local_ref); + return flatpak_decomposed_dup_ref (local_ref); } g_set_error (error, FLATPAK_ERROR, FLATPAK_ERROR_NOT_INSTALLED, @@ -12773,7 +12773,7 @@ filter_out_deployed_refs (FlatpakDir *self, for (i = 0; i < local_refspecs->len; ++i) { FlatpakDecomposed *decomposed = g_ptr_array_index (local_refspecs, i); - const gchar *ref = flatpak_decomposed_peek_ref (decomposed); + const gchar *ref = flatpak_decomposed_get_ref (decomposed); g_autoptr(GBytes) deploy_data = NULL; deploy_data = flatpak_dir_get_deploy_data (self, ref, FLATPAK_DEPLOY_VERSION_ANY, NULL, NULL); @@ -12834,8 +12834,8 @@ flatpak_dir_cleanup_undeployed_refs (FlatpakDir *self, for (; i < undeployed_refs->len; ++i) { FlatpakDecomposed *decomposed = g_ptr_array_index (undeployed_refs, i); - const gchar *ref = flatpak_decomposed_peek_ref (decomposed); - g_autofree gchar *remote = flatpak_decomposed_get_remote (decomposed); + const gchar *ref = flatpak_decomposed_get_ref (decomposed); + g_autofree gchar *remote = flatpak_decomposed_dup_remote (decomposed); if (!flatpak_dir_remove_ref (self, remote, ref, cancellable, error)) return FALSE; diff --git a/common/flatpak-utils-private.h b/common/flatpak-utils-private.h index a4642ef0..2e7265cf 100644 --- a/common/flatpak-utils-private.h +++ b/common/flatpak-utils-private.h @@ -206,6 +206,9 @@ gboolean flatpak_is_valid_branch (const char *string, GError **error); gboolean flatpak_has_name_prefix (const char *string, const char *name); +gboolean flatpak_is_valid_arch (const char *string, + gssize len, + GError **error); char * flatpak_make_valid_id_prefix (const char *orig_id); gboolean flatpak_id_has_subref_suffix (const char *id, @@ -220,40 +223,62 @@ const char *flatpak_get_compat_arch_reverse (const char *compat_arch); typedef struct _FlatpakDecomposed FlatpakDecomposed; FlatpakDecomposed *flatpak_decomposed_new_from_ref (const char *ref, GError **error); +FlatpakDecomposed *flatpak_decomposed_new_from_col_ref (const char *ref, + const char *collection_id, + GError **error); FlatpakDecomposed *flatpak_decomposed_new_from_refspec (const char *refspec, GError **error); FlatpakDecomposed *flatpak_decomposed_new_from_ref_take (char *ref, GError **error); FlatpakDecomposed *flatpak_decomposed_new_from_refspec_take (char *refspec, GError **error); +FlatpakDecomposed *flatpak_decomposed_new_from_decomposed (FlatpakDecomposed *ref, + FlatpakKinds opt_kind, + const char *opt_id, + const char *opt_arch, + const char *opt_branch, + GError **error); FlatpakDecomposed *flatpak_decomposed_ref (FlatpakDecomposed *ref); void flatpak_decomposed_unref (FlatpakDecomposed *ref); -const char * flatpak_decomposed_peek_ref (FlatpakDecomposed *ref); -const char * flatpak_decomposed_peek_refspec (FlatpakDecomposed *ref); -char * flatpak_decomposed_get_ref (FlatpakDecomposed *ref); -char * flatpak_decomposed_get_refspec (FlatpakDecomposed *ref); -char * flatpak_decomposed_get_remote (FlatpakDecomposed *ref); +const char * flatpak_decomposed_get_ref (FlatpakDecomposed *ref); +const char * flatpak_decomposed_get_refspec (FlatpakDecomposed *ref); +char * flatpak_decomposed_dup_ref (FlatpakDecomposed *ref); +char * flatpak_decomposed_dup_refspec (FlatpakDecomposed *ref); +char * flatpak_decomposed_dup_remote (FlatpakDecomposed *ref); +const char * flatpak_decomposed_get_collection_id (FlatpakDecomposed *ref); +char * flatpak_decomposed_dup_collection_id (FlatpakDecomposed *ref); gboolean flatpak_decomposed_equal (FlatpakDecomposed *ref_a, FlatpakDecomposed *ref_b); +gint flatpak_decomposed_strcmp (FlatpakDecomposed *ref_a, + FlatpakDecomposed *ref_b); +gint flatpak_decomposed_strcmp_p (FlatpakDecomposed **ref_a, + FlatpakDecomposed **ref_b); guint flatpak_decomposed_hash (FlatpakDecomposed *ref); gboolean flatpak_decomposed_is_app (FlatpakDecomposed *ref); gboolean flatpak_decomposed_is_runtime (FlatpakDecomposed *ref); FlatpakKinds flatpak_decomposed_get_kind (FlatpakDecomposed *ref); -const char * flatpak_decomposed_peek_id (FlatpakDecomposed *ref); -char * flatpak_decomposed_get_id (FlatpakDecomposed *ref); +const char * flatpak_decomposed_get_kind_str (FlatpakDecomposed *ref); +const char * flatpak_decomposed_get_pref (FlatpakDecomposed *ref); +char * flatpak_decomposed_dup_pref (FlatpakDecomposed *ref); +const char * flatpak_decomposed_peek_id (FlatpakDecomposed *ref, + gsize *out_len); +char * flatpak_decomposed_dup_id (FlatpakDecomposed *ref); gboolean flatpak_decomposed_is_id (FlatpakDecomposed *ref, const char *id); gboolean flatpak_decomposed_is_id_fuzzy (FlatpakDecomposed *ref, const char *id); gboolean flatpak_decomposed_id_is_subref (FlatpakDecomposed *ref); -const char * flatpak_decomposed_peek_arch (FlatpakDecomposed *ref); -char * flatpak_decomposed_get_arch (FlatpakDecomposed *ref); +const char * flatpak_decomposed_peek_arch (FlatpakDecomposed *ref, + gsize *out_len); +char * flatpak_decomposed_dup_arch (FlatpakDecomposed *ref); gboolean flatpak_decomposed_is_arch (FlatpakDecomposed *ref, const char *arch); gboolean flatpak_decomposed_is_arches (FlatpakDecomposed *ref, const char **arches); -const char * flatpak_decomposed_peek_branch (FlatpakDecomposed *ref); -char * flatpak_decomposed_get_branch (FlatpakDecomposed *ref); +const char * flatpak_decomposed_peek_branch (FlatpakDecomposed *ref, + gsize *out_len); +const char * flatpak_decomposed_get_branch (FlatpakDecomposed *ref); +char * flatpak_decomposed_dup_branch (FlatpakDecomposed *ref); gboolean flatpak_decomposed_is_branch (FlatpakDecomposed *ref, const char *branch); diff --git a/common/flatpak-utils.c b/common/flatpak-utils.c index 8fc21c72..d39c727e 100644 --- a/common/flatpak-utils.c +++ b/common/flatpak-utils.c @@ -933,6 +933,50 @@ flatpak_name_matches_one_wildcard_prefix (const char *name, !is_valid_name_character (*remainder, FALSE); } + +static gboolean +is_valid_arch_character (char c) +{ + return + (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || + (c >= '0' && c <= '9') || + (c == '_'); +} + +gboolean +flatpak_is_valid_arch (const char *string, + gssize len, + GError **error) +{ + const gchar *end; + + if (len < 0) + len = strlen (string); + + if (G_UNLIKELY (len == 0)) + { + flatpak_fail_error (error, FLATPAK_ERROR_INVALID_NAME, + _("Arch can't be empty")); + return FALSE; + } + + end = string + len; + + while (string != end) + { + if (G_UNLIKELY (!is_valid_arch_character (*string))) + { + flatpak_fail_error (error, FLATPAK_ERROR_INVALID_NAME, + _("Arch can't contain %c"), *string); + return FALSE; + } + string += 1; + } + + return TRUE; +} + gboolean flatpak_get_allowed_exports (const char *source_path, const char *app_id, @@ -1465,7 +1509,12 @@ struct _FlatpakDecomposed { guint16 id_offset; guint16 arch_offset; guint16 branch_offset; - char *ref; + char *data; + + /* This is only used when we're directly manipulating sideload repos, by giving + * a file:// uri as the remote name. Typically we don't really care about collection ids + * internally in flatpak as we use refs tied to a remote. */ + char *collection_id; }; static gboolean @@ -1588,9 +1637,9 @@ _flatpak_decomposed_new (char *ref, return NULL; } - if (slash - p == 0) /* empty arch */ + if (!flatpak_is_valid_arch (p, slash - p, &local_error)) { - flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Invalid arch %.*s"), (int)(slash - p), p); + flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Invalid arch: %.*s: %s"), (int)(slash - p), p, local_error->message); return NULL; } @@ -1610,13 +1659,13 @@ _flatpak_decomposed_new (char *ref, return NULL; } - decomposed = g_malloc (sizeof (struct _FlatpakDecomposed) + len); /* len == strlen, and then the terminating zero fits in data[1] */ + decomposed = g_new0 (FlatpakDecomposed, 1); decomposed->ref_count = 1; decomposed->ref_offset = (guint16)ref_offset; decomposed->id_offset = (guint16)id_offset; decomposed->arch_offset = (guint16)arch_offset; decomposed->branch_offset = (guint16)branch_offset; - decomposed->ref = take ? ref : g_strdup (ref); + decomposed->data = take ? ref : g_strdup (ref); return decomposed; } @@ -1649,6 +1698,146 @@ flatpak_decomposed_new_from_refspec_take (char *refspec, return _flatpak_decomposed_new (refspec, TRUE, TRUE, error); } +FlatpakDecomposed * +flatpak_decomposed_new_from_col_ref (const char *ref, + const char *collection_id, + GError **error) +{ + g_autoptr(FlatpakDecomposed) decomposed = NULL; + + if (collection_id != NULL && + !ostree_validate_collection_id (collection_id, error)) + return FALSE; + + decomposed = flatpak_decomposed_new_from_ref (ref, error); + if (decomposed == NULL) + return FALSE; + + decomposed->collection_id = g_strdup (collection_id); + + return g_steal_pointer (&decomposed); +} + +FlatpakDecomposed * +flatpak_decomposed_new_from_decomposed (FlatpakDecomposed *old, + FlatpakKinds opt_kind, + const char *opt_id, + const char *opt_arch, + const char *opt_branch, + GError **error) +{ + FlatpakDecomposed *decomposed; + g_autoptr(GError) local_error = NULL; + const char *kind_str; + gsize kind_len; + gsize id_len; + gsize arch_len; + gsize branch_len; + gsize ref_len; + char *ref; + gsize offset; + + g_assert (old != NULL); + + if (opt_kind == 0) + kind_str = flatpak_decomposed_get_kind_str (old); + else if (opt_kind == FLATPAK_KINDS_APP) + kind_str = "app"; + else + kind_str = "runtime"; + + kind_len = strlen (kind_str); + + if (opt_id) + { + if (!flatpak_is_valid_name (opt_id, -1, &local_error)) + { + flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Invalid name %s: %s"), opt_id, local_error->message); + return NULL; + } + + id_len = strlen (opt_id); + } + else + { + opt_id = flatpak_decomposed_peek_id (old, &id_len); + } + + if (opt_arch) + { + if (!flatpak_is_valid_arch (opt_arch, -1, &local_error)) + { + flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Invalid arch: %s: %s"), opt_arch, local_error->message); + return NULL; + } + + arch_len = strlen (opt_arch); + } + else + { + opt_arch = flatpak_decomposed_peek_arch (old, &arch_len); + } + + if (opt_branch) + { + if (!flatpak_is_valid_branch (opt_branch, -1, &local_error)) + { + flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Invalid branch: %s: %s"), opt_branch, local_error->message); + return NULL; + } + + branch_len = strlen (opt_branch); + } + else + { + opt_branch = flatpak_decomposed_peek_branch (old, &branch_len); + } + + ref_len = kind_len + 1 + id_len + 1 + arch_len + 1 + branch_len; + if (ref_len > 0xffff) + { + flatpak_fail_error (error, FLATPAK_ERROR_INVALID_REF, _("Ref too long")); + return NULL; + } + + decomposed = g_new0 (FlatpakDecomposed, 1); + decomposed->ref_count = 1; + decomposed->data = g_malloc (ref_len + 1); + + ref = decomposed->data; + offset = 0; + + decomposed->ref_offset = (guint16)offset; + memcpy (ref + offset, kind_str, kind_len); + offset += kind_len; + + memcpy (ref + offset, "/", 1); + offset += 1; + + decomposed->id_offset = (guint16)offset; + memcpy (ref + offset, opt_id, id_len); + offset += id_len; + + memcpy (ref + offset, "/", 1); + offset += 1; + + decomposed->arch_offset = (guint16)offset; + memcpy (ref + offset, opt_arch, arch_len); + offset += arch_len; + + memcpy (ref + offset, "/", 1); + offset += 1; + + decomposed->branch_offset = (guint16)offset; + memcpy (ref + offset, opt_branch, branch_len); + offset += branch_len; + + g_assert (offset == ref_len); + *(ref + offset) = 0; + + return decomposed; +} + FlatpakDecomposed * flatpak_decomposed_ref (FlatpakDecomposed *ref) { @@ -1661,67 +1850,118 @@ flatpak_decomposed_unref (FlatpakDecomposed *ref) { if (g_atomic_int_dec_and_test (&ref->ref_count)) { - g_free (ref->ref); + g_free (ref->data); + g_free (ref->collection_id); g_free (ref); } } const char * -flatpak_decomposed_peek_ref (FlatpakDecomposed *ref) +flatpak_decomposed_get_ref (FlatpakDecomposed *ref) { - return (const char *)&ref->ref[ref->ref_offset]; + return (const char *)&ref->data[ref->ref_offset]; } char * -flatpak_decomposed_get_ref (FlatpakDecomposed *ref) +flatpak_decomposed_dup_ref (FlatpakDecomposed *ref) { - return g_strdup (flatpak_decomposed_peek_ref (ref)); + return g_strdup (flatpak_decomposed_get_ref (ref)); } const char * -flatpak_decomposed_peek_refspec (FlatpakDecomposed *ref) -{ - return (const char *)&ref->ref[0]; -} - -char * flatpak_decomposed_get_refspec (FlatpakDecomposed *ref) { - return g_strdup (flatpak_decomposed_peek_refspec (ref)); + return (const char *)&ref->data[0]; } char * -flatpak_decomposed_get_remote (FlatpakDecomposed *ref) +flatpak_decomposed_dup_refspec (FlatpakDecomposed *ref) +{ + return g_strdup (flatpak_decomposed_get_refspec (ref)); +} + +char * +flatpak_decomposed_dup_remote (FlatpakDecomposed *ref) { if (ref->ref_offset == 0) return NULL; - return g_strndup (ref->ref, ref->ref_offset - 1); + return g_strndup (ref->data, ref->ref_offset - 1); +} + +/* Note: These are always NULL for regular refs, as they generally + * tied to a remote and uses the collection_id from that. + * The only case this is set is if we enumerate a remote + * of the form `file:///path/to/repo`, as we don't then know + * which remote name it is from. + */ +const char * +flatpak_decomposed_get_collection_id (FlatpakDecomposed *ref) +{ + return ref->collection_id; +} + +/* Note: These are always NULL for regular refs, as they generally + * tied to a remote and uses the collection_id from that. + * The only case this is set is if we enumerate a remote + * of the form `file:///path/to/repo`, as we don't then know + * which remote name it is from. + */ +char * +flatpak_decomposed_dup_collection_id (FlatpakDecomposed *ref) +{ + return g_strdup (ref->collection_id); } gboolean flatpak_decomposed_equal (FlatpakDecomposed *ref_a, FlatpakDecomposed *ref_b) { - return strcmp (ref_a->ref, ref_b->ref) == 0; + return strcmp (ref_a->data, ref_b->data) == 0 && + g_strcmp0 (ref_a->collection_id, ref_b->collection_id) == 0; +} + +gint +flatpak_decomposed_strcmp (FlatpakDecomposed *ref_a, + FlatpakDecomposed *ref_b) +{ + int res = strcmp (ref_a->data, ref_b->data); + if (res != 0) + return res; + + return g_strcmp0 (ref_a->collection_id, ref_b->collection_id); +} + +gint +flatpak_decomposed_strcmp_p (FlatpakDecomposed **ref_a, + FlatpakDecomposed **ref_b) +{ + return flatpak_decomposed_strcmp (*ref_a, *ref_b); } guint flatpak_decomposed_hash (FlatpakDecomposed *ref) { - return g_str_hash (ref->ref); + guint h = g_str_hash (ref->data); + + if (ref->collection_id) + h |= g_str_hash (ref->collection_id); + + return h; } gboolean flatpak_decomposed_is_app (FlatpakDecomposed *ref) { - return ref->ref[0] == 'a'; + const char *r = flatpak_decomposed_get_ref (ref); + return r[0] == 'a'; } gboolean flatpak_decomposed_is_runtime (FlatpakDecomposed *ref) { - return ref->ref[0] == 'r'; + const char *r = flatpak_decomposed_get_ref (ref); + return r[0] == 'r'; } FlatpakKinds @@ -1733,6 +1973,15 @@ flatpak_decomposed_get_kind (FlatpakDecomposed *ref) return FLATPAK_KINDS_RUNTIME; } +const char * +flatpak_decomposed_get_kind_str (FlatpakDecomposed *ref) +{ + if (flatpak_decomposed_is_app (ref)) + return "app"; + else + return "runtime"; +} + /* A slashed string ends at '/' instead of nul */ static gboolean slashed_str_equal (const char *slashed_str, const char *str) @@ -1781,24 +2030,40 @@ slashed_str_strcasestr (const char *haystack, } const char * -flatpak_decomposed_peek_id (FlatpakDecomposed *ref) +flatpak_decomposed_get_pref (FlatpakDecomposed *ref) { - return &ref->ref[ref->id_offset]; + return &ref->data[ref->id_offset]; } char * -flatpak_decomposed_get_id (FlatpakDecomposed *ref) +flatpak_decomposed_dup_pref (FlatpakDecomposed *ref) { - const char *ref_id = flatpak_decomposed_peek_id (ref); + return g_strdup (flatpak_decomposed_get_pref (ref)); +} - return g_strndup (ref_id, ref->arch_offset - ref->id_offset - 1); +const char * +flatpak_decomposed_peek_id (FlatpakDecomposed *ref, + gsize *out_len) +{ + if (out_len) + *out_len = ref->arch_offset - ref->id_offset - 1; + return &ref->data[ref->id_offset]; +} + +char * +flatpak_decomposed_dup_id (FlatpakDecomposed *ref) +{ + gsize len; + const char *ref_id = flatpak_decomposed_peek_id (ref, &len); + + return g_strndup (ref_id, len); } gboolean flatpak_decomposed_is_id (FlatpakDecomposed *ref, const char *id) { - const char *ref_id = flatpak_decomposed_peek_id (ref); + const char *ref_id = flatpak_decomposed_peek_id (ref, NULL); return slashed_str_equal (ref_id, id); } @@ -1809,8 +2074,8 @@ gboolean flatpak_decomposed_is_id_fuzzy (FlatpakDecomposed *ref, const char *id) { - const char *ref_id = flatpak_decomposed_peek_id (ref); - gsize ref_id_len = ref->arch_offset - ref->id_offset - 1; + gsize ref_id_len; + const char *ref_id = flatpak_decomposed_peek_id (ref, &ref_id_len); if (slashed_str_strcasestr (ref_id, ref_id_len, id)) return TRUE; @@ -1821,31 +2086,35 @@ flatpak_decomposed_is_id_fuzzy (FlatpakDecomposed *ref, gboolean flatpak_decomposed_id_is_subref (FlatpakDecomposed *ref) { - const char *ref_id = flatpak_decomposed_peek_id (ref); - gsize ref_id_len = ref->arch_offset - ref->id_offset - 1; + gsize ref_id_len; + const char *ref_id = flatpak_decomposed_peek_id (ref, &ref_id_len); return flatpak_id_has_subref_suffix (ref_id, ref_id_len); } const char * -flatpak_decomposed_peek_arch (FlatpakDecomposed *ref) +flatpak_decomposed_peek_arch (FlatpakDecomposed *ref, + gsize *out_len) { - return &ref->ref[ref->arch_offset]; + if (out_len) + *out_len = ref->branch_offset - ref->arch_offset - 1; + return &ref->data[ref->arch_offset]; } char * -flatpak_decomposed_get_arch (FlatpakDecomposed *ref) +flatpak_decomposed_dup_arch (FlatpakDecomposed *ref) { - const char *ref_arch = flatpak_decomposed_peek_arch (ref); + gsize len; + const char *ref_arch = flatpak_decomposed_peek_arch (ref, &len); - return g_strndup (ref_arch, ref->branch_offset - ref->arch_offset - 1); + return g_strndup (ref_arch, len); } gboolean flatpak_decomposed_is_arch (FlatpakDecomposed *ref, const char *arch) { - const char *ref_arch = flatpak_decomposed_peek_arch (ref); + const char *ref_arch = flatpak_decomposed_peek_arch (ref, NULL); return slashed_str_equal (ref_arch, arch); } @@ -1854,7 +2123,7 @@ gboolean flatpak_decomposed_is_arches (FlatpakDecomposed *ref, const char **arches) { - const char *ref_arch = flatpak_decomposed_peek_arch (ref); + const char *ref_arch = flatpak_decomposed_peek_arch (ref, NULL); for (int i = 0; arches[i] != NULL; i++) { @@ -1865,16 +2134,27 @@ flatpak_decomposed_is_arches (FlatpakDecomposed *ref, return FALSE; } +/* We can add a getter for this, because the branch is last so guaranteed to be null-terminated */ const char * -flatpak_decomposed_peek_branch (FlatpakDecomposed *ref) +flatpak_decomposed_get_branch (FlatpakDecomposed *ref) { - return &ref->ref[ref->branch_offset]; + return &ref->data[ref->branch_offset]; +} + +const char * +flatpak_decomposed_peek_branch (FlatpakDecomposed *ref, + gsize *out_len) +{ + const char *branch = flatpak_decomposed_get_branch (ref); + if (out_len) + *out_len = strlen (branch); + return branch; } char * -flatpak_decomposed_get_branch (FlatpakDecomposed *ref) +flatpak_decomposed_dup_branch (FlatpakDecomposed *ref) { - const char *ref_branch = flatpak_decomposed_peek_branch (ref); + const char *ref_branch = flatpak_decomposed_peek_branch (ref, NULL); return g_strdup (ref_branch); } @@ -1883,7 +2163,7 @@ gboolean flatpak_decomposed_is_branch (FlatpakDecomposed *ref, const char *branch) { - const char *ref_branch = flatpak_decomposed_peek_branch (ref); + const char *ref_branch = flatpak_decomposed_get_branch (ref); return strcmp (ref_branch, branch) == 0; } diff --git a/tests/testcommon.c b/tests/testcommon.c index b28cda04..94917650 100644 --- a/tests/testcommon.c +++ b/tests/testcommon.c @@ -113,6 +113,7 @@ test_decompose (void) g_autofree char *runtime_id = NULL; g_autofree char *runtime_arch = NULL; g_autofree char *runtime_branch = NULL; + gsize len, len2; g_assert_null (flatpak_decomposed_new_from_ref ("app/wrong/x86_64/master", &error)); g_assert (error != NULL); @@ -154,30 +155,33 @@ test_decompose (void) g_assert (runtime_ref != NULL); g_assert_null (error); - g_assert_cmpstr (flatpak_decomposed_peek_ref (runtime_ref), ==, "runtime/org.the.runtime/x86_64/master"); - g_assert_cmpstr (flatpak_decomposed_peek_refspec (runtime_ref), ==, "runtime/org.the.runtime/x86_64/master"); + g_assert_cmpstr (flatpak_decomposed_get_ref (runtime_ref), ==, "runtime/org.the.runtime/x86_64/master"); + g_assert_cmpstr (flatpak_decomposed_get_refspec (runtime_ref), ==, "runtime/org.the.runtime/x86_64/master"); g_assert (flatpak_decomposed_equal (runtime_ref, runtime_ref)); g_assert (flatpak_decomposed_hash (runtime_ref) == g_str_hash ("runtime/org.the.runtime/x86_64/master")); g_assert (!flatpak_decomposed_is_app (runtime_ref)); g_assert (flatpak_decomposed_is_runtime (runtime_ref)); g_assert (flatpak_decomposed_get_kind (runtime_ref) == FLATPAK_KINDS_RUNTIME); - g_assert_cmpstr (flatpak_decomposed_peek_id (runtime_ref), ==, "org.the.runtime/x86_64/master"); - runtime_id = flatpak_decomposed_get_id (runtime_ref); + g_assert_cmpstr (flatpak_decomposed_peek_id (runtime_ref, &len), ==, "org.the.runtime/x86_64/master"); + g_assert (len == strlen("org.the.runtime")); + runtime_id = flatpak_decomposed_dup_id (runtime_ref); g_assert_cmpstr (runtime_id, ==, "org.the.runtime"); g_assert (flatpak_decomposed_is_id (runtime_ref, "org.the.runtime")); g_assert (!flatpak_decomposed_is_id (runtime_ref, "org.the.runtim")); g_assert (!flatpak_decomposed_is_id (runtime_ref, "org.the.runtimee")); - g_assert_cmpstr (flatpak_decomposed_peek_arch (runtime_ref), ==, "x86_64/master"); - runtime_arch = flatpak_decomposed_get_arch (runtime_ref); + g_assert_cmpstr (flatpak_decomposed_peek_arch (runtime_ref, &len), ==, "x86_64/master"); + g_assert (len == strlen ("x86_64")); + runtime_arch = flatpak_decomposed_dup_arch (runtime_ref); g_assert_cmpstr (runtime_arch, ==, "x86_64"); g_assert (flatpak_decomposed_is_arch (runtime_ref, "x86_64")); g_assert (!flatpak_decomposed_is_arch (runtime_ref, "x86_6")); g_assert (!flatpak_decomposed_is_arch (runtime_ref, "x86_644")); - g_assert_cmpstr (flatpak_decomposed_peek_branch (runtime_ref), ==, "master"); - runtime_branch = flatpak_decomposed_get_branch (runtime_ref); + g_assert_cmpstr (flatpak_decomposed_peek_branch (runtime_ref, &len), ==, "master"); + g_assert (len == strlen ("master")); + runtime_branch = flatpak_decomposed_dup_branch (runtime_ref); g_assert_cmpstr (runtime_branch, ==, "master"); g_assert (flatpak_decomposed_is_branch (runtime_ref, "master")); g_assert (!flatpak_decomposed_is_arch (runtime_ref, "maste")); @@ -187,8 +191,8 @@ test_decompose (void) g_assert (app_ref != NULL); g_assert_null (error); - g_assert_cmpstr (flatpak_decomposed_peek_ref (app_ref), ==, "app/org.the.app/x86_64/master"); - g_assert_cmpstr (flatpak_decomposed_peek_refspec (app_ref), ==, "app/org.the.app/x86_64/master"); + g_assert_cmpstr (flatpak_decomposed_get_ref (app_ref), ==, "app/org.the.app/x86_64/master"); + g_assert_cmpstr (flatpak_decomposed_get_refspec (app_ref), ==, "app/org.the.app/x86_64/master"); g_assert (flatpak_decomposed_equal (app_ref, app_ref)); g_assert (!flatpak_decomposed_equal (app_ref, runtime_ref)); g_assert (flatpak_decomposed_hash (app_ref) == g_str_hash ("app/org.the.app/x86_64/master")); @@ -196,22 +200,26 @@ test_decompose (void) g_assert (!flatpak_decomposed_is_runtime (app_ref)); g_assert (flatpak_decomposed_get_kind (app_ref) == FLATPAK_KINDS_APP); - g_assert_cmpstr (flatpak_decomposed_peek_id (app_ref), ==, "org.the.app/x86_64/master"); - app_id = flatpak_decomposed_get_id (app_ref); + g_assert_cmpstr (flatpak_decomposed_peek_id (app_ref, &len), ==, "org.the.app/x86_64/master"); + g_assert (len == strlen ("org.the.app")); + app_id = flatpak_decomposed_dup_id (app_ref); g_assert_cmpstr (app_id, ==, "org.the.app"); g_assert (flatpak_decomposed_is_id (app_ref, "org.the.app")); g_assert (!flatpak_decomposed_is_id (app_ref, "org.the.ap")); g_assert (!flatpak_decomposed_is_id (app_ref, "org.the.appp")); - g_assert_cmpstr (flatpak_decomposed_peek_arch (app_ref), ==, "x86_64/master"); - app_arch = flatpak_decomposed_get_arch (app_ref); + g_assert_cmpstr (flatpak_decomposed_peek_arch (app_ref, &len), ==, "x86_64/master"); + g_assert (len == strlen ("x86_64")); + app_arch = flatpak_decomposed_dup_arch (app_ref); g_assert_cmpstr (app_arch, ==, "x86_64"); g_assert (flatpak_decomposed_is_arch (app_ref, "x86_64")); g_assert (!flatpak_decomposed_is_arch (app_ref, "x86_6")); g_assert (!flatpak_decomposed_is_arch (app_ref, "x86_644")); - g_assert_cmpstr (flatpak_decomposed_peek_branch (app_ref), ==, "master"); - app_branch = flatpak_decomposed_get_branch (app_ref); + g_assert_cmpstr (flatpak_decomposed_get_branch (app_ref), ==, "master"); + g_assert_cmpstr (flatpak_decomposed_peek_branch (app_ref, &len), ==, "master"); + g_assert (len == strlen ("master")); + app_branch = flatpak_decomposed_dup_branch (app_ref); g_assert_cmpstr (app_branch, ==, "master"); g_assert (flatpak_decomposed_is_branch (app_ref, "master")); g_assert (!flatpak_decomposed_is_arch (app_ref, "maste")); @@ -235,14 +243,141 @@ test_decompose (void) g_assert (refspec != NULL); g_assert_null (error); - g_assert_cmpstr (flatpak_decomposed_peek_ref (refspec), ==, "app/org.the.app/x86_64/master"); - g_assert_cmpstr (flatpak_decomposed_peek_refspec (refspec), ==, "remote:app/org.the.app/x86_64/master"); - g_autofree char *refspec_remote = flatpak_decomposed_get_remote (refspec); + g_assert_cmpstr (flatpak_decomposed_get_ref (refspec), ==, "app/org.the.app/x86_64/master"); + g_assert_cmpstr (flatpak_decomposed_get_refspec (refspec), ==, "remote:app/org.the.app/x86_64/master"); + g_autofree char *refspec_remote = flatpak_decomposed_dup_remote (refspec); g_assert_cmpstr (refspec_remote, ==, "remote"); - g_autofree char *refspec_ref = flatpak_decomposed_get_ref (refspec); + g_autofree char *refspec_ref = flatpak_decomposed_dup_ref (refspec); g_assert_cmpstr (refspec_ref, ==, "app/org.the.app/x86_64/master"); - g_autofree char *refspec_refspec = flatpak_decomposed_get_refspec (refspec); + g_autofree char *refspec_refspec = flatpak_decomposed_dup_refspec (refspec); g_assert_cmpstr (refspec_refspec, ==, "remote:app/org.the.app/x86_64/master"); + + { + FlatpakDecomposed *old = runtime_ref; + g_autoptr(FlatpakDecomposed) new = flatpak_decomposed_new_from_decomposed (old, 0, NULL, NULL, NULL, &error); + g_assert (new != NULL); + g_assert_null (error); + + g_assert_cmpstr (flatpak_decomposed_get_ref (new), ==, flatpak_decomposed_get_ref (old)); + g_assert_cmpstr (flatpak_decomposed_peek_id (new, &len), ==, flatpak_decomposed_peek_id (old, &len2)); + g_assert (len == len2); + g_assert_cmpstr (flatpak_decomposed_peek_arch (new, &len), ==, flatpak_decomposed_peek_arch (old, &len2)); + g_assert (len == len2); + g_assert_cmpstr (flatpak_decomposed_peek_branch (new, &len), ==, flatpak_decomposed_peek_branch (old, &len2)); + g_assert (len == len2); + } + + { + FlatpakDecomposed *old = app_ref; + g_autoptr(FlatpakDecomposed) new = flatpak_decomposed_new_from_decomposed (old, 0, NULL, NULL, NULL, &error); + g_assert (new != NULL); + g_assert_null (error); + + g_assert_cmpstr (flatpak_decomposed_get_ref (new), ==, flatpak_decomposed_get_ref (old)); + g_assert_cmpstr (flatpak_decomposed_peek_id (new, &len), ==, flatpak_decomposed_peek_id (old, &len2)); + g_assert (len == len2); + g_assert_cmpstr (flatpak_decomposed_peek_arch (new, &len), ==, flatpak_decomposed_peek_arch (old, &len2)); + g_assert (len == len2); + g_assert_cmpstr (flatpak_decomposed_peek_branch (new, &len), ==, flatpak_decomposed_peek_branch (old, &len2)); + g_assert (len == len2); + } + + { + FlatpakDecomposed *old = app_ref; + g_autofree gchar *new_id = NULL; + + g_autoptr(FlatpakDecomposed) new = flatpak_decomposed_new_from_decomposed (old, FLATPAK_KINDS_RUNTIME, "org.new.app", NULL, NULL, &error); + g_assert (new != NULL); + g_assert_null (error); + + g_assert_cmpstr (flatpak_decomposed_get_ref (new), ==, "runtime/org.new.app/x86_64/master"); + + g_assert (flatpak_decomposed_get_kind (new) == FLATPAK_KINDS_RUNTIME); + new_id = flatpak_decomposed_dup_id (new); + g_assert_cmpstr (new_id, ==, "org.new.app"); + + g_assert_cmpstr (flatpak_decomposed_peek_arch (new, &len), ==, flatpak_decomposed_peek_arch (old, &len2)); + g_assert (len == len2); + g_assert_cmpstr (flatpak_decomposed_peek_branch (new, &len), ==, flatpak_decomposed_peek_branch (old, &len2)); + g_assert (len == len2); + } + + { + FlatpakDecomposed *old = app_ref; + g_autofree gchar *old_id = NULL; + g_autofree gchar *new_id = NULL; + g_autofree gchar *new_arch = NULL; + g_autofree gchar *old_branch = NULL; + g_autofree gchar *new_branch = NULL; + + g_autoptr(FlatpakDecomposed) new = flatpak_decomposed_new_from_decomposed (old, 0, NULL, "i386", NULL, &error); + g_assert (new != NULL); + g_assert_null (error); + + g_assert_cmpstr (flatpak_decomposed_get_ref (new), ==, "app/org.the.app/i386/master"); + + g_assert (flatpak_decomposed_get_kind (new) == FLATPAK_KINDS_APP); + + new_id = flatpak_decomposed_dup_id (new); + old_id = flatpak_decomposed_dup_id (old); + g_assert_cmpstr (new_id, ==, old_id); + + new_arch = flatpak_decomposed_dup_arch (new); + g_assert_cmpstr (new_arch, ==, "i386"); + + new_branch = flatpak_decomposed_dup_branch (new); + old_branch = flatpak_decomposed_dup_branch (old); + g_assert_cmpstr (new_branch, ==, old_branch); + } + + { + FlatpakDecomposed *old = app_ref; + g_autofree gchar *old_id = NULL; + g_autofree gchar *new_id = NULL; + g_autofree gchar *new_arch = NULL; + g_autofree gchar *old_arch = NULL; + g_autofree gchar *new_branch = NULL; + + g_autoptr(FlatpakDecomposed) new = flatpak_decomposed_new_from_decomposed (old, 0, NULL, NULL, "beta", &error); + g_assert (new != NULL); + g_assert_null (error); + + g_assert_cmpstr (flatpak_decomposed_get_ref (new), ==, "app/org.the.app/x86_64/beta"); + + g_assert (flatpak_decomposed_get_kind (new) == FLATPAK_KINDS_APP); + + new_id = flatpak_decomposed_dup_id (new); + old_id = flatpak_decomposed_dup_id (old); + g_assert_cmpstr (new_id, ==, old_id); + + new_arch = flatpak_decomposed_dup_arch (new); + old_arch = flatpak_decomposed_dup_arch (old); + g_assert_cmpstr (new_arch, ==, old_arch); + + new_branch = flatpak_decomposed_dup_branch (new); + g_assert_cmpstr (new_branch, ==, "beta"); + } + + { + FlatpakDecomposed *old = app_ref; + g_autofree gchar *new_id = NULL; + g_autofree gchar *new_arch = NULL; + g_autofree gchar *new_branch = NULL; + + g_autoptr(FlatpakDecomposed) new = flatpak_decomposed_new_from_decomposed (old, FLATPAK_KINDS_RUNTIME, "org.new.app", "i386", "beta", &error); + g_assert (new != NULL); + g_assert_null (error); + + g_assert_cmpstr (flatpak_decomposed_get_ref (new), ==, "runtime/org.new.app/i386/beta"); + + g_assert (flatpak_decomposed_get_kind (new) == FLATPAK_KINDS_RUNTIME); + new_id = flatpak_decomposed_dup_id (new); + g_assert_cmpstr (new_id, ==, "org.new.app"); + new_arch = flatpak_decomposed_dup_arch (new); + g_assert_cmpstr (new_arch, ==, "i386"); + new_branch = flatpak_decomposed_dup_branch (new); + g_assert_cmpstr (new_branch, ==, "beta"); + } }