Author: Adam <git@apiote.tk>
check boundaries in sum files
meowsum.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
diff --git a/meowsum.c b/meowsum.c index 277742a5f5932a3c995bd5b170b69378db5bd832..adece33854f926bb99c949d586b5833961675d98 100644 --- a/meowsum.c +++ b/meowsum.c @@ -8,6 +8,7 @@ #define MODE_SUM 0 #define MODE_CHECK 1 #include <assert.h> +#include <errno.h> #include <fcntl.h> #include <stdbool.h> #include <stdint.h> @@ -185,14 +186,14 @@ bool strict_errors) { char *line = NULL; size_t line_size = 0; FILE *file = NULL; - char expected_hex_hash[33]; unsigned long expected_size = 0, size = 0; - char *path = NULL; + char *expected_hex_hash = NULL, *expected_size_string = NULL, *path = NULL; ssize_t read_bytes = 0; meow_u128 *hash = NULL; char *hex_hash = NULL; int hash_size = 0; bool result = true; + char *next = NULL; for (int i = start; i < argc; ++i) { file = fopen(argv[i], "r"); @@ -214,22 +215,76 @@ } if (line[read_bytes - 1] == '\n') { line[read_bytes - 1] = 0; } + expected_hex_hash = malloc(line_size * sizeof(char)); + if (expected_hex_hash == NULL) { + perror("error"); + fprintf(stderr, "error mallocing expected_hex_hash for %s\n", argv[i]); + return false; + } + expected_size_string = malloc(line_size * sizeof(char)); + if (expected_size_string == NULL) { + perror("error"); + fprintf(stderr, "error mallocing expected_size_string for %s\n", + argv[i]); + free(expected_hex_hash); + return false; + } path = malloc(line_size * sizeof(char)); if (path == NULL) { perror("error"); fprintf(stderr, "error mallocing path for %s\n", argv[i]); + free(expected_hex_hash); + free(expected_size_string); return false; } - // todo check boundries (|ex_hex_hash| > 32, ex_size overflows) - int n = - sscanf(line, "%s %ld %s", expected_hex_hash, &expected_size, path); + // NOLINTNEXTLINE + int n = sscanf(line, "%s %s %s", expected_hex_hash, expected_size_string, + path); if (n != 3) { - fprintf(stderr, "line '%s' in %s malformed", line, argv[i]); + fprintf(stderr, "line '%s' in %s malformed\n", line, argv[i]); + free(expected_hex_hash); + free(expected_size_string); free(path); free(line); - return false; + continue; } - hash_size = strlen(expected_hex_hash) / 2 * 8; + hash_size = strlen(expected_hex_hash) * 8 / 2; + if (!(hash_size == 32 || hash_size == 64 || hash_size == 128)) { + fprintf(stderr, "hash size is wrong in line '%s' in %s\n", line, + argv[i]); + free(expected_hex_hash); + free(expected_size_string); + free(path); + free(line); + continue; + } + expected_size = strtoul(expected_size_string, &next, 10); + if (errno == ERANGE) { + fprintf(stderr, "expected size out of range in line '%s' in %s\n", line, + argv[i]); + free(expected_hex_hash); + free(expected_size_string); + free(path); + free(line); + continue; + } else if (next == expected_size_string) { + fprintf(stderr, + "expected size is an invalid number in line '%s' in %s\n", line, + argv[i]); + free(expected_hex_hash); + free(expected_size_string); + free(path); + free(line); + continue; + } else if (*next != '\n' && *next != '\0') { + fprintf(stderr, "rubbish in expected size in line '%s' in %s\n", line, + argv[i]); + free(expected_hex_hash); + free(expected_size_string); + free(path); + free(line); + continue; + } if (strcmp("-", path) == 0) { if (!quiet) { @@ -241,6 +296,8 @@ printf("ERM %s\n", path); if (strict_errors) { result &= false; } + free(expected_hex_hash); + free(expected_size_string); free(path); free(line); continue; @@ -248,6 +305,8 @@ } hash = calculate_checksum(path, &size); if (hash == NULL) { fprintf(stderr, "error while calculating %s\n", path); + free(expected_hex_hash); + free(expected_size_string); free(path); free(line); continue; @@ -255,6 +314,8 @@ } hex_hash = format_sum(*hash, hash_size); if (hex_hash == NULL) { fprintf(stderr, "error while formating hex hash for %s\n", path); + free(expected_hex_hash); + free(expected_size_string); free(hash); free(path); free(line); @@ -279,6 +340,8 @@ } free(hex_hash); free(hash); } + free(expected_hex_hash); + free(expected_size_string); free(path); free(line); }