1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 11:50:28 +02:00

Copy the result from 'nl_langinfo' before it can be overwritten.

Based on a patch by Eli Zaretskii <eliz@gnu.org>.

* libguile/i18n.c (copy_string_or_null): New static function.
  (scm_nl_langinfo): Use 'copy_string_or_null' to copy the result from
  'nl_langinfo' and 'nl_langinfo_l' before the next call and before
  releasing the locale mutex.
This commit is contained in:
Mark H Weaver 2014-08-13 22:47:32 -04:00
parent 7c848fe572
commit cfefef6bd9

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. /* Copyright (C) 2006-2014 Free Software Foundation, Inc.
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License * modify it under the terms of the GNU Lesser General Public License
@ -1465,6 +1465,14 @@ SCM_DEFINE (scm_locale_string_to_inexact, "locale-string->inexact",
Note: We don't use Gnulib's `nl_langinfo' module because it's currently not Note: We don't use Gnulib's `nl_langinfo' module because it's currently not
as complete as the compatibility hacks in `i18n.scm'. */ as complete as the compatibility hacks in `i18n.scm'. */
static char *
copy_string_or_null (const char *s)
{
if (s == NULL)
return NULL;
else
return strdup (s);
}
SCM_DEFINE (scm_nl_langinfo, "nl-langinfo", 1, 1, 0, SCM_DEFINE (scm_nl_langinfo, "nl-langinfo", 1, 1, 0,
(SCM item, SCM locale), (SCM item, SCM locale),
@ -1496,8 +1504,8 @@ SCM_DEFINE (scm_nl_langinfo, "nl-langinfo", 1, 1, 0,
if (c_locale != NULL) if (c_locale != NULL)
{ {
#ifdef USE_GNU_LOCALE_API #ifdef USE_GNU_LOCALE_API
c_result = nl_langinfo_l (c_item, c_locale); c_result = copy_string_or_null (nl_langinfo_l (c_item, c_locale));
codeset = nl_langinfo_l (CODESET, c_locale); codeset = copy_string_or_null (nl_langinfo_l (CODESET, c_locale));
#else /* !USE_GNU_LOCALE_API */ #else /* !USE_GNU_LOCALE_API */
/* We can't use `RUN_IN_LOCALE_SECTION ()' here because the locale /* We can't use `RUN_IN_LOCALE_SECTION ()' here because the locale
mutex is already taken. */ mutex is already taken. */
@ -1521,8 +1529,8 @@ SCM_DEFINE (scm_nl_langinfo, "nl-langinfo", 1, 1, 0,
scm_locale_error (FUNC_NAME, lsec_err); scm_locale_error (FUNC_NAME, lsec_err);
else else
{ {
c_result = nl_langinfo (c_item); c_result = copy_string_or_null (nl_langinfo (c_item));
codeset = nl_langinfo (CODESET); codeset = copy_string_or_null (nl_langinfo (CODESET));
restore_locale_settings (&lsec_prev_locale); restore_locale_settings (&lsec_prev_locale);
free_locale_settings (&lsec_prev_locale); free_locale_settings (&lsec_prev_locale);
@ -1531,13 +1539,10 @@ SCM_DEFINE (scm_nl_langinfo, "nl-langinfo", 1, 1, 0,
} }
else else
{ {
c_result = nl_langinfo (c_item); c_result = copy_string_or_null (nl_langinfo (c_item));
codeset = nl_langinfo (CODESET); codeset = copy_string_or_null (nl_langinfo (CODESET));
} }
if (c_result != NULL)
c_result = strdup (c_result);
unlock_locale_mutex (); unlock_locale_mutex ();
if (c_result == NULL) if (c_result == NULL)
@ -1669,6 +1674,9 @@ SCM_DEFINE (scm_nl_langinfo, "nl-langinfo", 1, 1, 0,
} }
} }
if (codeset != NULL)
free (codeset);
return result; return result;
} }
#undef FUNC_NAME #undef FUNC_NAME