[PATCH v6] locale: memory leak in newlocale [BZ #25770]
Florian Weimer
fweimer@redhat.com
Mon Jun 2 09:09:24 GMT 2025
* Dmitry Kovalenko:
> diff --git a/locale/Makefile b/locale/Makefile
> index 9d9c1a7691..a9d29d08bc 100644
> --- a/locale/Makefile
> +++ b/locale/Makefile
> @@ -184,3 +195,13 @@ $(objpfx)tst-locale-locpath.out : tst-locale-locpath.sh $(objpfx)locale
> $(evaluate-test)
>
> $(objpfx)tst-localedef-path-norm: $(shared-thread-library)
> +
> +ifeq ($(run-built-tests),yes)
> +endif # $(run-built-tests) == yes
This appears to be a spurious change.
> +LDLIBS-tst-newlocale = $(shared-thread-library)
> +tst-newlocale-ENV = MALLOC_TRACE=$(objpfx)tst-newlocale.mtrace \
> + LD_PRELOAD=$(common-objpfx)/malloc/libc_malloc_debug.so
> +$(objpfx)tst-newlocale-mem.out: $(objpfx)tst-newlocale.out
> + $(common-objpfx)malloc/mtrace $(objpfx)tst-newlocale.mtrace > $@; \
> + $(evaluate-test)
> diff --git a/locale/newlocale.c b/locale/newlocale.c
> index d25a6038d3..cc93131fe8 100644
> --- a/locale/newlocale.c
> +++ b/locale/newlocale.c
> @@ -22,6 +22,7 @@
> #include <locale.h>
> #include <stdlib.h>
> #include <string.h>
> +#include <assert.h>
>
> #include "localeinfo.h"
>
> @@ -38,19 +39,21 @@ __libc_rwlock_define (extern , __libc_setlocale_lock attribute_hidden)
> } while (0)
>
>
> -locale_t
> -__newlocale (int category_mask, const char *locale, locale_t base)
> +static locale_t
> +__newlocale_1 (int category_mask, const char *locale, locale_t base, char ** const locale_path_ptr)
> {
> /* Intermediate memory for result. */
> const char *newnames[__LC_LAST];
> struct __locale_struct result;
> locale_t result_ptr;
> - char *locale_path;
> size_t locale_path_len;
> const char *locpath_var;
> int cnt;
> size_t names_len;
>
> + assert(locale_path_ptr != NULL);
> + assert((*locale_path_ptr) == NULL);
Please use ' (' in function-like macro calls, so:
assert (locale_path_ptr != NULL);
assert (*locale_path_ptr == NULL);
> +locale_t
> +__newlocale (int category_mask, const char *locale, locale_t base)
> +{
> + char *tmp_buffer = NULL;
> +
> + const locale_t result = __newlocale_1(
> + category_mask,
> + locale,
> + base,
> + &tmp_buffer);
> +
> + free(tmp_buffer);
> +
> + return result;
> +}
We generally do not write function calls in this way. Just list the
arguments on a single line, and wrap as needed. The first argument on
each line should be at the same column.
(Also missing space before '('.)
I can fix up these style issues for you before pushing on your behalf.
> +
> weak_alias (__newlocale, newlocale)
> diff --git a/locale/tst-newlocale.c b/locale/tst-newlocale.c
> new file mode 100755
> index 0000000000..fc49eabe84
> --- /dev/null
> +++ b/locale/tst-newlocale.c
> @@ -0,0 +1,55 @@
> +/* This test checks a memory leak in newlocal function [BZ #25770].
> + Copyright (C) 2025 Free Software Foundation, Inc.
If you are submitting under DCO, this should say:
Copyright The GNU Toolchain Authors.
You are not assigning copright to the FSF.
> + {
> + char s[] = "LOCPATH=/usr/share/locale";
As far as I understand it, this path is not actually used. Is this
accurate? If so, please add a comment. Ordinarily, this would be a
test bug because it fails to isolate the test from the host environment.
> + int const r = putenv (s);
> +
> + if (r != 0)
> + {
> + printf ("putenv failed: %m\n");
> + exit (EXIT_FAILURE);
> + }
> + }
You could include <support/check.h> and use
if (r != 0)
FAIL_EXIT1 ("putenv: %m");
> + {
> + locale_t const l = newlocale (1 << LC_CTYPE, "POSIX", NULL);
> +
> + if (l == NULL)
> + {
> + printf ("newlocale failed: %m\n");
> + exit (EXIT_FAILURE);
> + }
Likewise.
Thanks,
Florian
More information about the Libc-alpha
mailing list