Fix BZ #19012 -- iconv_open leaks memory on error path.

This commit is contained in:
Paul Pluzhnikov 2015-10-05 20:03:48 -07:00
parent cec7d28af8
commit be64c2ef2a
3 changed files with 39 additions and 10 deletions

View File

@ -1,3 +1,9 @@
2015-10-05 Paul Pluzhnikov <ppluzhnikov@google.com>
[BZ #19012]
* iconv/gconv_db.c (gen_steps): Check for additional errors.
Clean up on failure.
2015-10-05 Joseph Myers <joseph@codesourcery.com> 2015-10-05 Joseph Myers <joseph@codesourcery.com>
[BZ #19071] [BZ #19071]

4
NEWS
View File

@ -17,8 +17,8 @@ Version 2.23
18757, 18778, 18781, 18787, 18789, 18790, 18795, 18796, 18803, 18820, 18757, 18778, 18781, 18787, 18789, 18790, 18795, 18796, 18803, 18820,
18823, 18824, 18825, 18857, 18863, 18870, 18872, 18873, 18875, 18887, 18823, 18824, 18825, 18857, 18863, 18870, 18872, 18873, 18875, 18887,
18921, 18951, 18952, 18956, 18961, 18966, 18967, 18969, 18970, 18977, 18921, 18951, 18952, 18956, 18961, 18966, 18967, 18969, 18970, 18977,
18980, 18981, 18985, 19003, 19016, 19032, 19046, 19049, 19050, 19059, 18980, 18981, 18985, 19003, 19012, 19016, 19032, 19046, 19049, 19050,
19071. 19059, 19071.
* The obsolete header <regexp.h> has been removed. Programs that require * The obsolete header <regexp.h> has been removed. Programs that require
this header must be updated to use <regex.h> instead. this header must be updated to use <regex.h> instead.

View File

@ -243,6 +243,8 @@ gen_steps (struct derivation_step *best, const char *toset,
struct __gconv_step *result; struct __gconv_step *result;
struct derivation_step *current; struct derivation_step *current;
int status = __GCONV_NOMEM; int status = __GCONV_NOMEM;
char *from_name = NULL;
char *to_name = NULL;
/* First determine number of steps. */ /* First determine number of steps. */
for (current = best; current->last != NULL; current = current->last) for (current = best; current->last != NULL; current = current->last)
@ -259,12 +261,30 @@ gen_steps (struct derivation_step *best, const char *toset,
current = best; current = best;
while (step_cnt-- > 0) while (step_cnt-- > 0)
{ {
result[step_cnt].__from_name = (step_cnt == 0 if (step_cnt == 0)
? __strdup (fromset) {
: (char *)current->last->result_set); result[step_cnt].__from_name = from_name = __strdup (fromset);
result[step_cnt].__to_name = (step_cnt + 1 == *nsteps if (from_name == NULL)
? __strdup (current->result_set) {
: result[step_cnt + 1].__from_name); failed = 1;
break;
}
}
else
result[step_cnt].__from_name = (char *)current->last->result_set;
if (step_cnt + 1 == *nsteps)
{
result[step_cnt].__to_name = to_name
= __strdup (current->result_set);
if (to_name == NULL)
{
failed = 1;
break;
}
}
else
result[step_cnt].__to_name = result[step_cnt + 1].__from_name;
result[step_cnt].__counter = 1; result[step_cnt].__counter = 1;
result[step_cnt].__data = NULL; result[step_cnt].__data = NULL;
@ -332,6 +352,8 @@ gen_steps (struct derivation_step *best, const char *toset,
while (++step_cnt < *nsteps) while (++step_cnt < *nsteps)
__gconv_release_step (&result[step_cnt]); __gconv_release_step (&result[step_cnt]);
free (result); free (result);
free (from_name);
free (to_name);
*nsteps = 0; *nsteps = 0;
*handle = NULL; *handle = NULL;
if (status == __GCONV_OK) if (status == __GCONV_OK)
@ -828,8 +850,9 @@ free_modules_db (struct gconv_module *node)
/* Free all resources if necessary. */ /* Free all resources if necessary. */
libc_freeres_fn (free_mem) libc_freeres_fn (free_mem)
{ {
/* First free locale memory. This needs to be done before freeing derivations, /* First free locale memory. This needs to be done before freeing
as ctype cleanup functions dereference steps arrays which we free below. */ derivations, as ctype cleanup functions dereference steps arrays which we
free below. */
_nl_locale_subfreeres (); _nl_locale_subfreeres ();
/* finddomain.c has similar problem. */ /* finddomain.c has similar problem. */