]> git.seodisparate.com - SimpleArchiver/commitdiff
Fix integer conversions in 32-bit systems
authorStephen Seo <seo.disparate@gmail.com>
Fri, 18 Apr 2025 07:36:19 +0000 (16:36 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Fri, 18 Apr 2025 07:36:19 +0000 (16:36 +0900)
src/archiver.c
src/archiver.h
src/helpers.c
src/helpers.h

index 026e813ff6dfaf1fbf99b22c6336a23e3c3ccb09..87ff9bb3b3bba8e636b9856e9da5ca15cf8f494e 100644 (file)
@@ -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)) {
index ddb2ed0f949cc59c734a145478d697010d9d2e19..7a618648905dc768e36dce1bb31dd514a9bfa929 100644 (file)
@@ -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 {
index 66cccf1cc1f67ace8c2782541833471f81ccbb0f..2b9696ede46ee4d90661ab01f5641358fc147d05 100644 (file)
@@ -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;
index a028c201658ae8276ad0a5eeb9483e8b89bb99af..d9f98fa8feaf425cc9719bb60affb75b3b98b1d6 100644 (file)
@@ -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,