Imported Upstream version 0.19.7
[platform/upstream/gettext.git] / gettext-runtime / intl / loadmsgcat.c
index 9abee08..268e1bf 100644 (file)
@@ -1,5 +1,5 @@
 /* Load needed message catalogs.
-   Copyright (C) 1995-1999, 2000-2008, 2010 Free Software Foundation, Inc.
+   Copyright (C) 1995-2015 Free Software Foundation, Inc.
 
    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
@@ -25,6 +25,7 @@
 # include <config.h>
 #endif
 
+#include <assert.h>
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -99,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.  */
@@ -780,7 +785,6 @@ internal_function
 _nl_load_domain (struct loaded_l10nfile *domain_file,
                 struct binding *domainbinding)
 {
-  __libc_lock_define_initialized_recursive (static, lock)
   int fd = -1;
   size_t size;
 #ifdef _LIBC
@@ -794,6 +798,7 @@ _nl_load_domain (struct loaded_l10nfile *domain_file,
   int revision;
   const char *nullentry;
   size_t nullentrylen;
+  __libc_lock_define_initialized_recursive (static, lock);
 
   __libc_lock_lock_recursive (lock);
   if (domain_file->decided != 0)
@@ -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
@@ -878,6 +885,7 @@ _nl_load_domain (struct loaded_l10nfile *domain_file,
              if (nb == -1 && errno == EINTR)
                continue;
 #endif
+              free (data);
              goto out;
            }
          read_ptr += nb;
@@ -1258,7 +1266,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 +1282,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 +1295,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 +1329,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)