mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +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));
|
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
|
in_memory_attribute_storage storage(coerce_attribute_count
|
||||||
? (decl != nullptr
|
? (decl != nullptr
|
||||||
? (std::min)(parameter_types.size(), tokens_.size())
|
? parameter_types.size()
|
||||||
: tokens_.size())
|
: tokens_.size())
|
||||||
: tokens_.size()
|
: tokens_.size()
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user