51 lines
1.6 KiB
C++
51 lines
1.6 KiB
C++
// libFuzzer entry point: drive the full load → inspect → render → select path
|
|
// with arbitrary bytes, so the fuzzer can find crashes, OOMs, and UB in the
|
|
// PDF parsing and rendering code.
|
|
//
|
|
// Build with a Clang toolchain via the `fuzz-linux` preset (see engine/fuzz/
|
|
// README.md). Every operation is wrapped so a clean error never aborts the run —
|
|
// only a real crash (caught by the sanitizer) should stop the fuzzer.
|
|
|
|
#include "pdfengine/hardened_limits.h"
|
|
#include "pdfengine/pdf_document.hpp"
|
|
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <vector>
|
|
|
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
|
using namespace pdfengine;
|
|
|
|
if (!limits::documentSizeOk(size)) return 0;
|
|
|
|
std::vector<uint8_t> bytes(data, data + size);
|
|
auto doc = PdfDocument::loadFromMemory(bytes, "");
|
|
if (!doc) return 0;
|
|
PdfDocument& d = **doc;
|
|
|
|
const int pages = d.pageCount();
|
|
if (!limits::pageCountOk(pages)) return 0;
|
|
|
|
(void)d.metadata();
|
|
(void)d.extractOutline();
|
|
|
|
const int limit = pages < 3 ? pages : 3; // bound work per input
|
|
for (int i = 0; i < limit; ++i) {
|
|
auto page = d.getPage(i);
|
|
if (!page) continue;
|
|
PdfPage& p = **page;
|
|
|
|
(void)p.render(72);
|
|
(void)p.extractText();
|
|
(void)p.extractAnnotations();
|
|
|
|
auto glyphs = p.orderedGlyphs();
|
|
if (glyphs && !glyphs->empty()) {
|
|
const auto& g = glyphs->front();
|
|
(void)p.hitGlyph(g.x, g.y);
|
|
(void)p.selectRange(g.x, g.y, g.x + 50.0, g.y + 20.0);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|