From a2976b6403ce3a98e8bb4f8db8c1703588800ee8 Mon Sep 17 00:00:00 2001 From: Alan Coopersmith Date: Fri, 18 Oct 2013 23:23:44 -0700 Subject: Ensure fgets read at least one byte before modifying string If a file has a \0 byte (binary file, strange encoding, corruption), fgets() can return a string starting with a \0 byte - check for that before checking to see if the byte before the \0 is a \n, so we don't reach back before the start of our memory buffer. Also check that the penultimate byte is a \n before we chop it off, in case we're reading from a file missing a newline, or a line longer than fit in the buffer provided to fgets(). Signed-off-by: Alan Coopersmith --- man.c | 7 ++++++- misc.c | 4 +++- search.c | 6 ++++-- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/man.c b/man.c index e8432f0..b430060 100644 --- a/man.c +++ b/man.c @@ -290,7 +290,12 @@ ReadMandescFile(SectionList ** section_list, char *path) snprintf(mandesc_file, sizeof(mandesc_file), "%s/%s", path, MANDESC); if ((descfile = fopen(mandesc_file, "r")) != NULL) { while (fgets(string, BUFSIZ, descfile) != NULL) { - string[strlen(string) - 1] = '\0'; /* Strip off the CR. */ + size_t len = strlen(string); + + if (len == 0) + continue; + if (string[len - 1] == '\n') + string[len - 1] = '\0'; /* Strip off the CR. */ if (streq(string, NO_SECTION_DEFAULTS)) { use_defaults = FALSE; diff --git a/misc.c b/misc.c index 33c69c7..06891cd 100644 --- a/misc.c +++ b/misc.c @@ -526,7 +526,9 @@ Format(ManpageGlobals * man_globals, const char *entry) if (fgets(line, sizeof(line), file) != NULL) { if (strncmp(line, ".so ", 4) == 0) { - line[strlen(line) - 1] = '\0'; + size_t len = strlen(line); /* must be >= 4 to pass strncmp */ + if (line[len - 1] == '\n') + line[len - 1] = '\0'; fclose(file); remove(filename); if (line[4] != '/') { diff --git a/search.c b/search.c index 03cc697..365ce6a 100644 --- a/search.c +++ b/search.c @@ -240,8 +240,10 @@ DoSearch(ManpageGlobals * man_globals, int type) count = 0; flag = FALSE; while ((fgets(cmp_str, BUFSIZ, file) != NULL) && (count < LOOKLINES)) { - if (cmp_str[strlen(cmp_str) - 1] == '\n') /* strip off the '\n' */ - cmp_str[strlen(cmp_str) - 1] = '\0'; + size_t len = strlen(cmp_str); + + if (len > 0 && cmp_str[len - 1] == '\n') /* strip off the '\n' */ + cmp_str[len - 1] = '\0'; if (streq(cmp_str, string_buf)) { flag = TRUE; -- cgit v1.2.3