fix(message): guard parsing and command args

This commit is contained in:
scawful
2025-12-22 14:55:14 -05:00
parent 2fd740e529
commit c8ec329f14

View File

@@ -217,6 +217,14 @@ DictionaryEntry FindRealDictionaryEntry(
absl::StatusOr<MessageData> ParseSingleMessage( absl::StatusOr<MessageData> ParseSingleMessage(
const std::vector<uint8_t>& rom_data, int* current_pos) { const std::vector<uint8_t>& rom_data, int* current_pos) {
if (current_pos == nullptr) {
return absl::InvalidArgumentError("current_pos is null");
}
if (*current_pos < 0 ||
static_cast<size_t>(*current_pos) >= rom_data.size()) {
return absl::OutOfRangeError("current_pos is out of range");
}
MessageData message_data; MessageData message_data;
int pos = *current_pos; int pos = *current_pos;
uint8_t current_byte; uint8_t current_byte;
@@ -226,7 +234,7 @@ absl::StatusOr<MessageData> ParseSingleMessage(
std::string current_message_parsed; std::string current_message_parsed;
// Read the message data // Read the message data
while (true) { while (pos < static_cast<int>(rom_data.size())) {
current_byte = rom_data[pos++]; current_byte = rom_data[pos++];
if (current_byte == kMessageTerminator) { if (current_byte == kMessageTerminator) {
@@ -242,9 +250,10 @@ absl::StatusOr<MessageData> ParseSingleMessage(
current_message_raw.clear(); current_message_raw.clear();
current_message_parsed.clear(); current_message_parsed.clear();
break; *current_pos = pos;
return message_data;
} else if (current_byte == 0xFF) { } else if (current_byte == 0xFF) {
break; return absl::InvalidArgumentError("message terminator not found");
} }
temp_bytes_raw.push_back(current_byte); temp_bytes_raw.push_back(current_byte);
@@ -252,8 +261,28 @@ absl::StatusOr<MessageData> ParseSingleMessage(
// Check for command. // Check for command.
auto text_element = FindMatchingCommand(current_byte); auto text_element = FindMatchingCommand(current_byte);
if (text_element != std::nullopt) { if (text_element != std::nullopt) {
current_message_raw.append(text_element->GetParamToken()); temp_bytes_parsed.push_back(current_byte);
current_message_parsed.append(text_element->GetParamToken()); if (text_element->HasArgument) {
if (pos >= static_cast<int>(rom_data.size())) {
return absl::OutOfRangeError("message command argument out of range");
}
uint8_t arg_byte = rom_data[pos++];
temp_bytes_raw.push_back(arg_byte);
temp_bytes_parsed.push_back(arg_byte);
current_message_raw.append(text_element->GetParamToken(arg_byte));
current_message_parsed.append(text_element->GetParamToken(arg_byte));
} else {
current_message_raw.append(text_element->GetParamToken());
current_message_parsed.append(text_element->GetParamToken());
}
continue;
}
// Check for special characters.
if (auto special_element = FindMatchingSpecial(current_byte);
special_element != std::nullopt) {
current_message_raw.append(special_element->GetParamToken());
current_message_parsed.append(special_element->GetParamToken());
temp_bytes_parsed.push_back(current_byte); temp_bytes_parsed.push_back(current_byte);
continue; continue;
} }
@@ -261,24 +290,12 @@ absl::StatusOr<MessageData> ParseSingleMessage(
// Check for dictionary. // Check for dictionary.
int8_t dictionary = FindDictionaryEntry(current_byte); int8_t dictionary = FindDictionaryEntry(current_byte);
if (dictionary >= 0) { if (dictionary >= 0) {
current_message_raw.append("["); std::string token = absl::StrFormat(
current_message_raw.append(DICTIONARYTOKEN); "[%s:%02X]", DICTIONARYTOKEN,
current_message_raw.append(":"); static_cast<unsigned char>(dictionary));
current_message_raw.append( current_message_raw.append(token);
util::HexWord(static_cast<unsigned char>(dictionary))); current_message_parsed.append(token);
current_message_raw.append("]"); temp_bytes_parsed.push_back(current_byte);
auto mutable_rom_data = const_cast<uint8_t*>(rom_data.data());
uint32_t address = Get24LocalFromPC(
mutable_rom_data, kPointersDictionaries + (dictionary * 2));
uint32_t address_end = Get24LocalFromPC(
mutable_rom_data, kPointersDictionaries + ((dictionary + 1) * 2));
for (uint32_t i = address; i < address_end; i++) {
temp_bytes_parsed.push_back(rom_data[i]);
current_message_parsed.append(ParseTextDataByte(rom_data[i]));
}
continue; continue;
} }
@@ -293,7 +310,7 @@ absl::StatusOr<MessageData> ParseSingleMessage(
} }
*current_pos = pos; *current_pos = pos;
return message_data; return absl::InvalidArgumentError("message terminator not found");
} }
std::vector<std::string> ParseMessageData( std::vector<std::string> ParseMessageData(