From: Junio C Hamano Date: Thu, 22 Mar 2018 21:24:12 +0000 (-0700) Subject: Merge branch 'jt/fsck-code-cleanup' into maint X-Git-Tag: v2.16.3~25 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/d78b7eb2d50bd1cf57d7f06c1b4bdd8e08057926?ds=inline;hp=-c Merge branch 'jt/fsck-code-cleanup' into maint Plug recently introduced leaks in fsck. * jt/fsck-code-cleanup: fsck: fix leak when traversing trees --- d78b7eb2d50bd1cf57d7f06c1b4bdd8e08057926 diff --combined builtin/fsck.c index 04846d46f9,5aa4a1b336..92ce775a74 --- a/builtin/fsck.c +++ b/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) @@@ -180,9 -185,14 +186,9 @@@ 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; @@@ -334,13 -342,20 +340,13 @@@ 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)); } @@@ -356,12 -371,7 +362,12 @@@ } } - 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; } @@@ -759,7 -769,6 +765,7 @@@ if (keep_cache_objects) { verify_index_checksum = 1; + verify_ce_order = 1; read_cache(); for (i = 0; i < active_nr; i++) { unsigned int mode;