meowsum.git

commit 4d2d4105bd482cdc7f8489091b25328a5875518c

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);
     }