[hackers] [sbase] Audit head(1) || FRIGN

From: <git_AT_suckless.org>
Date: Thu, 5 Mar 2015 01:17:36 +0100 (CET)

commit d27e24a1ac9c337f329adc033bee508788d4ee34
Author: FRIGN <dev_AT_frign.de>
Date: Thu Mar 5 00:58:12 2015 +0100

    Audit head(1)
    
    1) Use (s)size_t in head().
    2) BUGFIX: only check buf[len - 1] when len > 0, else there would
       be an overflow when getline returns 0 (which can happen) and a
       very potential segmentation fault.
    3) fix error-messages.
    4) update usage().
    5) argv-argc-style.
    6) clear up the main loop with if (newline).
    7) add newline before return.

diff --git a/README b/README
index 79170ea..524c369 100644
--- a/README
+++ b/README
_AT_@ -35,7 +35,7 @@ The following tools are implemented ('*' == finished, '#' == UTF-8 support,
 = find yes none
 #* fold yes none
 =* grep yes none
-=* head yes none
+=*| head yes none
 =*| hostname non-posix none
 =* kill yes none
 =*| link yes none
diff --git a/head.c b/head.c
index a66520e..0b17647 100644
--- a/head.c
+++ b/head.c
_AT_@ -6,27 +6,25 @@
 #include "util.h"
 
 static void
-head(FILE *fp, const char *str, long n)
+head(FILE *fp, const char *fname, size_t n)
 {
         char *buf = NULL;
- size_t size = 0;
+ size_t i = 0, size = 0;
         ssize_t len;
- unsigned long i = 0;
 
- while (i < n && ((len = getline(&buf, &size, fp)) != -1)) {
+ while (i < n && (len = getline(&buf, &size, fp)) >= 0) {
                 fputs(buf, stdout);
- if (buf[len - 1] == '\n')
- i++;
+ i += (len && (buf[len - 1] == '\n'));
         }
         free(buf);
         if (ferror(fp))
- eprintf("%s: read error:", str);
+ eprintf("getline %s:", fname);
 }
 
 static void
 usage(void)
 {
- eprintf("usage: %s [-n lines] [-N] [file...]\n", argv0);
+ eprintf("usage: %s [-n num] [-N] [file ...]\n", argv0);
 }
 
 int
_AT_@ -34,8 +32,7 @@ main(int argc, char *argv[])
 {
         size_t n = 10;
         FILE *fp;
- int ret = 0;
- int newline, many;
+ int ret = 0, newline, many;
 
         ARGBEGIN {
         case 'n':
_AT_@ -48,23 +45,25 @@ main(int argc, char *argv[])
                 usage();
         } ARGEND;
 
- if (argc == 0) {
+ if (!argc) {
                 head(stdin, "<stdin>", n);
         } else {
                 many = argc > 1;
- for (newline = 0; argc > 0; argc--, argv++) {
- if (!(fp = fopen(argv[0], "r"))) {
- weprintf("fopen %s:", argv[0]);
+ for (newline = 0; *argv; argc--, argv++) {
+ if (!(fp = fopen(*argv, "r"))) {
+ weprintf("fopen %s:", *argv);
                                 ret = 1;
                                 continue;
                         }
+ if (newline)
+ putchar('\n');
                         if (many)
- printf("%s==> %s <==\n",
- newline ? "\n" : "", argv[0]);
+ printf("==> %s <==\n", *argv);
                         newline = 1;
- head(fp, argv[0], n);
+ head(fp, *argv, n);
                         fclose(fp);
                 }
         }
+
         return ret;
 }
Received on Thu Mar 05 2015 - 01:17:36 CET

This archive was generated by hypermail 2.3.0 : Thu Mar 05 2015 - 01:24:13 CET