Internal change PiperOrigin-RevId: 364810910 Change-Id: I4e1ea9b30f01b22ba1e1cd5ac3d956b0727ab408
diff --git a/google3/third_party/grte/v4_src/glibc-2.19/ChangeLog.google b/google3/third_party/grte/v4_src/glibc-2.19/ChangeLog.google index 90d70b8..e5be96f 100644 --- a/google3/third_party/grte/v4_src/glibc-2.19/ChangeLog.google +++ b/google3/third_party/grte/v4_src/glibc-2.19/ChangeLog.google
@@ -745,3 +745,8 @@ Fix segfault in getaddrinfo() with large numbers of local ipaddrs [BZ16002] https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=44152e4b05fcc8bae5628cdb37342d9b7bd5ac3c (stanshebs, backport) + +iconv/gconv_db.c + Fix leak in error path of iconv_open. + https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=be64c2ef2ac2357ddff61841f2cc8246e5da1b20 + (stanshebs, backport)
diff --git a/google3/third_party/grte/v4_src/glibc-2.19/iconv/gconv_db.c b/google3/third_party/grte/v4_src/glibc-2.19/iconv/gconv_db.c index 7d752bc..51d7353 100644 --- a/google3/third_party/grte/v4_src/glibc-2.19/iconv/gconv_db.c +++ b/google3/third_party/grte/v4_src/glibc-2.19/iconv/gconv_db.c
@@ -243,6 +243,8 @@ struct __gconv_step *result; struct derivation_step *current; int status = __GCONV_NOMEM; + char *from_name = NULL; + char *to_name = NULL; /* First determine number of steps. */ for (current = best; current->last != NULL; current = current->last) @@ -259,12 +261,30 @@ current = best; while (step_cnt-- > 0) { - result[step_cnt].__from_name = (step_cnt == 0 - ? __strdup (fromset) - : (char *)current->last->result_set); - result[step_cnt].__to_name = (step_cnt + 1 == *nsteps - ? __strdup (current->result_set) - : result[step_cnt + 1].__from_name); + if (step_cnt == 0) + { + result[step_cnt].__from_name = from_name = __strdup (fromset); + if (from_name == NULL) + { + 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].__data = NULL; @@ -332,6 +352,8 @@ while (++step_cnt < *nsteps) __gconv_release_step (&result[step_cnt]); free (result); + free (from_name); + free (to_name); *nsteps = 0; *handle = NULL; if (status == __GCONV_OK) @@ -828,8 +850,9 @@ /* Free all resources if necessary. */ libc_freeres_fn (free_mem) { - /* First free locale memory. This needs to be done before freeing derivations, - as ctype cleanup functions dereference steps arrays which we free below. */ + /* First free locale memory. This needs to be done before freeing + derivations, as ctype cleanup functions dereference steps arrays which we + free below. */ _nl_locale_subfreeres (); /* finddomain.c has similar problem. */