Rework how lead is read and add function to validate it
authorJonathan Dieter <jdieter@gmail.com>
Mon, 11 Jun 2018 18:47:59 +0000 (21:47 +0300)
committerJonathan Dieter <jdieter@gmail.com>
Mon, 11 Jun 2018 18:52:27 +0000 (21:52 +0300)
Signed-off-by: Jonathan Dieter <jdieter@gmail.com>
include/zck.h
src/lib/header.c

index fe3239ad8259a132d9408003ae50baab3f7a3e04..f51f70407007bcbbe1c0270ae86eddfaabea1eda 100644 (file)
@@ -199,6 +199,8 @@ int zck_read_lead(zckCtx *zck)
 int zck_read_header(zckCtx *zck)
     __attribute__ ((warn_unused_result));
 
+int zck_validate_lead(zckCtx *zck)
+    __attribute__ ((warn_unused_result));
 
 /*******************************************************************
  * Indexes
index 6a35c5d168c82ecb19f40f4b6246d4130a5f9b06..68e86c90022f50dcb6fc26e9c0595dd192944da9 100644 (file)
@@ -421,7 +421,7 @@ int write_header(zckCtx *zck) {
     return True;
 }
 
-int PUBLIC zck_read_lead(zckCtx *zck) {
+static int read_lead(zckCtx *zck, zck_log_type log_level) {
     VALIDATE_READ(zck);
 
     int lead = 5 + 2*MAX_COMP_SIZE;
@@ -438,7 +438,7 @@ int PUBLIC zck_read_lead(zckCtx *zck) {
 
     if(memcmp(header, "\0ZCK1", 5) != 0) {
         free(header);
-        zck_log(ZCK_LOG_ERROR,
+        zck_log(log_level,
                 "Invalid lead, perhaps this is not a zck file?\n");
         return False;
     }
@@ -446,23 +446,31 @@ int PUBLIC zck_read_lead(zckCtx *zck) {
 
     /* Read hash type for header and full digest and initialize check hash */
     int hash_type = 0;
-    if(!compint_to_int(&hash_type, header+length, &length, lead))
+    if(!compint_to_int(&hash_type, header+length, &length, lead)) {
+        free(header);
         return False;
+    }
     if(zck->prep_hash_type > -1 && zck->prep_hash_type != hash_type) {
-        zck_log(ZCK_LOG_ERROR,
+        free(header);
+        zck_log(log_level,
                 "Hash type (%i) doesn't match requested hash type "
                 "(%i)\n", hash_type, zck->prep_hash_type);
         return False;
     }
-    if(!hash_setup(&(zck->hash_type), hash_type))
+    if(!hash_setup(&(zck->hash_type), hash_type)) {
+        free(header);
         return False;
+    }
     zck_log(ZCK_LOG_DEBUG, "Setting header and full digest hash type to %s\n",
             zck_hash_name_from_type(hash_type));
 
     /* Read header size */
     size_t header_length = 0;
-    if(!compint_to_size(&header_length, header+length, &length, lead))
+    if(!compint_to_size(&header_length, header+length, &length, lead)) {
+        free(header);
+        hash_reset(&(zck->hash_type));
         return False;
+    }
     zck->header_length = header_length;
 
     /* Set header digest location */
@@ -472,6 +480,9 @@ int PUBLIC zck_read_lead(zckCtx *zck) {
     zck_log(ZCK_LOG_DEBUG, "Reading header digest\n");
     header = realloc(header, length + zck->hash_type.digest_size);
     if(header == NULL) {
+        zck->header_length = 0;
+        zck->hdr_digest_loc = 0;
+        hash_reset(&(zck->hash_type));
         zck_log(ZCK_LOG_ERROR, "Unable to re-allocate %lu bytes\n",
                 length + zck->hash_type.digest_size);
         return False;
@@ -479,13 +490,22 @@ int PUBLIC zck_read_lead(zckCtx *zck) {
     size_t to_read = 0;
     if(lead < length + zck->hash_type.digest_size)
         to_read = length + zck->hash_type.digest_size - lead;
-    if(read_data(zck->fd, header + lead, to_read) < to_read)
+    if(read_data(zck->fd, header + lead, to_read) < to_read) {
+        free(header);
+        zck->header_length = 0;
+        zck->hdr_digest_loc = 0;
+        hash_reset(&(zck->hash_type));
         return False;
+    }
     lead += to_read;
 
     if(zck->prep_digest &&
        memcmp(zck->prep_digest, header + length, zck->hash_type.digest_size) != 0) {
-        zck_log(ZCK_LOG_ERROR,
+        free(header);
+        zck->header_length = 0;
+        zck->hdr_digest_loc = 0;
+        hash_reset(&(zck->hash_type));
+        zck_log(log_level,
                 "Header digest doesn't match requested header digest\n"
                 "Expected: %s\nActual: %s\n",
                 get_digest_string(zck->prep_digest, zck->hash_type.digest_size),
@@ -494,6 +514,10 @@ int PUBLIC zck_read_lead(zckCtx *zck) {
     }
     zck->header_digest = zmalloc(zck->hash_type.digest_size);
     if(zck->header_digest == NULL) {
+        free(header);
+        zck->header_length = 0;
+        zck->hdr_digest_loc = 0;
+        hash_reset(&(zck->hash_type));
         zck_log(ZCK_LOG_ERROR, "Unable to allocate %lu bytes\n",
                 zck->hash_type.digest_size);
         return False;
@@ -504,7 +528,13 @@ int PUBLIC zck_read_lead(zckCtx *zck) {
     /* Check whether full header length matches specified header length */
     if(zck->prep_hdr_size > -1 &&
        (size_t)zck->prep_hdr_size != zck->header_length + length) {
-        zck_log(ZCK_LOG_ERROR,
+        free(header);
+        zck->header_length = 0;
+        zck->hdr_digest_loc = 0;
+        hash_reset(&(zck->hash_type));
+        free(zck->header_digest);
+        zck->header_digest = NULL;
+        zck_log(log_level,
                 "Header length (%lu) doesn't match requested header length "
                 "(%lu)\n", zck->header_length + length,
                 zck->prep_hdr_size);
@@ -519,6 +549,32 @@ int PUBLIC zck_read_lead(zckCtx *zck) {
     return True;
 }
 
+int PUBLIC zck_read_lead(zckCtx *zck) {
+    if(zck == NULL)
+        return False;
+    return read_lead(zck, ZCK_LOG_ERROR);
+}
+
+int PUBLIC zck_validate_lead(zckCtx *zck) {
+    if(zck == NULL)
+        return False;
+    int retval = read_lead(zck, ZCK_LOG_DEBUG);
+    free(zck->header);
+    free(zck->header_digest);
+    zck->header = NULL;
+    zck->header_size = 0;
+    zck->header_length = 0;
+    zck->hdr_digest_loc = 0;
+    zck->lead_string = NULL;
+    zck->lead_size = 0;
+    zck->header_digest = NULL;
+    zck->hdr_digest_loc = 0;
+    hash_reset(&(zck->hash_type));
+    if(!seek_data(zck->fd, 0, SEEK_SET))
+        return False;
+    return retval;
+}
+
 int PUBLIC zck_read_header(zckCtx *zck) {
     VALIDATE_READ(zck);