From: Nicholas Vinson Date: Sun, 13 Apr 2025 11:33:43 +0000 (-0400) Subject: Copy ae digests to mtree_entry X-Git-Tag: v3.8.0~12^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ea49bb305733982468c3fc0687d206abdc0ac580;p=thirdparty%2Flibarchive.git Copy ae digests to mtree_entry Copy ae digests to mtree_entry. This simplifies porting non-archive formats to archive formats while preserving supported message digests specifically in cases where recomputing digests is not viable. Signed-off-by: Nicholas Vinson --- diff --git a/Makefile.am b/Makefile.am index 4e17ab2e2..74cb6e14b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -633,6 +633,7 @@ libarchive_test_SOURCES= \ libarchive/test/test_write_format_mtree_classic_indent.c\ libarchive/test/test_write_format_mtree_fflags.c \ libarchive/test/test_write_format_mtree_no_separator.c \ + libarchive/test/test_write_format_mtree_preset_digests.c \ libarchive/test/test_write_format_mtree_quoted_filename.c\ libarchive/test/test_write_format_pax.c \ libarchive/test/test_write_format_raw.c \ diff --git a/libarchive/archive_entry.c b/libarchive/archive_entry.c index c727b9cd8..7e7d51870 100644 --- a/libarchive/archive_entry.c +++ b/libarchive/archive_entry.c @@ -1607,21 +1607,27 @@ archive_entry_set_digest(struct archive_entry *entry, int type, switch (type) { case ARCHIVE_ENTRY_DIGEST_MD5: copy_digest(entry, md5, digest); + entry->mset_digest.md5 = 1; break; case ARCHIVE_ENTRY_DIGEST_RMD160: copy_digest(entry, rmd160, digest); + entry->mset_digest.rmd160 = 1; break; case ARCHIVE_ENTRY_DIGEST_SHA1: copy_digest(entry, sha1, digest); + entry->mset_digest.sha1 = 1; break; case ARCHIVE_ENTRY_DIGEST_SHA256: copy_digest(entry, sha256, digest); + entry->mset_digest.sha256 = 1; break; case ARCHIVE_ENTRY_DIGEST_SHA384: copy_digest(entry, sha384, digest); + entry->mset_digest.sha384 = 1; break; case ARCHIVE_ENTRY_DIGEST_SHA512: copy_digest(entry, sha512, digest); + entry->mset_digest.sha512 = 1; break; default: return ARCHIVE_WARN; diff --git a/libarchive/archive_entry_private.h b/libarchive/archive_entry_private.h index 0eba648d2..2af7b2b8c 100644 --- a/libarchive/archive_entry_private.h +++ b/libarchive/archive_entry_private.h @@ -48,6 +48,15 @@ struct ae_sparse { int64_t length; }; +struct ae_mset_digest { + char md5; + char rmd160; + char sha1; + char sha256; + char sha384; + char sha512; +}; + struct ae_digest { unsigned char md5[16]; unsigned char rmd160[20]; @@ -174,6 +183,7 @@ struct archive_entry { size_t mac_metadata_size; /* Digest support. */ + struct ae_mset_digest mset_digest; struct ae_digest digest; /* ACL support. */ diff --git a/libarchive/archive_write_set_format_mtree.c b/libarchive/archive_write_set_format_mtree.c index 14d68516f..b2767bfec 100644 --- a/libarchive/archive_write_set_format_mtree.c +++ b/libarchive/archive_write_set_format_mtree.c @@ -82,6 +82,7 @@ struct dir_info { struct reg_info { int compute_sum; uint32_t crc; + struct ae_mset_digest mset_digest; struct ae_digest digest; }; @@ -862,6 +863,40 @@ mtree_entry_free(struct mtree_entry *me) free(me); } +static void +mtree_copy_ae_digests(struct reg_info *reg, struct archive_entry *entry, int compute_sum) +{ + reg->compute_sum = compute_sum; + if ((reg->compute_sum & F_MD5) && entry->mset_digest.md5) { + memcpy(®->digest.md5, entry->digest.md5, sizeof(reg->digest.md5)); + reg->mset_digest.md5 = entry->mset_digest.md5; + } + if (reg->compute_sum & F_RMD160 && entry->mset_digest.rmd160) { + memcpy(®->digest.rmd160, entry->digest.rmd160, + sizeof(reg->digest.rmd160)); + reg->mset_digest.rmd160 = entry->mset_digest.rmd160; + } + if (reg->compute_sum & F_SHA1 && entry->mset_digest.sha1) { + memcpy(®->digest.sha1, entry->digest.sha1, sizeof(reg->digest.sha1)); + reg->mset_digest.sha1 = entry->mset_digest.sha1; + } + if (reg->compute_sum & F_SHA256 && entry->mset_digest.sha256) { + memcpy(®->digest.sha256, entry->digest.sha256, + sizeof(reg->digest.sha256)); + reg->mset_digest.sha256 = entry->mset_digest.sha256; + } + if (reg->compute_sum & F_SHA384 && entry->mset_digest.sha384) { + memcpy(®->digest.sha384, entry->digest.sha384, + sizeof(reg->digest.sha384)); + reg->mset_digest.sha384 = entry->mset_digest.sha384; + } + if (reg->compute_sum & F_SHA512 && entry->mset_digest.sha512) { + memcpy(®->digest.sha512, entry->digest.sha512, + sizeof(reg->digest.sha512)); + reg->mset_digest.sha512 = entry->mset_digest.sha512; + } +} + static int archive_write_mtree_header(struct archive_write *a, struct archive_entry *entry) @@ -896,8 +931,12 @@ archive_write_mtree_header(struct archive_write *a, /* If the current file is a regular file, we have to * compute the sum of its content. * Initialize a bunch of checksum context. */ - if (mtree_entry->reg_info) + if (mtree_entry->reg_info) { sum_init(mtree); + /* honor archive_entry_set_digest() calls. These values will be + * overwritten if archive_write_mtree_data() is called */ + mtree_copy_ae_digests(mtree_entry->reg_info, entry, mtree->compute_sum); + } return (r2); } @@ -1516,28 +1555,40 @@ sum_update(struct mtree_writer *mtree, const void *buff, size_t n) mtree->crc_len += n; } #ifdef ARCHIVE_HAS_MD5 - if (mtree->compute_sum & F_MD5) + if (mtree->compute_sum & F_MD5) { archive_md5_update(&mtree->md5ctx, buff, n); + mtree->mtree_entry->reg_info->mset_digest.md5 = 0; + } #endif #ifdef ARCHIVE_HAS_RMD160 - if (mtree->compute_sum & F_RMD160) + if (mtree->compute_sum & F_RMD160) { archive_rmd160_update(&mtree->rmd160ctx, buff, n); + mtree->mtree_entry->reg_info->mset_digest.rmd160 = 0; + } #endif #ifdef ARCHIVE_HAS_SHA1 - if (mtree->compute_sum & F_SHA1) + if (mtree->compute_sum & F_SHA1) { archive_sha1_update(&mtree->sha1ctx, buff, n); + mtree->mtree_entry->reg_info->mset_digest.sha1 = 0; + } #endif #ifdef ARCHIVE_HAS_SHA256 - if (mtree->compute_sum & F_SHA256) + if (mtree->compute_sum & F_SHA256) { archive_sha256_update(&mtree->sha256ctx, buff, n); + mtree->mtree_entry->reg_info->mset_digest.sha256 = 0; + } #endif #ifdef ARCHIVE_HAS_SHA384 - if (mtree->compute_sum & F_SHA384) + if (mtree->compute_sum & F_SHA384) { archive_sha384_update(&mtree->sha384ctx, buff, n); + mtree->mtree_entry->reg_info->mset_digest.sha384 = 0; + } #endif #ifdef ARCHIVE_HAS_SHA512 - if (mtree->compute_sum & F_SHA512) + if (mtree->compute_sum & F_SHA512) { archive_sha512_update(&mtree->sha512ctx, buff, n); + mtree->mtree_entry->reg_info->mset_digest.sha512 = 0; + } #endif } @@ -1553,27 +1604,27 @@ sum_final(struct mtree_writer *mtree, struct reg_info *reg) reg->crc = ~mtree->crc; } #ifdef ARCHIVE_HAS_MD5 - if (mtree->compute_sum & F_MD5) + if (mtree->compute_sum & F_MD5 && !reg->mset_digest.md5) archive_md5_final(&mtree->md5ctx, reg->digest.md5); #endif #ifdef ARCHIVE_HAS_RMD160 - if (mtree->compute_sum & F_RMD160) + if (mtree->compute_sum & F_RMD160 && !reg->mset_digest.rmd160) archive_rmd160_final(&mtree->rmd160ctx, reg->digest.rmd160); #endif #ifdef ARCHIVE_HAS_SHA1 - if (mtree->compute_sum & F_SHA1) + if (mtree->compute_sum & F_SHA1 && !reg->mset_digest.sha1) archive_sha1_final(&mtree->sha1ctx, reg->digest.sha1); #endif #ifdef ARCHIVE_HAS_SHA256 - if (mtree->compute_sum & F_SHA256) + if (mtree->compute_sum & F_SHA256 && !reg->mset_digest.sha256) archive_sha256_final(&mtree->sha256ctx, reg->digest.sha256); #endif #ifdef ARCHIVE_HAS_SHA384 - if (mtree->compute_sum & F_SHA384) + if (mtree->compute_sum & F_SHA384 && !reg->mset_digest.sha384) archive_sha384_final(&mtree->sha384ctx, reg->digest.sha384); #endif #ifdef ARCHIVE_HAS_SHA512 - if (mtree->compute_sum & F_SHA512) + if (mtree->compute_sum & F_SHA512 && !reg->mset_digest.sha512) archive_sha512_final(&mtree->sha512ctx, reg->digest.sha512); #endif /* Save what types of sum are computed. */ diff --git a/libarchive/test/CMakeLists.txt b/libarchive/test/CMakeLists.txt index 4217e4362..ffdb5b4ef 100644 --- a/libarchive/test/CMakeLists.txt +++ b/libarchive/test/CMakeLists.txt @@ -276,6 +276,7 @@ IF(ENABLE_TEST) test_write_format_mtree_classic_indent.c test_write_format_mtree_fflags.c test_write_format_mtree_no_separator.c + test_write_format_mtree_preset_digests.c test_write_format_mtree_quoted_filename.c test_write_format_pax.c test_write_format_raw.c diff --git a/libarchive/test/test_write_format_mtree_preset_digests.c b/libarchive/test/test_write_format_mtree_preset_digests.c new file mode 100644 index 000000000..cdf789b4b --- /dev/null +++ b/libarchive/test/test_write_format_mtree_preset_digests.c @@ -0,0 +1,2107 @@ +/*- + * Copyright (c) 2025 Nicholas Vinson + * + * 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 + * in this position and unchanged. + * 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 AUTHOR(S) ``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 AUTHOR(S) 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 "test.h" + +#define __LIBARCHIVE_BUILD 1 +#include "archive_digest_private.h" + +struct expected_digests { + unsigned char md5[16]; + unsigned char rmd160[20]; + unsigned char sha1[20]; + unsigned char sha256[32]; + unsigned char sha384[48]; + unsigned char sha512[64]; +}; + +archive_md5_ctx expectedMd5Ctx; +archive_rmd160_ctx expectedRmd160Ctx; +archive_sha1_ctx expectedSha1Ctx; +archive_sha256_ctx expectedSha256Ctx; +archive_sha384_ctx expectedSha384Ctx; +archive_sha512_ctx expectedSha512Ctx; + +DEFINE_TEST(test_write_format_mtree_digests_no_digests_set_no_data) +{ + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + +#ifdef ARCHIVE_HAS_MD5 + assertEqualInt(ARCHIVE_OK, archive_md5_init(&expectedMd5Ctx)); + assertEqualInt(ARCHIVE_OK, archive_md5_update(&expectedMd5Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_md5_final(&expectedMd5Ctx, ed.md5)); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assertEqualInt(ARCHIVE_OK, archive_sha1_init(&expectedSha1Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha1_update(&expectedSha1Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha1_final(&expectedSha1Ctx, ed.sha1)); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assertEqualInt(ARCHIVE_OK, archive_sha256_init(&expectedSha256Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha256_update(&expectedSha256Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha256_final(&expectedSha256Ctx, ed.sha256)); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assertEqualInt(ARCHIVE_OK, archive_sha384_init(&expectedSha384Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha384_update(&expectedSha384Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha384_final(&expectedSha384Ctx, ed.sha384)); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assertEqualInt(ARCHIVE_OK, archive_sha512_init(&expectedSha512Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha512_update(&expectedSha512Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha512_final(&expectedSha512Ctx, ed.sha512)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + +#ifdef ARCHIVE_HAS_MD5 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); +#endif + archive_entry_free(entry); +} + +DEFINE_TEST(test_write_format_mtree_digests_no_digests_set_empty_data) +{ + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + +#ifdef ARCHIVE_HAS_MD5 + assertEqualInt(ARCHIVE_OK, archive_md5_init(&expectedMd5Ctx)); + assertEqualInt(ARCHIVE_OK, archive_md5_update(&expectedMd5Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_md5_final(&expectedMd5Ctx, ed.md5)); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assertEqualInt(ARCHIVE_OK, archive_sha1_init(&expectedSha1Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha1_update(&expectedSha1Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha1_final(&expectedSha1Ctx, ed.sha1)); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assertEqualInt(ARCHIVE_OK, archive_sha256_init(&expectedSha256Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha256_update(&expectedSha256Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha256_final(&expectedSha256Ctx, ed.sha256)); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assertEqualInt(ARCHIVE_OK, archive_sha384_init(&expectedSha384Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha384_update(&expectedSha384Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha384_final(&expectedSha384Ctx, ed.sha384)); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assertEqualInt(ARCHIVE_OK, archive_sha512_init(&expectedSha512Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha512_update(&expectedSha512Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha512_final(&expectedSha512Ctx, ed.sha512)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_write_data(a, "", 0); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + +#ifdef ARCHIVE_HAS_MD5 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); +#endif + archive_entry_free(entry); +} + +DEFINE_TEST(test_write_format_mtree_digests_no_digests_set_non_empty_data) +{ + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + char *data = "abcd"; + +#ifdef ARCHIVE_HAS_MD5 + assertEqualInt(ARCHIVE_OK, archive_md5_init(&expectedMd5Ctx)); + assertEqualInt(ARCHIVE_OK, archive_md5_update(&expectedMd5Ctx, data, 4)); + assertEqualInt(ARCHIVE_OK, archive_md5_final(&expectedMd5Ctx, ed.md5)); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, data, 4)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assertEqualInt(ARCHIVE_OK, archive_sha1_init(&expectedSha1Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha1_update(&expectedSha1Ctx, data, 4)); + assertEqualInt(ARCHIVE_OK, archive_sha1_final(&expectedSha1Ctx, ed.sha1)); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assertEqualInt(ARCHIVE_OK, archive_sha256_init(&expectedSha256Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha256_update(&expectedSha256Ctx, data, 4)); + assertEqualInt(ARCHIVE_OK, archive_sha256_final(&expectedSha256Ctx, ed.sha256)); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assertEqualInt(ARCHIVE_OK, archive_sha384_init(&expectedSha384Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha384_update(&expectedSha384Ctx, data, 4)); + assertEqualInt(ARCHIVE_OK, archive_sha384_final(&expectedSha384Ctx, ed.sha384)); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assertEqualInt(ARCHIVE_OK, archive_sha512_init(&expectedSha512Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha512_update(&expectedSha512Ctx, data, 4)); + assertEqualInt(ARCHIVE_OK, archive_sha512_final(&expectedSha512Ctx, ed.sha512)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_write_data(a, data, 4); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + +#ifdef ARCHIVE_HAS_MD5 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); +#endif + archive_entry_free(entry); +} + +DEFINE_TEST(test_write_format_mtree_digests_md5_digest_set_no_data) +{ +#ifdef ARCHIVE_HAS_MD5 + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + + memcpy(ed.md5, (unsigned char[]) { + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + }, sizeof(ed.md5)); + +#ifdef ARCHIVE_HAS_RMD160 + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assertEqualInt(ARCHIVE_OK, archive_sha1_init(&expectedSha1Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha1_update(&expectedSha1Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha1_final(&expectedSha1Ctx, ed.sha1)); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assertEqualInt(ARCHIVE_OK, archive_sha256_init(&expectedSha256Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha256_update(&expectedSha256Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha256_final(&expectedSha256Ctx, ed.sha256)); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assertEqualInt(ARCHIVE_OK, archive_sha384_init(&expectedSha384Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha384_update(&expectedSha384Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha384_final(&expectedSha384Ctx, ed.sha384)); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assertEqualInt(ARCHIVE_OK, archive_sha512_init(&expectedSha512Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha512_update(&expectedSha512Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha512_final(&expectedSha512Ctx, ed.sha512)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + archive_entry_set_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5, ed.md5); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); + +#ifdef ARCHIVE_HAS_RMD160 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); +#endif + archive_entry_free(entry); +#else + skipping("This platform does not support MD5"); + return; +#endif +} + +DEFINE_TEST(test_write_format_mtree_digests_md5_digest_set_empty_data) +{ +#ifdef ARCHIVE_HAS_MD5 + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + + memcpy(ed.md5, (unsigned char[]) { + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + }, sizeof(ed.md5)); + +#ifdef ARCHIVE_HAS_RMD160 + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assertEqualInt(ARCHIVE_OK, archive_sha1_init(&expectedSha1Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha1_update(&expectedSha1Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha1_final(&expectedSha1Ctx, ed.sha1)); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assertEqualInt(ARCHIVE_OK, archive_sha256_init(&expectedSha256Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha256_update(&expectedSha256Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha256_final(&expectedSha256Ctx, ed.sha256)); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assertEqualInt(ARCHIVE_OK, archive_sha384_init(&expectedSha384Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha384_update(&expectedSha384Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha384_final(&expectedSha384Ctx, ed.sha384)); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assertEqualInt(ARCHIVE_OK, archive_sha512_init(&expectedSha512Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha512_update(&expectedSha512Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha512_final(&expectedSha512Ctx, ed.sha512)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + archive_entry_set_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5, ed.md5); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_write_data(a, "", 0); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) != 0); + + assertEqualInt(ARCHIVE_OK, archive_md5_init(&expectedMd5Ctx)); + assertEqualInt(ARCHIVE_OK, archive_md5_update(&expectedMd5Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_md5_final(&expectedMd5Ctx, ed.md5)); + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); + +#ifdef ARCHIVE_HAS_RMD160 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); +#endif + archive_entry_free(entry); +#else + skipping("This platform does not support MD5"); + return; +#endif +} + +DEFINE_TEST(test_write_format_mtree_digests_md5_digest_set_non_empty_data) +{ +#ifdef ARCHIVE_HAS_MD5 + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + + memcpy(ed.md5, (unsigned char[]) { + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + }, sizeof(ed.md5)); + +#ifdef ARCHIVE_HAS_RMD160 + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assertEqualInt(ARCHIVE_OK, archive_sha1_init(&expectedSha1Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha1_update(&expectedSha1Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha1_final(&expectedSha1Ctx, ed.sha1)); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assertEqualInt(ARCHIVE_OK, archive_sha256_init(&expectedSha256Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha256_update(&expectedSha256Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha256_final(&expectedSha256Ctx, ed.sha256)); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assertEqualInt(ARCHIVE_OK, archive_sha384_init(&expectedSha384Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha384_update(&expectedSha384Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha384_final(&expectedSha384Ctx, ed.sha384)); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assertEqualInt(ARCHIVE_OK, archive_sha512_init(&expectedSha512Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha512_update(&expectedSha512Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha512_final(&expectedSha512Ctx, ed.sha512)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + archive_entry_set_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5, ed.md5); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_write_data(a, "abcd", 4); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) != 0); + + assertEqualInt(ARCHIVE_OK, archive_md5_init(&expectedMd5Ctx)); + assertEqualInt(ARCHIVE_OK, archive_md5_update(&expectedMd5Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_md5_final(&expectedMd5Ctx, ed.md5)); + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); + +#ifdef ARCHIVE_HAS_RMD160 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); +#endif + archive_entry_free(entry); +#else + skipping("This platform does not support MD5"); + return; +#endif +} + +DEFINE_TEST(test_write_format_mtree_digests_rmd160_digest_set_no_data) +{ +#ifdef ARCHIVE_HAS_RMD160 + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + +#ifdef ARCHIVE_HAS_MD5 + assertEqualInt(ARCHIVE_OK, archive_md5_init(&expectedMd5Ctx)); + assertEqualInt(ARCHIVE_OK, archive_md5_update(&expectedMd5Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_md5_final(&expectedMd5Ctx, ed.md5)); +#endif + + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); + +#ifdef ARCHIVE_HAS_SHA1 + assertEqualInt(ARCHIVE_OK, archive_sha1_init(&expectedSha1Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha1_update(&expectedSha1Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha1_final(&expectedSha1Ctx, ed.sha1)); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assertEqualInt(ARCHIVE_OK, archive_sha256_init(&expectedSha256Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha256_update(&expectedSha256Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha256_final(&expectedSha256Ctx, ed.sha256)); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assertEqualInt(ARCHIVE_OK, archive_sha384_init(&expectedSha384Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha384_update(&expectedSha384Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha384_final(&expectedSha384Ctx, ed.sha384)); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assertEqualInt(ARCHIVE_OK, archive_sha512_init(&expectedSha512Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha512_update(&expectedSha512Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha512_final(&expectedSha512Ctx, ed.sha512)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + +#ifdef ARCHIVE_HAS_MD5 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); +#endif + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); + +#ifdef ARCHIVE_HAS_SHA1 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); +#endif + archive_entry_free(entry); +#else + skipping("This platform does not support RMD160"); + return; +#endif +} + +DEFINE_TEST(test_write_format_mtree_digests_rmd160_digest_set_empty_data) +{ +#ifdef ARCHIVE_HAS_RMD160 + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + + memcpy(ed.rmd160, (unsigned char[]) { + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed + }, sizeof(ed.rmd160)); + +#ifdef ARCHIVE_HAS_MD5 + assertEqualInt(ARCHIVE_OK, archive_md5_init(&expectedMd5Ctx)); + assertEqualInt(ARCHIVE_OK, archive_md5_update(&expectedMd5Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_md5_final(&expectedMd5Ctx, ed.md5)); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assertEqualInt(ARCHIVE_OK, archive_sha1_init(&expectedSha1Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha1_update(&expectedSha1Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha1_final(&expectedSha1Ctx, ed.sha1)); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assertEqualInt(ARCHIVE_OK, archive_sha256_init(&expectedSha256Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha256_update(&expectedSha256Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha256_final(&expectedSha256Ctx, ed.sha256)); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assertEqualInt(ARCHIVE_OK, archive_sha384_init(&expectedSha384Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha384_update(&expectedSha384Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha384_final(&expectedSha384Ctx, ed.sha384)); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assertEqualInt(ARCHIVE_OK, archive_sha512_init(&expectedSha512Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha512_update(&expectedSha512Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha512_final(&expectedSha512Ctx, ed.sha512)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + archive_entry_set_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160, ed.rmd160); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_write_data(a, "", 0); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + +#ifdef ARCHIVE_HAS_MD5 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); +#endif + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) != 0); + + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); + +#ifdef ARCHIVE_HAS_SHA1 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); +#endif + archive_entry_free(entry); +#else + skipping("This platform does not support RMD160"); + return; +#endif +} + +DEFINE_TEST(test_write_format_mtree_digests_rmd160_digest_set_non_empty_data) +{ +#ifdef ARCHIVE_HAS_RMD160 + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + + memcpy(ed.rmd160, (unsigned char[]) { + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed + }, sizeof(ed.rmd160)); + +#ifdef ARCHIVE_HAS_MD5 + assertEqualInt(ARCHIVE_OK, archive_md5_init(&expectedMd5Ctx)); + assertEqualInt(ARCHIVE_OK, archive_md5_update(&expectedMd5Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_md5_final(&expectedMd5Ctx, ed.md5)); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assertEqualInt(ARCHIVE_OK, archive_sha1_init(&expectedSha1Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha1_update(&expectedSha1Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha1_final(&expectedSha1Ctx, ed.sha1)); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assertEqualInt(ARCHIVE_OK, archive_sha256_init(&expectedSha256Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha256_update(&expectedSha256Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha256_final(&expectedSha256Ctx, ed.sha256)); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assertEqualInt(ARCHIVE_OK, archive_sha384_init(&expectedSha384Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha384_update(&expectedSha384Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha384_final(&expectedSha384Ctx, ed.sha384)); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assertEqualInt(ARCHIVE_OK, archive_sha512_init(&expectedSha512Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha512_update(&expectedSha512Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha512_final(&expectedSha512Ctx, ed.sha512)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + archive_entry_set_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160, ed.rmd160); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_write_data(a, "abcd", 4); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + +#ifdef ARCHIVE_HAS_MD5 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); +#endif + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) != 0); + + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); + +#ifdef ARCHIVE_HAS_SHA1 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); +#endif + archive_entry_free(entry); +#else + skipping("This platform does not support RMD160"); + return; +#endif +} + +DEFINE_TEST(test_write_format_mtree_digests_sha1_digest_set_no_data) +{ +#ifdef ARCHIVE_HAS_SHA1 + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + + memcpy(ed.sha1, (unsigned char[]) { + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed + }, sizeof(ed.sha1)); + +#ifdef ARCHIVE_HAS_MD5 + assertEqualInt(ARCHIVE_OK, archive_md5_init(&expectedMd5Ctx)); + assertEqualInt(ARCHIVE_OK, archive_md5_update(&expectedMd5Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_md5_final(&expectedMd5Ctx, ed.md5)); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assertEqualInt(ARCHIVE_OK, archive_sha256_init(&expectedSha256Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha256_update(&expectedSha256Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha256_final(&expectedSha256Ctx, ed.sha256)); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assertEqualInt(ARCHIVE_OK, archive_sha384_init(&expectedSha384Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha384_update(&expectedSha384Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha384_final(&expectedSha384Ctx, ed.sha384)); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assertEqualInt(ARCHIVE_OK, archive_sha512_init(&expectedSha512Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha512_update(&expectedSha512Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha512_final(&expectedSha512Ctx, ed.sha512)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + archive_entry_set_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1, ed.sha1); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + +#ifdef ARCHIVE_HAS_MD5 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); +#endif + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); + +#ifdef ARCHIVE_HAS_SHA256 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); +#endif + archive_entry_free(entry); +#else + skipping("This platform does not support SHA1"); + return; +#endif +} + +DEFINE_TEST(test_write_format_mtree_digests_sha1_digest_set_empty_data) +{ +#ifdef ARCHIVE_HAS_SHA1 + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + + memcpy(ed.sha1, (unsigned char[]) { + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed + }, sizeof(ed.sha1)); + +#ifdef ARCHIVE_HAS_MD5 + assertEqualInt(ARCHIVE_OK, archive_md5_init(&expectedMd5Ctx)); + assertEqualInt(ARCHIVE_OK, archive_md5_update(&expectedMd5Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_md5_final(&expectedMd5Ctx, ed.md5)); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assertEqualInt(ARCHIVE_OK, archive_sha256_init(&expectedSha256Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha256_update(&expectedSha256Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha256_final(&expectedSha256Ctx, ed.sha256)); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assertEqualInt(ARCHIVE_OK, archive_sha384_init(&expectedSha384Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha384_update(&expectedSha384Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha384_final(&expectedSha384Ctx, ed.sha384)); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assertEqualInt(ARCHIVE_OK, archive_sha512_init(&expectedSha512Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha512_update(&expectedSha512Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha512_final(&expectedSha512Ctx, ed.sha512)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + archive_entry_set_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1, ed.sha1); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_write_data(a, "", 0); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + +#ifdef ARCHIVE_HAS_MD5 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); +#endif + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) != 0); + + assertEqualInt(ARCHIVE_OK, archive_sha1_init(&expectedSha1Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha1_update(&expectedSha1Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha1_final(&expectedSha1Ctx, ed.sha1)); + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); + +#ifdef ARCHIVE_HAS_SHA256 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); +#endif + archive_entry_free(entry); +#else + skipping("This platform does not support SHA1"); + return; +#endif +} + +DEFINE_TEST(test_write_format_mtree_digests_sha1_digest_set_non_empty_data) +{ +#ifdef ARCHIVE_HAS_SHA1 + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + + memcpy(ed.sha1, (unsigned char[]) { + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed + }, sizeof(ed.sha1)); + +#ifdef ARCHIVE_HAS_MD5 + assertEqualInt(ARCHIVE_OK, archive_md5_init(&expectedMd5Ctx)); + assertEqualInt(ARCHIVE_OK, archive_md5_update(&expectedMd5Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_md5_final(&expectedMd5Ctx, ed.md5)); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assertEqualInt(ARCHIVE_OK, archive_sha256_init(&expectedSha256Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha256_update(&expectedSha256Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha256_final(&expectedSha256Ctx, ed.sha256)); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assertEqualInt(ARCHIVE_OK, archive_sha384_init(&expectedSha384Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha384_update(&expectedSha384Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha384_final(&expectedSha384Ctx, ed.sha384)); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assertEqualInt(ARCHIVE_OK, archive_sha512_init(&expectedSha512Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha512_update(&expectedSha512Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha512_final(&expectedSha512Ctx, ed.sha512)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + archive_entry_set_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1, ed.sha1); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_write_data(a, "abcd", 4); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + +#ifdef ARCHIVE_HAS_MD5 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); +#endif + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) != 0); + + assertEqualInt(ARCHIVE_OK, archive_sha1_init(&expectedSha1Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha1_update(&expectedSha1Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha1_final(&expectedSha1Ctx, ed.sha1)); + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); + +#ifdef ARCHIVE_HAS_SHA256 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); +#endif + archive_entry_free(entry); +#else + skipping("This platform does not support SHA1"); + return; +#endif +} + +DEFINE_TEST(test_write_format_mtree_digests_sha256_digest_set_no_data) +{ +#ifdef ARCHIVE_HAS_SHA256 + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + + memcpy(ed.sha256, (unsigned char[]) { + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed + }, sizeof(ed.sha256)); + +#ifdef ARCHIVE_HAS_MD5 + assertEqualInt(ARCHIVE_OK, archive_md5_init(&expectedMd5Ctx)); + assertEqualInt(ARCHIVE_OK, archive_md5_update(&expectedMd5Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_md5_final(&expectedMd5Ctx, ed.md5)); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assertEqualInt(ARCHIVE_OK, archive_sha1_init(&expectedSha1Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha1_update(&expectedSha1Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha1_final(&expectedSha1Ctx, ed.sha1)); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assertEqualInt(ARCHIVE_OK, archive_sha384_init(&expectedSha384Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha384_update(&expectedSha384Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha384_final(&expectedSha384Ctx, ed.sha384)); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assertEqualInt(ARCHIVE_OK, archive_sha512_init(&expectedSha512Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha512_update(&expectedSha512Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha512_final(&expectedSha512Ctx, ed.sha512)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + archive_entry_set_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256, ed.sha256); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + +#ifdef ARCHIVE_HAS_MD5 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); +#endif + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); + +#ifdef ARCHIVE_HAS_SHA384 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); +#endif + archive_entry_free(entry); +#else + skipping("This platform does not support SHA256"); + return; +#endif +} + +DEFINE_TEST(test_write_format_mtree_digests_sha256_digest_set_empty_data) +{ +#ifdef ARCHIVE_HAS_SHA256 + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + + memcpy(ed.sha256, (unsigned char[]) { + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed + }, sizeof(ed.sha256)); + +#ifdef ARCHIVE_HAS_MD5 + assertEqualInt(ARCHIVE_OK, archive_md5_init(&expectedMd5Ctx)); + assertEqualInt(ARCHIVE_OK, archive_md5_update(&expectedMd5Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_md5_final(&expectedMd5Ctx, ed.md5)); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assertEqualInt(ARCHIVE_OK, archive_sha1_init(&expectedSha1Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha1_update(&expectedSha1Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha1_final(&expectedSha1Ctx, ed.sha1)); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assertEqualInt(ARCHIVE_OK, archive_sha384_init(&expectedSha384Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha384_update(&expectedSha384Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha384_final(&expectedSha384Ctx, ed.sha384)); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assertEqualInt(ARCHIVE_OK, archive_sha512_init(&expectedSha512Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha512_update(&expectedSha512Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha512_final(&expectedSha512Ctx, ed.sha512)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + archive_entry_set_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256, ed.sha256); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_write_data(a, "", 0); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + +#ifdef ARCHIVE_HAS_MD5 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); +#endif + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) != 0); + + assertEqualInt(ARCHIVE_OK, archive_sha256_init(&expectedSha256Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha256_update(&expectedSha256Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha256_final(&expectedSha256Ctx, ed.sha256)); + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); + +#ifdef ARCHIVE_HAS_SHA384 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); +#endif + archive_entry_free(entry); +#else + skipping("This platform does not support SHA256"); + return; +#endif +} + +DEFINE_TEST(test_write_format_mtree_digests_sha256_digest_set_non_empty_data) +{ +#ifdef ARCHIVE_HAS_SHA256 + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + + memcpy(ed.sha256, (unsigned char[]) { + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed + }, sizeof(ed.sha256)); + +#ifdef ARCHIVE_HAS_MD5 + assertEqualInt(ARCHIVE_OK, archive_md5_init(&expectedMd5Ctx)); + assertEqualInt(ARCHIVE_OK, archive_md5_update(&expectedMd5Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_md5_final(&expectedMd5Ctx, ed.md5)); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assertEqualInt(ARCHIVE_OK, archive_sha1_init(&expectedSha1Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha1_update(&expectedSha1Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha1_final(&expectedSha1Ctx, ed.sha1)); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assertEqualInt(ARCHIVE_OK, archive_sha384_init(&expectedSha384Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha384_update(&expectedSha384Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha384_final(&expectedSha384Ctx, ed.sha384)); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assertEqualInt(ARCHIVE_OK, archive_sha512_init(&expectedSha512Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha512_update(&expectedSha512Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha512_final(&expectedSha512Ctx, ed.sha512)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + archive_entry_set_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256, ed.sha256); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_write_data(a, "abcd", 4); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + +#ifdef ARCHIVE_HAS_MD5 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); +#endif + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) != 0); + + assertEqualInt(ARCHIVE_OK, archive_sha256_init(&expectedSha256Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha256_update(&expectedSha256Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha256_final(&expectedSha256Ctx, ed.sha256)); + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); + +#ifdef ARCHIVE_HAS_SHA384 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); +#endif + archive_entry_free(entry); +#else + skipping("This platform does not support SHA256"); + return; +#endif +} + +DEFINE_TEST(test_write_format_mtree_digests_sha384_digest_set_no_data) +{ +#ifdef ARCHIVE_HAS_SHA384 + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + + memcpy(ed.sha384, (unsigned char[]) { + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed + }, sizeof(ed.sha384)); + +#ifdef ARCHIVE_HAS_MD5 + assertEqualInt(ARCHIVE_OK, archive_md5_init(&expectedMd5Ctx)); + assertEqualInt(ARCHIVE_OK, archive_md5_update(&expectedMd5Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_md5_final(&expectedMd5Ctx, ed.md5)); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assertEqualInt(ARCHIVE_OK, archive_sha1_init(&expectedSha1Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha1_update(&expectedSha1Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha1_final(&expectedSha1Ctx, ed.sha1)); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assertEqualInt(ARCHIVE_OK, archive_sha256_init(&expectedSha256Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha256_update(&expectedSha256Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha256_final(&expectedSha256Ctx, ed.sha256)); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assertEqualInt(ARCHIVE_OK, archive_sha512_init(&expectedSha512Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha512_update(&expectedSha512Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha512_final(&expectedSha512Ctx, ed.sha512)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + archive_entry_set_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384, ed.sha384); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + +#ifdef ARCHIVE_HAS_MD5 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); +#endif + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); + +#ifdef ARCHIVE_HAS_SHA512 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); +#endif + archive_entry_free(entry); +#else + skipping("This platform does not support SHA384"); + return; +#endif +} + +DEFINE_TEST(test_write_format_mtree_digests_sha384_digest_set_empty_data) +{ +#ifdef ARCHIVE_HAS_SHA384 + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + + memcpy(ed.sha384, (unsigned char[]) { + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed + }, sizeof(ed.sha384)); + +#ifdef ARCHIVE_HAS_MD5 + assertEqualInt(ARCHIVE_OK, archive_md5_init(&expectedMd5Ctx)); + assertEqualInt(ARCHIVE_OK, archive_md5_update(&expectedMd5Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_md5_final(&expectedMd5Ctx, ed.md5)); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assertEqualInt(ARCHIVE_OK, archive_sha1_init(&expectedSha1Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha1_update(&expectedSha1Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha1_final(&expectedSha1Ctx, ed.sha1)); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assertEqualInt(ARCHIVE_OK, archive_sha256_init(&expectedSha256Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha256_update(&expectedSha256Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha256_final(&expectedSha256Ctx, ed.sha256)); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assertEqualInt(ARCHIVE_OK, archive_sha512_init(&expectedSha512Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha512_update(&expectedSha512Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha512_final(&expectedSha512Ctx, ed.sha512)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + archive_entry_set_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384, ed.sha384); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_write_data(a, "", 0); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + +#ifdef ARCHIVE_HAS_MD5 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); +#endif + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) != 0); + + assertEqualInt(ARCHIVE_OK, archive_sha384_init(&expectedSha384Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha384_update(&expectedSha384Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha384_final(&expectedSha384Ctx, ed.sha384)); + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); + +#ifdef ARCHIVE_HAS_SHA512 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); +#endif + archive_entry_free(entry); +#else + skipping("This platform does not support SHA384"); + return; +#endif +} + +DEFINE_TEST(test_write_format_mtree_digests_sha384_digest_set_non_empty_data) +{ +#ifdef ARCHIVE_HAS_SHA384 + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + + memcpy(ed.sha384, (unsigned char[]) { + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed + }, sizeof(ed.sha384)); + +#ifdef ARCHIVE_HAS_MD5 + assertEqualInt(ARCHIVE_OK, archive_md5_init(&expectedMd5Ctx)); + assertEqualInt(ARCHIVE_OK, archive_md5_update(&expectedMd5Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_md5_final(&expectedMd5Ctx, ed.md5)); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assertEqualInt(ARCHIVE_OK, archive_sha1_init(&expectedSha1Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha1_update(&expectedSha1Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha1_final(&expectedSha1Ctx, ed.sha1)); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assertEqualInt(ARCHIVE_OK, archive_sha256_init(&expectedSha256Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha256_update(&expectedSha256Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha256_final(&expectedSha256Ctx, ed.sha256)); +#endif + +#ifdef ARCHIVE_HAS_SHA512 + assertEqualInt(ARCHIVE_OK, archive_sha512_init(&expectedSha512Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha512_update(&expectedSha512Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha512_final(&expectedSha512Ctx, ed.sha512)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + archive_entry_set_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384, ed.sha384); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_write_data(a, "abcd", 4); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + +#ifdef ARCHIVE_HAS_MD5 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); +#endif + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) != 0); + + assertEqualInt(ARCHIVE_OK, archive_sha384_init(&expectedSha384Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha384_update(&expectedSha384Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha384_final(&expectedSha384Ctx, ed.sha384)); + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); + +#ifdef ARCHIVE_HAS_SHA512 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); +#endif + archive_entry_free(entry); +#else + skipping("This platform does not support SHA384"); + return; +#endif +} + +DEFINE_TEST(test_write_format_mtree_digests_sha512_digest_set_no_data) +{ +#ifdef ARCHIVE_HAS_SHA512 + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + + memcpy(ed.sha512, (unsigned char[]) { + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed + }, sizeof(ed.sha512)); + +#ifdef ARCHIVE_HAS_MD5 + assertEqualInt(ARCHIVE_OK, archive_md5_init(&expectedMd5Ctx)); + assertEqualInt(ARCHIVE_OK, archive_md5_update(&expectedMd5Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_md5_final(&expectedMd5Ctx, ed.md5)); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assertEqualInt(ARCHIVE_OK, archive_sha1_init(&expectedSha1Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha1_update(&expectedSha1Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha1_final(&expectedSha1Ctx, ed.sha1)); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assertEqualInt(ARCHIVE_OK, archive_sha256_init(&expectedSha256Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha256_update(&expectedSha256Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha256_final(&expectedSha256Ctx, ed.sha256)); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assertEqualInt(ARCHIVE_OK, archive_sha384_init(&expectedSha384Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha384_update(&expectedSha384Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha384_final(&expectedSha384Ctx, ed.sha384)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + archive_entry_set_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512, ed.sha512); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + +#ifdef ARCHIVE_HAS_MD5 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); +#endif + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); + + archive_entry_free(entry); +#else + skipping("This platform does not support SHA512"); + return; +#endif +} + +DEFINE_TEST(test_write_format_mtree_digests_sha512_digest_set_empty_data) +{ +#ifdef ARCHIVE_HAS_SHA512 + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + + memcpy(ed.sha512, (unsigned char[]) { + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed + }, sizeof(ed.sha512)); + +#ifdef ARCHIVE_HAS_MD5 + assertEqualInt(ARCHIVE_OK, archive_md5_init(&expectedMd5Ctx)); + assertEqualInt(ARCHIVE_OK, archive_md5_update(&expectedMd5Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_md5_final(&expectedMd5Ctx, ed.md5)); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assertEqualInt(ARCHIVE_OK, archive_sha1_init(&expectedSha1Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha1_update(&expectedSha1Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha1_final(&expectedSha1Ctx, ed.sha1)); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assertEqualInt(ARCHIVE_OK, archive_sha256_init(&expectedSha256Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha256_update(&expectedSha256Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha256_final(&expectedSha256Ctx, ed.sha256)); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assertEqualInt(ARCHIVE_OK, archive_sha384_init(&expectedSha384Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha384_update(&expectedSha384Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha384_final(&expectedSha384Ctx, ed.sha384)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + archive_entry_set_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512, ed.sha512); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_write_data(a, "", 0); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + +#ifdef ARCHIVE_HAS_MD5 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); +#endif + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) != 0); + + assertEqualInt(ARCHIVE_OK, archive_sha512_init(&expectedSha512Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha512_update(&expectedSha512Ctx, "", 0)); + assertEqualInt(ARCHIVE_OK, archive_sha512_final(&expectedSha512Ctx, ed.sha512)); + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); + + archive_entry_free(entry); +#else + skipping("This platform does not support SHA512"); + return; +#endif +} + +DEFINE_TEST(test_write_format_mtree_digests_sha512_digest_set_non_empty_data) +{ +#ifdef ARCHIVE_HAS_SHA512 + char buff[4096] = {0}; + size_t used = 0; + struct archive *a; + struct archive_entry *entry; + struct expected_digests ed; + + memcpy(ed.sha512, (unsigned char[]) { + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, 0xfe, 0xed, + 0xfe, 0xed, 0xfe, 0xed + }, sizeof(ed.sha512)); + +#ifdef ARCHIVE_HAS_MD5 + assertEqualInt(ARCHIVE_OK, archive_md5_init(&expectedMd5Ctx)); + assertEqualInt(ARCHIVE_OK, archive_md5_update(&expectedMd5Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_md5_final(&expectedMd5Ctx, ed.md5)); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assertEqualInt(ARCHIVE_OK, archive_rmd160_init(&expectedRmd160Ctx)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_update(&expectedRmd160Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_rmd160_final(&expectedRmd160Ctx, ed.rmd160)); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assertEqualInt(ARCHIVE_OK, archive_sha1_init(&expectedSha1Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha1_update(&expectedSha1Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha1_final(&expectedSha1Ctx, ed.sha1)); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assertEqualInt(ARCHIVE_OK, archive_sha256_init(&expectedSha256Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha256_update(&expectedSha256Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha256_final(&expectedSha256Ctx, ed.sha256)); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assertEqualInt(ARCHIVE_OK, archive_sha384_init(&expectedSha384Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha384_update(&expectedSha384Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha384_final(&expectedSha384Ctx, ed.sha384)); +#endif + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_mtree(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_options(a, "all")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, sizeof(buff) - 1, &used)); + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, "test.data"); + archive_entry_set_filetype(entry, AE_IFREG); + archive_entry_set_size(entry, 4); + archive_entry_set_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512, ed.sha512); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, entry)); + archive_write_data(a, "abcd", 4); + archive_entry_free(entry); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assert((entry = archive_entry_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, buff, used)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &entry)); + +#ifdef ARCHIVE_HAS_MD5 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_MD5), ed.md5, sizeof(ed.md5)) == 0); +#endif + +#ifdef ARCHIVE_HAS_RMD160 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_RMD160), ed.rmd160, sizeof(ed.rmd160)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA1 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA1), ed.sha1, sizeof(ed.sha1)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA256 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA256), ed.sha256, sizeof(ed.sha256)) == 0); +#endif + +#ifdef ARCHIVE_HAS_SHA384 + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA384), ed.sha384, sizeof(ed.sha384)) == 0); +#endif + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) != 0); + + assertEqualInt(ARCHIVE_OK, archive_sha512_init(&expectedSha512Ctx)); + assertEqualInt(ARCHIVE_OK, archive_sha512_update(&expectedSha512Ctx, "abcd", 4)); + assertEqualInt(ARCHIVE_OK, archive_sha512_final(&expectedSha512Ctx, ed.sha512)); + + assert(memcmp(archive_entry_digest(entry, ARCHIVE_ENTRY_DIGEST_SHA512), ed.sha512, sizeof(ed.sha512)) == 0); + + archive_entry_free(entry); +#else + skipping("This platform does not support SHA512"); + return; +#endif +}