From cfefef6bd96294b373104e85d80bc3f4f3fb482b Mon Sep 17 00:00:00 2001 From: Mark H Weaver Date: Wed, 13 Aug 2014 22:47:32 -0400 Subject: [PATCH] Copy the result from 'nl_langinfo' before it can be overwritten. Based on a patch by Eli Zaretskii . * 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. --- libguile/i18n.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/libguile/i18n.c b/libguile/i18n.c index e38e5602e..c6b9b845e 100644 --- a/libguile/i18n.c +++ b/libguile/i18n.c @@ -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 * 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 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 item, SCM locale), @@ -1496,8 +1504,8 @@ SCM_DEFINE (scm_nl_langinfo, "nl-langinfo", 1, 1, 0, if (c_locale != NULL) { #ifdef USE_GNU_LOCALE_API - c_result = nl_langinfo_l (c_item, c_locale); - codeset = nl_langinfo_l (CODESET, c_locale); + c_result = copy_string_or_null (nl_langinfo_l (c_item, c_locale)); + codeset = copy_string_or_null (nl_langinfo_l (CODESET, c_locale)); #else /* !USE_GNU_LOCALE_API */ /* We can't use `RUN_IN_LOCALE_SECTION ()' here because the locale 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); else { - c_result = nl_langinfo (c_item); - codeset = nl_langinfo (CODESET); + c_result = copy_string_or_null (nl_langinfo (c_item)); + codeset = copy_string_or_null (nl_langinfo (CODESET)); restore_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 { - c_result = nl_langinfo (c_item); - codeset = nl_langinfo (CODESET); + c_result = copy_string_or_null (nl_langinfo (c_item)); + codeset = copy_string_or_null (nl_langinfo (CODESET)); } - if (c_result != NULL) - c_result = strdup (c_result); - unlock_locale_mutex (); 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; } #undef FUNC_NAME -- 2.20.1