]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
* locale/programs/locarchive.c (open_archive): Map the entire file
authorUlrich Drepper <drepper@redhat.com>
Sat, 18 Apr 2009 12:12:33 +0000 (12:12 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sat, 18 Apr 2009 12:12:33 +0000 (12:12 +0000)
and not just the administrative data.
(add_locale): When we find a hash sum match compare the content
to be sure.

ChangeLog
locale/programs/locarchive.c

index bbb4a57f946dc902abed88455e33a0e41027e02d..65f2c0a1b279d314eadfd16493ad3126830b1ce3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2009-04-18  Ulrich Drepper  <drepper@redhat.com>
 
+       * locale/programs/locarchive.c (open_archive): Map the entire file
+       and not just the administrative data.
+       (add_locale): When we find a hash sum match compare the content
+       to be sure.
+
        * malloc/malloc.c (malloc_info): Output address space information.
 
 2009-04-17  Ulrich Drepper  <drepper@redhat.com>
index 42e661846e13c9dd7d070850831b7114d3ef351a..ada8ab49bff6873d59e8b8643a98b6f9701faf80 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -380,7 +380,7 @@ enlarge_archive (struct locarhandle *ah, const struct locarhead *head)
            = ((char *) ah->addr
               + oldnamehashtab[oldlocrecarray[cnt - 1].cnt].name_offset);
 
-         add_alias (&new_ah, 
+         add_alias (&new_ah,
                     ((char *) ah->addr
                      + oldnamehashtab[oldlocrecarray[cnt].cnt].name_offset),
                     0, oldname, &last_locrec_offset);
@@ -517,9 +517,9 @@ open_archive (struct locarhandle *ah, bool readonly)
   ah->len = (head.sumhash_offset
             + head.sumhash_size * sizeof (struct sumhashent));
 
-  /* Now we know how large the administrative information part is.
-     Map all of it.  */
-  ah->addr = mmap64 (NULL, ah->len, PROT_READ | (readonly ? 0 : PROT_WRITE),
+  /* Map the entire file.  We might need to compare the category data
+     in the file with the newly added data.  */
+  ah->addr = mmap64 (NULL, st.st_size, PROT_READ | (readonly ? 0 : PROT_WRITE),
                     MAP_SHARED, fd, 0);
   if (ah->addr == MAP_FAILED)
     {
@@ -760,10 +760,32 @@ add_locale (struct locarhandle *ah,
          {
            if (memcmp (data[cnt].sum, sumhashtab[idx].sum, 16) == 0)
              {
-               /* Found it.  */
-               file_offsets[cnt] = sumhashtab[idx].file_offset;
-               --num_new_offsets;
-               break;
+               /* Check the content, there could be a collision of
+                  the hash sum.
+
+                  Unfortunately the sumhashent record does not include
+                  the size of the stored data.  So we have to search for
+                  it.  */
+               locrecent = (struct locrecent *) ((char *) ah->addr
+                                                 + head->locrectab_offset);
+               size_t iloc;
+               for (iloc = 0; iloc < head->locrectab_used; ++iloc)
+                 if (locrecent[iloc].refs != 0
+                     && (locrecent[iloc].record[cnt].offset
+                         == sumhashtab[idx].file_offset))
+                   break;
+
+               if (iloc != head->locrectab_used
+                   && data[cnt].size == locrecent[iloc].record[cnt].len
+                   && memcmp (data[cnt].addr,
+                              (char *) ah->addr + sumhashtab[idx].file_offset,
+                              data[cnt].size) == 0)
+                 {
+                   /* Found it.  */
+                   file_offsets[cnt] = sumhashtab[idx].file_offset;
+                   --num_new_offsets;
+                   break;
+                 }
              }
 
            idx += incr;