/******************************************************************************** * * * This file is part of IfcOpenShell. * * * * IfcOpenShell is free software: you can redistribute it and/or modify * * it under the terms of the Lesser GNU General Public License as published by * * the Free Software Foundation, either version 3.0 of the License, or * * (at your option) any later version. * * * * IfcOpenShell is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * Lesser GNU General Public License for more details. * * * * You should have received a copy of the Lesser GNU General Public License * * along with this program. If not, see . * * * ********************************************************************************/ // libFuzzer entry point for IfcParse::IfcFile. Parses the input entirely // in-memory (no subprocess, no temp files) so a coverage-guided fuzzer can // reach the tokenizer and argument parser directly instead of only ever // observing IfcConvert's exit code. #include "ifcparse/IfcFile.h" #include #include #include #include extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { if (size == 0 || size > static_cast(std::numeric_limits::max())) { return 0; } try { IfcParse::IfcFile file(const_cast(static_cast(data)), static_cast(size)); if (file.good()) { // IfcOpenShell parses lazily: merely constructing IfcFile only // tokenizes the header and indexes instance byte offsets. // toString() forces every attribute of every instance to be // fully parsed, which is where most tokenizer/argument bugs // would actually be reachable. std::ostringstream discard; for (const auto& entity : file) { try { entity.second->toString(discard); } catch (const std::exception&) { // Malformed attributes are expected on fuzzed input. } } } } catch (const std::exception&) { // IfcException (and friends) is expected control flow for malformed // input, not a bug. Only crashes caught by ASan/UBSan/libFuzzer // itself - which bypass try/catch - are findings. } return 0; }