mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-08 17:01:40 +00:00
Size entity attribute storage to schema arity, not token count
When a STEP instance has fewer attribute tokens than its schema declares
(commonly from corrupted/malformed syntax), parse_context::construct()
sized the in-memory attribute storage to the smaller token count instead
of the schema's attribute count. This left the storage's last N attribute
slots simply nonexistent rather than blank, so any later read of one of
those trailing attributes by index threw an uncaught IfcParse::IfcException
("Index N is out of range for storage of size N") that terminated the
whole process (SIGABRT) instead of being handled as a parse warning.
Fix: when the schema declaration is known, size the storage to the
schema's attribute count. Indices beyond the number of tokens found are
left at their existing default-constructed blank value (the storage
constructor already blank-initializes every slot), so a truncated
instance now degrades to blank values for its missing trailing
attributes, matching the parser's existing "expected N attribute values,
found M" warning intent instead of crashing.
Reproduced with the fuzzing script attached to #5679: single-byte
mutations of a minimal IFC4 file that corrupt the IFCPROJECT instance's
token stream reliably aborted IfcConvert with this exact exception before
the fix, and now parse with a logged syntax error and exit code 0.
Fixes #5679
Generated with the assistance of an AI coding tool.
This commit is contained in:
committed by
Thomas Krijnen
parent
6603c8459a
commit
c68e4a0eee
@@ -273,9 +273,18 @@ IfcEntityInstanceData IfcParse::parse_context::construct(boost::optional<size_t>
|
||||
return IfcEntityInstanceData(in_memory_attribute_storage(0));
|
||||
}
|
||||
|
||||
// When the schema declaration is known, size the storage to the schema's
|
||||
// attribute count rather than the (possibly smaller) number of tokens
|
||||
// actually found. Attributes are only assigned for indices covered by
|
||||
// tokens_ below; any remaining trailing indices stay at their
|
||||
// default-constructed blank value. This keeps every instance's storage
|
||||
// consistent with its schema arity, so that a malformed/truncated
|
||||
// instance (e.g. corrupted STEP syntax dropping a trailing attribute)
|
||||
// degrades to a blank value for the missing attribute instead of an
|
||||
// out-of-range access when that attribute is later read by index.
|
||||
in_memory_attribute_storage storage(coerce_attribute_count
|
||||
? (decl != nullptr
|
||||
? (std::min)(parameter_types.size(), tokens_.size())
|
||||
? parameter_types.size()
|
||||
: tokens_.size())
|
||||
: tokens_.size()
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user