Skip to content

Commit 8a1a8d2

Browse files
peffgitster
authored andcommitted
worktree: check the result of read_in_full()
We try to read "len" bytes into a buffer and just assume that it happened correctly. In practice this should usually be the case, since we just stat'd the file to get the length. But we could be fooled by transient errors or by other processes racily truncating the file. Let's be more careful. There's a slim chance this could catch a real error, but it also prevents people and tools from getting worried while reading the code. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 228740b commit 8a1a8d2

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

builtin/worktree.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ static int prune_worktree(const char *id, struct strbuf *reason)
4040
char *path;
4141
int fd;
4242
size_t len;
43+
ssize_t read_result;
4344

4445
if (!is_directory(git_path("worktrees/%s", id))) {
4546
strbuf_addf(reason, _("Removing worktrees/%s: not a valid directory"), id);
@@ -59,8 +60,24 @@ static int prune_worktree(const char *id, struct strbuf *reason)
5960
}
6061
len = xsize_t(st.st_size);
6162
path = xmallocz(len);
62-
read_in_full(fd, path, len);
63+
64+
read_result = read_in_full(fd, path, len);
65+
if (read_result < 0) {
66+
strbuf_addf(reason, _("Removing worktrees/%s: unable to read gitdir file (%s)"),
67+
id, strerror(errno));
68+
close(fd);
69+
free(path);
70+
return 1;
71+
}
6372
close(fd);
73+
74+
if (read_result != len) {
75+
strbuf_addf(reason,
76+
_("Removing worktrees/%s: short read (expected %"PRIuMAX" bytes, read %"PRIuMAX")"),
77+
id, (uintmax_t)len, (uintmax_t)read_result);
78+
free(path);
79+
return 1;
80+
}
6481
while (len && (path[len - 1] == '\n' || path[len - 1] == '\r'))
6582
len--;
6683
if (!len) {

0 commit comments

Comments
 (0)