[PATCH:xman] Ensure fgets read at least one byte before modifying string

Alan Coopersmith alan.coopersmith at oracle.com
Sun Oct 20 03:06:18 CEST 2013


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 <alan.coopersmith at oracle.com>
---
 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;
-- 
1.7.9.2



More information about the xorg-devel mailing list