mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
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).
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user