Merge branch 'jk/info-alternates-fix' into maint
authorJunio C Hamano <gitster@pobox.com>
Mon, 23 Oct 2017 05:40:00 +0000 (14:40 +0900)
committerJunio C Hamano <gitster@pobox.com>
Mon, 23 Oct 2017 05:40:00 +0000 (14:40 +0900)
A regression fix for 2.11 that made the code to read the list of
alternate object stores overrun the end of the string.

* jk/info-alternates-fix:
read_info_alternates: warn on non-trivial errors
read_info_alternates: read contents into strbuf

1  2 
sha1_file.c
diff --combined sha1_file.c
index 4d0e0c554d348d4104157bc16dd4795c1810689a,d65ca432459e7be287ec6ed85125a9afa6b74de1..bd5f82e66425c5ecec0aa45de611bed2eabf2793
@@@ -422,7 -422,7 +422,7 @@@ static const char *parse_alt_odb_entry(
        return end;
  }
  
- static void link_alt_odb_entries(const char *alt, int len, int sep,
+ static void link_alt_odb_entries(const char *alt, int sep,
                                 const char *relative_base, int depth)
  {
        struct strbuf objdirbuf = STRBUF_INIT;
  
  static void read_info_alternates(const char * relative_base, int depth)
  {
-       char *map;
-       size_t mapsz;
-       struct stat st;
        char *path;
-       int fd;
+       struct strbuf buf = STRBUF_INIT;
  
        path = xstrfmt("%s/info/alternates", relative_base);
-       fd = git_open(path);
-       free(path);
-       if (fd < 0)
-               return;
-       if (fstat(fd, &st) || (st.st_size == 0)) {
-               close(fd);
+       if (strbuf_read_file(&buf, path, 1024) < 0) {
+               warn_on_fopen_errors(path);
+               free(path);
                return;
        }
-       mapsz = xsize_t(st.st_size);
-       map = xmmap(NULL, mapsz, PROT_READ, MAP_PRIVATE, fd, 0);
-       close(fd);
  
-       link_alt_odb_entries(map, mapsz, '\n', relative_base, depth);
-       munmap(map, mapsz);
+       link_alt_odb_entries(buf.buf, '\n', relative_base, depth);
+       strbuf_release(&buf);
+       free(path);
  }
  
  struct alternate_object_database *alloc_alt_odb(const char *dir)
@@@ -527,7 -518,7 +518,7 @@@ void add_to_alternates_file(const char 
                if (commit_lock_file(lock))
                        die_errno("unable to move new alternates file into place");
                if (alt_odb_tail)
-                       link_alt_odb_entries(reference, strlen(reference), '\n', NULL, 0);
+                       link_alt_odb_entries(reference, '\n', NULL, 0);
        }
        free(alts);
  }
@@@ -540,7 -531,7 +531,7 @@@ void add_to_alternates_memory(const cha
         */
        prepare_alt_odb();
  
-       link_alt_odb_entries(reference, strlen(reference), '\n', NULL, 0);
+       link_alt_odb_entries(reference, '\n', NULL, 0);
  }
  
  /*
@@@ -643,7 -634,7 +634,7 @@@ void prepare_alt_odb(void
        if (!alt) alt = "";
  
        alt_odb_tail = &alt_odb_list;
-       link_alt_odb_entries(alt, strlen(alt), PATH_SEP, NULL, 0);
+       link_alt_odb_entries(alt, PATH_SEP, NULL, 0);
  
        read_info_alternates(get_object_directory(), 0);
  }
@@@ -2761,6 -2752,7 +2752,6 @@@ off_t find_pack_entry_one(const unsigne
        const uint32_t *level1_ofs = p->index_data;
        const unsigned char *index = p->index_data;
        unsigned hi, lo, stride;
 -      static int use_lookup = -1;
        static int debug_lookup = -1;
  
        if (debug_lookup < 0)
                printf("%02x%02x%02x... lo %u hi %u nr %"PRIu32"\n",
                       sha1[0], sha1[1], sha1[2], lo, hi, p->num_objects);
  
 -      if (use_lookup < 0)
 -              use_lookup = !!getenv("GIT_USE_LOOKUP");
 -      if (use_lookup) {
 -              int pos = sha1_entry_pos(index, stride, 0,
 -                                       lo, hi, p->num_objects, sha1);
 -              if (pos < 0)
 -                      return 0;
 -              return nth_packed_object_offset(p, pos);
 -      }
 -
        while (lo < hi) {
                unsigned mi = (lo + hi) / 2;
                int cmp = hashcmp(index + mi * stride, sha1);
@@@ -2952,14 -2954,10 +2943,14 @@@ static int sha1_loose_object_info(cons
        } else if ((status = parse_sha1_header_extended(hdr, oi, flags)) < 0)
                status = error("unable to parse %s header", sha1_to_hex(sha1));
  
 -      if (status >= 0 && oi->contentp)
 +      if (status >= 0 && oi->contentp) {
                *oi->contentp = unpack_sha1_rest(&stream, hdr,
                                                 *oi->sizep, sha1);
 -      else
 +              if (!*oi->contentp) {
 +                      git_inflate_end(&stream);
 +                      status = -1;
 +              }
 +      } else
                git_inflate_end(&stream);
  
        munmap(map, mapsize);
@@@ -3715,7 -3713,7 +3706,7 @@@ int index_path(unsigned char *sha1, con
  
  int read_pack_header(int fd, struct pack_header *header)
  {
 -      if (read_in_full(fd, header, sizeof(*header)) < sizeof(*header))
 +      if (read_in_full(fd, header, sizeof(*header)) != sizeof(*header))
                /* "eof before pack header was fully read" */
                return PH_ERROR_EOF;