aboutsummaryrefslogtreecommitdiffstats
path: root/intl/loadmsgcat.c
diff options
context:
space:
mode:
Diffstat (limited to 'intl/loadmsgcat.c')
-rw-r--r--intl/loadmsgcat.c52
1 files changed, 35 insertions, 17 deletions
diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c
index bf883a37e..570f47693 100644
--- a/intl/loadmsgcat.c
+++ b/intl/loadmsgcat.c
@@ -1,20 +1,18 @@
/* Load needed message catalogs.
- Copyright (C) 1995-1999, 2000-2008 Free Software Foundation, Inc.
+ Copyright (C) 1995-1999, 2000-2008, 2010 Free Software Foundation, Inc.
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published
- by the Free Software Foundation; either version 2, or (at your option)
- any later version.
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2.1 of the License, or
+ (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- USA. */
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* Tell glibc's <string.h> to provide a prototype for mempcpy().
This must come before <config.h> because <config.h> may include
@@ -27,6 +25,7 @@
# include <config.h>
#endif
+#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
@@ -101,6 +100,10 @@ char *alloca ();
# include "lock.h"
#endif
+#ifdef _LIBC
+# define PRI_MACROS_BROKEN 0
+#endif
+
/* Provide fallback values for macros that ought to be defined in <inttypes.h>.
Note that our fallback values need not be literal strings, because we don't
use them with preprocessor string concatenation. */
@@ -760,10 +763,12 @@ get_sysdep_segment_value (const char *name)
/* Test for a glibc specific printf() format directive flag. */
if (name[0] == 'I' && name[1] == '\0')
{
-#if defined _LIBC || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)
+#if defined _LIBC \
+ || ((__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)) \
+ && !defined __UCLIBC__)
/* The 'I' flag, in numeric format directives, replaces ASCII digits
with the 'outdigits' defined in the LC_CTYPE locale facet. This is
- used for Farsi (Persian) and maybe Arabic. */
+ used for Farsi (Persian), some Indic languages, and maybe Arabic. */
return "I";
#else
return "";
@@ -780,7 +785,7 @@ internal_function
_nl_load_domain (struct loaded_l10nfile *domain_file,
struct binding *domainbinding)
{
- __libc_lock_define_initialized_recursive (static, lock)
+ __libc_lock_define_initialized_recursive (static, lock);
int fd = -1;
size_t size;
#ifdef _LIBC
@@ -847,13 +852,15 @@ _nl_load_domain (struct loaded_l10nfile *domain_file,
data = (struct mo_file_header *) mmap (NULL, size, PROT_READ,
MAP_PRIVATE, fd, 0);
- if (__builtin_expect (data != (struct mo_file_header *) -1, 1))
+ if (__builtin_expect (data != MAP_FAILED, 1))
{
/* mmap() call was successful. */
close (fd);
fd = -1;
use_mmap = 1;
}
+
+ assert (MAP_FAILED == (void *) -1);
#endif
/* If the data is not yet available (i.e. mmap'ed) we try to load
@@ -1258,7 +1265,7 @@ _nl_load_domain (struct loaded_l10nfile *domain_file,
default:
/* This is an invalid revision. */
invalid:
- /* This is an invalid .mo file. */
+ /* This is an invalid .mo file or we ran out of resources. */
free (domain->malloced);
#ifdef HAVE_MMAP
if (use_mmap)
@@ -1274,7 +1281,11 @@ _nl_load_domain (struct loaded_l10nfile *domain_file,
/* No caches of converted translations so far. */
domain->conversions = NULL;
domain->nconversions = 0;
+#ifdef _LIBC
+ __libc_rwlock_init (domain->conversions_lock);
+#else
gl_rwlock_init (domain->conversions_lock);
+#endif
/* Get the header entry and look for a plural specification. */
#ifdef IN_LIBGLOCALE
@@ -1283,6 +1294,13 @@ _nl_load_domain (struct loaded_l10nfile *domain_file,
#else
nullentry = _nl_find_msg (domain_file, domainbinding, "", 0, &nullentrylen);
#endif
+ if (__builtin_expect (nullentry == (char *) -1, 0))
+ {
+#ifdef _LIBC
+ __libc_rwlock_fini (domain->conversions_lock);
+#endif
+ goto invalid;
+ }
EXTRACT_PLURAL_EXPRESSION (nullentry, &domain->plural, &domain->nplurals);
out:
@@ -1310,7 +1328,7 @@ _nl_unload_domain (struct loaded_domain *domain)
{
struct converted_domain *convd = &domain->conversions[i];
- free (convd->encoding);
+ free ((char *) convd->encoding);
if (convd->conv_tab != NULL && convd->conv_tab != (char **) -1)
free (convd->conv_tab);
if (convd->conv != (__gconv_t) -1)