From b7ac76440a9e951105513903c70cb3c346e37fb1 Mon Sep 17 00:00:00 2001 From: Mid Favila Date: Wed, 7 Sep 2022 16:45:37 -0400 Subject: [PATCH] Add splint checking to Makefile. Rewrite programs to pass lint. Add an error handling mechanism to common, and rename it support.h. --- README | 3 ++ src/Makefile | 13 ++++---- src/cat.c | 38 ++++++++++------------- src/common.h | 30 ------------------ src/echo.c | 2 +- src/support.h | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/true.c | 2 +- src/yes.c | 2 +- 8 files changed, 113 insertions(+), 61 deletions(-) delete mode 100644 src/common.h create mode 100644 src/support.h diff --git a/README b/README index 49a4590..0e26cf3 100644 --- a/README +++ b/README @@ -10,3 +10,6 @@ than Busybox. I recommend compiling these statically. + + If SPLint is available, 'make check' can perform static analysis of + all available programs. diff --git a/src/Makefile b/src/Makefile index b0718d2..3f5f94d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -4,7 +4,7 @@ CC = cc CFLAGS = -Wall -O2 LDFLAGS = -static LDLIBS = -PREFIX = /usr/local/ +PREFIX = usr/local DESTDIR = BIN = echo yes true false cat @@ -18,14 +18,15 @@ false: cat: cat.c install: all - install -Dm0775 ${BIN} ${DESTDIR}${PREFIX}bin + install -Dm0755 ${BIN} ${DESTDIR}/${PREFIX}/bin -clean: - rm echo true yes false cat +clean: all + rm ${BIN} *.o + +check: + splint +checks +posix-strict-lib +showsummary +forcehints +showscan +showsourceloc +toctou +its4low +its4moderate +its4risky +its4veryrisky +its4mostrisky +bufferoverflow *.c *.h .SUFFIXES: .c .o .c.o: ${CC} ${CFLAGS} ${LDFLAGS} -c $< -: - echo hello diff --git a/src/cat.c b/src/cat.c index b0ba1ca..a9be760 100644 --- a/src/cat.c +++ b/src/cat.c @@ -1,28 +1,22 @@ -/* cat.c -- provides a routine to output the contents of the named files in either a buffered or unbuffered fashion. */ -/* Accepts the following parameters: */ -/* -u: Output should be unbuffered. */ +#include +#include +#include -/* Returns the following values: */ -/* 0: All files were printed successfully. */ -/* 1: One or more files could not be opened. */ - +#include "support.h" -#include "common.h" -/* If mode is set to zero, return a null pointer and print characters directly. Otherwise, return a pointer to a buffer containing */ -/* the contents of the file pointed to by fp. The size of the new buffer is stored in the int pointed to by bufsize. */ char *cat(FILE *fp, const int mode, long unsigned *bufsize) { char c; - + static long unsigned int i, finalbuflen, tmpbuflen; + char *arr, *tmparr, *finalarr; + tmpbuflen = 4096; + if(!mode) { - static long unsigned int i, finalbuflen, tmpbuflen; - tmpbuflen = 4096; - char *arr = malloc(tmpbuflen); - char *tmparr = 0; - char *finalarr = 0; - + arr = malloc(tmpbuflen); + tmparr = finalarr = 0; + for(i = 0, finalbuflen = 0; (c = fgetc(fp)) != EOF; i++, finalbuflen++) { if(i >= tmpbuflen) @@ -57,14 +51,14 @@ char *cat(FILE *fp, const int mode, long unsigned *bufsize) int main(int argc, char **argv) { + long unsigned int i, upresence, fppresence, buflen, newbuflen; char *buf, *newbuf, *tmpbuf; - long unsigned int i, upresence, fppresence; - i = upresence = fppresence = 0; - long unsigned int buflen, newbuflen; - buflen = newbuflen = 0; FILE *fp; - fp = 0; + + i = upresence = fppresence = buflen = newbuflen = 0; buf = newbuf = tmpbuf = 0; + fp = 0; + if((upresence = (getopt(argc, argv, ":u") == 'u'))) { diff --git a/src/common.h b/src/common.h deleted file mode 100644 index 5d3bac9..0000000 --- a/src/common.h +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include -#include -#include -#include - -/* arrccat -- function to copy arr2len bytes from arr2 to the arr1len'th position of arr1. returns *newarr, and stores the length */ -/* of newarr[] in arr1len (that's why it needs to be a pointer to arr1len and not just a long unsigned integer). */ -char *arrccat(char *arr1, char *arr2, size_t *arr1len, size_t arr2len) - { - char *newarr; - unsigned int i, i2; - newarr = malloc(*arr1len+arr2len); - i = i2 = 0; - - for(i = 0; i < *arr1len; i++) - { - newarr[i] = arr1[i]; - } - - for(i2 = 0; i2 < arr2len; i2++, i++) - { - newarr[i] = arr2[i2]; - } - - *arr1len = *arr1len+arr2len; - - return newarr; - } diff --git a/src/echo.c b/src/echo.c index 2cf96ed..c6e70d4 100644 --- a/src/echo.c +++ b/src/echo.c @@ -1,4 +1,4 @@ -#include "common.h" +#include "support.h" int main(int argc, char **argv) { diff --git a/src/support.h b/src/support.h new file mode 100644 index 0000000..b655b5e --- /dev/null +++ b/src/support.h @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include +#include + + +enum { + UNKNOWN_FAIL = 1, + MALLOC_FAIL, + NEEDARG_FAIL, + FOPEN_FAIL, + WRITE_FAIL + }; + + +/* arrccat -- function to copy arr2len bytes from arr2 to the arr1len'th position of arr1. returns *newarr, and stores the length */ +/* of newarr[] in arr1len (that's why it needs to be a pointer to arr1len and not just a long unsigned integer). */ +char *arrccat(char *arr1, char *arr2, size_t *arr1len, size_t arr2len) + { + char *newarr; + unsigned int i, i2; + newarr = malloc(*arr1len+arr2len); + i = i2 = 0; + + for(i = 0; i < *arr1len; i++) + { + newarr[i] = arr1[i]; + } + + for(i2 = 0; i2 < arr2len; i2++, i++) + { + newarr[i] = arr2[i2]; + } + + *arr1len = *arr1len+arr2len; + + return newarr; + } + +/* Condition should be one of the above enum'd strings. Info is optional; it can just be NULL when irrelevant. */ +void throw(long unsigned int condition, void *info) + { + switch(condition) + { + case UNKNOWN_FAIL: printf("unknown failure\n"); + exit(UNKNOWN_FAIL); + case MALLOC_FAIL: printf("malloc failure\n"); + exit(MALLOC_FAIL); + case NEEDARG_FAIL: printf("usage: %s\n", (char *) info); + exit(NEEDARG_FAIL); + case FOPEN_FAIL: printf("failed to open: %s\n", (char *) info); + exit(FOPEN_FAIL); + case WRITE_FAIL: printf("failed to write: %s\n", (char *) info); + exit(WRITE_FAIL); + default: printf("You shouldn't be seeing this.\nSomething is very wrong.\n"); + exit(-256); + } + } + +/* mastrcat -- improved string concat function. returns a pointer to the first element in a buffer containing the strings str1 */ +/* and str2 joined end-to-end. */ +char *mastrcat(char *str1, char *str2) + { + unsigned long int nbi, stri, nbsize; + char *nbuf; + nbi = stri = 0; + nbsize = (strlen(str1) + strlen(str2)); + nbuf = malloc(nbsize); + + for(stri = 0; str1[stri] != '\0'; nbi++, stri++) + { + nbuf[nbi] = str1[stri]; + } + + for(stri = 0; str2[stri] != '\0'; nbi++, stri++) + { + nbuf[nbi] = str2[stri]; + } + + return nbuf; + } + diff --git a/src/true.c b/src/true.c index dfaefc9..29c5f69 100644 --- a/src/true.c +++ b/src/true.c @@ -1,4 +1,4 @@ -#include "common.h" +#include "support.h" int main(int argc, char **argv) { diff --git a/src/yes.c b/src/yes.c index 97b6c85..1b172c2 100644 --- a/src/yes.c +++ b/src/yes.c @@ -1,4 +1,4 @@ -#include "common.h" +#include "support.h" int main(int argc, char **argv) {