diff --git a/pressure-vessel/flatpak-bwrap-private.h b/pressure-vessel/flatpak-bwrap-private.h index 98cd82ebe827ed6d69570654aeed53553824bdb1..3bf5bfe5cd2b0803741613507e280e3fb70af817 100644 --- a/pressure-vessel/flatpak-bwrap-private.h +++ b/pressure-vessel/flatpak-bwrap-private.h @@ -76,6 +76,7 @@ void flatpak_bwrap_add_bind_arg (FlatpakBwrap *bwrap, const char *type, const char *src, const char *dest); +void flatpak_bwrap_sort_envp (FlatpakBwrap *bwrap); gboolean flatpak_bwrap_bundle_args (FlatpakBwrap *bwrap, int start, int end, diff --git a/pressure-vessel/flatpak-bwrap.c b/pressure-vessel/flatpak-bwrap.c index e3d0a482eb1b298fdd6d454080b06efd3278743e..2a90e4d30f5f2bcbe6f1bff7d23cc2afd0c5dc59 100644 --- a/pressure-vessel/flatpak-bwrap.c +++ b/pressure-vessel/flatpak-bwrap.c @@ -277,6 +277,21 @@ flatpak_bwrap_add_bind_arg (FlatpakBwrap *bwrap, } } +/* + * Sort bwrap->envp. This has no practical effect, but it's easier to + * see what is going on in a large environment block if the variables + * are sorted. + */ +void +flatpak_bwrap_sort_envp (FlatpakBwrap *bwrap) +{ + if (bwrap->envp != NULL) + { + qsort (bwrap->envp, g_strv_length (bwrap->envp), sizeof (char *), + flatpak_envp_cmp); + } +} + gboolean flatpak_bwrap_bundle_args (FlatpakBwrap *bwrap, int start, diff --git a/pressure-vessel/flatpak-utils-private.h b/pressure-vessel/flatpak-utils-private.h index 9e418e5a0c5c5cd464ef8bb84c518a96d8804e95..cdb75b11afba4837d6b91ef91cc3eb1d1dd24a91 100644 --- a/pressure-vessel/flatpak-utils-private.h +++ b/pressure-vessel/flatpak-utils-private.h @@ -92,4 +92,7 @@ null_safe_g_ptr_array_unref (gpointer data) { g_clear_pointer (&data, g_ptr_array_unref); } + +int flatpak_envp_cmp (const void *p1, + const void *p2); #endif /* __FLATPAK_UTILS_H__ */ diff --git a/pressure-vessel/flatpak-utils.c b/pressure-vessel/flatpak-utils.c index c3b913de261995fb7e83afea1a49b566c54fe68c..aca0a32a18225231874169ce00c5ac1a17e1ac32 100644 --- a/pressure-vessel/flatpak-utils.c +++ b/pressure-vessel/flatpak-utils.c @@ -7105,5 +7105,73 @@ flatpak_dconf_path_is_similar (const char *path1, return (path1[i1] == '\0'); } - #endif + +/** + * flatpak_envp_cmp: + * @p1: a `const char * const *` + * @p2: a `const char * const *` + * + * Compare two environment variables, given as pointers to pointers + * to the actual `KEY=value` string. + * + * In particular this is suitable for sorting a #GStrv using `qsort`. + * + * Returns: negative, 0 or positive if `*p1` compares before, equal to + * or after `*p2` + */ +int +flatpak_envp_cmp (const void *p1, + const void *p2) +{ + const char * const * s1 = p1; + const char * const * s2 = p2; + size_t l1 = strlen (*s1); + size_t l2 = strlen (*s2); + size_t min; + const char *tmp; + int ret; + + tmp = strchr (*s1, '='); + + if (tmp != NULL) + l1 = tmp - *s1; + + tmp = strchr (*s2, '='); + + if (tmp != NULL) + l2 = tmp - *s2; + + min = MIN (l1, l2); + ret = strncmp (*s1, *s2, min); + + /* If they differ before the first '=' (if any) in either s1 or s2, + * then they are certainly different */ + if (ret != 0) + return ret; + + ret = strcmp (*s1, *s2); + + /* If they do not differ at all, then they are equal */ + if (ret == 0) + return ret; + + /* FOO < FOO=..., and FOO < FOOBAR */ + if ((*s1)[min] == '\0') + return -1; + + /* FOO=... > FOO, and FOOBAR > FOO */ + if ((*s2)[min] == '\0') + return 1; + + /* FOO= < FOOBAR */ + if ((*s1)[min] == '=' && (*s2)[min] != '=') + return -1; + + /* FOOBAR > FOO= */ + if ((*s2)[min] == '=' && (*s1)[min] != '=') + return 1; + + /* Fall back to plain string comparison */ + return ret; +} diff --git a/pressure-vessel/utils.c b/pressure-vessel/utils.c index 49843c57af6985848a6fa64df90b4ecf72571ec5..ae76f8ff153bfb849b27a911269d16237c9a3585 100644 --- a/pressure-vessel/utils.c +++ b/pressure-vessel/utils.c @@ -46,75 +46,6 @@ static int my_pid = -1; static const gchar *my_prgname = NULL; -/** - * pv_envp_cmp: - * @p1: a `const char * const *` - * @p2: a `const char * const *` - * - * Compare two environment variables, given as pointers to pointers - * to the actual `KEY=value` string. - * - * In particular this is suitable for sorting a #GStrv using `qsort`. - * - * Returns: negative, 0 or positive if `*p1` compares before, equal to - * or after `*p2` - */ -int -pv_envp_cmp (const void *p1, - const void *p2) -{ - const char * const * s1 = p1; - const char * const * s2 = p2; - size_t l1 = strlen (*s1); - size_t l2 = strlen (*s2); - size_t min; - const char *tmp; - int ret; - - tmp = strchr (*s1, '='); - - if (tmp != NULL) - l1 = tmp - *s1; - - tmp = strchr (*s2, '='); - - if (tmp != NULL) - l2 = tmp - *s2; - - min = MIN (l1, l2); - ret = strncmp (*s1, *s2, min); - - /* If they differ before the first '=' (if any) in either s1 or s2, - * then they are certainly different */ - if (ret != 0) - return ret; - - ret = strcmp (*s1, *s2); - - /* If they do not differ at all, then they are equal */ - if (ret == 0) - return ret; - - /* FOO < FOO=..., and FOO < FOOBAR */ - if ((*s1)[min] == '\0') - return -1; - - /* FOO=... > FOO, and FOOBAR > FOO */ - if ((*s2)[min] == '\0') - return 1; - - /* FOO= < FOOBAR */ - if ((*s1)[min] == '=' && (*s2)[min] != '=') - return -1; - - /* FOOBAR > FOO= */ - if ((*s2)[min] == '=' && (*s1)[min] != '=') - return 1; - - /* Fall back to plain string comparison */ - return ret; -} - /** * pv_get_current_dirs: * @cwd_p: (out) (transfer full) (optional): Used to return the diff --git a/pressure-vessel/utils.h b/pressure-vessel/utils.h index 63cbf2093553f8c5f45002109fe3428efbe7fc4d..a2d11fb230424fbb37f47d3acc3c86ccc6f3ece8 100644 --- a/pressure-vessel/utils.h +++ b/pressure-vessel/utils.h @@ -44,9 +44,6 @@ #define pv_log_failure(...) \ g_log (G_LOG_DOMAIN, PV_LOG_LEVEL_FAILURE, __VA_ARGS__) -int pv_envp_cmp (const void *p1, - const void *p2); - void pv_get_current_dirs (gchar **cwd_p, gchar **cwd_l); diff --git a/pressure-vessel/wrap.c b/pressure-vessel/wrap.c index fe13913f0bd97ce04666c676ae5b714d9ed16dda..69159c56eae7991011d96e3fbae3f86a4eda4d1d 100644 --- a/pressure-vessel/wrap.c +++ b/pressure-vessel/wrap.c @@ -1725,7 +1725,7 @@ main (int argc, g_debug ("Environment variables:"); - qsort (env, g_strv_length (env), sizeof (char *), pv_envp_cmp); + qsort (env, g_strv_length (env), sizeof (char *), flatpak_envp_cmp); for (i = 0; env[i] != NULL; i++) { @@ -2748,9 +2748,7 @@ main (int argc, /* We'll have permuted the order anyway, so we might as well sort it, * to make debugging a bit easier. */ - if (final_argv->envp != NULL) - qsort (final_argv->envp, g_strv_length (final_argv->envp), - sizeof (char *), pv_envp_cmp); + flatpak_bwrap_sort_envp (final_argv); if (opt_verbose) { diff --git a/tests/pressure-vessel/utils.c b/tests/pressure-vessel/utils.c index 0856c8e24fff8591e08ff1cef39297ca3fe04043..b10ac4dc7d055c729a4cf7e4cd49136b212ef3af 100644 --- a/tests/pressure-vessel/utils.c +++ b/tests/pressure-vessel/utils.c @@ -34,6 +34,7 @@ #include "libglnx/libglnx.h" #include "tests/test-utils.h" +#include "flatpak-utils-private.h" #include "mtree.h" #include "utils.h" @@ -281,14 +282,14 @@ test_envp_cmp (Fixture *f, g_autofree gchar *copy = g_strdup (sorted[i]); g_test_message ("%s == %s", copy, sorted[i]); - g_assert_cmpint (pv_envp_cmp (©, &sorted[i]), ==, 0); - g_assert_cmpint (pv_envp_cmp (&sorted[i], ©), ==, 0); + g_assert_cmpint (flatpak_envp_cmp (©, &sorted[i]), ==, 0); + g_assert_cmpint (flatpak_envp_cmp (&sorted[i], ©), ==, 0); for (j = i + 1; j < G_N_ELEMENTS (sorted); j++) { g_test_message ("%s < %s", sorted[i], sorted[j]); - g_assert_cmpint (pv_envp_cmp (&sorted[i], &sorted[j]), <, 0); - g_assert_cmpint (pv_envp_cmp (&sorted[j], &sorted[i]), >, 0); + g_assert_cmpint (flatpak_envp_cmp (&sorted[i], &sorted[j]), <, 0); + g_assert_cmpint (flatpak_envp_cmp (&sorted[j], &sorted[i]), >, 0); } } @@ -297,7 +298,7 @@ test_envp_cmp (Fixture *f, for (i = 0; i < G_N_ELEMENTS (unsorted); i++) sort_this[i] = unsorted[i]; - qsort (sort_this, G_N_ELEMENTS (unsorted), sizeof (char *), pv_envp_cmp); + qsort (sort_this, G_N_ELEMENTS (unsorted), sizeof (char *), flatpak_envp_cmp); for (i = 0; i < G_N_ELEMENTS (sorted); i++) g_assert_cmpstr (sorted[i], ==, sort_this[i]);