summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <smcv@collabora.com>2021-01-31 14:01:06 +0000
committerSimon McVittie <smcv@collabora.com>2021-01-31 14:15:37 +0000
commita85c126602a8927a11a437a1dde71d253d3d38b6 (patch)
tree4248f7987a58b82555ecd3255b43fc0645baf75d
parente864c6577ad45ecf614c63850ef059edf3313670 (diff)
downloadglib-wip/avoid-searching-path.tar.gz
Expand test coverage for G_SPAWN_SEARCH_PATHwip/avoid-searching-path
Signed-off-by: Simon McVittie <smcv@collabora.com>
-rw-r--r--glib/tests/spawn-path-search-helper.c15
-rw-r--r--glib/tests/spawn-path-search.c200
2 files changed, 215 insertions, 0 deletions
diff --git a/glib/tests/spawn-path-search-helper.c b/glib/tests/spawn-path-search-helper.c
index b417c7896..378c203c7 100644
--- a/glib/tests/spawn-path-search-helper.c
+++ b/glib/tests/spawn-path-search-helper.c
@@ -55,6 +55,7 @@ main (int argc,
gboolean search_path = FALSE;
gboolean search_path_from_envp = FALSE;
gboolean slow_path = FALSE;
+ gboolean unset_path_in_envp = FALSE;
gchar *chdir_child = NULL;
gchar *set_path_in_envp = NULL;
gchar **envp = NULL;
@@ -72,6 +73,9 @@ main (int argc,
{ "set-path-in-envp", '\0',
G_OPTION_FLAG_NONE, G_OPTION_ARG_FILENAME, &set_path_in_envp,
"Set PATH in specified environment to this value", "PATH", },
+ { "unset-path-in-envp", '\0',
+ G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &unset_path_in_envp,
+ "Unset PATH in specified environment", NULL },
{ "slow-path", '\0',
G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &slow_path,
"Use a child-setup function to avoid the posix_spawn fast path", NULL },
@@ -102,9 +106,20 @@ main (int argc,
envp = g_get_environ ();
+ if (set_path_in_envp != NULL && unset_path_in_envp)
+ {
+ g_set_error (&error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
+ "Cannot both set PATH and unset it");
+ ret = 2;
+ goto out;
+ }
+
if (set_path_in_envp != NULL)
envp = g_environ_setenv (envp, "PATH", set_path_in_envp, TRUE);
+ if (unset_path_in_envp)
+ envp = g_environ_unsetenv (envp, "PATH");
+
if (search_path)
spawn_flags |= G_SPAWN_SEARCH_PATH;
diff --git a/glib/tests/spawn-path-search.c b/glib/tests/spawn-path-search.c
index 9fbfd478e..f4278f3e0 100644
--- a/glib/tests/spawn-path-search.c
+++ b/glib/tests/spawn-path-search.c
@@ -239,6 +239,200 @@ test_search_path_ambiguous (void)
g_ptr_array_unref (argv);
}
+static void
+test_search_path_fallback_in_environ (void)
+{
+ GPtrArray *argv = g_ptr_array_new_with_free_func (g_free);
+ gchar *here = g_test_build_filename (G_TEST_BUILT, ".", NULL);
+ gchar *subdir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", NULL);
+ gchar **envp = g_get_environ ();
+ gchar *out = NULL;
+ gchar *err = NULL;
+ GError *error = NULL;
+ int wait_status = -1;
+
+ g_test_summary ("With G_SPAWN_SEARCH_PATH but no PATH, a fallback is used.");
+ /* We can't make a meaningful assertion about what the fallback *is*,
+ * but we can assert that it *includes* the current working directory. */
+
+ if (g_file_test ("/usr/bin/spawn-test-helper", G_FILE_TEST_IS_EXECUTABLE) ||
+ g_file_test ("/bin/spawn-test-helper", G_FILE_TEST_IS_EXECUTABLE))
+ {
+ g_test_skip ("Not testing fallback with unknown spawn-test-helper "
+ "executable in /usr/bin:/bin");
+ return;
+ }
+
+ envp = g_environ_unsetenv (envp, "PATH");
+
+ g_ptr_array_add (argv,
+ g_test_build_filename (G_TEST_BUILT, "spawn-path-search-helper", NULL));
+ g_ptr_array_add (argv, g_strdup ("--search-path"));
+ g_ptr_array_add (argv, g_strdup ("--set-path-in-envp"));
+ g_ptr_array_add (argv, g_strdup (subdir));
+ g_ptr_array_add (argv, g_strdup ("--"));
+ g_ptr_array_add (argv, g_strdup ("spawn-test-helper"));
+ g_ptr_array_add (argv, NULL);
+
+ g_spawn_sync (here,
+ (char **) argv->pdata,
+ envp,
+ G_SPAWN_DEFAULT,
+ NULL, /* child setup */
+ NULL, /* user data */
+ &out,
+ &err,
+ &wait_status,
+ &error);
+ g_assert_no_error (error);
+
+ g_test_message ("%s", out);
+ g_test_message ("%s", err);
+ g_assert_nonnull (strstr (err, "this is spawn-test-helper from glib/tests"));
+
+#ifdef G_OS_UNIX
+ g_assert_true (WIFEXITED (wait_status));
+ g_assert_cmpint (WEXITSTATUS (wait_status), ==, 0);
+#endif
+
+ g_strfreev (envp);
+ g_free (here);
+ g_free (subdir);
+ g_free (out);
+ g_free (err);
+ g_ptr_array_unref (argv);
+}
+
+static void
+test_search_path_fallback_in_envp (void)
+{
+ GPtrArray *argv = g_ptr_array_new_with_free_func (g_free);
+ gchar *here = g_test_build_filename (G_TEST_BUILT, ".", NULL);
+ gchar *subdir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", NULL);
+ gchar **envp = g_get_environ ();
+ gchar *out = NULL;
+ gchar *err = NULL;
+ GError *error = NULL;
+ int wait_status = -1;
+
+ g_test_summary ("With G_SPAWN_SEARCH_PATH_FROM_ENVP but no PATH, a fallback is used.");
+ /* We can't make a meaningful assertion about what the fallback *is*,
+ * but we can assert that it *includes* the current working directory. */
+
+ if (g_file_test ("/usr/bin/spawn-test-helper", G_FILE_TEST_IS_EXECUTABLE) ||
+ g_file_test ("/bin/spawn-test-helper", G_FILE_TEST_IS_EXECUTABLE))
+ {
+ g_test_skip ("Not testing fallback with unknown spawn-test-helper "
+ "executable in /usr/bin:/bin");
+ return;
+ }
+
+ envp = g_environ_setenv (envp, "PATH", subdir, TRUE);
+
+ g_ptr_array_add (argv,
+ g_test_build_filename (G_TEST_BUILT, "spawn-path-search-helper", NULL));
+ g_ptr_array_add (argv, g_strdup ("--search-path-from-envp"));
+ g_ptr_array_add (argv, g_strdup ("--unset-path-in-envp"));
+ g_ptr_array_add (argv, g_strdup ("--"));
+ g_ptr_array_add (argv, g_strdup ("spawn-test-helper"));
+ g_ptr_array_add (argv, NULL);
+
+ g_spawn_sync (here,
+ (char **) argv->pdata,
+ envp,
+ G_SPAWN_DEFAULT,
+ NULL, /* child setup */
+ NULL, /* user data */
+ &out,
+ &err,
+ &wait_status,
+ &error);
+ g_assert_no_error (error);
+
+ g_test_message ("%s", out);
+ g_test_message ("%s", err);
+ g_assert_nonnull (strstr (err, "this is spawn-test-helper from glib/tests"));
+
+#ifdef G_OS_UNIX
+ g_assert_true (WIFEXITED (wait_status));
+ g_assert_cmpint (WEXITSTATUS (wait_status), ==, 0);
+#endif
+
+ g_strfreev (envp);
+ g_free (here);
+ g_free (subdir);
+ g_free (out);
+ g_free (err);
+ g_ptr_array_unref (argv);
+}
+
+static void
+test_search_path_heap_allocation (void)
+{
+ GPtrArray *argv = g_ptr_array_new_with_free_func (g_free);
+ /* Must be longer than the arbitrary 4000 byte limit for stack allocation
+ * in gspawn.c */
+ char placeholder[4096];
+ gchar *here = g_test_build_filename (G_TEST_BUILT, ".", NULL);
+ gchar *subdir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", NULL);
+ gchar *long_dir = NULL;
+ gchar *long_path = NULL;
+ gchar **envp = g_get_environ ();
+ gchar *out = NULL;
+ gchar *err = NULL;
+ GError *error = NULL;
+ int wait_status = -1;
+ gsize i;
+
+ memset (placeholder, '_', sizeof (placeholder));
+ /* Force search_path_buffer to be heap-allocated */
+ long_dir = g_test_build_filename (G_TEST_BUILT, "path-test-subdir", placeholder, NULL);
+ long_path = g_strjoin (G_SEARCHPATH_SEPARATOR_S, subdir, long_dir, NULL);
+ envp = g_environ_setenv (envp, "PATH", long_path, TRUE);
+
+ g_ptr_array_add (argv,
+ g_test_build_filename (G_TEST_BUILT, "spawn-path-search-helper", NULL));
+ g_ptr_array_add (argv, g_strdup ("--search-path"));
+ g_ptr_array_add (argv, g_strdup ("--"));
+ g_ptr_array_add (argv, g_strdup ("spawn-test-helper"));
+
+ /* Add enough arguments to make argv longer than the arbitrary 4000 byte
+ * limit for stack allocation in gspawn.c.
+ * This assumes sizeof (char *) >= 4. */
+ for (i = 0; i < 1001; i++)
+ g_ptr_array_add (argv, g_strdup ("_"));
+
+ g_ptr_array_add (argv, NULL);
+
+ g_spawn_sync (here,
+ (char **) argv->pdata,
+ envp,
+ G_SPAWN_DEFAULT,
+ NULL, /* child setup */
+ NULL, /* user data */
+ &out,
+ &err,
+ &wait_status,
+ &error);
+ g_assert_no_error (error);
+
+ g_test_message ("%s", out);
+ g_test_message ("%s", err);
+ g_assert_nonnull (strstr (err, "this is spawn-test-helper from path-test-subdir"));
+
+#ifdef G_OS_UNIX
+ g_assert_true (WIFEXITED (wait_status));
+ g_assert_cmpint (WEXITSTATUS (wait_status), ==, 5);
+#endif
+
+ g_strfreev (envp);
+ g_free (here);
+ g_free (subdir);
+ g_free (out);
+ g_free (err);
+ g_ptr_array_unref (argv);
+}
+
int
main (int argc,
char **argv)
@@ -249,6 +443,12 @@ main (int argc,
g_test_add_func ("/spawn/search-path", test_search_path);
g_test_add_func ("/spawn/search-path-from-envp", test_search_path_from_envp);
g_test_add_func ("/spawn/search-path-ambiguous", test_search_path_ambiguous);
+ g_test_add_func ("/spawn/search-path-heap-allocation",
+ test_search_path_heap_allocation);
+ g_test_add_func ("/spawn/search-path-fallback-in-environ",
+ test_search_path_fallback_in_environ);
+ g_test_add_func ("/spawn/search-path-fallback-in-envp",
+ test_search_path_fallback_in_envp);
return g_test_run ();
}