]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Refactor all fuzzers to use shared fuzz_helpers.h 2820/head
authorLeslie P. Polzer <polzer@fastmail.com>
Mon, 22 Dec 2025 04:53:06 +0000 (04:53 +0000)
committerLeslie P. Polzer <polzer@fastmail.com>
Mon, 22 Dec 2025 04:53:06 +0000 (04:53 +0000)
Complete the refactoring of all 25 fuzzers:
- Remove duplicate Buffer struct definitions from 15 format fuzzers
- Remove duplicate DataConsumer class from 7 API fuzzers
- Update consume_bytes() calls to match new signature
- All fuzzers now use shared helpers from fuzz_helpers.h

This eliminates ~1000 lines of duplicated code.

22 files changed:
contrib/oss-fuzz/libarchive_7zip_fuzzer.cc
contrib/oss-fuzz/libarchive_ar_fuzzer.cc
contrib/oss-fuzz/libarchive_cab_fuzzer.cc
contrib/oss-fuzz/libarchive_cpio_fuzzer.cc
contrib/oss-fuzz/libarchive_encryption_fuzzer.cc
contrib/oss-fuzz/libarchive_filter_fuzzer.cc
contrib/oss-fuzz/libarchive_fuzzer.cc
contrib/oss-fuzz/libarchive_iso9660_fuzzer.cc
contrib/oss-fuzz/libarchive_lha_fuzzer.cc
contrib/oss-fuzz/libarchive_linkify_fuzzer.cc
contrib/oss-fuzz/libarchive_match_fuzzer.cc
contrib/oss-fuzz/libarchive_mtree_fuzzer.cc
contrib/oss-fuzz/libarchive_rar5_fuzzer.cc
contrib/oss-fuzz/libarchive_rar_fuzzer.cc
contrib/oss-fuzz/libarchive_read_disk_fuzzer.cc
contrib/oss-fuzz/libarchive_roundtrip_fuzzer.cc
contrib/oss-fuzz/libarchive_seek_fuzzer.cc
contrib/oss-fuzz/libarchive_string_fuzzer.cc
contrib/oss-fuzz/libarchive_warc_fuzzer.cc
contrib/oss-fuzz/libarchive_write_fuzzer.cc
contrib/oss-fuzz/libarchive_xar_fuzzer.cc
contrib/oss-fuzz/libarchive_zip_fuzzer.cc

index b46e17d1fe0dcc3fc9f30b40bab906af2a7631b7..74b3b2ad98d00295b16bb6547c27a810841468fe 100644 (file)
@@ -8,23 +8,11 @@
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 512 * 1024;  // 512KB
 
-struct Buffer {
-  const uint8_t *buf;
-  size_t len;
-};
 
