gbranden pushed a commit to branch master
in repository groff.

commit 5c923303a9ef44bb4bc4f44d09799f93193fc079
Author: G. Branden Robinson <[email protected]>
AuthorDate: Thu Mar 7 10:20:17 2024 -0600

    [troff]: Fix Savannah #65427 (check fp==nullptr).
    
    * src/roff/troff/node.cpp (ascii_output_file::outc)
      (ascii_output_file::outs, put_string, troff_output_file::put)
      (ascii_output_file::really_transparent_char)
      (ascii_output_file::really_print_line): Guard uses of standard C
      library `putc()` and `fputc()` functions with a null pointer check.
      They could fail if the output stream has been invalidated.  Problem
      present from groff's birth and apparently exposed by man-db man's use
      of AppArmor.  See
      <https://bugs.launchpad.net/ubuntu/+source/lintian/+bug/2055402> and
      follow-up discussion there.
    
    Fixes <https://savannah.gnu.org/bugs/?65427>.  Thanks to an anonymous
    submitter for the report.
    
    No apparent performance degradation, even _without_ optimization, on
    20 rebuilds of automake.pdf, contrib/mom/examples/*.pdf, and
    groff-man-pages.pdf.
    
    CFLAGS="-O0 -Og -ggdb"
    
    Before:
    + awk /Elapsed/ {time = $NF; sub("0:", "", time); print time}
    + datamash range 1 mean 1 sstdev 1
    3.35    11.0475 1.0103510333178
    
    After:
    + awk /Elapsed/ {time = $NF; sub("0:", "", time); print time}
    + datamash range 1 mean 1 sstdev 1
    2.49    10.81380952381  0.62027797148114
---
 ChangeLog               | 16 ++++++++++++++++
 src/roff/troff/node.cpp | 31 ++++++++++++++++++++-----------
 2 files changed, 36 insertions(+), 11 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d7722bb4c..bf09e3a69 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2024-03-07  G. Branden Robinson <[email protected]>
+
+       * src/roff/troff/node.cpp (ascii_output_file::outc)
+       (ascii_output_file::outs, put_string, troff_output_file::put)
+       (ascii_output_file::really_transparent_char)
+       (ascii_output_file::really_print_line): Guard uses of standard C
+       library `putc()` and `fputc()` functions with a null pointer
+       check.  They could fail if the output stream has been
+       invalidated.  Problem present from groff's birth and apparently
+       exposed by man-db man's use of AppArmor.  See
+       <https://bugs.launchpad.net/ubuntu/+source/lintian/+bug/2055402>
+       and follow-up discussion there.
+
+       Fixes <https://savannah.gnu.org/bugs/?65427>.  Thanks to an
+       anonymous submitter for the report.
+
 2024-03-04  G. Branden Robinson <[email protected]>
 
        * tmac/pdf.tmac (pdf*href): Fix (harmless?) `ie`/`if` thinko.
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 0240d0501..c2e029899 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -766,15 +766,18 @@ public:
 
 void ascii_output_file::outc(unsigned char c)
 {
-  fputc(c, fp);
+  if (fp != 0 /* nullptr */)
+    fputc(c, fp);
 }
 
 void ascii_output_file::outs(const char *s)
 {
-  fputc('<', fp);
-  if (s)
-    fputs(s, fp);
-  fputc('>', fp);
+  if (fp != 0 /* nullptr */) {
+    fputc('<', fp);
+    if (s)
+      fputs(s, fp);
+    fputc('>', fp);
+  }
 }
 
 struct hvpair;
@@ -844,18 +847,22 @@ public:
 
 static void put_string(const char *s, FILE *fp)
 {
-  for (; *s != '\0'; ++s)
-    putc(*s, fp);
+  if (fp != 0 /* nullptr */) {
+    for (; *s != '\0'; ++s)
+      putc(*s, fp);
+  }
 }
 
 inline void troff_output_file::put(char c)
 {
-  putc(c, fp);
+  if (fp != 0 /* nullptr */)
+    putc(c, fp);
 }
 
 inline void troff_output_file::put(unsigned char c)
 {
-  putc(c, fp);
+  if (fp != 0 /* nullptr */)
+    putc(c, fp);
 }
 
 inline void troff_output_file::put(const char *s)
@@ -1782,7 +1789,8 @@ void real_output_file::really_off()
 
 void ascii_output_file::really_transparent_char(unsigned char c)
 {
-  putc(c, fp);
+  if (fp != 0 /* nullptr */)
+    putc(c, fp);
 }
 
 void ascii_output_file::really_print_line(hunits, vunits, node *n,
@@ -1792,7 +1800,8 @@ void ascii_output_file::really_print_line(hunits, vunits, 
node *n,
     n->ascii_print(this);
     n = n->next;
   }
-  fputc('\n', fp);
+  if (fp != 0 /* nullptr */)
+    fputc('\n', fp);
 }
 
 void ascii_output_file::really_begin_page(int /*pageno*/, vunits 
/*page_length*/)

_______________________________________________
Groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit

Reply via email to