[glib] Plug a mem leak in g_environ_unsetenv



commit 26f238e85d751aded81602f68cd69bf73cfc8350
Author: Christian Persch <chpe gnome org>
Date:   Sun Feb 5 16:00:31 2012 +0100

    Plug a mem leak in g_environ_unsetenv
    
    And clarify the memory allocation requirement of the string arrays passed to
    g_environ_{,un}setenv().
    
    ==9458== 10 bytes in 1 blocks are definitely lost in loss record 16 of 39
    ==9458==    at 0x402AD89: malloc (vg_replace_malloc.c:236)
    ==9458==    by 0x4221A1F: vasprintf (vasprintf.c:78)
    ==9458==    by 0x40C6065: g_vasprintf (gprintf.c:314)
    ==9458==    by 0x409D894: g_strdup_vprintf (gstrfuncs.c:509)
    ==9458==    by 0x409D8C9: g_strdup_printf (gstrfuncs.c:535)
    ==9458==    by 0x40672E9: g_environ_setenv (genviron.c:156)
    ==9458==    by 0x80490E7: test_environ_array (environment.c:78)
    ==9458==    by 0x40A3DB5: test_case_run (gtestutils.c:1662)
    ==9458==    by 0x40A40B2: g_test_run_suite_internal (gtestutils.c:1715)
    ==9458==    by 0x40A417C: g_test_run_suite_internal (gtestutils.c:1726)
    ==9458==    by 0x40A42F9: g_test_run_suite (gtestutils.c:1771)
    ==9458==    by 0x40A3441: g_test_run (gtestutils.c:1319)
    ==9458==    by 0x80493F1: main (environment.c:108)
    
    Bug #669412.

 glib/genviron.c |   63 ++++++++++++++++++++++++++++++++++---------------------
 1 files changed, 39 insertions(+), 24 deletions(-)
---
diff --git a/glib/genviron.c b/glib/genviron.c
index b876451..b92c865 100644
--- a/glib/genviron.c
+++ b/glib/genviron.c
@@ -109,7 +109,7 @@ g_environ_getenv (gchar       **envp,
 /**
  * g_environ_setenv:
  * @envp: (array zero-terminated=1) (transfer full): an environment
- *     list (eg, as returned from g_get_environ())
+ *     list that can be freed using g_strfreev() (e.g., as returned from g_get_environ())
  * @variable: the environment variable to set, must not contain '='
  * @value: the value for to set the variable to
  * @overwrite: whether to change the variable if it already exists
@@ -122,7 +122,7 @@ g_environ_getenv (gchar       **envp,
  * arbitrary byte strings. On Windows, they should be in UTF-8.
  *
  * Return value: (array zero-terminated=1) (transfer full): the
- *     updated environment
+ *     updated environment list. Free it using g_strfreev().
  *
  * Since: 2.32
  */
@@ -160,31 +160,14 @@ g_environ_setenv (gchar       **envp,
   return envp;
 }
 
-/**
- * g_environ_unsetenv:
- * @envp: (array zero-terminated=1) (transfer full): an environment
- *     list (eg, as returned from g_get_environ())
- * @variable: the environment variable to remove, must not contain '='
- *
- * Removes the environment variable @variable from the provided
- * environment @envp.
- *
- * Return value: (array zero-terminated=1) (transfer full): the
- *     updated environment
- *
- * Since: 2.32
- */
-gchar **
-g_environ_unsetenv (gchar       **envp,
-                    const gchar  *variable)
+static gchar **
+g_environ_unsetenv_internal (gchar        **envp,
+                             const gchar   *variable,
+                             gboolean       free_value)
 {
   gint len;
   gchar **e, **f;
 
-  g_return_val_if_fail (envp != NULL, NULL);
-  g_return_val_if_fail (variable != NULL, NULL);
-  g_return_val_if_fail (strchr (variable, '=') == NULL, NULL);
-
   len = strlen (variable);
 
   /* Note that we remove *all* environment entries for
@@ -198,6 +181,12 @@ g_environ_unsetenv (gchar       **envp,
           *f = *e;
           f++;
         }
+      else
+        {
+          if (free_value)
+            g_free (*e);
+        }
+
       e++;
     }
   *f = NULL;
@@ -205,6 +194,32 @@ g_environ_unsetenv (gchar       **envp,
   return envp;
 }
 
+
+/**
+ * g_environ_unsetenv:
+ * @envp: (array zero-terminated=1) (transfer full): an environment
+ *     list that can be freed using g_strfreev() (e.g., as returned from g_get_environ())
+ * @variable: the environment variable to remove, must not contain '='
+ *
+ * Removes the environment variable @variable from the provided
+ * environment @envp.
+ *
+ * Return value: (array zero-terminated=1) (transfer full): the
+ *     updated environment list. Free it using g_strfreev().
+ *
+ * Since: 2.32
+ */
+gchar **
+g_environ_unsetenv (gchar       **envp,
+                    const gchar  *variable)
+{
+  g_return_val_if_fail (envp != NULL, NULL);
+  g_return_val_if_fail (variable != NULL, NULL);
+  g_return_val_if_fail (strchr (variable, '=') == NULL, NULL);
+
+  return g_environ_unsetenv_internal (envp, variable, TRUE);
+}
+
 /* UNIX implemention {{{1 */
 #ifndef G_OS_WIN32
 
@@ -346,7 +361,7 @@ g_unsetenv (const gchar *variable)
   /* Mess directly with the environ array.
    * This seems to be the only portable way to do this.
    */
-  g_environ_unsetenv (environ, variable);
+  g_environ_unsetenv_internal (environ, variable, FALSE);
 #endif /* !HAVE_UNSETENV */
 }
 



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