From: Stephen Seo Date: Fri, 18 Apr 2025 07:36:19 +0000 (+0900) Subject: Fix integer conversions in 32-bit systems X-Git-Tag: 1.20^2~5 X-Git-Url: https://git.seodisparate.com/stephenseo/LD53?a=commitdiff_plain;h=6fe1a25b025eba080db6fa0dcfa2700e12af6ef7;p=SimpleArchiver Fix integer conversions in 32-bit systems --- diff --git a/src/archiver.c b/src/archiver.c index 026e813..87ff9bb 100644 --- a/src/archiver.c +++ b/src/archiver.c @@ -42,8 +42,8 @@ #include "users.h" #define FILE_COUNTS_OUTPUT_FORMAT_STR_0 \ - "\nFile %%%zu" PRIu32 " of %%%zu" PRIu32 ".\n" -#define FILE_COUNTS_OUTPUT_FORMAT_STR_1 "[%%%zuzu/%%%zuzu]\n" + "\nFile %%%" PRIu64 PRIu32 " of %%%" PRIu64 PRIu32 ".\n" +#define FILE_COUNTS_OUTPUT_FORMAT_STR_1 "[%%%" PRIu64 "zu/%%%" PRIu64 PRIu64 "]\n" #define SIMPLE_ARCHIVER_BUFFER_SIZE (1024 * 32) @@ -92,7 +92,20 @@ int write_list_datas_fn(void *data, void *ud) { SDArchiverInternalToWrite *to_write = data; FILE *out_f = ud; - fwrite(to_write->buf, 1, to_write->size, out_f); + // Handling in case of 32-bit system, but this function probably will never + // have to write more than 0xFFFFFFFF bytes (2^32 - 1). + uint64_t temp = to_write->size; + char *buf_ptr = to_write->buf; + while (temp > 0) { + if (sizeof(uintptr_t) == 4 && temp > 0xFFFFFFFF) { + fwrite(buf_ptr, 1, 0xFFFFFFFF, out_f); + temp -= 0xFFFFFFFF; + buf_ptr += 0xFFFFFFFF; + } else { + fwrite(buf_ptr, 1, (size_t)temp, out_f); + temp = 0; + } + } return 0; } @@ -1055,24 +1068,26 @@ int filenames_to_abs_map_fn(void *data, void *ud) { SDArchiverStateReturns read_buf_full_from_fd(FILE *fd, char *read_buf, const size_t read_buf_size, - const size_t amount_total, + const uint64_t amount_total, char *dst_buf) { - size_t amount = amount_total; + uint64_t amount = amount_total; while (amount != 0) { - if (amount >= read_buf_size) { + if (amount >= (uint64_t)read_buf_size) { if (fread(read_buf, 1, read_buf_size, fd) != read_buf_size) { return SDAS_INVALID_FILE; } if (dst_buf) { - memcpy(dst_buf + (amount_total - amount), read_buf, read_buf_size); + memcpy(dst_buf, read_buf, read_buf_size); + dst_buf += read_buf_size; } - amount -= read_buf_size; + amount -= (uint64_t)read_buf_size; } else { - if (fread(read_buf, 1, amount, fd) != amount) { + if (fread(read_buf, 1, (size_t)amount, fd) != (size_t)amount) { return SDAS_INVALID_FILE; } if (dst_buf) { - memcpy(dst_buf + (amount_total - amount), read_buf, amount); + memcpy(dst_buf, read_buf, (size_t)amount); + dst_buf += (size_t)amount; } amount = 0; } @@ -1085,20 +1100,20 @@ SDArchiverStateReturns read_fd_to_out_fd(FILE *in_fd, FILE *out_fd, char *read_buf, const size_t read_buf_size, - const size_t amount_total) { - size_t amount = amount_total; + const uint64_t amount_total) { + uint64_t amount = amount_total; while (amount != 0) { - if (amount >= read_buf_size) { + if (amount >= (uint64_t)read_buf_size) { if (fread(read_buf, 1, read_buf_size, in_fd) != read_buf_size) { return SDAS_INVALID_FILE; } else if (fwrite(read_buf, 1, read_buf_size, out_fd) != read_buf_size) { return SDAS_FAILED_TO_WRITE; } - amount -= read_buf_size; + amount -= (uint64_t)read_buf_size; } else { - if (fread(read_buf, 1, amount, in_fd) != amount) { + if (fread(read_buf, 1, (size_t)amount, in_fd) != (size_t)amount) { return SDAS_INVALID_FILE; - } else if (fwrite(read_buf, 1, amount, out_fd) != amount) { + } else if (fwrite(read_buf, 1, (size_t)amount, out_fd) != (size_t)amount) { return SDAS_FAILED_TO_WRITE; } amount = 0; @@ -1165,7 +1180,14 @@ SDArchiverStateReturns try_write_to_decomp(int *to_dec_pipe, } } else { if (*has_hold < 0) { - size_t fread_ret = fread(buf, 1, *chunk_remaining, in_f); + // Handling for 32-bit systems. + // size_t and uintptr_t is 4 bytes on 32-bit systems. + size_t fread_ret; + if (sizeof(uintptr_t) == 4 && *chunk_remaining > 0xFFFFFFFF) { + fread_ret = fread(buf, 1, 0xFFFFFFFF, in_f); + } else { + fread_ret = fread(buf, 1, (size_t)*chunk_remaining, in_f); + } if (fread_ret == 0) { goto TRY_WRITE_TO_DECOMP_END; } else { @@ -1309,7 +1331,14 @@ SDArchiverStateReturns read_decomp_to_out_file(const char *out_filename, } } } else { - read_ret = read(in_pipe, read_buf, file_size - written_amt); + // Handling for 32-bit systems. + // size_t and uintptr_t is 4 bytes on 32-bit systems. + uint64_t read_amount = file_size - written_amt; + if (sizeof(uintptr_t) == 4 && read_amount > 0xFFFFFFFF) { + read_ret = read(in_pipe, read_buf, 0xFFFFFFFF); + } else { + read_ret = read(in_pipe, read_buf, (size_t)read_amount); + } if (read_ret > 0) { if (out_fd) { fwrite_ret = fwrite(read_buf, 1, (size_t)read_ret, out_fd); @@ -6918,7 +6947,7 @@ SDArchiverStateRetStruct simple_archiver_parse_archive_version_0( } const uint32_t size = u32; - const size_t digits = simple_archiver_helper_num_digits(size); + const uint64_t digits = simple_archiver_helper_num_digits(size); char format_str[128]; snprintf(format_str, 128, FILE_COUNTS_OUTPUT_FORMAT_STR_0, digits, digits); int_fast8_t skip; @@ -7389,7 +7418,7 @@ SDArchiverStateRetStruct simple_archiver_parse_archive_version_0( int_fast8_t read_pipe_done = 0; size_t fread_ret = 0; char recv_buf[SIMPLE_ARCHIVER_BUFFER_SIZE]; - size_t amount_to_read; + uint64_t amount_to_read; while (!write_pipe_done || !read_pipe_done) { if (is_sig_int_occurred) { if (pipe_into_cmd[1] >= 0) { @@ -7416,7 +7445,11 @@ SDArchiverStateRetStruct simple_archiver_parse_archive_version_0( } else { amount_to_read = compressed_file_size; } - fread_ret = fread(buf, 1, amount_to_read, in_f); + + // amount_to_read is at most SIMPLE_ARCHIVER_BUFFER_SIZE, so + // it should be safe to convert to size_t. + fread_ret = fread(buf, 1, (size_t)amount_to_read, in_f); + if (fread_ret > 0) { compressed_file_size -= fread_ret; } @@ -7530,7 +7563,9 @@ SDArchiverStateRetStruct simple_archiver_parse_archive_version_0( } compressed_file_size -= fread_ret; } else { - fread_ret = fread(buf, 1, compressed_file_size, in_f); + // Safe to convert to size_t since in this branch it is not + // bigger than SIMPLE_ARCHIVER_BUFFER_SIZE. + fread_ret = fread(buf, 1, (size_t)compressed_file_size, in_f); if (ferror(in_f)) { // Error. return SDA_RET_STRUCT(SDAS_NON_DEC_EXTRACT_ERROR); @@ -7569,7 +7604,9 @@ SDArchiverStateRetStruct simple_archiver_parse_archive_version_0( return SDA_RET_STRUCT(SDAS_INVALID_FILE); } } else { - size_t read_ret = fread(buf, 1, u64, in_f); + // Safe to convert to size_t since u64 is not bigger than + // SIMPLE_ARCHIVER_BUFFER_SIZE. + size_t read_ret = fread(buf, 1, (size_t)u64, in_f); if (read_ret > 0) { u64 -= read_ret; } else if (ferror(in_f)) { diff --git a/src/archiver.h b/src/archiver.h index ddb2ed0..7a61864 100644 --- a/src/archiver.h +++ b/src/archiver.h @@ -36,8 +36,8 @@ typedef struct SDArchiverState { FILE *out_f; SDArchiverHashMap *map; size_t count; - size_t max; - size_t digits; + uint64_t max; + uint64_t digits; } SDArchiverState; typedef enum SDArchiverStateReturns { diff --git a/src/helpers.c b/src/helpers.c index 66cccf1..2b9696e 100644 --- a/src/helpers.c +++ b/src/helpers.c @@ -314,8 +314,8 @@ char *simple_archiver_helper_cut_substr(const char *s, size_t start_idx, } } -size_t simple_archiver_helper_num_digits(size_t value) { - size_t digits = 0; +uint64_t simple_archiver_helper_num_digits(uint64_t value) { + uint64_t digits = 0; do { ++digits; value /= 10; diff --git a/src/helpers.h b/src/helpers.h index a028c20..d9f98fa 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -66,7 +66,7 @@ int simple_archiver_helper_make_dirs_perms(const char *file_path, char *simple_archiver_helper_cut_substr(const char *s, size_t start_idx, size_t end_idx); -size_t simple_archiver_helper_num_digits(size_t value); +uint64_t simple_archiver_helper_num_digits(uint64_t value); typedef enum SAHelperPrefixValResult { SAHPrefixVal_OK = 0,