bundle: don't leak an fd in case of early return
In successful operation `write_pack_data` will close the `bundle_fd`, but when we exit early, we need to take care of the file descriptor as well as the lock file ourselves. The lock file may be deleted at the end of running the program, but we are in library code, so we should not rely on that. Helped-by: Jeff King <peff@peff.net> Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Stefan Beller committed
Mar 31, 2016 at 17:35 UTC
f5ff5fb56485979895cff5954e4db1ea4ff4c9f7
1 file changed
+17
-6
bundle.c
+17
-6
@@ -435,12 +435,14 @@ int create_bundle(struct bundle_header *header, const char *path,
435
436
/* write prerequisites */
437
if (compute_and_write_prerequisites(bundle_fd, &revs, argc, argv))
438
- return -1;
438
+ goto err;
439
440
argc = setup_revisions(argc, argv, &revs, NULL);
441
442
- if (argc > 1)
443
- return error(_("unrecognized argument: %s"), argv[1]);
442
+ if (argc > 1) {
443
+ error(_("unrecognized argument: %s"), argv[1]);
444
+ goto err;
445
+ }
446
447
object_array_remove_duplicates(&revs.pending);
448
@@ -448,17 +450,26 @@ int create_bundle(struct bundle_header *header, const char *path,
450
if (!ref_count)
451
die(_("Refusing to create empty bundle."));
452
else if (ref_count < 0)
451
- return -1;
453
+ goto err;
454
455
/* write pack */
454
- if (write_pack_data(bundle_fd, &revs))
455
- return -1;
456
+ if (write_pack_data(bundle_fd, &revs)) {
457
+ bundle_fd = -1; /* already closed by the above call */
458
+ goto err;
459
+ }
460
461
if (!bundle_to_stdout) {
462
if (commit_lock_file(&lock))
463
die_errno(_("cannot create '%s'"), path);
464
}
465
return 0;
466
+err:
467
+ if (!bundle_to_stdout) {
468
+ if (0 <= bundle_fd)
469
+ close(bundle_fd);
470
+ rollback_lock_file(&lock);
471
+ }
472
+ return -1;
473
}
474
475
int unbundle(struct bundle_header *header, int bundle_fd, int flags)