Merge branch 'kd/auto-col-with-pager-fix' into maint
[gitweb.git] / builtin / worktree.c
index ff5dfd2b1022fd94314f2cefe3ca91a4820e8abf..7b9307aa588a70a47de4c53a380e165f90924ab9 100644 (file)
@@ -1,4 +1,5 @@
 #include "cache.h"
+#include "config.h"
 #include "builtin.h"
 #include "dir.h"
 #include "parse-options.h"
@@ -31,13 +32,15 @@ struct add_opts {
 
 static int show_only;
 static int verbose;
-static unsigned long expire;
+static timestamp_t expire;
 
 static int prune_worktree(const char *id, struct strbuf *reason)
 {
        struct stat st;
        char *path;
-       int fd, len;
+       int fd;
+       size_t len;
+       ssize_t read_result;
 
        if (!is_directory(git_path("worktrees/%s", id))) {
                strbuf_addf(reason, _("Removing worktrees/%s: not a valid directory"), id);
@@ -55,10 +58,26 @@ static int prune_worktree(const char *id, struct strbuf *reason)
                            id, strerror(errno));
                return 1;
        }
-       len = st.st_size;
+       len = xsize_t(st.st_size);
        path = xmallocz(len);
-       read_in_full(fd, path, len);
+
+       read_result = read_in_full(fd, path, len);
+       if (read_result < 0) {
+               strbuf_addf(reason, _("Removing worktrees/%s: unable to read gitdir file (%s)"),
+                           id, strerror(errno));
+               close(fd);
+               free(path);
+               return 1;
+       }
        close(fd);
+
+       if (read_result != len) {
+               strbuf_addf(reason,
+                           _("Removing worktrees/%s: short read (expected %"PRIuMAX" bytes, read %"PRIuMAX")"),
+                           id, (uintmax_t)len, (uintmax_t)read_result);
+               free(path);
+               return 1;
+       }
        while (len && (path[len - 1] == '\n' || path[len - 1] == '\r'))
                len--;
        if (!len) {
@@ -131,7 +150,7 @@ static int prune(int ac, const char **av, const char *prefix)
                OPT_END()
        };
 
-       expire = ULONG_MAX;
+       expire = TIME_MAX;
        ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
        if (ac)
                usage_with_options(worktree_usage, options);
@@ -299,10 +318,8 @@ static int add_worktree(const char *path, const char *refname,
        }
 
        is_junk = 0;
-       free(junk_work_tree);
-       free(junk_git_dir);
-       junk_work_tree = NULL;
-       junk_git_dir = NULL;
+       FREE_AND_NULL(junk_work_tree);
+       FREE_AND_NULL(junk_git_dir);
 
 done:
        if (ret || !opts->keep_locked) {
@@ -382,6 +399,8 @@ static int add(int ac, const char **av, const char *prefix)
                branch = opts.new_branch;
        }
 
+       UNLEAK(path);
+       UNLEAK(opts);
        return add_worktree(path, branch, &opts);
 }