mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-30 03:59:55 +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();
|
std::string& str = token.lexer->GetTempString();
|
||||||
token.lexer->TokenString(token.startPos, str);
|
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
|
//remove start+end characters in-place
|
||||||
str.erase(str.end() - 1);
|
str.erase(str.end() - 1);
|
||||||
str.erase(str.begin());
|
str.erase(str.begin());
|
||||||
|
|||||||
Reference in New Issue
Block a user