Compare commits

...

1 Commits

Author SHA1 Message Date
Bruno Postle aa1a893285 IfcParse: don't abort when a string literal runs off the end of the file
read_string() looped on stream_.peek() to scan a STEP string/binary
literal, assuming peek() returns 0 at EOF. It actually throws
std::out_of_range("peek at EOF"). A fuzzed file with a missing or
relocated closing quote leaves the decoder with no terminator before
it, so the loop runs the cursor past the end of the buffer and the
exception comes up uncaught, aborting the process.

Check stream_.eof() in the loop condition so an unterminated literal
ends the scan at EOF instead of throwing, and log a SYN warning for
the unterminated case (tracked via a "closed" flag so this doesn't
fire for the pre-existing null-byte early exit).
2026-07-16 22:42:58 +01:00
+6 -1
View File
@@ -98,8 +98,9 @@ namespace {
int codepage = 1;
unsigned int hex = 0;
unsigned int hex_count = 0;
bool closed = false;
while ((current_char = stream_.peek()) != 0) {
while (!stream_.eof() && (current_char = stream_.peek()) != 0) {
if (EXPECTS_CHARACTER(parse_state)) {
builder_.push_back(IfcUtil::convert_codepage(codepage, current_char + 0x80));
parse_state = 0;
@@ -162,6 +163,7 @@ namespace {
(current_char == '\\' && parse_state == FIRST_SOLIDUS) ||
(current_char == '\'' && parse_state == APOSTROPHE))) {
if (parse_state == APOSTROPHE && current_char != '\'') {
closed = true;
break;
}
throw IfcInvalidTokenException(stream_.tell(), current_char);
@@ -171,6 +173,9 @@ namespace {
}
stream_.increment();
}
if (!closed && stream_.eof()) {
logger.Warning("SYN", 41, "Unterminated string literal at offset " + std::to_string(stream_.tell()));
}
builder_.push_back('\'');
if (mode == IfcParse::IfcCharacterDecoder::UTF8) {