Drop assert in zmalloc and raise runtime error
authorStefano Babic <sbabic@denx.de>
Tue, 17 Aug 2021 11:21:43 +0000 (13:21 +0200)
committerStefano Babic <sbabic@denx.de>
Tue, 31 Aug 2021 12:59:23 +0000 (14:59 +0200)
Most assert in code are useful because they signal a real bug. However,
if allocation on the heap fails, it is a runtime error because system
gets rid of memory. This is more important on embedded systems,
and the caller process cannot exit but it should be informed with return
code and it will decide how to work on.

This drop the assert clause and add error code handling when zmalloc is
called.

Signed-off-by: Stefano Babic <sbabic@denx.de>
13 files changed:
src/lib/comp/comp.c
src/lib/comp/nocomp/nocomp.c
src/lib/comp/zstd/zstd.c
src/lib/dl/dl.c
src/lib/dl/multipart.c
src/lib/dl/range.c
src/lib/error.c
src/lib/hash/hash.c
src/lib/header.c
src/lib/index/index_create.c
src/lib/index/index_read.c
src/lib/io.c
src/lib/zck.c

index dbbbefe20b1e5c926401cc64d5886efc2304d5af..e80e6134ef9310ab8a49ef23b52697b6cb01d13f 100644 (file)
@@ -394,6 +394,10 @@ bool comp_add_to_dc(zckCtx *zck, zckComp *comp, const char *src,
 
     /* Get rid of any already read data and allocate space for new data */
     char *temp = zmalloc(comp->dc_data_size - comp->dc_data_loc + src_size);
+    if (!temp) {
+        zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+        return false;
+    }
     if(comp->dc_data_loc != 0)
         zck_log(ZCK_LOG_DEBUG, "Freeing %lu bytes from decompressed buffer",
                 comp->dc_data_loc);
@@ -430,6 +434,10 @@ ssize_t comp_read(zckCtx *zck, char *dst, size_t dst_size, bool use_dict) {
 
     size_t dc = 0;
     char *src = zmalloc(dst_size - dc);
+    if (!src) {
+        zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+        return false;
+    }
     bool finished_rd = false;
     bool finished_dc = false;
     zck_log(ZCK_LOG_DEBUG, "Trying to read %lu bytes", dst_size);
index 0b9f85a57eed21fe36789004e34fd4d7c99da0b8..c6e80ba0e6b1faa34476e3c540c53017ea994d4b 100644 (file)
@@ -49,6 +49,10 @@ static ssize_t compress(zckCtx *zck, zckComp *comp, const char *src,
     ALLOCD_INT(zck, comp);
 
     *dst = zmalloc(src_size);
+    if (!dst) {
+        zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+        return 0;
+    }
 
     memcpy(*dst, src, src_size);
     *dst_size = src_size;
index 921426fcfc489a61806e279590e8cbfa31c2a412..acf6582eccf38c24bd36535cea3b7a2f8f47705b 100644 (file)
@@ -140,6 +140,10 @@ static bool end_cchunk(zckCtx *zck, zckComp *comp, char **dst, size_t *dst_size,
     }
 
     *dst = zmalloc(max_size);
+    if (!dst) {
+        zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+        return false;
+    }
 #ifdef OLD_ZSTD
     /* Currently, compression isn't deterministic when using contexts in
      * zstd 1.3.5, so this works around it */
@@ -205,6 +209,10 @@ static bool end_dchunk(zckCtx *zck, zckComp *comp, const bool use_dict,
     comp->data_size = 0;
 
     char *dst = zmalloc(fd_size);
+    if (!dst) {
+        zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+        return false;
+    }
     size_t retval = 0;
     zck_log(ZCK_LOG_DEBUG, "Decompressing %lu bytes to %lu bytes", src_size,
             fd_size);
index c66de7a7ea0f5c4022648ddf4ba35979a35bc60f..1242669302ab6a6b91ec722d2b526bbb214aec94 100644 (file)
@@ -271,6 +271,10 @@ ssize_t PUBLIC zck_dl_get_bytes_uploaded(zckDL *dl) {
 /* Initialize zckDL.  When finished, zckDL *must* be freed by zck_dl_free() */
 zckDL PUBLIC *zck_dl_init(zckCtx *zck) {
     zckDL *dl = zmalloc(sizeof(zckDL));
+    if (!dl) {
+       zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+       return NULL;
+    }
     dl->mp = zmalloc(sizeof(zckMP));
     dl->zck = zck;
     return dl;
index f8c11dfa587eb59f97c536a89e7fadfabb7965f4..3e05e94364ef4447128e4685994d564a2dab4305 100644 (file)
@@ -41,7 +41,7 @@ static char *add_boundary_to_regex(zckCtx *zck, const char *regex,
     if(regex == NULL || boundary == NULL)
         return NULL;
     char *regex_b = zmalloc(strlen(regex) + strlen(boundary) + 1);
-    if(snprintf(regex_b, strlen(regex) + strlen(boundary), regex,
+    if(!regex_b || snprintf(regex_b, strlen(regex) + strlen(boundary), regex,
                 boundary) != strlen(regex) + strlen(boundary) - 2) {
         free(regex_b);
         set_error(zck, "Unable to build regular expression");
@@ -81,7 +81,7 @@ static bool gen_regex(zckDL *dl) {
     if(regex_n == NULL)
         return false;
     dl->dl_regex = zmalloc(sizeof(regex_t));
-    if(!create_regex(dl->zck, dl->dl_regex, regex_n)) {
+    if(!dl->dl_regex || !create_regex(dl->zck, dl->dl_regex, regex_n)) {
         free(regex_n);
         return false;
     }
@@ -90,7 +90,7 @@ static bool gen_regex(zckDL *dl) {
     if(regex_e == NULL)
         return false;
     dl->end_regex = zmalloc(sizeof(regex_t));
-    if(!create_regex(dl->zck, dl->end_regex, regex_e)) {
+    if(!dl->end_regex || !create_regex(dl->zck, dl->end_regex, regex_e)) {
         free(regex_e);
         return false;
     }
@@ -164,6 +164,10 @@ size_t multipart_extract(zckDL *dl, char *b, size_t l) {
             size_t size = buf + l - header_start;
             if(size > 0) {
                 mp->buffer = zmalloc(size);
+                if (!mp->buffer) {
+                   zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+                   return 0;
+                }
                 memcpy(mp->buffer, header_start, size);
                 mp->buffer_len = size;
             }
@@ -226,13 +230,17 @@ size_t multipart_get_boundary(zckDL *dl, char *b, size_t size) {
     if(dl->hdr_regex == NULL) {
         char *regex = "boundary *= *(.*?) *\r";
         dl->hdr_regex = zmalloc(sizeof(regex_t));
-        if(!create_regex(dl->zck, dl->hdr_regex, regex))
+        if(!dl->hdr_regex || !create_regex(dl->zck, dl->hdr_regex, regex))
             return 0;
     }
 
     /* Copy buffer to null-terminated string because POSIX regex requires null-
      * terminated string */
     char *buf = zmalloc(size+1);
+    if (!buf) {
+        zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+        return 0;
+    }
     buf[size] = '\0';
     memcpy(buf, b, size);
 
@@ -249,6 +257,11 @@ size_t multipart_get_boundary(zckDL *dl, char *b, size_t size) {
            boundary_length -= 2;
        }
         char *boundary = zmalloc(boundary_length + 1);
+        if (!boundary) {
+            zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+            free(buf);
+            return 0;
+        }
         memcpy(boundary, boundary_start, boundary_length);
         zck_log(ZCK_LOG_DEBUG, "Multipart boundary: %s", boundary);
         dl->boundary = boundary;
index a366f9bde697850d83dad082ba751562bf7a4b06..3a565d758697e448015d4d61c57ee32b618b9513 100644 (file)
@@ -42,6 +42,10 @@ static zckRangeItem *range_insert_new(zckCtx *zck, zckRangeItem *prev,
     VALIDATE_PTR(zck);
 
     zckRangeItem *new = zmalloc(sizeof(zckRangeItem));
+    if (!new) {
+       zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+       return NULL;
+    }
     new->start = start;
     new->end = end;
     if(prev) {
@@ -151,6 +155,10 @@ void PUBLIC zck_range_free(zckRange **info) {
 char PUBLIC *zck_get_range_char(zckCtx *zck, zckRange *range) {
     int buf_size = BUF_SIZE;
     char *output = zmalloc(buf_size);
+    if (!output) {
+       zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+       return NULL;
+    }
     int loc = 0;
     int count = 0;
     zckRangeItem *ri = range->first;
@@ -181,6 +189,10 @@ zckRange PUBLIC *zck_get_missing_range(zckCtx *zck, int max_ranges) {
     VALIDATE_PTR(zck);
 
     zckRange *range = zmalloc(sizeof(zckRange));
+    if (!range) {
+       zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+       return NULL;
+    }
     for(zckChunk *chk = zck->index.first; chk; chk = chk->next) {
         if(chk->valid)
             continue;
index b04d61fd69ee69f332d1eae8baf28e1e644d04ce..bd3ce9e2030c25f02d46139d5a5632a129285806 100644 (file)
@@ -65,6 +65,10 @@ void set_error_wf(zckCtx *zck, int fatal, const char *function,
         zck->msg = zmalloc(size + old_size + 3);
     else
         zck->msg = zmalloc(size + 2);
+    if (!zck->msg) {
+       zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+       return;
+    }
     va_start(args, format);
     vsnprintf(zck->msg, size + 1, format, args);
     va_end(args);
index 25768ae2a299b3571ccad5a6f81e2b171e10d58b..b4e6c2ca642aaaddf9dd1e287e41f90436954ca5 100644 (file)
@@ -146,6 +146,10 @@ static int validate_checksums(zckCtx *zck, zck_log_type bad_checksums) {
 char *get_digest_string(const char *digest, int size) {
     char *str = zmalloc(size*2+1);
 
+    if (!str) {
+       zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+       return NULL;
+    }
     for(int i=0; i<size; i++)
         snprintf(str + i*2, 3, "%02x", (unsigned char)digest[i]);
     return str;
@@ -212,12 +216,20 @@ bool hash_init(zckCtx *zck, zckHash *hash, zckHashType *hash_type) {
     if(hash_type->type == ZCK_HASH_SHA1) {
         zck_log(ZCK_LOG_DDEBUG, "Initializing SHA-1 hash");
         hash->ctx = zmalloc(sizeof(SHA_CTX));
+        if (!hash->ctx) {
+           zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+           return false;
+        }
         hash->type = hash_type;
         SHA1_Init((SHA_CTX *) hash->ctx);
         return true;
     } else if(hash_type->type == ZCK_HASH_SHA256) {
         zck_log(ZCK_LOG_DDEBUG, "Initializing SHA-256 hash");
         hash->ctx = zmalloc(sizeof(SHA256_CTX));
+        if (!hash->ctx) {
+           zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+           return false;
+        }
         hash->type = hash_type;
         SHA256_Init((SHA256_CTX *) hash->ctx);
         return true;
@@ -225,6 +237,10 @@ bool hash_init(zckCtx *zck, zckHash *hash, zckHashType *hash_type) {
               hash_type->type <= ZCK_HASH_SHA512_128) {
         zck_log(ZCK_LOG_DDEBUG, "Initializing SHA-512 hash");
         hash->ctx = zmalloc(sizeof(SHA512_CTX));
+        if (!hash->ctx) {
+           zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+           return false;
+        }
         hash->type = hash_type;
         SHA512_Init((SHA512_CTX *) hash->ctx);
         return true;
@@ -279,17 +295,29 @@ char *hash_finalize(zckCtx *zck, zckHash *hash) {
     }
     if(hash->type->type == ZCK_HASH_SHA1) {
         unsigned char *digest = zmalloc(SHA1_DIGEST_LENGTH);
+        if (!digest) {
+           zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+           return false;
+        }
         SHA1_Final((sha1_byte*)digest, (SHA_CTX *)hash->ctx);
         hash_close(hash);
         return (char *)digest;
     } else if(hash->type->type == ZCK_HASH_SHA256) {
         unsigned char *digest = zmalloc(SHA256_DIGEST_SIZE);
+        if (!digest) {
+           zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+           return false;
+        }
         SHA256_Final(digest, (SHA256_CTX *)hash->ctx);
         hash_close(hash);
         return (char *)digest;
     } else if(hash->type->type >= ZCK_HASH_SHA512 &&
               hash->type->type <= ZCK_HASH_SHA512_128) {
         unsigned char *digest = zmalloc(SHA512_DIGEST_SIZE);
+        if (!digest) {
+           zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+           return false;
+        }
         SHA512_Final(digest, (SHA512_CTX *)hash->ctx);
         hash_close(hash);
         return (char *)digest;
index 0d276f8e83313a2c2660b538de231d844d8e6780..46f21d3b0b43ff29299c41a72b9b401acd6e0f36 100644 (file)
@@ -120,6 +120,10 @@ static bool read_preface(zckCtx *zck) {
         return false;
     }
     zck->full_hash_digest = zmalloc(zck->hash_type.digest_size);
+    if (!zck->full_hash_digest) {
+           zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+           return false;
+    }
     memcpy(zck->full_hash_digest, header+length, zck->hash_type.digest_size);
     length += zck->hash_type.digest_size;
 
@@ -238,6 +242,10 @@ static bool preface_create(zckCtx *zck) {
     int header_malloc = zck->hash_type.digest_size + 4 + 2*MAX_COMP_SIZE;
 
     char *header = zmalloc(header_malloc);
+    if (!header) {
+           zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+           return false;
+    }
     size_t length = 0;
 
     /* Write out the full data digest */
@@ -272,6 +280,10 @@ static bool sig_create(zckCtx *zck) {
     char *header = zmalloc(MAX_COMP_SIZE);
     size_t length = 0;
 
+    if (!header) {
+           zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+           return false;
+    }
     zck_log(ZCK_LOG_DEBUG, "Calculating %i signatures", zck->sigs.count);
 
     /* Write out signature count and signatures */
@@ -295,6 +307,10 @@ static bool lead_create(zckCtx *zck) {
     memcpy(header, "\0ZCK1", 5);
     length += 5;
 
+    if (!header) {
+           zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+           return false;
+    }
     /* Write out full data and header hash type */
     compint_from_size(header + length, zck->hash_type.type, &length);
     /* Write out header length */
@@ -345,6 +361,10 @@ bool header_create(zckCtx *zck) {
     zck_log(ZCK_LOG_DEBUG, "Merging into header: %lu bytes",
             zck->data_offset);
     zck->header = zmalloc(zck->data_offset);
+    if (!zck->header) {
+           zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+           return false;
+    }
     size_t offs = 0;
     memcpy(zck->header + offs, zck->lead_string, zck->lead_size);
     free(zck->lead_string);
@@ -404,6 +424,10 @@ static bool read_lead(zckCtx *zck) {
     int lead = 5 + 2*MAX_COMP_SIZE;
 
     char *header = zmalloc(lead);
+    if (!header) {
+           zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+           return false;
+    }
     size_t length = 0;
 
     if(read_data(zck, header, lead) < lead) {
@@ -481,6 +505,11 @@ static bool read_lead(zckCtx *zck) {
         return false;
     }
     zck->header_digest = zmalloc(zck->hash_type.digest_size);
+    if (!zck->header_digest) {
+           zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+           free(header);
+           return false;
+    }
     memcpy(zck->header_digest, header + length, zck->hash_type.digest_size);
     length += zck->hash_type.digest_size;
 
index a035c843268d0ce98a3ba587b00adb57aa03d713..c4c08c7e61329f3741c2c240f47dc832a9734892 100644 (file)
@@ -37,6 +37,10 @@ static bool create_chunk(zckCtx *zck) {
 
     clear_work_index(zck);
     zck->work_index_item = zmalloc(sizeof(zckChunk));
+    if (!zck->work_index_item) {
+       zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+       return false;
+    }
     if(!hash_init(zck, &(zck->work_index_hash), &(zck->chunk_hash_type)) ||
       (!hash_init(zck, &(zck->work_index_hash_uncomp), &(zck->chunk_hash_type))))
         return false;
@@ -51,6 +55,11 @@ static bool finish_chunk(zckIndex *index, zckChunk *item, char *digest,
 
     item->digest = zmalloc(index->digest_size);
     item->digest_uncompressed = zmalloc(index->digest_size);
+    if (!item->digest || !item->digest_uncompressed) {
+       free(item->digest);
+       zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+       return false;
+    }
     if(digest) {
         memcpy(item->digest, digest, index->digest_size);
         item->digest_size = index->digest_size;
@@ -111,6 +120,10 @@ bool index_create(zckCtx *zck) {
 
     /* Write index */
     index = zmalloc(index_malloc);
+    if (!index) {
+       zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+       return false;
+    }
     compint_from_size(index+index_size, zck->index.hash_type, &index_size);
     compint_from_size(index+index_size, zck->index.count, &index_size);
     if(zck->index.first) {
@@ -155,6 +168,10 @@ bool index_new_chunk(zckCtx *zck, zckIndex *index, char *digest,
         return false;
     }
     zckChunk *chk = zmalloc(sizeof(zckChunk));
+    if (!chk) {
+       zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+       return false;
+    }
     index->digest_size = digest_size;
     chk->comp_length = comp_size;
     chk->length = orig_size;
@@ -209,6 +226,11 @@ bool index_finish_chunk(zckCtx *zck) {
     } else {
         digest = zmalloc(zck->chunk_hash_type.digest_size);
         digest_uncompressed = zmalloc(zck->chunk_hash_type.digest_size);
+        if (!digest || !digest_uncompressed) {
+           free(digest);
+           zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+           return false;
+        }
     }
     if(!finish_chunk(&(zck->index), zck->work_index_item, digest, digest_uncompressed, true, zck)) {
         free(digest);
index 42b4efecdd1f7e6727302fe8797a147c861cc68a..ea0ecbec5d815aaebab1c5bb701e6bb71e774571 100644 (file)
@@ -74,9 +74,18 @@ bool index_read(zckCtx *zck, char *data, size_t size, size_t max_length) {
 
         zckChunk *tmp = NULL;
         zckChunk *new = zmalloc(sizeof(zckChunk));
+        if (!new) {
+           zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+           return false;
+        }
 
         /* Read index entry digest */
         new->digest = zmalloc(zck->index.digest_size);
+        if (!new->digest) {
+           zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+           free(new);
+           return false;
+        }
         memcpy(new->digest, data+length, zck->index.digest_size);
         new->digest_size = zck->index.digest_size;
         HASH_FIND(hh, zck->index.ht, new->digest, new->digest_size, tmp);
@@ -89,6 +98,12 @@ bool index_read(zckCtx *zck, char *data, size_t size, size_t max_length) {
         if (zck->has_uncompressed_source) {
             /* same size for digest as compressed */
             new->digest_uncompressed = zmalloc(zck->index.digest_size);
+            if (!new->digest_uncompressed) {
+                free(new->digest);
+                free(new);
+                zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+                return false;
+            }
             memcpy(new->digest_uncompressed, data+length, zck->index.digest_size);
             new->digest_size_uncompressed = zck->index.digest_size;
             length += zck->index.digest_size;
index b91b7ca4f3cc64deacd0c3136186deb77557eaf7..6e5ebc7db9d0c33c13264db483fe72877af43532 100644 (file)
@@ -113,6 +113,10 @@ int chunks_from_temp(zckCtx *zck) {
         return false;
 
     char *data = zmalloc(BUF_SIZE);
+    if (!data) {
+       zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+       return false;
+    }
 
     while((read_count = read(zck->temp_fd, data, BUF_SIZE)) > 0) {
         if(!write_data(zck, zck->fd, data, read_count)) {
index d563350fa4f3f8e49e2cf7254cfe06bab7470129..9a81142c0ace1bcf50c90cba9b9abe3da1b1357b 100644 (file)
@@ -102,6 +102,10 @@ static char *ascii_checksum_to_bin (zckCtx *zck, char *checksum,
     char *raw_checksum = zmalloc(checksum_length/2);
     char *rp = raw_checksum;
     int buf = 0;
+    if (!raw_checksum) {
+       zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+       return NULL;
+    }
     for (int i=0; i<checksum_length; i++) {
         // Get integer value of hex checksum character.  If -1 is returned, then
         // the character wasn't actually hex, so return NULL
@@ -122,13 +126,11 @@ static char *ascii_checksum_to_bin (zckCtx *zck, char *checksum,
 
 void *zmalloc(size_t size) {
     void *ret = calloc(1, size);
-    assert(ret);
     return ret;
 }
 
 void *zrealloc(void *ptr, size_t size) {
     void *ret = realloc(ptr, size);
-    assert(ret);
     return ret;
 }
 
@@ -148,6 +150,10 @@ int get_tmp_fd(zckCtx *zck) {
     }
 
     fname = zmalloc(strlen(template) + strlen(tmpdir) + 2);
+    if (!fname) {
+       zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+       return -ENOMEM;
+    }
     int i=0;
     for(i=0; i<strlen(tmpdir); i++)
         fname[i] = tmpdir[i];
@@ -188,6 +194,10 @@ bool import_dict(zckCtx *zck) {
 
     zck_log(ZCK_LOG_DEBUG, "Reading compression dict");
     char *data = zmalloc(size);
+    if (!data) {
+       zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+       return false;
+    }
     if(comp_read(zck, data, size, 0) != size) {
         set_error(zck, "Error reading compressed dict");
         return false;
@@ -208,6 +218,10 @@ bool PUBLIC zck_set_soption(zckCtx *zck, zck_soption option, const char *value,
                             size_t length) {
     VALIDATE_BOOL(zck);
     char *data = zmalloc(length);
+    if (!data) {
+       zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+       return false;
+    }
     memcpy(data, value, length);
 
     /* Validation options */
@@ -351,6 +365,10 @@ void PUBLIC zck_free(zckCtx **zck) {
 
 zckCtx PUBLIC *zck_create() {
     zckCtx *zck = zmalloc(sizeof(zckCtx));
+    if (!zck) {
+       zck_log(ZCK_LOG_ERROR, "OOM in %s", __func__);
+       return false;
+    }
     zck_clear_error(NULL);
     zck->prep_hash_type = -1;
     zck->prep_hdr_size = -1;