diff options
| author | Martin Matuska <mm@FreeBSD.org> | 2020-05-20 16:13:02 +0000 | 
|---|---|---|
| committer | Martin Matuska <mm@FreeBSD.org> | 2020-05-20 16:13:02 +0000 | 
| commit | e117869ad30ae48ff0943c9497c626fddbc899ba (patch) | |
| tree | 432435807803593d9403f8d1e831a5ce2dc5cc33 /contrib/oss-fuzz/libarchive_fuzzer.cc | |
| parent | d0916f2d0df0ec41077369eeaefeba50e5e38b0d (diff) | |
Diffstat (limited to 'contrib/oss-fuzz/libarchive_fuzzer.cc')
| -rw-r--r-- | contrib/oss-fuzz/libarchive_fuzzer.cc | 49 | 
1 files changed, 49 insertions, 0 deletions
diff --git a/contrib/oss-fuzz/libarchive_fuzzer.cc b/contrib/oss-fuzz/libarchive_fuzzer.cc new file mode 100644 index 0000000000000..bc7f865b69c57 --- /dev/null +++ b/contrib/oss-fuzz/libarchive_fuzzer.cc @@ -0,0 +1,49 @@ +#include <stddef.h> +#include <stdint.h> +#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; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) { +  int ret; +  ssize_t r; +  struct archive *a = archive_read_new(); + +  archive_read_support_filter_all(a); +  archive_read_support_format_all(a); + +  Buffer buffer = {buf, len}; +  archive_read_open(a, &buffer, NULL, reader_callback, NULL); + +  std::vector<uint8_t> data_buffer(getpagesize(), 0); +  struct archive_entry *entry; +  while(1) { +    ret = archive_read_next_header(a, &entry); +    if (ret == ARCHIVE_EOF || ret == ARCHIVE_FATAL) +      break; +    if (ret == ARCHIVE_RETRY) +      continue; +    while ((r = archive_read_data(a, data_buffer.data(), +            data_buffer.size())) > 0) +      ; +    if (r == ARCHIVE_FATAL) +      break; +  } + +  archive_read_free(a); +  return 0; +}  | 
