Merge branch 'jt/fsck-code-cleanup' into maint
authorJunio C Hamano <gitster@pobox.com>
Thu, 22 Mar 2018 21:24:12 +0000 (14:24 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 22 Mar 2018 21:24:12 +0000 (14:24 -0700)
Plug recently introduced leaks in fsck.

* jt/fsck-code-cleanup:
  fsck: fix leak when traversing trees

1  2 
builtin/fsck.c

diff --combined builtin/fsck.c
@@@ -15,7 -15,6 +15,7 @@@
  #include "progress.h"
  #include "streaming.h"
  #include "decorate.h"
 +#include "packfile.h"
  
  #define REACHABLE 0x0001
  #define SEEN      0x0002
@@@ -171,7 -170,13 +171,13 @@@ static void mark_object_reachable(struc
  
  static int traverse_one_object(struct object *obj)
  {
-       return fsck_walk(obj, obj, &fsck_walk_options);
+       int result = fsck_walk(obj, obj, &fsck_walk_options);
+       if (obj->type == OBJ_TREE) {
+               struct tree *tree = (struct tree *)obj;
+               free_tree_buffer(tree);
+       }
+       return result;
  }
  
  static int traverse_reachable(void)
        unsigned int nr = 0;
        int result = 0;
        if (show_progress)
 -              progress = start_progress_delay(_("Checking connectivity"), 0, 0, 2);
 +              progress = start_delayed_progress(_("Checking connectivity"), 0);
        while (pending.nr) {
 -              struct object_array_entry *entry;
 -              struct object *obj;
 -
 -              entry = pending.objects + --pending.nr;
 -              obj = entry->item;
 -              result |= traverse_one_object(obj);
 +              result |= traverse_one_object(object_array_pop(&pending));
                display_progress(progress, ++nr);
        }
        stop_progress(&progress);
@@@ -322,8 -332,6 +328,8 @@@ static void check_connectivity(void
  
  static int fsck_obj(struct object *obj)
  {
 +      int err;
 +
        if (obj->flags & SEEN)
                return 0;
        obj->flags |= SEEN;
  
        if (fsck_walk(obj, NULL, &fsck_obj_options))
                objerror(obj, "broken links");
 -      if (fsck_object(obj, NULL, 0, &fsck_obj_options))
 -              return -1;
 -
 -      if (obj->type == OBJ_TREE) {
 -              struct tree *item = (struct tree *) obj;
 -
 -              free_tree_buffer(item);
 -      }
 +      err = fsck_object(obj, NULL, 0, &fsck_obj_options);
 +      if (err)
 +              goto out;
  
        if (obj->type == OBJ_COMMIT) {
                struct commit *commit = (struct commit *) obj;
  
 -              free_commit_buffer(commit);
 -
                if (!commit->parents && show_root)
                        printf("root %s\n", describe_object(&commit->object));
        }
                }
        }
  
 -      return 0;
 +out:
 +      if (obj->type == OBJ_TREE)
 +              free_tree_buffer((struct tree *)obj);
 +      if (obj->type == OBJ_COMMIT)
 +              free_commit_buffer((struct commit *)obj);
 +      return err;
  }
  
  static int fsck_obj_buffer(const struct object_id *oid, enum object_type type,
@@@ -555,7 -565,7 +561,7 @@@ static int fsck_head_link(void
        if (verbose)
                fprintf(stderr, "Checking HEAD link\n");
  
 -      head_points_at = resolve_ref_unsafe("HEAD", 0, head_oid.hash, NULL);
 +      head_points_at = resolve_ref_unsafe("HEAD", 0, &head_oid, NULL);
        if (!head_points_at) {
                errors_found |= ERROR_REFS;
                return error("Invalid HEAD");
@@@ -726,12 -736,12 +732,12 @@@ int cmd_fsck(int argc, const char **arg
  
        for (i = 0; i < argc; i++) {
                const char *arg = argv[i];
 -              unsigned char sha1[20];
 -              if (!get_sha1(arg, sha1)) {
 -                      struct object *obj = lookup_object(sha1);
 +              struct object_id oid;
 +              if (!get_oid(arg, &oid)) {
 +                      struct object *obj = lookup_object(oid.hash);
  
                        if (!obj || !(obj->flags & HAS_OBJ)) {
 -                              error("%s: object missing", sha1_to_hex(sha1));
 +                              error("%s: object missing", oid_to_hex(&oid));
                                errors_found |= ERROR_OBJECT;
                                continue;
                        }
  
        if (keep_cache_objects) {
                verify_index_checksum = 1;
 +              verify_ce_order = 1;
                read_cache();
                for (i = 0; i < active_nr; i++) {
                        unsigned int mode;