From: Jonathan Dieter Date: Fri, 28 Dec 2018 22:13:41 +0000 (+0000) Subject: Fix bug when comparing chunks and add test case. X-Git-Tag: archive/raspbian/1.1.9+ds1-1+rpi1~1^2~53 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=818d55fcedaa40df97fb643469993a4882749ec7;p=zchunk.git Fix bug when comparing chunks and add test case. Signed-off-by: Jonathan Dieter --- diff --git a/src/lib/dl/dl.c b/src/lib/dl/dl.c index 5f18afa..e5e1e57 100644 --- a/src/lib/dl/dl.c +++ b/src/lib/dl/dl.c @@ -238,7 +238,6 @@ bool PUBLIC zck_copy_chunks(zckCtx *src, zckCtx *tgt) { zckIndex *tgt_info = &(tgt->index); zckIndex *src_info = &(src->index); zckChunk *tgt_idx = tgt_info->first; - zckChunk *src_idx = src_info->first; while(tgt_idx) { /* No need to copy already valid chunk */ if(tgt_idx->valid == 1) { @@ -247,10 +246,10 @@ bool PUBLIC zck_copy_chunks(zckCtx *src, zckCtx *tgt) { } zckChunk *f = NULL; - HASH_FIND(hh, src_info->ht, src_idx->digest, src_idx->digest_size, f); + HASH_FIND(hh, src_info->ht, tgt_idx->digest, tgt_idx->digest_size, f); if(f && f->length == tgt_idx->length && f->comp_length == tgt_idx->comp_length) - write_and_verify_chunk(src, tgt, src_idx, tgt_idx); + write_and_verify_chunk(src, tgt, f, tgt_idx); tgt_idx = tgt_idx->next; } return true; diff --git a/test/copy_chunks.c b/test/copy_chunks.c new file mode 100644 index 0000000..f5d78c8 --- /dev/null +++ b/test/copy_chunks.c @@ -0,0 +1,121 @@ +/* + * Copyright 2018 Jonathan Dieter + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "zck_private.h" +#include "util.h" + +int main (int argc, char *argv[]) { + zck_set_log_level(ZCK_LOG_DEBUG); + char *path = zmalloc(strlen(argv[1])); + strcpy(path, argv[1]); + + char *base_name = basename(path); + int in = open(argv[1], O_RDONLY); + if(in < 0) { + perror("Unable to open LICENSE.header.new.nodict.fodt.zck for reading"); + exit(1); + } + int tgt = open(base_name, O_RDWR | O_CREAT, 0644); + if(tgt < 0) { + perror("Unable to open LICENSE.header.new.nodict.fodt.zck for writing"); + exit(1); + } + char buffer[4096] = {0}; + int len = 0; + while((len=read(in, buffer, 4096)) > 0) { + if(write(tgt, buffer, len) < len) { + perror("Unable to write to LICENSE.header.new.nodict.fodt.zck"); + exit(1); + } + } + lseek(tgt, 0, SEEK_SET); + + /* Open target zchunk header and read */ + zckCtx *tgt_zck = zck_create(); + if(tgt_zck == NULL) + exit(1); + if(!zck_init_adv_read(tgt_zck, tgt)) { + printf("%s", zck_get_error(tgt_zck)); + exit(1); + } + + /* Open source zchunk file and read header */ + int src = open(argv[2], O_RDONLY); + if(src < 0) { + perror("Unable to open LICENSE.nodict.fodt.zck for reading"); + exit(1); + } + + zckCtx *src_zck = zck_create(); + if(src_zck == NULL) + exit(1); + if(!zck_init_read(src_zck, src)) { + printf("%s", zck_get_error(src_zck)); + exit(1); + } + + if(!zck_read_lead(tgt_zck) || !zck_read_header(tgt_zck)) { + printf("%s", zck_get_error(tgt_zck)); + exit(1); + } + if(zck_find_valid_chunks(tgt_zck) > 0) { + printf("All chunks were valid, but the target shouldn't have any " + "chunks\n"); + exit(1); + } + int out = zck_copy_chunks(src_zck, tgt_zck); + if(!out) { + printf("%i: %s%s\n", out, zck_get_error(src_zck), zck_get_error(tgt_zck)); + exit(1); + } + zck_reset_failed_chunks(tgt_zck); + printf("Missing chunks: %i\n", zck_missing_chunks(tgt_zck)); + if(zck_missing_chunks(tgt_zck) != 1) { + printf("Should be only one chunk missing"); + exit(1); + } + + if(zck_close(tgt_zck)) { + printf("Should have run into an error closing " + "LICENSE.header.new.nodict.fodt.zck"); + exit(1); + } + + zck_free(&tgt_zck); + zck_free(&src_zck); + return 0; +} diff --git a/test/files/LICENSE.header.new.nodict.fodt.zck b/test/files/LICENSE.header.new.nodict.fodt.zck new file mode 100644 index 0000000..550eade Binary files /dev/null and b/test/files/LICENSE.header.new.nodict.fodt.zck differ diff --git a/test/files/LICENSE.nodict.fodt.zck b/test/files/LICENSE.nodict.fodt.zck index d46b68d..06172a0 100644 Binary files a/test/files/LICENSE.nodict.fodt.zck and b/test/files/LICENSE.nodict.fodt.zck differ diff --git a/test/meson.build b/test/meson.build index 386f9b0..d010b92 100644 --- a/test/meson.build +++ b/test/meson.build @@ -7,6 +7,10 @@ empty = executable('empty', ['empty.c'] + util_sources, optelems = executable('optelems', ['optelems.c'] + util_sources, include_directories: incdir, dependencies: [zstd_dep, openssl_dep]) +copy_chunks = executable('copy_chunks', ['copy_chunks.c'] + util_sources, + include_directories: incdir, + dependencies: [zstd_dep, openssl_dep]) + invalid_input_checksum = executable('invalid_input_checksum', ['invalid_input_checksum.c'] + util_sources, include_directories: incdir, @@ -139,6 +143,14 @@ test( 'empty.zck' ] ) +test( + 'copy chunks from source', + copy_chunks, + args: [ + join_paths(file_path, 'LICENSE.header.new.nodict.fodt.zck'), + join_paths(file_path, 'LICENSE.nodict.fodt.zck') + ] +) test( 'decompress auto-chunked file - nocomp', shacheck,