bug-groff
[Top][All Lists]
Advanced

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

[bug #62131] [preconv] should test for non-seekable stream input


From: G. Branden Robinson
Subject: [bug #62131] [preconv] should test for non-seekable stream input
Date: Wed, 2 Mar 2022 14:30:36 -0500 (EST)

URL:
  <https://savannah.gnu.org/bugs/?62131>

                 Summary: [preconv] should test for non-seekable stream input
                 Project: GNU troff
            Submitted by: gbranden
            Submitted on: Wed 02 Mar 2022 07:30:34 PM UTC
                Category: Preprocessor preconv
                Severity: 3 - Normal
              Item Group: Incorrect behaviour
                  Status: In Progress
                 Privacy: Public
             Assigned to: gbranden
             Open/Closed: Open
         Discussion Lock: Any
         Planned Release: None

    _______________________________________________________

Details:

preconv(1) should test for non-seekable stream input instead of assuming a
biconditional between non-seekability and an operand of "-" (a special token
indicating the standard input stream).

This issue is spawned from bug #55334.

Here's Ingo's original comment:


I would like to raise a minor concern, maybe you can tweak your solution. 
Comparing the filename to "-" seems fragile.  There may be other ways to get a
non-seekable file descriptor, for example someone passing "/dev/stdin" on the
command line or someone passing the name of a file created with mkfifo(1).

Instead of strcmp(filename, "-") in do_file(), i suggest doing something like
the following inside detect_file_encoding():

-rewind(fp);
+if (fseek(fp, 0L, SEEK_SET) == -1)
+    goto end;

That seems like the canonical way to test for the feature actually needed,
which feels much more robust than some crude guesswork based on tangentially
related string data.  Testing at the place where the feature is really needed
(and where other error handling is already present) also seems easier to
understand than having an additional check one level up in the call stack.

What do you think?


Here's my pending patch, still in test.  It's the same method Ingo proposed.


diff --git a/src/preproc/preconv/preconv.cpp
b/src/preproc/preconv/preconv.cpp
index b5b5a8cd2..581333658 100644
--- a/src/preproc/preconv/preconv.cpp
+++ b/src/preproc/preconv/preconv.cpp
@@ -1070,7 +1070,8 @@ end:
 }
 
 // ---------------------------------------------------------
-// Handle an input file.  If filename is '-' handle stdin.
+// Handle an input file.  If `filename` is "-", read the
+// standard input stream.
 //
 // Return 1 on success, 0 otherwise.
 // ---------------------------------------------------------
@@ -1079,21 +1080,28 @@ do_file(const char *filename)
 {
   FILE *fp;
   string BOM, data;
+  bool is_seekable = false;
+  const char *reported_filename;
 
-  if (strcmp(filename, "-")) {
-    if (debug_flag)
-      fprintf(stderr, "file '%s':\n", filename);
+  if (strcmp(filename, "-") == 0) {
+    fp = stdin;
+    reported_filename = "<standard input>";
+  }
+  else
     fp = fopen(filename, FOPEN_RB);
-    if (!fp) {
-      error("can't open '%1': %2", filename, strerror(errno));
-      return 0;
-    }
+  if (!fp) {
+    error("can't open '%1': %2", reported_filename, strerror(errno));
+    return 0;
+  }
+  if (debug_flag)
+    fprintf(stderr, "processing '%s'\n", reported_filename);
+  if (fseek(fp, 0L, SEEK_SET) == 0) {
+    is_seekable = true;
   }
   else {
+    SET_BINARY(fileno(fp));
     if (debug_flag)
-      fprintf(stderr, "standard input:\n");
-    SET_BINARY(fileno(stdin));
-    fp = stdin;
+      fprintf(stderr, " stream is not seekable: %s\n", strerror(errno));
   }
   const char *BOM_encoding = get_BOM(fp, BOM, data);
   // Determine the encoding.
@@ -1121,7 +1129,7 @@ do_file(const char *filename)
     if (!file_encoding) {
       if (debug_flag)
        fprintf(stderr, "  no coding tag\n");
-      if (strcmp(filename, "-"))
+      if (is_seekable)
          file_encoding = detect_file_encoding(fp);
       if (!file_encoding) {
         if (debug_flag)
@@ -1286,4 +1294,8 @@ main(int argc, char **argv)
   return nbad != 0;
 }
 
-/* end of preconv.cpp */
+// Local Variables:
+// fill-column: 72
+// mode: C++
+// End:
+// vim: set cindent noexpandtab shiftwidth=2 textwidth=72:





    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?62131>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/




reply via email to

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