diff options
context:
space:
mode:
authorBryce Kwon <bryce@brycekwon.com>
committerBryce Kwon <bryce@brycekwon.com>
commit
parent
tree
download
Bail out on a read error in `read_first_line`
`read_in_full` returns a signed -1 on error, which became SIZE_MAX once stored in the size_t length and then wrote a terminator far out of bounds.
Diffstat (limited to '')
-rw-r--r--source/shared.c13
1 file changed, 11 insertions, 2 deletions
diff --git a/source/shared.c b/source/shared.c
index c509aa1..1c11bc6 100644
--- a/source/shared.c
+++ b/source/shared.c
@@ -448,6 +448,7 @@ void cgit_prepare_repo_env(struct cgit_repo * repo)
int read_first_line(const char *path, char **buf, size_t *size)
{
int fd, e;
+ ssize_t got;
struct stat st;
fd = open(path, O_RDONLY);
@@ -463,12 +464,20 @@ int read_first_line(const char *path, char **buf, size_t *size)
return EISDIR;
}
*buf = xmalloc(st.st_size + 1);
- *size = read_in_full(fd, *buf, st.st_size);
+ got = read_in_full(fd, *buf, st.st_size);
e = errno;
+ if (got < 0) {
+ free(*buf);
+ *buf = NULL;
+ *size = 0;
+ close(fd);
+ return e;
+ }
+ *size = got;
(*buf)[*size] = '\0';
*strchrnul(*buf, '\n') = '\0';
close(fd);
- return (*size == st.st_size ? 0 : e);
+ return (*size == (size_t)st.st_size ? 0 : e);
}
char *strdup_first_line(const char *txt)