groff-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[groff] 10/13: [grn]: Add more input validity checking.


From: G. Branden Robinson
Subject: [groff] 10/13: [grn]: Add more input validity checking.
Date: Sat, 16 Apr 2022 04:37:33 -0400 (EDT)

gbranden pushed a commit to branch master
in repository groff.

commit 9c4da4d6925431b4969fe01bac8ec4f8e51da4d4
Author: G. Branden Robinson <g.branden.robinson@gmail.com>
AuthorDate: Fri Apr 15 08:14:07 2022 +1000

    [grn]: Add more input validity checking.
    
    * src/preproc/grn/hdb.cpp (DBRead): Add more validity checking.  Verify
      that the number of conversions returned by fscanf() is as expected
      instead of throwing this information away--abort processing ("giving
      up" like pic(1) does) if it does not.  Consistently report this
      abandonment in diagnostic messages.  Similarly validate pointer
      returned by fgets().  Soften handling of invalid text condition from
      fatal errors, introduced in commit eb4f0675e, 16 August, to throw an
      error and give up.  Addresses "-Wunused-result" warnings from GCC.
---
 ChangeLog               | 12 +++++++
 src/preproc/grn/hdb.cpp | 87 +++++++++++++++++++++++++++++++++++++++----------
 2 files changed, 82 insertions(+), 17 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index fe3d227a..133ec36a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2022-04-15  G. Branden Robinson <g.branden.robinson@gmail.com>
+
+       * src/preproc/grn/hdb.cpp (DBRead): Add more validity checking.
+       Verify that the number of conversions returned by fscanf() is as
+       expected instead of throwing this information away--abort
+       processing ("giving up" like pic(1) does) if it does not.
+       Consistently report this abandonment in diagnostic messages.
+       Similarly validate pointer returned by fgets().  Soften handling
+       of invalid text condition from fatal errors, introduced in
+       commit eb4f0675e, 16 August, to throw an error and give up.
+       Addresses "-Wunused-result" warnings from GCC.
+
 2022-04-14  G. Branden Robinson <g.branden.robinson@gmail.com>
 
        * src/preproc/grn/main.cpp (conv): Throw an error diagnostic
diff --git a/src/preproc/grn/hdb.cpp b/src/preproc/grn/hdb.cpp
index 44a822a2..e8cd9675 100644
--- a/src/preproc/grn/hdb.cpp
+++ b/src/preproc/grn/hdb.cpp
@@ -96,18 +96,31 @@ DBRead(FILE *file)
 
   SUNFILE = FALSE;
   elist = DBInit();
-  (void) fscanf(file, "%" MAXSTRING_S "s%*[^\n]\n", string);
+  int nitems = fscanf(file, "%" MAXSTRING_S "s%*[^\n]\n", string);
+  if (nitems != 1) {
+    error_with_file_and_line(gremlinfile, lineno,
+                            "malformed input; giving up on this"
+                            " picture");
+    return (elist);
+  }
   lineno++;
   if (strcmp(string, "gremlinfile")) {
     if (strcmp(string, "sungremlinfile")) {
       error_with_file_and_line(gremlinfile, lineno,
-                              "not a gremlin file");
+                              "not a gremlin file; giving up on this"
+                              " picture");
       return (elist);
     }
     SUNFILE = TRUE;
   }
 
-  (void) fscanf(file, "%d%lf%lf\n", &size, &x, &y);
+  nitems = fscanf(file, "%d%lf%lf\n", &size, &x, &y);
+  if (nitems != 3) {
+    error_with_file_and_line(gremlinfile, lineno,
+                            "malformed input; giving up on this"
+                            " picture");
+    return (elist);
+  }
   lineno++;
   /* ignore orientation and file positioning point */
 
@@ -120,7 +133,8 @@ DBRead(FILE *file)
                      MAXSTRING_S
                     "[^\n]%*[^\n]\n", string) == EOF) {
       lineno++;
-      error_with_file_and_line(gremlinfile, lineno, "error in format");
+      error_with_file_and_line(gremlinfile, lineno, "error in format;"
+                              " giving up on this picture");
       return (elist);
     }
     lineno++;
