Merge branch 'sn/null-pointer-arith-in-mark-tree-uninteresting' into maint
authorJunio C Hamano <gitster@pobox.com>
Fri, 11 Dec 2015 19:14:38 +0000 (11:14 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 11 Dec 2015 19:14:38 +0000 (11:14 -0800)
mark_tree_uninteresting() has code to handle the case where it gets
passed a NULL pointer in its 'tree' parameter, but the function had
'object = &tree->object' assignment before checking if tree is
NULL. This gives a compiler an excuse to declare that tree will
never be NULL and apply a wrong optimization. Avoid it.

* sn/null-pointer-arith-in-mark-tree-uninteresting:
revision.c: fix possible null pointer arithmetic

1  2 
revision.c
diff --combined revision.c
index 351fb5b9f12cf7dffe14f7aca49dad1576248696,7f4acad456a3f5adbf2a5828718ab4488d947388..f6caef067220e9ecae7cc1b21b7b01380544c066
  #include "commit-slab.h"
  #include "dir.h"
  #include "cache-tree.h"
 +#include "bisect.h"
  
  volatile show_early_output_fn_t show_early_output;
  
 +static const char *term_bad;
 +static const char *term_good;
 +
  char *path_name(const struct name_path *path, const char *name)
  {
        const struct name_path *p;
@@@ -135,10 -131,12 +135,12 @@@ static void mark_tree_contents_unintere
  
  void mark_tree_uninteresting(struct tree *tree)
  {
-       struct object *obj = &tree->object;
+       struct object *obj;
  
        if (!tree)
                return;
+       obj = &tree->object;
        if (obj->flags & UNINTERESTING)
                return;
        obj->flags |= UNINTERESTING;
@@@ -153,7 -151,10 +155,7 @@@ void mark_parents_uninteresting(struct 
                commit_list_insert(l->item, &parents);
  
        while (parents) {
 -              struct commit *commit = parents->item;
 -              l = parents;
 -              parents = parents->next;
 -              free(l);
 +              struct commit *commit = pop_commit(&parents);
  
                while (commit) {
                        /*
@@@ -1099,10 -1100,14 +1101,10 @@@ static int limit_list(struct rev_info *
        }
  
        while (list) {
 -              struct commit_list *entry = list;
 -              struct commit *commit = list->item;
 +              struct commit *commit = pop_commit(&list);
                struct object *obj = &commit->object;
                show_early_output_fn_t show;
  
 -              list = list->next;
 -              free(entry);
 -
                if (commit == interesting_cache)
                        interesting_cache = NULL;
  
@@@ -1993,10 -1998,10 +1995,10 @@@ static int handle_revision_opt(struct r
        } else if (!strcmp(arg, "--full-history")) {
                revs->simplify_history = 0;
        } else if (!strcmp(arg, "--relative-date")) {
 -              revs->date_mode = DATE_RELATIVE;
 +              revs->date_mode.type = DATE_RELATIVE;
                revs->date_mode_explicit = 1;
        } else if ((argcount = parse_long_opt("date", argv, &optarg))) {
 -              revs->date_mode = parse_date_format(optarg);
 +              parse_date_format(optarg, &revs->date_mode);
                revs->date_mode_explicit = 1;
                return argcount;
        } else if (!strcmp(arg, "--log-size")) {
@@@ -2073,23 -2078,14 +2075,23 @@@ void parse_revision_opt(struct rev_inf
        ctx->argc -= n;
  }
  
 +static int for_each_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data, const char *term) {
 +      struct strbuf bisect_refs = STRBUF_INIT;
 +      int status;
 +      strbuf_addf(&bisect_refs, "refs/bisect/%s", term);
 +      status = for_each_ref_in_submodule(submodule, bisect_refs.buf, fn, cb_data);
 +      strbuf_release(&bisect_refs);
 +      return status;
 +}
 +
  static int for_each_bad_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)
  {
 -      return for_each_ref_in_submodule(submodule, "refs/bisect/bad", fn, cb_data);
 +      return for_each_bisect_ref(submodule, fn, cb_data, term_bad);
  }
  
  static int for_each_good_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)
  {
 -      return for_each_ref_in_submodule(submodule, "refs/bisect/good", fn, cb_data);
 +      return for_each_bisect_ref(submodule, fn, cb_data, term_good);
  }
  
  static int handle_revision_pseudo_opt(const char *submodule,
                handle_refs(submodule, revs, *flags, for_each_branch_ref_submodule);
                clear_ref_exclusion(&revs->ref_excludes);
        } else if (!strcmp(arg, "--bisect")) {
 +              read_bisect_terms(&term_bad, &term_good);
                handle_refs(submodule, revs, *flags, for_each_bad_bisect_ref);
                handle_refs(submodule, revs, *flags ^ (UNINTERESTING | BOTTOM), for_each_good_bisect_ref);
                revs->bisect = 1;
@@@ -2726,7 -2721,10 +2728,7 @@@ static void simplify_merges(struct rev_
                yet_to_do = NULL;
                tail = &yet_to_do;
                while (list) {
 -                      commit = list->item;
 -                      next = list->next;
 -                      free(list);
 -                      list = next;
 +                      commit = pop_commit(&list);
                        tail = simplify_one(revs, commit, tail);
                }
        }
        while (list) {
                struct merge_simplify_state *st;
  
 -              commit = list->item;
 -              next = list->next;
 -              free(list);
 -              list = next;
 +              commit = pop_commit(&list);
                st = locate_simplify_state(revs, commit);
                if (st->simplified == commit)
                        tail = &commit_list_insert(commit, tail)->next;
@@@ -3112,7 -3113,11 +3114,7 @@@ static struct commit *get_revision_1(st
                return NULL;
  
        do {
 -              struct commit_list *entry = revs->commits;
 -              struct commit *commit = entry->item;
 -
 -              revs->commits = entry->next;
 -              free(entry);
 +              struct commit *commit = pop_commit(&revs->commits);
  
                if (revs->reflog_info) {
                        save_parents(revs, commit);