Fix leak of IfcSpfLexer when read_from_stream returns early or throws

tokens was a raw new'd pointer only freed at the very end of
in_memory_file_storage::read_from_stream(). Every early return along the
way (e.g. NO_HEADER / UNSUPPORTED_SCHEMA / no matching schema, which is
almost any malformed input) skipped that delete and leaked it, along with
whatever exceptions escaping readInstance() during the scan loop.

Own it via a local unique_ptr for the duration of the function instead, so
every exit path frees it.

Found via fuzzing (see the ifcfuzz harness in src/ifcfuzz/).
This commit is contained in:
Bruno Postle
2026-07-18 18:04:46 +01:00
parent 71a598e63a
commit f54724502a
+8 -2
View File
@@ -1584,7 +1584,12 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead
return;
}
tokens = new IfcSpfLexer(s, logger());
// Owned via RAII so that any early return or exception while scanning
// the file (e.g. a malformed header, see fuzzer-z6u) still frees the
// lexer instead of leaking it; `tokens` itself stays a raw pointer since
// it's read by in_memory_file_storage::load() during the scan below.
std::unique_ptr<IfcSpfLexer> tokens_owner(new IfcSpfLexer(s, logger()));
tokens = tokens_owner.get();
std::vector<std::string> schemas;
@@ -1689,7 +1694,8 @@ void IfcParse::impl::in_memory_file_storage::read_from_stream(IfcParse::FileRead
logger().Status("\rDone scanning file ");
delete tokens;
tokens_owner.reset();
tokens = nullptr;
if (good_ != file_open_status::SUCCESS) {
return;