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 <nvinson234@gmail.com>
This commit is contained in:
Nicholas Vinson committed 2025-05-17 11:33:15 -04:00
1 parent 981fd9afed
commit ea49bb3057
6 files changed
+2189 -13

No files matched your search

+1
View File
@@ -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 \
+6
View File
@@ -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;
+10
View File
@@ -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. */
+64 -13
View File
@@ -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(&reg->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(&reg->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(&reg->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(&reg->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(&reg->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(&reg->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. */
+1
View File
@@ -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
File diff suppressed because it is too large. Load diff