Merge branch 'ds/find-unique-abbrev-optim' into next
authorJunio C Hamano <gitster@pobox.com>
Fri, 2 Mar 2018 20:18:26 +0000 (12:18 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 2 Mar 2018 20:18:26 +0000 (12:18 -0800)
While finding unique object name abbreviation, the code may
accidentally have read beyond the end of the array of object names
in a pack.

* ds/find-unique-abbrev-optim:
sha1_name: fix uninitialized memory errors

1  2 
sha1_name.c
diff --combined sha1_name.c
index e7c18ffc26daf1962f90da9ff5c16cc608149d9d,f1c3d37a6d06db55c0c65f07a4ab65d81bdbec90..735c1c0b8ec032b3aac8b6a8976dcdb09ba5e91d
@@@ -159,7 -159,7 +159,7 @@@ static void unique_in_pack(struct packe
        num = p->num_objects;
        last = num;
        while (first < last) {
 -              uint32_t mid = (first + last) / 2;
 +              uint32_t mid = first + (last - first) / 2;
                const unsigned char *current;
                int cmp;
  
@@@ -381,7 -381,7 +381,7 @@@ static int show_ambiguous_object(const 
  
        advise("  %s %s%s",
               find_unique_abbrev(oid->hash, DEFAULT_ABBREV),
 -             typename(type) ? typename(type) : "unknown type",
 +             type_name(type) ? type_name(type) : "unknown type",
               desc.buf);
  
        strbuf_release(&desc);
@@@ -542,20 -542,20 +542,20 @@@ static void find_abbrev_len_for_pack(st
        /*
         * first is now the position in the packfile where we would insert
         * mad->hash if it does not exist (or the position of mad->hash if
-        * it does exist). Hence, we consider a maximum of three objects
+        * it does exist). Hence, we consider a maximum of two objects
         * nearby for the abbreviation length.
         */
        mad->init_len = 0;
        if (!match) {
-               nth_packed_object_oid(&oid, p, first);
-               extend_abbrev_len(&oid, mad);
+               if (nth_packed_object_oid(&oid, p, first))
+                       extend_abbrev_len(&oid, mad);
        } else if (first < num - 1) {
-               nth_packed_object_oid(&oid, p, first + 1);
-               extend_abbrev_len(&oid, mad);
+               if (nth_packed_object_oid(&oid, p, first + 1))
+                       extend_abbrev_len(&oid, mad);
        }
        if (first > 0) {
-               nth_packed_object_oid(&oid, p, first - 1);
-               extend_abbrev_len(&oid, mad);
+               if (nth_packed_object_oid(&oid, p, first - 1))
+                       extend_abbrev_len(&oid, mad);
        }
        mad->init_len = mad->cur_len;
  }
@@@ -706,7 -706,7 +706,7 @@@ static int get_oid_basic(const char *st
  
        if (len == GIT_SHA1_HEXSZ && !get_oid_hex(str, oid)) {
                if (warn_ambiguous_refs && warn_on_object_refname_ambiguity) {
 -                      refs_found = dwim_ref(str, len, tmp_oid.hash, &real_ref);
 +                      refs_found = dwim_ref(str, len, &tmp_oid, &real_ref);
                        if (refs_found > 0) {
                                warning(warn_msg, len, str);
                                if (advice_object_name_warning)
  
        if (!len && reflog_len)
                /* allow "@{...}" to mean the current branch reflog */
 -              refs_found = dwim_ref("HEAD", 4, oid->hash, &real_ref);
 +              refs_found = dwim_ref("HEAD", 4, oid, &real_ref);
        else if (reflog_len)
 -              refs_found = dwim_log(str, len, oid->hash, &real_ref);
 +              refs_found = dwim_log(str, len, oid, &real_ref);
        else
 -              refs_found = dwim_ref(str, len, oid->hash, &real_ref);
 +              refs_found = dwim_ref(str, len, oid, &real_ref);
  
        if (!refs_found)
                return -1;
                                return -1;
                        }
                }
 -              if (read_ref_at(real_ref, flags, at_time, nth, oid->hash, NULL,
 +              if (read_ref_at(real_ref, flags, at_time, nth, oid, NULL,
                                &co_time, &co_tz, &co_cnt)) {
                        if (!len) {
                                if (starts_with(real_ref, "refs/heads/")) {
@@@ -901,8 -901,8 +901,8 @@@ struct object *peel_to_type(const char 
                        if (name)
                                error("%.*s: expected %s type, but the object "
                                      "dereferences to %s type",
 -                                    namelen, name, typename(expected_type),
 -                                    typename(o->type));
 +                                    namelen, name, type_name(expected_type),
 +                                    type_name(o->type));
                        return NULL;
                }
        }
@@@ -1434,23 -1434,10 +1434,23 @@@ void strbuf_branchname(struct strbuf *s
  
  int strbuf_check_branch_ref(struct strbuf *sb, const char *name)
  {
 -      strbuf_branchname(sb, name, INTERPRET_BRANCH_LOCAL);
 -      if (name[0] == '-')
 -              return -1;
 +      if (startup_info->have_repository)
 +              strbuf_branchname(sb, name, INTERPRET_BRANCH_LOCAL);
 +      else
 +              strbuf_addstr(sb, name);
 +
 +      /*
 +       * This splice must be done even if we end up rejecting the
 +       * name; builtin/branch.c::copy_or_rename_branch() still wants
 +       * to see what the name expanded to so that "branch -m" can be
 +       * used as a tool to correct earlier mistakes.
 +       */
        strbuf_splice(sb, 0, 0, "refs/heads/", 11);
 +
 +      if (*name == '-' ||
 +          !strcmp(sb->buf, "refs/heads/HEAD"))
 +              return -1;
 +
        return check_refname_format(sb->buf, 0);
  }