meowsum.git

commit 3ee7e3cb96d984c6102747ea3526ede33deb7efa

Author: Adam <git@apiote.tk>

fix potential leaks

 meowsum.c | 58 +++++++++++++++++++++++++++++++++++++-------------------


diff --git a/meowsum.c b/meowsum.c
index d98caf796afa691362eee9bb8179fdbd51503947..277742a5f5932a3c995bd5b170b69378db5bd832 100644
--- a/meowsum.c
+++ b/meowsum.c
@@ -10,9 +10,9 @@
 #include <assert.h>
 #include <fcntl.h>
 #include <stdbool.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <stdint.h>
 #include <string.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -82,9 +82,9 @@   assert(path != NULL);
 
   int fd;
   meow_state state;
-  ssize_t read_bytes;
+  ssize_t read_bytes = 0;
   char buffer[BUFFER_SIZE];
-  meow_u128 *hash;
+  meow_u128 *hash = NULL;
 
   if (strcmp(path, "-") == 0) {
     fd = 0;
@@ -113,6 +113,7 @@     if (read_bytes == -1) {
       perror("error");
       fprintf(stderr, "error reading file %s\n", path);
       close(fd);
+      free(hash);
       return NULL;
     }
     *size += read_bytes;
@@ -132,18 +133,21 @@ }
 
 char *format_sum(meow_u128 hash, int size) {
   char *result;
-
   result = malloc((size * 2 / 8 * sizeof(char)) + 1);
 
   if (size == 32) {
+    // NOLINTNEXTLINE
     sprintf(result, "%08x", MeowU32From(hash, 0));
   }
   if (size == 64) {
+    // NOLINTNEXTLINE
     sprintf(result, "%016llx", MeowU64From(hash, 0));
   }
   if (size == 128) {
     int64_t v64val[2];
+    // NOLINTNEXTLINE
     memcpy(v64val, &hash, sizeof(v64val));
+    // NOLINTNEXTLINE
     sprintf(result, "%016lx%016lx", v64val[1], v64val[0]);
   }
 
@@ -178,16 +182,16 @@ }
 
 bool check_files(char *argv[], int start, int argc, bool quiet,
                  bool strict_errors) {
-  char *line;
-  size_t line_size;
-  FILE *file;
+  char *line = NULL;
+  size_t line_size = 0;
+  FILE *file = NULL;
   char expected_hex_hash[33];
-  unsigned long expected_size, size;
-  char *path;
-  ssize_t read_bytes;
-  meow_u128 *hash;
-  char *hex_hash;
-  int hash_size;
+  unsigned long expected_size = 0, size = 0;
+  char *path = NULL;
+  ssize_t read_bytes = 0;
+  meow_u128 *hash = NULL;
+  char *hex_hash = NULL;
+  int hash_size = 0;
   bool result = true;
 
   for (int i = start; i < argc; ++i) {
@@ -207,9 +211,24 @@           fprintf(stderr, "while reading line in %s\n", argv[i]);
           return false;
         }
       }
-
+      if (line[read_bytes - 1] == '\n') {
+        line[read_bytes - 1] = 0;
+      }
       path = malloc(line_size * sizeof(char));
-      sscanf(line, "%s %ld %s", expected_hex_hash, &expected_size, path); // fixme if empty or malformed
+      if (path == NULL) {
+        perror("error");
+        fprintf(stderr, "error mallocing path for %s\n", argv[i]);
+        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);
+      if (n != 3) {
+        fprintf(stderr, "line '%s' in %s malformed", line, argv[i]);
+        free(path);
+        free(line);
+        return false;
+      }
       hash_size = strlen(expected_hex_hash) / 2 * 8;
 
       if (strcmp("-", path) == 0) {
@@ -222,12 +241,13 @@           printf("ERM %s\n", path);
           if (strict_errors) {
             result &= false;
           }
+          free(path);
+          free(line);
           continue;
         }
         hash = calculate_checksum(path, &size);
         if (hash == NULL) {
           fprintf(stderr, "error while calculating %s\n", path);
-          free(hash);
           free(path);
           free(line);
           continue;
@@ -235,7 +255,6 @@         }
         hex_hash = format_sum(*hash, hash_size);
         if (hex_hash == NULL) {
           fprintf(stderr, "error while formating hex hash for %s\n", path);
-          free(hex_hash);
           free(hash);
           free(path);
           free(line);
@@ -257,10 +276,9 @@           if (!quiet) {
             printf("OK %s\n", path);
           }
         }
+        free(hex_hash);
+        free(hash);
       }
-
-      free(hex_hash);
-      free(hash);
       free(path);
       free(line);
     }