pofParser: added bound check tests

This commit is contained in:
Gwenhael Goavec-Merou 2026-04-01 10:58:22 +02:00
parent ff9e10085a
commit a56b9f61ca
1 changed files with 40 additions and 2 deletions

View File

@ -67,6 +67,7 @@ void POFParser::displayHeader()
int POFParser::parse() int POFParser::parse()
{ {
const uint32_t file_size = static_cast<uint32_t>(_file_size);
uint8_t *ptr = (uint8_t *)_raw_data.data(); uint8_t *ptr = (uint8_t *)_raw_data.data();
uint32_t pos = 0; uint32_t pos = 0;
@ -77,6 +78,10 @@ int POFParser::parse()
pos += 4; pos += 4;
/* unknown */ /* unknown */
if (_verbose) { if (_verbose) {
if ((pos + 4) > file_size) {
printError("POFParser: Can't read first section");
return -1;
}
uint32_t first_section = ARRAY2INT32(ptr); uint32_t first_section = ARRAY2INT32(ptr);
printf("first section: %08x %4u\n", first_section, first_section); printf("first section: %08x %4u\n", first_section, first_section);
} }
@ -84,18 +89,39 @@ int POFParser::parse()
pos += 4; pos += 4;
/* number of packets */ /* number of packets */
if (_verbose) { if (_verbose) {
if ((pos + 4) > file_size) {
printError("POFParser: Can't read first section");
return -1;
}
uint32_t num_packets = ARRAY2INT32(ptr); uint32_t num_packets = ARRAY2INT32(ptr);
printf("number of packets: %08x %4u\n", num_packets, num_packets); printf("number of packets: %08x %4u\n", num_packets, num_packets);
} }
pos += 4; pos += 4;
/* 16bit code + 32bits size + content */ /* 16bit code + 32bits size + content */
while (pos < static_cast<uint32_t>(_file_size)) { while (pos < file_size) {
if ((pos + 2) > file_size) {
printError("POFParser: Bound check failure: can't read flag");
return -1;
}
uint16_t flag = ARRAY2INT16((&_raw_data.data()[pos])); uint16_t flag = ARRAY2INT16((&_raw_data.data()[pos]));
pos += 2; pos += 2;
if ((pos + 4) > file_size) {
printError("POFParser: Bound check failure: can't read size");
return -1;
}
uint32_t size = ARRAY2INT32((&_raw_data.data()[pos])); uint32_t size = ARRAY2INT32((&_raw_data.data()[pos]));
pos += 4; pos += 4;
pos += parseSection(flag, pos, size); if ((pos >= file_size) || ((pos + size) > file_size)) {
printError("POFParser: Bound check: can't parse section");
return -1;
}
uint32_t ret = parseSection(flag, pos, size);
if (ret != size) {
printError("POFParser: parseSection Failed");
return -1;
}
pos += ret;
} }
/* update pointers to memory area */ /* update pointers to memory area */
@ -147,6 +173,10 @@ uint32_t POFParser::parseSection(uint16_t flag, uint32_t pos, uint32_t size)
_hdr["design_name"] = _raw_data.substr(pos, size); _hdr["design_name"] = _raw_data.substr(pos, size);
break; break;
case 0x08: // last packet: CRC ? case 0x08: // last packet: CRC ?
if (size < 2) {
printError("POFParser: flag 0x08 failed size too small");
return 0;
}
_hdr["maybeCRC"] = std::to_string(ARRAY2INT16((&_raw_data.data()[pos]))); _hdr["maybeCRC"] = std::to_string(ARRAY2INT16((&_raw_data.data()[pos])));
break; break;
case 0x11: // cfg data case 0x11: // cfg data
@ -154,6 +184,10 @@ uint32_t POFParser::parseSection(uint16_t flag, uint32_t pos, uint32_t size)
// followed by UFM/CFM/DSM data // followed by UFM/CFM/DSM data
if (_verbose) { if (_verbose) {
content = _raw_data.substr(pos, size); content = _raw_data.substr(pos, size);
if ((3 * 4) > size) {
printError("POFParser: can't display 0x11 area");
return -1;
}
uint32_t val0 = ARRAY2INT32((&content.c_str()[0])); uint32_t val0 = ARRAY2INT32((&content.c_str()[0]));
uint32_t val1 = ARRAY2INT32((&content.c_str()[4])); uint32_t val1 = ARRAY2INT32((&content.c_str()[4]));
uint32_t val2 = ARRAY2INT32((&content.c_str()[8])); uint32_t val2 = ARRAY2INT32((&content.c_str()[8]));
@ -170,6 +204,10 @@ uint32_t POFParser::parseSection(uint16_t flag, uint32_t pos, uint32_t size)
case 0x13: // contains usercode / checksum case 0x13: // contains usercode / checksum
_hdr["usercode"] = std::to_string(ARRAY2INT32((&_raw_data.data()[pos+size-4]))); _hdr["usercode"] = std::to_string(ARRAY2INT32((&_raw_data.data()[pos+size-4])));
if (_verbose) { if (_verbose) {
if (size < 12) {
printf("POFParser: Can't display flag 0x13 area");
return -1;
}
t = _raw_data.substr(pos, size); t = _raw_data.substr(pos, size);
for (size_t i = 0; i < t.size(); i++) for (size_t i = 0; i < t.size(); i++)
printf("%02x ", static_cast<uint8_t>(t[i])); printf("%02x ", static_cast<uint8_t>(t[i]));