From 286df29e7d78ae4a6b4474bb14d517e02e4f0489 Mon Sep 17 00:00:00 2001 From: FRIGN Date: Mon, 2 Mar 2015 14:19:26 +0100 Subject: [PATCH] Make already audited tools argv-centric instead of argc-centric This has already been suggested by Evan Gates and he's totally right about it. So, what's the problem? I wrote a testing program asshole.c with int main(void) { execl("/path/to/sbase/echo", "echo", "test"); return 0; } and checked the results with glibc and musl. Note that the sentinel NULL is missing from the end of the argument list. glibc calculates an argc of 5, musl 4 (instead of 2) and thus mess up things anyway. The powerful arg.h also focuses on argv instead of argc as well, but ignoring argc completely is also the wrong way to go. Instead, a more idiomatic approach is to check *argv only and decrement argc on the go. While at it, I rewrote yes(1) in an argv-centric way as well. All audited tools have been "fixed" and each following audited tool will receive the same treatment. --- cat.c | 2 +- echo.c | 2 +- libutil/crypt.c | 4 ++-- printenv.c | 8 ++++---- rm.c | 4 ++-- yes.c | 8 ++++---- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/cat.c b/cat.c index 90eefd5..1890e49 100644 --- a/cat.c +++ b/cat.c @@ -28,7 +28,7 @@ main(int argc, char *argv[]) if (argc == 0) { concat(stdin, "", stdout, ""); } else { - for (; argc > 0; argc--, argv++) { + for (; *argv; argc--, argv++) { if ((*argv)[0] == '-' && !(*argv)[1]) { concat(stdin, "", stdout, ""); } else if (!(fp = fopen(*argv, "r"))) { diff --git a/echo.c b/echo.c index 8b58bcc..8280137 100644 --- a/echo.c +++ b/echo.c @@ -22,7 +22,7 @@ main(int argc, char *argv[]) usage(); } ARGEND; - for (; argc > 0; argc--, argv++) + for (; *argv; argc--, argv++) putword(*argv); if (!nflag) putchar('\n'); diff --git a/libutil/crypt.c b/libutil/crypt.c index 9237cc5..91f80e6 100644 --- a/libutil/crypt.c +++ b/libutil/crypt.c @@ -87,7 +87,7 @@ cryptcheck(int argc, char *argv[], struct crypt_ops *ops, uint8_t *md, size_t sz if (argc == 0) { mdchecklist(stdin, ops, md, sz, &formatsucks, &noread, &nonmatch); } else { - for (; argc > 0; argc--, argv++) { + for (; *argv; argc--, argv++) { if (!(fp = fopen(*argv, "r"))) { weprintf("fopen %s:", *argv); ret = 1; @@ -124,7 +124,7 @@ cryptmain(int argc, char *argv[], struct crypt_ops *ops, uint8_t *md, size_t sz) cryptsum(ops, stdin, "", md); mdprint(md, "", sz); } else { - for (; argc > 0; argc--, argv++) { + for (; *argv; argc--, argv++) { if (!(fp = fopen(*argv, "r"))) { weprintf("fopen %s:", *argv); ret = 1; diff --git a/printenv.c b/printenv.c index ff210cb..135e0e3 100644 --- a/printenv.c +++ b/printenv.c @@ -24,12 +24,12 @@ main(int argc, char *argv[]) } ARGEND; if (!argc) { - while (*environ) - printf("%s\n", *environ++); + for (; *environ; environ++) + puts(*environ); } else { - for (; argc > 0; argc--, argv++) { + for (; *argv; argc--, argv++) { if ((var = getenv(*argv))) - printf("%s\n", var); + puts(var); else ret = 1; } diff --git a/rm.c b/rm.c index 73f3c31..3b539e6 100644 --- a/rm.c +++ b/rm.c @@ -30,8 +30,8 @@ main(int argc, char *argv[]) return 0; } - for (; argc > 0; argc--, argv++) - rm(argv[0], 0); + for (; *argv; argc--, argv++) + rm(*argv, 0); return rm_status; } diff --git a/yes.c b/yes.c index eddc0f0..000f367 100644 --- a/yes.c +++ b/yes.c @@ -12,16 +12,16 @@ usage(void) int main(int argc, char *argv[]) { - size_t i; + char **p; ARGBEGIN { default: usage(); } ARGEND; - for (i = 0; ; i++, i %= argc ? argc : 1) { - fputs(argc ? argv[i] : "y", stdout); - putchar((!argc || i == argc - 1) ? '\n' : ' '); + for (p = argv; ; p = (*p && *(p + 1)) ? p + 1 : argv) { + fputs(*p ? *p : "y", stdout); + putchar((!*p || !*(p + 1)) ? '\n' : ' '); } return 1; /* not reached */