In wc(1), the "file" argument to cnt() is NULL when we're enumerating
the standard input.  This causes a NULL pointer dereference if we ever
hit one of the warn(3) calls in that function.

To fix, change the argument name to "path" and make "file" a local
variable that is always initialized to point to a C string.

While we're here we may as well const the argument pointers.

ok?

Index: wc.c
===================================================================
RCS file: /cvs/src/usr.bin/wc/wc.c,v
retrieving revision 1.27
diff -u -p -r1.27 wc.c
--- wc.c        24 Oct 2021 21:24:18 -0000      1.27
+++ wc.c        16 Nov 2021 18:34:14 -0000
@@ -48,9 +48,9 @@ int   doline, doword, dochar, humanchar, m
 int    rval;
 extern char *__progname;
 
-static void print_counts(int64_t, int64_t, int64_t, char *);
+static void print_counts(int64_t, int64_t, int64_t, const char *);
 static void format_and_print(int64_t);
-static void cnt(char *);
+static void cnt(const char *);
 
 int
 main(int argc, char *argv[])
@@ -115,12 +115,13 @@ main(int argc, char *argv[])
 }
 
 static void
-cnt(char *file)
+cnt(const char *path)
 {
        static char *buf;
        static size_t bufsz;
 
        FILE *stream;
+       const char *file;
        char *C;
        wchar_t wc;
        short gotsp;
@@ -131,13 +132,15 @@ cnt(char *file)
 
        linect = wordct = charct = 0;
        stream = NULL;
-       if (file) {
+       if (path != NULL) {
+               file = path;
                if ((fd = open(file, O_RDONLY)) == -1) {
                        warn("%s", file);
                        rval = 1;
                        return;
                }
        } else  {
+               file = "(stdin)";
                fd = STDIN_FILENO;
        }
 
@@ -191,7 +194,7 @@ cnt(char *file)
                        }
                }
        } else {
-               if (file == NULL)
+               if (path == NULL)
                        stream = stdin;
                else if ((stream = fdopen(fd, "r")) == NULL) {
                        warn("%s", file);
@@ -249,7 +252,7 @@ cnt(char *file)
                }
        }
 
-       print_counts(linect, wordct, charct, file);
+       print_counts(linect, wordct, charct, path);
 
        /*
         * Don't bother checking doline, doword, or dochar -- speeds
@@ -279,7 +282,7 @@ format_and_print(int64_t v)
 }
 
 static void
-print_counts(int64_t lines, int64_t words, int64_t chars, char *name)
+print_counts(int64_t lines, int64_t words, int64_t chars, const char *name)
 {
        if (doline)
                format_and_print(lines);

Reply via email to