Update error handling

Make sure open files are closed and allocated memory is freed.
This commit is contained in:
Joergen Ibsen 2019-01-13 21:07:22 +01:00
parent ef52ad2d06
commit 3240056d43
1 changed files with 53 additions and 20 deletions

View File

@ -23,6 +23,7 @@
* distribution. * distribution.
*/ */
#include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
@ -36,25 +37,35 @@ static unsigned int read_le32(const unsigned char *p)
| ((unsigned int) p[3] << 24); | ((unsigned int) p[3] << 24);
} }
static void exit_error(const char *what) static void printf_error(const char *fmt, ...)
{ {
fprintf(stderr, "tgunzip: %s\n", what); va_list arg;
exit(1);
fputs("tgunzip: ", stderr);
va_start(arg, fmt);
vfprintf(stderr, fmt, arg);
va_end(arg);
fputs("\n", stderr);
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
FILE *fin, *fout; FILE *fin = NULL;
FILE *fout = NULL;
unsigned char *source = NULL;
unsigned char *dest = NULL;
unsigned int len, dlen, outlen; unsigned int len, dlen, outlen;
unsigned char *source, *dest; int retval = EXIT_FAILURE;
int res; int res;
printf("tgunzip " TINF_VER_STRING " - example from the tiny inflate library (www.ibsensoftware.com)\n\n"); printf("tgunzip " TINF_VER_STRING " - example from the tiny inflate library (www.ibsensoftware.com)\n\n");
if (argc != 3) { if (argc != 3) {
printf("usage: tgunzip INFILE OUTFILE\n\n" fputs("usage: tgunzip INFILE OUTFILE\n\n"
"Both input and output are kept in memory, so do not use this on huge files.\n"); "Both input and output are kept in memory, so do not use this on huge files.\n", stderr);
return 1; return EXIT_FAILURE;
} }
tinf_init(); tinf_init();
@ -62,11 +73,13 @@ int main(int argc, char *argv[])
/* -- Open files -- */ /* -- Open files -- */
if ((fin = fopen(argv[1], "rb")) == NULL) { if ((fin = fopen(argv[1], "rb")) == NULL) {
exit_error("source file"); printf_error("unable to open input file '%s'", argv[1]);
goto out;
} }
if ((fout = fopen(argv[2], "wb")) == NULL) { if ((fout = fopen(argv[2], "wb")) == NULL) {
exit_error("destination file"); printf_error("unable to create output file '%s'", argv[2]);
goto out;
} }
/* -- Read source -- */ /* -- Read source -- */
@ -78,29 +91,31 @@ int main(int argc, char *argv[])
fseek(fin, 0, SEEK_SET); fseek(fin, 0, SEEK_SET);
if (len < 18) { if (len < 18) {
exit_error("input too small"); printf_error("input too small to be gzip");
goto out;
} }
source = (unsigned char *) malloc(len); source = (unsigned char *) malloc(len);
if (source == NULL) { if (source == NULL) {
exit_error("memory"); printf_error("not enough memory");
goto out;
} }
if (fread(source, 1, len, fin) != len) { if (fread(source, 1, len, fin) != len) {
exit_error("read"); printf_error("error reading input file");
goto out;
} }
fclose(fin);
/* -- Get decompressed length -- */ /* -- Get decompressed length -- */
dlen = read_le32(&source[len - 4]); dlen = read_le32(&source[len - 4]);
dest = (unsigned char *) malloc(dlen); dest = (unsigned char *) malloc(dlen ? dlen : 1);
if (dest == NULL) { if (dest == NULL) {
exit_error("memory"); printf_error("not enough memory");
goto out;
} }
/* -- Decompress data -- */ /* -- Decompress data -- */
@ -110,7 +125,8 @@ int main(int argc, char *argv[])
res = tinf_gzip_uncompress(dest, &outlen, source, len); res = tinf_gzip_uncompress(dest, &outlen, source, len);
if ((res != TINF_OK) || (outlen != dlen)) { if ((res != TINF_OK) || (outlen != dlen)) {
exit_error("inflate"); printf_error("decompression failed");
goto out;
} }
printf("decompressed %u bytes\n", outlen); printf("decompressed %u bytes\n", outlen);
@ -119,7 +135,24 @@ int main(int argc, char *argv[])
fwrite(dest, 1, outlen, fout); fwrite(dest, 1, outlen, fout);
fclose(fout); retval = EXIT_SUCCESS;
return 0; out:
if (fin != NULL) {
fclose(fin);
}
if (fout != NULL) {
fclose(fout);
}
if (source != NULL) {
free(source);
}
if (dest != NULL) {
free(dest);
}
return retval;
} }