-static ssize_t reader_callback(struct archive *a, void *client_data,
-                               const void **block) {
-  (void)a;
-  Buffer *buffer = reinterpret_cast<Buffer *>(client_data);
-  *block = buffer->buf;
-  ssize_t len = buffer->len;
-  buffer->len = 0;
-  return len;
-}
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   if (len == 0 || len > kMaxInputSize) {
@@ -44,7 +32,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   // Set passphrase for encrypted archives
   archive_read_add_passphrase(a, "password");
 
-  Buffer buffer = {buf, len};
+  Buffer buffer = {buf, len, 0};
   if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
     archive_read_free(a);
     return 0;
index 0d7c20911160284d21d5ab3733efb24d51390164..3ad88084d440a9b66992e73dd0b34c7df746770d 100644 (file)
@@ -8,23 +8,11 @@
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 512 * 1024;
 
-struct Buffer {
-  const uint8_t *buf;
-  size_t len;
-};
 
-static ssize_t reader_callback(struct archive *a, void *client_data,
-                               const void **block) {
-  (void)a;
-  Buffer *buffer = reinterpret_cast<Buffer *>(client_data);
-  *block = buffer->buf;
-  ssize_t len = buffer->len;
-  buffer->len = 0;
-  return len;
-}
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   if (len == 0 || len > kMaxInputSize) {
@@ -39,7 +27,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   archive_read_support_format_ar(a);
   archive_read_support_filter_all(a);
 
-  Buffer buffer = {buf, len};
+  Buffer buffer = {buf, len, 0};
   if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
     archive_read_free(a);
     return 0;
index 0b62eccbb69b45d716f40e17917953b05f754871..2b70860051316454ede79391a9ce02d13afc950b 100644 (file)
@@ -7,23 +7,11 @@
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 512 * 1024;
 
-struct Buffer {
-  const uint8_t *buf;
-  size_t len;
-};
-
-static ssize_t reader_callback(struct archive *a, void *client_data,
-                               const void **block) {
-  (void)a;
-  Buffer *buffer = reinterpret_cast<Buffer *>(client_data);
-  *block = buffer->buf;
-  ssize_t len = buffer->len;
-  buffer->len = 0;
-  return len;
-}
+
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   if (len == 0 || len > kMaxInputSize) {
@@ -38,7 +26,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   archive_read_support_format_cab(a);
   archive_read_support_filter_all(a);
 
-  Buffer buffer = {buf, len};
+  Buffer buffer = {buf, len, 0};
   if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
     archive_read_free(a);
     return 0;
index 06fe4217a8ce02907c681768132c04d426f06aea..acbca31c7433dc36bee58ff4cd20908bc81de6f0 100644 (file)
@@ -8,23 +8,11 @@
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 512 * 1024;
 
-struct Buffer {
-  const uint8_t *buf;
-  size_t len;
-};
 
-static ssize_t reader_callback(struct archive *a, void *client_data,
-                               const void **block) {
-  (void)a;
-  Buffer *buffer = reinterpret_cast<Buffer *>(client_data);
-  *block = buffer->buf;
-  ssize_t len = buffer->len;
-  buffer->len = 0;
-  return len;
-}
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   if (len == 0 || len > kMaxInputSize) {
@@ -39,7 +27,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   archive_read_support_format_cpio(a);
   archive_read_support_filter_all(a);
 
-  Buffer buffer = {buf, len};
+  Buffer buffer = {buf, len, 0};
   if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
     archive_read_free(a);
     return 0;
index 798b28db70e51d656aadde4c239880528e528c91..402265cb5e07142460b7d59474dfb7ccbf48478f 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 512 * 1024;
 
@@ -34,20 +35,7 @@ static const char* passphrase_callback(struct archive *a, void *client_data) {
   return pass;
 }
 
-struct Buffer {
-  const uint8_t *buf;
-  size_t len;
-};
 
-static ssize_t reader_callback(struct archive *a, void *client_data,
-                               const void **block) {
-  (void)a;
-  Buffer *buffer = reinterpret_cast<Buffer *>(client_data);
-  *block = buffer->buf;
-  ssize_t len = buffer->len;
-  buffer->len = 0;
-  return len;
-}
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   if (len == 0 || len > kMaxInputSize) {
@@ -76,7 +64,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   archive_read_add_passphrase(a, "password");
   archive_read_add_passphrase(a, "test123");
 
-  Buffer buffer = {buf, len};
+  Buffer buffer = {buf, len, 0};
   if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
     archive_read_free(a);
     return 0;
index cba2b3de64f541a4a17673ddc34ee864d4aba37a..cfd1807ecfd4ae06132c7b23fa978ca5646b3b83 100644 (file)
@@ -8,24 +8,11 @@
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 256 * 1024;
 
-struct Buffer {
-  const uint8_t *buf;
-  size_t len;
-  size_t pos;
-};
 
-static ssize_t reader_callback(struct archive *a, void *client_data,
-                               const void **block) {
-  (void)a;
-  Buffer *buffer = reinterpret_cast<Buffer *>(client_data);
-  *block = buffer->buf + buffer->pos;
-  ssize_t len = buffer->len - buffer->pos;
-  buffer->pos = buffer->len;
-  return len;
-}
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   if (len == 0 || len > kMaxInputSize) {
index bc7f865b69c570d45c1b20713b3c2cd36f0da502..09a9b1cc698fd9e2721837f70f89720111a011f4 100644 (file)
@@ -3,20 +3,7 @@
 #include <vector>
 
 #include "archive.h"
-
-struct Buffer {
-  const uint8_t *buf;
-  size_t len;
-};
-
-ssize_t reader_callback(struct archive *a, void *client_data,
-                        const void **block) {
-  Buffer *buffer = reinterpret_cast<Buffer *>(client_data);
-  *block = buffer->buf;
-  ssize_t len = buffer->len;
-  buffer->len = 0;
-  return len;
-}
+#include "fuzz_helpers.h"
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   int ret;
@@ -26,7 +13,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   archive_read_support_filter_all(a);
   archive_read_support_format_all(a);
 
-  Buffer buffer = {buf, len};
+  Buffer buffer = {buf, len, 0};
   archive_read_open(a, &buffer, NULL, reader_callback, NULL);
 
   std::vector<uint8_t> data_buffer(getpagesize(), 0);
index 9aa8316fe15b372bfa8a62fc3eb38cb997f62bd9..6cdaff23a09cb0e524913056534e02aac1ba5b66 100644 (file)
@@ -8,23 +8,11 @@
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 1024 * 1024;  // 1MB for ISO images
 
-struct Buffer {
-  const uint8_t *buf;
-  size_t len;
-};
 
-static ssize_t reader_callback(struct archive *a, void *client_data,
-                               const void **block) {
-  (void)a;
-  Buffer *buffer = reinterpret_cast<Buffer *>(client_data);
-  *block = buffer->buf;
-  ssize_t len = buffer->len;
-  buffer->len = 0;
-  return len;
-}
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   if (len == 0 || len > kMaxInputSize) {
@@ -42,7 +30,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   // Set options to test various ISO extensions
   archive_read_set_options(a, "iso9660:joliet,iso9660:rockridge");
 
-  Buffer buffer = {buf, len};
+  Buffer buffer = {buf, len, 0};
   if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
     archive_read_free(a);
     return 0;
index 58732aead20632bf37d4b1fb111e05d9057c4ff0..3957d3ed3d3837595d39f1538bc5ae8fe66a20f2 100644 (file)
@@ -7,23 +7,11 @@
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 512 * 1024;
 
-struct Buffer {
-  const uint8_t *buf;
-  size_t len;
-};
 
-static ssize_t reader_callback(struct archive *a, void *client_data,
-                               const void **block) {
-  (void)a;
-  Buffer *buffer = reinterpret_cast<Buffer *>(client_data);
-  *block = buffer->buf;
-  ssize_t len = buffer->len;
-  buffer->len = 0;
-  return len;
-}
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   if (len == 0 || len > kMaxInputSize) {
@@ -38,7 +26,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   archive_read_support_format_lha(a);
   archive_read_support_filter_all(a);
 
-  Buffer buffer = {buf, len};
+  Buffer buffer = {buf, len, 0};
   if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
     archive_read_free(a);
     return 0;
index 46348dac76bf6fe8f342288b72e65ece506c4b3a..64c22dca959c3fac2bd45cc7525c1394fd5392b6 100644 (file)
@@ -9,62 +9,11 @@
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 64 * 1024;  // 64KB
 
 // Simple data consumer
-class DataConsumer {
-public:
-  DataConsumer(const uint8_t *data, size_t size) : data_(data), size_(size), pos_(0) {
-    memset(string_buf_, 0, sizeof(string_buf_));
-  }
-
-  bool empty() const { return pos_ >= size_; }
-
-  uint8_t consume_byte() {
-    if (pos_ >= size_) return 0;
-    return data_[pos_++];
-  }
-
-  uint32_t consume_uint32() {
-    uint32_t val = 0;
-    for (int i = 0; i < 4 && pos_ < size_; i++) {
-      val |= static_cast<uint32_t>(data_[pos_++]) << (i * 8);
-    }
-    return val;
-  }
-
-  int64_t consume_int64() {
-    int64_t val = 0;
-    for (int i = 0; i < 8 && pos_ < size_; i++) {
-      val |= static_cast<int64_t>(data_[pos_++]) << (i * 8);
-    }
-    return val;
-  }
-
-  const char* consume_string(size_t max_len) {
-    if (max_len > sizeof(string_buf_) - 1) max_len = sizeof(string_buf_) - 1;
-    size_t avail = size_ - pos_;
-    size_t len = (avail < max_len) ? avail : max_len;
-
-    size_t actual_len = 0;
-    while (actual_len < len && pos_ < size_) {
-      char c = static_cast<char>(data_[pos_++]);
-      if (c == '\0') break;
-      string_buf_[actual_len++] = c;
-    }
-    string_buf_[actual_len] = '\0';
-    return string_buf_;
-  }
-
-  size_t remaining() const { return size_ - pos_; }
-
-private:
-  const uint8_t *data_;
-  size_t size_;
-  size_t pos_;
-  char string_buf_[256];
-};
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   if (len == 0 || len > kMaxInputSize) {
@@ -103,8 +52,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
     archive_entry_set_pathname(entry, consumer.consume_string(64));
 
     // Set inode and device for hardlink detection
-    archive_entry_set_ino(entry, consumer.consume_int64());
-    archive_entry_set_dev(entry, consumer.consume_uint32());
+    archive_entry_set_ino(entry, consumer.consume_i64());
+    archive_entry_set_dev(entry, consumer.consume_u32());
     archive_entry_set_nlink(entry, (consumer.consume_byte() % 5) + 1);
 
     // Set mode (regular file or directory)
@@ -112,9 +61,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
     mode_t mode = ftype ? (S_IFDIR | 0755) : (S_IFREG | 0644);
     archive_entry_set_mode(entry, mode);
 
-    archive_entry_set_size(entry, consumer.consume_int64() & 0xFFFF);
-    archive_entry_set_uid(entry, consumer.consume_uint32() & 0xFFFF);
-    archive_entry_set_gid(entry, consumer.consume_uint32() & 0xFFFF);
+    archive_entry_set_size(entry, consumer.consume_i64() & 0xFFFF);
+    archive_entry_set_uid(entry, consumer.consume_u32() & 0xFFFF);
+    archive_entry_set_gid(entry, consumer.consume_u32() & 0xFFFF);
 
     entries[num_entries++] = entry;
   }
index c5431b34b5b6826d06c372393b20fc285871f35a..a0f8ba7dae8487af8868fc4dde323de0f7f6798d 100644 (file)
@@ -8,53 +8,10 @@
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 32 * 1024;
 
-class DataConsumer {
-public:
-  DataConsumer(const uint8_t *data, size_t size) : data_(data), size_(size), pos_(0) {
-    memset(string_buf_, 0, sizeof(string_buf_));
-  }
-
-  bool empty() const { return pos_ >= size_; }
-
-  uint8_t consume_byte() {
-    if (pos_ >= size_) return 0;
-    return data_[pos_++];
-  }
-
-  int64_t consume_int64() {
-    int64_t val = 0;
-    for (int i = 0; i < 8 && pos_ < size_; i++) {
-      val |= static_cast<int64_t>(data_[pos_++]) << (i * 8);
-    }
-    return val;
-  }
-
-  const char* consume_string(size_t max_len) {
-    if (max_len > sizeof(string_buf_) - 1) max_len = sizeof(string_buf_) - 1;
-    size_t avail = size_ - pos_;
-    size_t len = (avail < max_len) ? avail : max_len;
-
-    size_t actual_len = 0;
-    while (actual_len < len && pos_ < size_) {
-      char c = static_cast<char>(data_[pos_++]);
-      if (c == '\0') break;
-      string_buf_[actual_len++] = c;
-    }
-    string_buf_[actual_len] = '\0';
-    return string_buf_;
-  }
-
-  size_t remaining() const { return size_ - pos_; }
-
-private:
-  const uint8_t *data_;
-  size_t size_;
-  size_t pos_;
-  char string_buf_[256];
-};
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   if (len == 0 || len > kMaxInputSize) {
@@ -87,29 +44,29 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
       }
       case 2: {
         // Time comparison (newer than)
-        int64_t sec = consumer.consume_int64();
-        int64_t nsec = consumer.consume_int64() % 1000000000;
+        int64_t sec = consumer.consume_i64();
+        int64_t nsec = consumer.consume_i64() % 1000000000;
         archive_match_include_time(match, ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER,
                                    sec, nsec);
         break;
       }
       case 3: {
         // Time comparison (older than)
-        int64_t sec = consumer.consume_int64();
-        int64_t nsec = consumer.consume_int64() % 1000000000;
+        int64_t sec = consumer.consume_i64();
+        int64_t nsec = consumer.consume_i64() % 1000000000;
         archive_match_include_time(match, ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER,
                                    sec, nsec);
         break;
       }
       case 4: {
         // UID inclusion
-        int64_t uid = consumer.consume_int64() & 0xFFFF;
+        int64_t uid = consumer.consume_i64() & 0xFFFF;
         archive_match_include_uid(match, uid);
         break;
       }
       case 5: {
         // GID inclusion
-        int64_t gid = consumer.consume_int64() & 0xFFFF;
+        int64_t gid = consumer.consume_i64() & 0xFFFF;
         archive_match_include_gid(match, gid);
         break;
       }
index e0c39249c6abb43d070b9fb5ffcca6cf36691ea0..e0110d4e1bc4f2732d2e2ce508d4f6e6d8fb9b83 100644 (file)
@@ -8,23 +8,11 @@
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 256 * 1024;
 
-struct Buffer {
-  const uint8_t *buf;
-  size_t len;
-};
 
-static ssize_t reader_callback(struct archive *a, void *client_data,
-                               const void **block) {
-  (void)a;
-  Buffer *buffer = reinterpret_cast<Buffer *>(client_data);
-  *block = buffer->buf;
-  ssize_t len = buffer->len;
-  buffer->len = 0;
-  return len;
-}
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   if (len == 0 || len > kMaxInputSize) {
@@ -42,7 +30,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   // Enable checkfs option to test more code paths
   archive_read_set_options(a, "mtree:checkfs");
 
-  Buffer buffer = {buf, len};
+  Buffer buffer = {buf, len, 0};
   if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
     archive_read_free(a);
     return 0;
index 4850879b30e2368d42f6c424b848e2f3d7428d4e..2a7b97f87e7afe2932fd4fc20303ca47f4d88998 100644 (file)
@@ -8,23 +8,11 @@
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 512 * 1024;  // 512KB
 
-struct Buffer {
-  const uint8_t *buf;
-  size_t len;
-};
 
-static ssize_t reader_callback(struct archive *a, void *client_data,
-                               const void **block) {
-  (void)a;
-  Buffer *buffer = reinterpret_cast<Buffer *>(client_data);
-  *block = buffer->buf;
-  ssize_t len = buffer->len;
-  buffer->len = 0;
-  return len;
-}
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   if (len == 0 || len > kMaxInputSize) {
@@ -44,7 +32,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   // Set passphrase for encrypted archives
   archive_read_add_passphrase(a, "password");
 
-  Buffer buffer = {buf, len};
+  Buffer buffer = {buf, len, 0};
   if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
     archive_read_free(a);
     return 0;
index bf88a8b18afdb75283ce37c707a432e30ac4ea94..dd94181bcc0679bf4315d850f985f9623e645f33 100644 (file)
@@ -7,23 +7,11 @@
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 512 * 1024;
 
-struct Buffer {
-  const uint8_t *buf;
-  size_t len;
-};
 
-static ssize_t reader_callback(struct archive *a, void *client_data,
-                               const void **block) {
-  (void)a;
-  Buffer *buffer = reinterpret_cast<Buffer *>(client_data);
-  *block = buffer->buf;
-  ssize_t len = buffer->len;
-  buffer->len = 0;
-  return len;
-}
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   if (len == 0 || len > kMaxInputSize) {
@@ -41,7 +29,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   // Add passphrase for encrypted RARs
   archive_read_add_passphrase(a, "password");
 
-  Buffer buffer = {buf, len};
+  Buffer buffer = {buf, len, 0};
   if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
     archive_read_free(a);
     return 0;
index 5d7fecf788fdb56a373ddddf414664c68b7859a7..91ccea15fde6833dc7706d0b993994a7ae49bc1f 100644 (file)
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 16 * 1024;
 
-class DataConsumer {
-public:
-  DataConsumer(const uint8_t *data, size_t size) : data_(data), size_(size), pos_(0) {
-    memset(string_buf_, 0, sizeof(string_buf_));
-  }
-
-  bool empty() const { return pos_ >= size_; }
-
-  uint8_t consume_byte() {
-    if (pos_ >= size_) return 0;
-    return data_[pos_++];
-  }
-
-  const char* consume_string(size_t max_len) {
-    if (max_len > sizeof(string_buf_) - 1) max_len = sizeof(string_buf_) - 1;
-    size_t avail = size_ - pos_;
-    size_t len = (avail < max_len) ? avail : max_len;
-
-    size_t actual_len = 0;
-    while (actual_len < len && pos_ < size_) {
-      char c = static_cast<char>(data_[pos_++]);
-      if (c == '\0') break;
-      // Sanitize path characters for safety
-      if (c == '/' || c == '\\' || c == ':' || c == '\n' || c == '\r') {
-        c = '_';
-      }
-      string_buf_[actual_len++] = c;
-    }
-    string_buf_[actual_len] = '\0';
-    return string_buf_;
-  }
-
-  size_t remaining() const { return size_ - pos_; }
-
-private:
-  const uint8_t *data_;
-  size_t size_;
-  size_t pos_;
-  char string_buf_[256];
-};
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   if (len == 0 || len > kMaxInputSize) {
index abe2b22af67081ec14dabb319cbeb799e13fcf93..15d4434bc4ebf007ed5defdd752f8585d557f85b 100644 (file)
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 64 * 1024;
 
-class DataConsumer {
-public:
-  DataConsumer(const uint8_t *data, size_t size) : data_(data), size_(size), pos_(0) {
-    memset(string_buf_, 0, sizeof(string_buf_));
-  }
-
-  bool empty() const { return pos_ >= size_; }
-
-  uint8_t consume_byte() {
-    if (pos_ >= size_) return 0;
-    return data_[pos_++];
-  }
-
-  uint32_t consume_uint32() {
-    uint32_t val = 0;
-    for (int i = 0; i < 4 && pos_ < size_; i++) {
-      val |= static_cast<uint32_t>(data_[pos_++]) << (i * 8);
-    }
-    return val;
-  }
-
-  const char* consume_string(size_t max_len) {
-    if (max_len > sizeof(string_buf_) - 1) max_len = sizeof(string_buf_) - 1;
-    size_t avail = size_ - pos_;
-    size_t len = (avail < max_len) ? avail : max_len;
-
-    size_t actual_len = 0;
-    while (actual_len < len && pos_ < size_) {
-      char c = static_cast<char>(data_[pos_++]);
-      if (c == '\0') break;
-      string_buf_[actual_len++] = c;
-    }
-    string_buf_[actual_len] = '\0';
-    return string_buf_;
-  }
-
-  const uint8_t* consume_bytes(size_t *out_len, size_t max_len) {
-    size_t avail = size_ - pos_;
-    size_t len = (avail < max_len) ? avail : max_len;
-    const uint8_t *ptr = data_ + pos_;
-    pos_ += len;
-    *out_len = len;
-    return ptr;
-  }
-
-  size_t remaining() const { return size_ - pos_; }
-
-private:
-  const uint8_t *data_;
-  size_t size_;
-  size_t pos_;
-  char string_buf_[128];
-};
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   if (len < 10 || len > kMaxInputSize) {
@@ -110,15 +58,15 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
 
     archive_entry_set_pathname(entry, consumer.consume_string(32));
     archive_entry_set_mode(entry, S_IFREG | 0644);
-    archive_entry_set_uid(entry, consumer.consume_uint32() & 0xFFFF);
-    archive_entry_set_gid(entry, consumer.consume_uint32() & 0xFFFF);
+    archive_entry_set_uid(entry, consumer.consume_u32() & 0xFFFF);
+    archive_entry_set_gid(entry, consumer.consume_u32() & 0xFFFF);
 
-    size_t data_len;
-    const uint8_t *data = consumer.consume_bytes(&data_len, 256);
+    uint8_t data_buf[256];
+    size_t data_len = consumer.consume_bytes(data_buf, 256);
     archive_entry_set_size(entry, data_len);
 
     if (archive_write_header(writer, entry) == ARCHIVE_OK && data_len > 0) {
-      archive_write_data(writer, data, data_len);
+      archive_write_data(writer, data_buf, data_len);
     }
 
     archive_entry_free(entry);
index 148727c7d1c9936cde89f83a82abe178e9a7cda7..11e958030701cf64481d8139d876a43f08c6db63 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 256 * 1024;
 
index 7fe3a99dc57f5640f7bc8de4ae6ef36e6245e8fe..24731da1c680f9f42563c9d9b460af3366601958 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 32 * 1024;
 
index f046bab4875533c882e8f1804515f21ad6b83c3f..2ae7a167f68a795f99b59b22a23b8abbd173e693 100644 (file)
@@ -7,23 +7,11 @@
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 512 * 1024;
 
-struct Buffer {
-  const uint8_t *buf;
-  size_t len;
-};
-
-static ssize_t reader_callback(struct archive *a, void *client_data,
-                               const void **block) {
-  (void)a;
-  Buffer *buffer = reinterpret_cast<Buffer *>(client_data);
-  *block = buffer->buf;
-  ssize_t len = buffer->len;
-  buffer->len = 0;
-  return len;
-}
+
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   if (len == 0 || len > kMaxInputSize) {
@@ -38,7 +26,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   archive_read_support_format_warc(a);
   archive_read_support_filter_all(a);
 
-  Buffer buffer = {buf, len};
+  Buffer buffer = {buf, len, 0};
   if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
     archive_read_free(a);
     return 0;
index 8612a6e9d17e796af4fd3cfe45e1d966c6d4acb7..012c5a4f5596f84544975996ddcecca74d3af1d1 100644 (file)
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 64 * 1024;  // 64KB
 
 // Simple data consumer
-class DataConsumer {
-public:
-  DataConsumer(const uint8_t *data, size_t size) : data_(data), size_(size), pos_(0) {
-    memset(string_buf_, 0, sizeof(string_buf_));
-  }
-
-  bool empty() const { return pos_ >= size_; }
-
-  uint8_t consume_byte() {
-    if (pos_ >= size_) return 0;
-    return data_[pos_++];
-  }
-
-  uint32_t consume_uint32() {
-    uint32_t val = 0;
-    for (int i = 0; i < 4 && pos_ < size_; i++) {
-      val |= static_cast<uint32_t>(data_[pos_++]) << (i * 8);
-    }
-    return val;
-  }
-
-  int64_t consume_int64() {
-    int64_t val = 0;
-    for (int i = 0; i < 8 && pos_ < size_; i++) {
-      val |= static_cast<int64_t>(data_[pos_++]) << (i * 8);
-    }
-    return val;
-  }
-
-  const char* consume_string(size_t max_len) {
-    if (max_len > sizeof(string_buf_) - 1) max_len = sizeof(string_buf_) - 1;
-    size_t avail = size_ - pos_;
-    size_t len = (avail < max_len) ? avail : max_len;
-
-    size_t actual_len = 0;
-    while (actual_len < len && pos_ < size_) {
-      char c = static_cast<char>(data_[pos_++]);
-      if (c == '\0') break;
-      string_buf_[actual_len++] = c;
-    }
-    string_buf_[actual_len] = '\0';
-    return string_buf_;
-  }
-
-  const uint8_t* consume_bytes(size_t *out_len, size_t max_len) {
-    size_t avail = size_ - pos_;
-    size_t len = (avail < max_len) ? avail : max_len;
-    const uint8_t *ptr = data_ + pos_;
-    pos_ += len;
-    *out_len = len;
-    return ptr;
-  }
-
-  size_t remaining() const { return size_ - pos_; }
-
-private:
-  const uint8_t *data_;
-  size_t size_;
-  size_t pos_;
-  char string_buf_[256];
-};
 
 // Memory write callback
 static std::vector<uint8_t> *g_output = nullptr;
@@ -159,18 +99,18 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
     }
     archive_entry_set_mode(entry, mode);
 
-    archive_entry_set_uid(entry, consumer.consume_uint32() & 0xFFFF);
-    archive_entry_set_gid(entry, consumer.consume_uint32() & 0xFFFF);
-    archive_entry_set_mtime(entry, consumer.consume_int64(), 0);
+    archive_entry_set_uid(entry, consumer.consume_u32() & 0xFFFF);
+    archive_entry_set_gid(entry, consumer.consume_u32() & 0xFFFF);
+    archive_entry_set_mtime(entry, consumer.consume_i64(), 0);
 
     // For regular files, write some data
     if (S_ISREG(mode)) {
-      size_t data_len;
-      const uint8_t *data = consumer.consume_bytes(&data_len, 1024);
+      uint8_t data_buf[1024];
+      size_t data_len = consumer.consume_bytes(data_buf, 1024);
       archive_entry_set_size(entry, data_len);
 
       if (archive_write_header(a, entry) == ARCHIVE_OK && data_len > 0) {
-        archive_write_data(a, data, data_len);
+        archive_write_data(a, data_buf, data_len);
       }
     } else if (S_ISLNK(mode)) {
       archive_entry_set_symlink(entry, consumer.consume_string(64));
index 8f787432a7c5a819d50b509d8d7747e1675e784a..be889643140d500f8d41b00fa97ad96114226bee 100644 (file)
@@ -8,23 +8,11 @@
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 512 * 1024;  // 512KB
 
-struct Buffer {
-  const uint8_t *buf;
-  size_t len;
-};
 
-static ssize_t reader_callback(struct archive *a, void *client_data,
-                               const void **block) {
-  (void)a;
-  Buffer *buffer = reinterpret_cast<Buffer *>(client_data);
-  *block = buffer->buf;
-  ssize_t len = buffer->len;
-  buffer->len = 0;
-  return len;
-}
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   if (len == 0 || len > kMaxInputSize) {
@@ -41,7 +29,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   // Enable common filters
   archive_read_support_filter_all(a);
 
-  Buffer buffer = {buf, len};
+  Buffer buffer = {buf, len, 0};
   if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
     archive_read_free(a);
     return 0;
index 57331f4b72baaa2ce3d2873df7f8538e9374bd8e..15ce1f4855aeeb99c4fcd006c682f3ff0dce1f30 100644 (file)
@@ -8,23 +8,11 @@
 
 #include "archive.h"
 #include "archive_entry.h"
+#include "fuzz_helpers.h"
 
 static constexpr size_t kMaxInputSize = 512 * 1024;
 
-struct Buffer {
-  const uint8_t *buf;
-  size_t len;
-};
 
-static ssize_t reader_callback(struct archive *a, void *client_data,
-                               const void **block) {
-  (void)a;
-  Buffer *buffer = reinterpret_cast<Buffer *>(client_data);
-  *block = buffer->buf;
-  ssize_t len = buffer->len;
-  buffer->len = 0;
-  return len;
-}
 
 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   if (len == 0 || len > kMaxInputSize) {
@@ -47,7 +35,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) {
   // Enable ZIP options
   archive_read_set_options(a, "zip:ignorecrc32");
 
-  Buffer buffer = {buf, len};
+  Buffer buffer = {buf, len, 0};
   if (archive_read_open(a, &buffer, NULL, reader_callback, NULL) != ARCHIVE_OK) {
     archive_read_free(a);
     return 0;