[glib: 1/2] genviron: make g_environ_* case-insensitive on Windows



commit a51ab0a5abfa7b65783ff5a73cfa5dd2eb5840a2
Author: Peter Wu <peter lekensteyn nl>
Date:   Tue Nov 27 16:02:37 2018 +0100

    genviron: make g_environ_* case-insensitive on Windows
    
    g_environ_getenv(env, "PATH") and g_environ_setenv(env, "PATH", newpath)
    did not have the intended effect on Windows due to the environment block
    containing "Path=". Make these functions case-insensitive for Windows.

 glib/genviron.c          | 22 +++++++++++++++++-----
 glib/tests/environment.c | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 56 insertions(+), 5 deletions(-)
---
diff --git a/glib/genviron.c b/glib/genviron.c
index 9c8151c20..c6edb8354 100644
--- a/glib/genviron.c
+++ b/glib/genviron.c
@@ -44,11 +44,24 @@
 #include "gquark.h"
 
 /* Environ array functions {{{1 */
+static gboolean
+g_environ_matches (const gchar *env, const gchar *variable, gsize len)
+{
+#ifdef G_OS_WIN32
+    /* TODO handle Unicode environment variable names */
+    /* Like filesystem paths, environment variables are case-insensitive. */
+    return g_ascii_strncasecmp (env, variable, len) == 0 && env[len] == '=';
+#else
+    return strncmp (env, variable, len) == 0 && env[len] == '=';
+#endif
+}
+
 static gint
 g_environ_find (gchar       **envp,
                 const gchar  *variable)
 {
-  gint len, i;
+  gsize len;
+  gint i;
 
   if (envp == NULL)
     return -1;
@@ -57,8 +70,7 @@ g_environ_find (gchar       **envp,
 
   for (i = 0; envp[i]; i++)
     {
-      if (strncmp (envp[i], variable, len) == 0 &&
-          envp[i][len] == '=')
+      if (g_environ_matches (envp[i], variable, len))
         return i;
     }
 
@@ -155,7 +167,7 @@ g_environ_unsetenv_internal (gchar        **envp,
                              const gchar   *variable,
                              gboolean       free_value)
 {
-  gint len;
+  gsize len;
   gchar **e, **f;
 
   len = strlen (variable);
@@ -166,7 +178,7 @@ g_environ_unsetenv_internal (gchar        **envp,
   e = f = envp;
   while (*e != NULL)
     {
-      if (strncmp (*e, variable, len) != 0 || (*e)[len] != '=')
+      if (!g_environ_matches (*e, variable, len))
         {
           *f = *e;
           f++;
diff --git a/glib/tests/environment.c b/glib/tests/environment.c
index 65ee7b092..aba19a7ae 100644
--- a/glib/tests/environment.c
+++ b/glib/tests/environment.c
@@ -116,6 +116,44 @@ test_environ_null (void)
   g_assert (env == NULL);
 }
 
+static void
+test_environ_case (void)
+{
+  gchar **env;
+  const gchar *value;
+
+  env = NULL;
+
+  env = g_environ_setenv (env, "foo", "bar", TRUE);
+  value = g_environ_getenv (env, "foo");
+  g_assert_cmpstr (value, ==, "bar");
+
+  value = g_environ_getenv (env, "Foo");
+#ifdef G_OS_WIN32
+  g_assert_cmpstr (value, ==, "bar");
+#else
+  g_assert (value == NULL);
+#endif
+
+  env = g_environ_setenv (env, "FOO", "x", TRUE);
+  value = g_environ_getenv (env, "foo");
+#ifdef G_OS_WIN32
+  g_assert_cmpstr (value, ==, "x");
+#else
+  g_assert_cmpstr (value, ==, "bar");
+#endif
+
+  env = g_environ_unsetenv (env, "Foo");
+  value = g_environ_getenv (env, "foo");
+#ifdef G_OS_WIN32
+  g_assert (value == NULL);
+#else
+  g_assert_cmpstr (value, ==, "bar");
+#endif
+
+  g_strfreev (env);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -125,6 +163,7 @@ main (int argc, char **argv)
   g_test_add_func ("/environ/setenv", test_setenv);
   g_test_add_func ("/environ/array", test_environ_array);
   g_test_add_func ("/environ/null", test_environ_null);
+  g_test_add_func ("/environ/case", test_environ_case);
 
   return g_test_run ();
 }


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