mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 10:57:49 +00:00
IfcParse: don't strip delimiters from a single-character token #5683
asStringRef removes the first and last characters of a string, enumeration or binary token to drop the delimiters, guarded only by !str.empty(). A malformed single-character token (e.g. a bare '.' left when a fuzzer turns '.PHYSICAL.' into '.)HYSICAL.') has length 1, so the first erase empties the string and the second erase(str.begin()) runs on an empty string. That is undefined behaviour: benign on a normal build, but it aborts (or throws std::length_error from a later append) under a hardened libstdc++ with _GLIBCXX_ASSERTIONS, which is why this file only segfaulted on the Fedora build. Require at least two characters before stripping. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
committed by
Thomas Krijnen
parent
5e539890f1
commit
d2381ad6c6
@@ -449,7 +449,14 @@ const std::string& TokenFunc::asStringRef(const Token& token) {
|
||||
}
|
||||
std::string& str = token.lexer->GetTempString();
|
||||
token.lexer->TokenString(token.startPos, str);
|
||||
if ((isString(token) || isEnumeration(token) || isBinary(token)) && !str.empty()) {
|
||||
// A well-formed string/enumeration/binary token has both delimiters (e.g.
|
||||
// '...', .XXX., "...."), so at least two characters. Malformed input from a
|
||||
// fuzzer can produce a single-character token (e.g. a bare '.' left by
|
||||
// ".)" instead of ".PHYSICAL."); stripping both ends would then erase past
|
||||
// the end of an already-empty string, which is undefined behaviour and
|
||||
// aborts under hardened standard libraries (_GLIBCXX_ASSERTIONS). Require
|
||||
// two characters before stripping. See #5683.
|
||||
if ((isString(token) || isEnumeration(token) || isBinary(token)) && str.size() >= 2) {
|
||||
//remove start+end characters in-place
|
||||
str.erase(str.end() - 1);
|
||||
str.erase(str.begin());
|
||||
|
||||
Reference in New Issue
Block a user