#define INTEGRITY_CHUNK_SIZE 10485760
/*
- * Verifies the integrity of a WIM.
+ * Verifies the integrity of a WIM.
*
- * @fp: FILE* of the WIM, currently positioned at the end of the header.
+ * @fp: FILE* of the WIM, currently positioned at the end of the header.
* @num_bytes: Number of bytes to verify the integrity of.
* @chunk_size: Chunk size per SHA1 message digest.
* @sha1sums: Array of SHA1 message digests; 20 bytes each, one per chunk.
* @show_progress: Nonzero if the percent complete is to be printed after every
* chunk.
- * @status: On success, set to WIM_INTEGRITY_OK or WIM_INTEGRITY_NOT_OK
+ * @status: On success, set to WIM_INTEGRITY_OK or WIM_INTEGRITY_NOT_OK
* based on whether the WIM is intact or not.
*/
-static int verify_integrity(FILE *fp, u64 num_bytes, u32 chunk_size,
+static int verify_integrity(FILE *fp, u64 num_bytes, u32 chunk_size,
const u8 *sha1sums, int show_progress,
int *status)
{
bytes_remaining = num_bytes;
while (bytes_remaining != 0) {
if (show_progress) {
- percent_done = (num_bytes - bytes_remaining) * 100 /
+ percent_done = (num_bytes - bytes_remaining) * 100 /
num_bytes;
printf("Verifying integrity of WIM (%"PRIu64" bytes "
- "remaining, %u%% done) \r",
+ "remaining, %u%% done) \r",
bytes_remaining, percent_done);
fflush(stdout);
}
}
/*
- * Verifies the integrity of the WIM.
+ * Verifies the integrity of the WIM.
*
* @show_progress: Nonzero if the percent complete is to be printed after every
* chunk.
}
/* Read the integrity table into memory. */
- buf = MALLOC(res_entry->original_size);
- if (!buf) {
+ if ((sizeof(size_t) < sizeof(u64)
+ && res_entry->original_size > ~(size_t)0)
+ || ((buf = MALLOC(res_entry->original_size)) == NULL))
+ {
ERROR("Out of memory (needed %zu bytes for integrity table)",
- res_entry->original_size);
+ (size_t)res_entry->original_size);
ret = WIMLIB_ERR_NOMEM;
goto out;
}
if (integrity_table_size != expected_size) {
ERROR("Integrity table is %u bytes, but expected %"PRIu64" "
- "bytes to hold %u entries",
+ "bytes to hold %u entries",
integrity_table_size, expected_size, num_entries);
ret = WIMLIB_ERR_INVALID_INTEGRITY_TABLE;
goto out;
}
/* call verify_integrity(), which does the actual checking of the SHA1
* message digests. */
- ret = verify_integrity(w->fp, bytes_to_check, chunk_size, p,
+ ret = verify_integrity(w->fp, bytes_to_check, chunk_size, p,
show_progress, status);
out:
FREE(buf);
return ret;
}
-/*
+/*
* Writes integrity information to the output stream for a WIM file being
- * written.
+ * written.
*
* @end_header_offset is the offset of the byte after the header, which is the
* beginning of the region that is checksummed.
*
* @end_lookup_table_offset is the offset of the byte after the lookup table,
- * which is the end of the region that is checksummed.
+ * which is the end of the region that is checksummed.
*/
-int write_integrity_table(FILE *out, u64 end_header_offset,
+int write_integrity_table(FILE *out, u64 end_header_offset,
u64 end_lookup_table_offset, int show_progress)
{
- u64 bytes_to_check;
- u64 bytes_remaining;
- u8 *buf;
- u8 *p;
- u8 *chunk_buf;
- u32 num_entries;
- u32 integrity_table_size;
- int ret;
-
- DEBUG("Writing integrity table");
+ u64 bytes_to_check;
+ u64 bytes_remaining;
+ u8 *buf;
+ u8 *p;
+ u8 *chunk_buf;
+ u32 num_entries;
+ u32 integrity_table_size;
+ int ret;
+
+ DEBUG("Calculating integrity table");
if (fseeko(out, end_header_offset, SEEK_SET) != 0) {
ERROR_WITH_ERRNO("Failed to seek to byte %"PRIu64" of WIM to "
"calculate integrity data", end_header_offset);
}
bytes_to_check = end_lookup_table_offset - end_header_offset;
- num_entries = bytes_to_check / INTEGRITY_CHUNK_SIZE +
- (bytes_to_check % INTEGRITY_CHUNK_SIZE != 0);
+ num_entries = (bytes_to_check + INTEGRITY_CHUNK_SIZE - 1) /
+ INTEGRITY_CHUNK_SIZE;
integrity_table_size = num_entries * SHA1_HASH_SIZE + 3 * sizeof(u32);
- DEBUG("integrity table size = %u", integrity_table_size);
-
+ DEBUG("integrity_table_size = %u", integrity_table_size);
buf = MALLOC(integrity_table_size);
if (!buf) {
ERROR("Failed to allocate %u bytes for integrity chunk buffer",
INTEGRITY_CHUNK_SIZE);
ret = WIMLIB_ERR_NOMEM;
- goto err2;
+ goto out_free_buf;
}
bytes_remaining = bytes_to_check;
while (bytes_remaining != 0) {
- uint percent_done = (bytes_to_check - bytes_remaining) *
+ uint percent_done = (bytes_to_check - bytes_remaining) *
100 / bytes_to_check;
if (show_progress) {
printf("Calculating integrity checksums for WIM "
"(%"PRIu64" bytes remaining, %u%% "
- "done) \r",
+ "done) \r",
bytes_remaining, percent_done);
fflush(stdout);
}
"checksums");
}
ret = WIMLIB_ERR_READ;
- goto err2;
+ goto out_free_chunk_buf;
}
sha1_buffer(chunk_buf, bytes_read, p);
p += SHA1_HASH_SIZE;
ERROR_WITH_ERRNO("Failed to seek to end of WIM to write "
"integrity table");
ret = WIMLIB_ERR_WRITE;
- goto err1;
+ goto out_free_chunk_buf;
}
if (fwrite(buf, 1, integrity_table_size, out) != integrity_table_size) {
ERROR_WITH_ERRNO("Failed to write integrity table to end of "
"WIM");
ret = WIMLIB_ERR_WRITE;
- goto err1;
+ goto out_free_chunk_buf;
}
ret = 0;
-err1:
+out_free_chunk_buf:
FREE(chunk_buf);
-err2:
+out_free_buf:
FREE(buf);
return ret;
}