[glib/glib-2-66: 4/5] Expand test coverage for G_SPAWN_SEARCH_PATH




commit 9eb4fe3c00a84190431f0e71143eafc48235d643
Author: Simon McVittie <smcv collabora com>
Date:   Sun Jan 31 14:01:06 2021 +0000

    Expand test coverage for G_SPAWN_SEARCH_PATH
    
    Signed-off-by: Simon McVittie <smcv collabora com>

 glib/tests/spawn-path-search-helper.c |  15 +++
 glib/tests/spawn-path-search.c        | 200 ++++++++++++++++++++++++++++++++++
 2 files changed, 215 insertions(+)
---
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 ();
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]