mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-11-04 01:58:54 +01:00 
			
		
		
		
	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.
			
			
This commit is contained in:
		@@ -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 */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user