@@ -129,10 +143,17 @@ DBRead(FILE *file)
     if (type < 0) {            /* no more data */
       done = TRUE;
     } else {
+      /* always one point */
 #ifdef UW_FASTSCAN
-      (void) xscanf(file, &x, &y);             /* always one point */
+      (void) xscanf(file, &x, &y);
 #else
-      (void) fscanf(file, "%lf%lf\n", &x, &y); /* always one point */
+      nitems = fscanf(file, "%lf%lf\n", &x, &y);
+      if (nitems != 2) {
+       error_with_file_and_line(gremlinfile, lineno,
+                                "malformed input; giving up on this"
+                                " picture");
+       return (elist);
+      }
       lineno++;
 #endif /* UW_FASTSCAN */
       plist = PTInit();                /* NULL point list */
@@ -154,14 +175,23 @@ DBRead(FILE *file)
 #else
        lastpoint = FALSE;
        do {
-         fgets(string, MAXSTRING, file);
+         char *cp = fgets(string, MAXSTRING, file);
+         if (0 /* nullptr */ == cp) {
+           error_with_file_and_line(gremlinfile, lineno,
+                                    "premature end-of-file or error"
+                                    " reading input; giving up on this"
+                                    " picture");
+           return(elist);
+         }
          lineno++;
          if (string[0] == '*') {       /* SUN gremlin file */
            lastpoint = TRUE;
          } else {
            if (!sscanf(string, "%lf%lf", &x, &y)) {
-             error("expected coordinate pair, got '%1';"
-                   " giving up on this picture", string);
+             error_with_file_and_line(gremlinfile, lineno,
+                                      "expected coordinate pair, got"
+                                      " '%1'; giving up on this"
+                                      " picture", string);
              return(elist);
            }
            if ((x == -1.00 && y == -1.00) && (!SUNFILE))
@@ -189,7 +219,14 @@ DBRead(FILE *file)
          (void) PTMakePoint(nx, y, &plist);
          savebounds(nx, y);
 
-         fgets(string, MAXSTRING, file);
+         char *cp = fgets(string, MAXSTRING, file);
+         if (0 /* nullptr */ == cp) {
+           error_with_file_and_line(gremlinfile, lineno,
+                                    "premature end-of-file or error"
+                                    " reading input; giving up on this"
+                                    " picture");
+           return(elist);
+         }
          lineno++;
          if (string[0] == '*') {       /* SUN gremlin file */
            lastpoint = TRUE;
@@ -201,15 +238,29 @@ DBRead(FILE *file)
        }
 #endif /* UW_FASTSCAN */
       }
-      (void) fscanf(file, "%d%d\n", &brush, &size);
+      nitems = fscanf(file, "%d%d\n", &brush, &size);
+      if (nitems != 2) {
+       error_with_file_and_line(gremlinfile, lineno,
+                                "malformed input; giving up on this"
+                                " picture");
+       return (elist);
+      }
       lineno++;
-      (void) fscanf(file, "%d", &len); /* text length */
+      nitems = fscanf(file, "%d", &len);       /* text length */
+      if (nitems != 1) {
+       error_with_file_and_line(gremlinfile, lineno,
+                                "malformed input; giving up on this"
+                                " picture");
+       return (elist);
+      }
       (void) getc(file);               /* eat blank */
       lineno++;                                /* advance line counter early */
       if (len < 0) {
-       fatal_with_file_and_line(gremlinfile, lineno,
-                               "length claimed for text is nonsense:"
-                               " '%1'", len);
+       error_with_file_and_line(gremlinfile, lineno,
+                                "length claimed for text is nonsense:"
+                                " '%1'; giving up on this picture",
+                                len);
+       return (elist);
       }
       txt = (char *) grnmalloc((unsigned) len + 1, "element text");
       for (i = 0; i < len; ++i) {      /* read text */
@@ -219,9 +270,11 @@ DBRead(FILE *file)
        txt[i] = c;
       }
       if (feof(file)) {
-       fatal_with_file_and_line(gremlinfile, lineno,
+       error_with_file_and_line(gremlinfile, lineno,
                                 "end of file while reading text of"
-                                " length %1", len);
+                                " length %1; giving up on this"
+                                " picture", len);
+       return (elist);
       }
       txt[len] = '\0';
       (void) DBCreateElt(type, plist, brush, size, txt, &elist);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]