Merge branch 'jk/show-branch-lift-name-len-limit'
authorJunio C Hamano <gitster@pobox.com>
Mon, 27 Feb 2017 21:57:16 +0000 (13:57 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 27 Feb 2017 21:57:16 +0000 (13:57 -0800)
"git show-branch" expected there were only very short branch names
in the repository and used a fixed-length buffer to hold them
without checking for overflow.

* jk/show-branch-lift-name-len-limit:
show-branch: use skip_prefix to drop magic numbers
show-branch: store resolved head in heap buffer
show-branch: drop head_len variable

1  2 
builtin/show-branch.c
diff --combined builtin/show-branch.c
index 974f3403abe76288dc98797e3ceac21a070828ec,c438853330d0e3b5f5cefd974f23a13396bb09d5..19756595d57f27c35c72449d03a95cefd55aef15
@@@ -275,8 -275,7 +275,7 @@@ static void show_one_commit(struct comm
                pp_commit_easy(CMIT_FMT_ONELINE, commit, &pretty);
                pretty_str = pretty.buf;
        }
-       if (starts_with(pretty_str, "[PATCH] "))
-               pretty_str += 8;
+       skip_prefix(pretty_str, "[PATCH] ", &pretty_str);
  
        if (!no_name) {
                if (name && name->head_name) {
@@@ -353,7 -352,8 +352,7 @@@ static int compare_ref_name(const void 
  
  static void sort_ref_range(int bottom, int top)
  {
 -      qsort(ref_name + bottom, top - bottom, sizeof(ref_name[0]),
 -            compare_ref_name);
 +      QSORT(ref_name + bottom, top - bottom, compare_ref_name);
  }
  
  static int append_ref(const char *refname, const struct object_id *oid,
                                return 0;
        }
        if (MAX_REVS <= ref_name_cnt) {
 -              warning("ignoring %s; cannot handle more than %d refs",
 -                      refname, MAX_REVS);
 +              warning(Q_("ignoring %s; cannot handle more than %d ref",
 +                         "ignoring %s; cannot handle more than %d refs",
 +                         MAX_REVS), refname, MAX_REVS);
                return 0;
        }
        ref_name[ref_name_cnt++] = xstrdup(refname);
@@@ -470,18 -469,14 +469,14 @@@ static void snarf_refs(int head, int re
        }
  }
  
- static int rev_is_head(char *head, int headlen, char *name,
+ static int rev_is_head(const char *head, const char *name,
                       unsigned char *head_sha1, unsigned char *sha1)
  {
-       if ((!head[0]) ||
-           (head_sha1 && sha1 && hashcmp(head_sha1, sha1)))
+       if (!head || (head_sha1 && sha1 && hashcmp(head_sha1, sha1)))
                return 0;
-       if (starts_with(head, "refs/heads/"))
-               head += 11;
-       if (starts_with(name, "refs/heads/"))
-               name += 11;
-       else if (starts_with(name, "heads/"))
-               name += 6;
+       skip_prefix(head, "refs/heads/", &head);
+       if (!skip_prefix(name, "refs/heads/", &name))
+               skip_prefix(name, "heads/", &name);
        return !strcmp(head, name);
  }
  
@@@ -538,8 -533,9 +533,8 @@@ static void append_one_rev(const char *
                for_each_ref(append_matching_ref, NULL);
                if (saved_matches == ref_name_cnt &&
                    ref_name_cnt < MAX_REVS)
 -                      error("no matching refs with %s", av);
 -              if (saved_matches + 1 < ref_name_cnt)
 -                      sort_ref_range(saved_matches, ref_name_cnt);
 +                      error(_("no matching refs with %s"), av);
 +              sort_ref_range(saved_matches, ref_name_cnt);
                return;
        }
        die("bad sha1 reference %s", av);
@@@ -620,9 -616,7 +615,7 @@@ int cmd_show_branch(int ac, const char 
        int all_heads = 0, all_remotes = 0;
        int all_mask, all_revs;
        enum rev_sort_order sort_order = REV_SORT_IN_GRAPH_ORDER;
-       char head[128];
-       const char *head_p;
-       int head_len;
+       char *head;
        struct object_id head_oid;
        int merge_base = 0;
        int independent = 0;
                         *
                         * Also --all and --remotes do not make sense either.
                         */
 -                      die("--reflog is incompatible with --all, --remotes, "
 -                          "--independent or --merge-base");
 +                      die(_("--reflog is incompatible with --all, --remotes, "
 +                            "--independent or --merge-base"));
        }
  
        /* If nothing is specified, show all branches by default */
                        av = fake_av;
                        ac = 1;
                        if (!*av)
 -                              die("no branches given, and HEAD is not valid");
 +                              die(_("no branches given, and HEAD is not valid"));
                }
                if (ac != 1)
 -                      die("--reflog option needs one branch name");
 +                      die(_("--reflog option needs one branch name"));
  
                if (MAX_REVS < reflog)
 -                      die("Only %d entries can be shown at one time.",
 -                          MAX_REVS);
 +                      die(Q_("only %d entry can be shown at one time.",
 +                             "only %d entries can be shown at one time.",
 +                             MAX_REVS), MAX_REVS);
                if (!dwim_ref(*av, strlen(*av), oid.hash, &ref))
 -                      die("No such ref %s", *av);
 +                      die(_("no such ref %s"), *av);
  
                /* Has the base been specified? */
                if (reflog_base) {
                        snarf_refs(all_heads, all_remotes);
        }
  
-       head_p = resolve_ref_unsafe("HEAD", RESOLVE_REF_READING,
-                                   head_oid.hash, NULL);
-       if (head_p) {
-               head_len = strlen(head_p);
-               memcpy(head, head_p, head_len + 1);
-       }
-       else {
-               head_len = 0;
-               head[0] = 0;
-       }
+       head = resolve_refdup("HEAD", RESOLVE_REF_READING,
+                             head_oid.hash, NULL);
  
-       if (with_current_branch && head_p) {
+       if (with_current_branch && head) {
                int has_head = 0;
                for (i = 0; !has_head && i < ref_name_cnt; i++) {
                        /* We are only interested in adding the branch
                         * HEAD points at.
                         */
                        if (rev_is_head(head,
-                                       head_len,
                                        ref_name[i],
                                        head_oid.hash, NULL))
                                has_head++;
                }
                if (!has_head) {
-                       int offset = starts_with(head, "refs/heads/") ? 11 : 0;
-                       append_one_rev(head + offset);
+                       const char *name = head;
+                       skip_prefix(name, "refs/heads/", &name);
+                       append_one_rev(name);
                }
        }
  
                unsigned int flag = 1u << (num_rev + REV_SHIFT);
  
                if (MAX_REVS <= num_rev)
 -                      die("cannot handle more than %d revs.", MAX_REVS);
 +                      die(Q_("cannot handle more than %d rev.",
 +                             "cannot handle more than %d revs.",
 +                             MAX_REVS), MAX_REVS);
                if (get_sha1(ref_name[num_rev], revkey.hash))
 -                      die("'%s' is not a valid ref.", ref_name[num_rev]);
 +                      die(_("'%s' is not a valid ref."), ref_name[num_rev]);
                commit = lookup_commit_reference(revkey.hash);
                if (!commit)
 -                      die("cannot find commit %s (%s)",
 +                      die(_("cannot find commit %s (%s)"),
                            ref_name[num_rev], oid_to_hex(&revkey));
                parse_commit(commit);
                mark_seen(commit, &seen);
                for (i = 0; i < num_rev; i++) {
                        int j;
                        int is_head = rev_is_head(head,
-                                                 head_len,
                                                  ref_name[i],
                                                  head_oid.hash,
                                                  rev[i]->object.oid.hash);