Merge branch 'hv/link-alt-odb-entry' into maint
authorJunio C Hamano <gitster@pobox.com>
Wed, 15 Aug 2012 20:36:47 +0000 (13:36 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 15 Aug 2012 20:36:47 +0000 (13:36 -0700)
* hv/link-alt-odb-entry:
link_alt_odb_entry: fix read over array bounds reported by valgrind

1  2 
sha1_file.c
diff --combined sha1_file.c
index 4ccaf7ac197c28400eddd496abcfc725528ca32b,a1f3bee5ed4811dc543136ed465491ea239196e8..af5cfbde63aed41d95ac7318d064d3012832d2c5
@@@ -19,7 -19,6 +19,7 @@@
  #include "pack-revindex.h"
  #include "sha1-lookup.h"
  #include "bulk-checkin.h"
 +#include "streaming.h"
  
  #ifndef O_NOATIME
  #if defined(__linux__) && (defined(__i386__) || defined(__PPC__))
@@@ -229,6 -228,7 +229,6 @@@ char *sha1_pack_index_name(const unsign
  struct alternate_object_database *alt_odb_list;
  static struct alternate_object_database **alt_odb_tail;
  
 -static void read_info_alternates(const char * alternates, int depth);
  static int git_open_noatime(const char *name);
  
  /*
@@@ -298,7 -298,7 +298,7 @@@ static int link_alt_odb_entry(const cha
                        return -1;
                }
        }
-       if (!memcmp(ent->base, objdir, pfxlen)) {
+       if (!strcmp(ent->base, objdir)) {
                free(ent);
                return -1;
        }
@@@ -353,7 -353,7 +353,7 @@@ static void link_alt_odb_entries(const 
        }
  }
  
 -static void read_info_alternates(const char * relative_base, int depth)
 +void read_info_alternates(const char * relative_base, int depth)
  {
        char *map;
        size_t mapsz;
@@@ -1146,47 -1146,10 +1146,47 @@@ static const struct packed_git *has_pac
        return NULL;
  }
  
 -int check_sha1_signature(const unsigned char *sha1, void *map, unsigned long size, const char *type)
 +/*
 + * With an in-core object data in "map", rehash it to make sure the
 + * object name actually matches "sha1" to detect object corruption.
 + * With "map" == NULL, try reading the object named with "sha1" using
 + * the streaming interface and rehash it to do the same.
 + */
 +int check_sha1_signature(const unsigned char *sha1, void *map,
 +                       unsigned long size, const char *type)
  {
        unsigned char real_sha1[20];
 -      hash_sha1_file(map, size, type, real_sha1);
 +      enum object_type obj_type;
 +      struct git_istream *st;
 +      git_SHA_CTX c;
 +      char hdr[32];
 +      int hdrlen;
 +
 +      if (map) {
 +              hash_sha1_file(map, size, type, real_sha1);
 +              return hashcmp(sha1, real_sha1) ? -1 : 0;
 +      }
 +
 +      st = open_istream(sha1, &obj_type, &size, NULL);
 +      if (!st)
 +              return -1;
 +
 +      /* Generate the header */
 +      hdrlen = sprintf(hdr, "%s %lu", typename(obj_type), size) + 1;
 +
 +      /* Sha1.. */
 +      git_SHA1_Init(&c);
 +      git_SHA1_Update(&c, hdr, hdrlen);
 +      for (;;) {
 +              char buf[1024 * 16];
 +              ssize_t readlen = read_istream(st, buf, sizeof(buf));
 +
 +              if (!readlen)
 +                      break;
 +              git_SHA1_Update(&c, buf, readlen);
 +      }
 +      git_SHA1_Final(real_sha1, &c);
 +      close_istream(st);
        return hashcmp(sha1, real_sha1) ? -1 : 0;
  }
  
@@@ -2416,7 -2379,7 +2416,7 @@@ int move_temp_to_file(const char *tmpfi
        unlink_or_warn(tmpfile);
        if (ret) {
                if (ret != EEXIST) {
 -                      return error("unable to write sha1 filename %s: %s\n", filename, strerror(ret));
 +                      return error("unable to write sha1 filename %s: %s", filename, strerror(ret));
                }
                /* FIXME!!! Collision check here ? */
        }
@@@ -2508,9 -2471,9 +2508,9 @@@ static int write_loose_object(const uns
        fd = create_tmpfile(tmp_file, sizeof(tmp_file), filename);
        if (fd < 0) {
                if (errno == EACCES)
 -                      return error("insufficient permission for adding an object to repository database %s\n", get_object_directory());
 +                      return error("insufficient permission for adding an object to repository database %s", get_object_directory());
                else
 -                      return error("unable to create temporary sha1 filename %s: %s\n", tmp_file, strerror(errno));
 +                      return error("unable to create temporary file: %s", strerror(errno));
        }
  
        /* Set it up */