fsparser: check lines length
This commit is contained in:
parent
78ab322615
commit
7a69d8353a
|
|
@ -42,30 +42,50 @@ int FsParser::parseHeader()
|
||||||
std::istringstream lineStream(_raw_data);
|
std::istringstream lineStream(_raw_data);
|
||||||
|
|
||||||
while (std::getline(lineStream, buffer, '\n')) {
|
while (std::getline(lineStream, buffer, '\n')) {
|
||||||
|
/* store full/real file lenght */
|
||||||
ret += buffer.size() + 1;
|
ret += buffer.size() + 1;
|
||||||
|
|
||||||
|
/* FIXME: a line can't be empty -> error */
|
||||||
|
if (buffer.empty())
|
||||||
|
break;
|
||||||
|
/* dos file */
|
||||||
|
if (buffer.back() == '\r')
|
||||||
|
buffer.pop_back();
|
||||||
|
|
||||||
|
/* FIXME: a line can't be empty -> error */
|
||||||
if (buffer.empty())
|
if (buffer.empty())
|
||||||
break;
|
break;
|
||||||
/* drop all comment, base analyze on header */
|
/* drop all comment, base analyze on header */
|
||||||
if (buffer[0] == '/')
|
if (buffer[0] == '/')
|
||||||
continue;
|
continue;
|
||||||
if (buffer[buffer.size()-1] == '\r')
|
|
||||||
buffer.pop_back();
|
|
||||||
|
|
||||||
/* store each line in dedicated buffer for future use
|
const size_t line_length = buffer.size();
|
||||||
*/
|
|
||||||
|
/* store each line in dedicated buffer for future use */
|
||||||
_lstRawData.push_back(buffer);
|
_lstRawData.push_back(buffer);
|
||||||
|
|
||||||
|
/* only headers are parsed by next portion of code */
|
||||||
if (!in_header)
|
if (!in_header)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* a line must have at least 8 1/0 for the key */
|
||||||
|
if (line_length < 8) {
|
||||||
|
printError("FsParser: Potential corrupted file");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
uint8_t c = bitToVal(buffer.substr(0, 8).c_str(), 8);
|
uint8_t c = bitToVal(buffer.substr(0, 8).c_str(), 8);
|
||||||
uint8_t key = c & 0x7F;
|
uint8_t key = c & 0x7F;
|
||||||
uint64_t val = bitToVal(buffer.c_str(), buffer.size());
|
/* the line length depends on key/information */
|
||||||
|
uint64_t val = bitToVal(buffer.c_str(), line_length);
|
||||||
|
|
||||||
char __buf[10];
|
char __buf[10];
|
||||||
int __buf_valid_bytes;
|
int __buf_valid_bytes;
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 0x06: /* idCode */
|
case 0x06: /* idCode */
|
||||||
|
if (line_length != 64) {
|
||||||
|
printError("FsParser: length too short for key 0x06");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
_idcode = (0xffffffff & val);
|
_idcode = (0xffffffff & val);
|
||||||
__buf_valid_bytes = snprintf(__buf, 9, "%08x", _idcode);
|
__buf_valid_bytes = snprintf(__buf, 9, "%08x", _idcode);
|
||||||
_hdr["idcode"] = std::string(__buf, __buf_valid_bytes);
|
_hdr["idcode"] = std::string(__buf, __buf_valid_bytes);
|
||||||
|
|
@ -77,9 +97,17 @@ int FsParser::parseHeader()
|
||||||
_hdr["CheckSum"].resize(8, ' ');
|
_hdr["CheckSum"].resize(8, ' ');
|
||||||
break;
|
break;
|
||||||
case 0x0B: /* only present when bit_security is set */
|
case 0x0B: /* only present when bit_security is set */
|
||||||
|
if (line_length != 32) {
|
||||||
|
printError("FsParser: length too short for key 0x0B");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
_hdr["SecurityBit"] = "ON";
|
_hdr["SecurityBit"] = "ON";
|
||||||
break;
|
break;
|
||||||
case 0x10: {
|
case 0x10: {
|
||||||
|
if (line_length != 64) {
|
||||||
|
printError("FsParser: length too short for key 0x10");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
unsigned rate = (val >> 16) & 0xff;
|
unsigned rate = (val >> 16) & 0xff;
|
||||||
if (rate) {
|
if (rate) {
|
||||||
rate &= 0x7f;
|
rate &= 0x7f;
|
||||||
|
|
@ -96,8 +124,16 @@ int FsParser::parseHeader()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x12: /* unknown */
|
case 0x12: /* unknown */
|
||||||
|
if (line_length != 32) {
|
||||||
|
printError("FsParser: length too short for key 0x12");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0x51:
|
case 0x51:
|
||||||
|
if (line_length != 64) {
|
||||||
|
printError("FsParser: length too short for key 0x51");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
[23:16] : a value used to replace 8x 0x00 in compress mode
|
[23:16] : a value used to replace 8x 0x00 in compress mode
|
||||||
[15: 8] : a value used to replace 4x 0x00 in compress mode
|
[15: 8] : a value used to replace 4x 0x00 in compress mode
|
||||||
|
|
@ -108,6 +144,10 @@ int FsParser::parseHeader()
|
||||||
_2Zero = 0xff & (val >> 0);
|
_2Zero = 0xff & (val >> 0);
|
||||||
break;
|
break;
|
||||||
case 0x52: /* documentation issue */
|
case 0x52: /* documentation issue */
|
||||||
|
if (line_length != 64) {
|
||||||
|
printError("FsParser: length too short for key 0x52");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
uint32_t flash_addr;
|
uint32_t flash_addr;
|
||||||
flash_addr = val & 0xffffffff;
|
flash_addr = val & 0xffffffff;
|
||||||
__buf_valid_bytes = snprintf(__buf, 9, "%08x", flash_addr);
|
__buf_valid_bytes = snprintf(__buf, 9, "%08x", flash_addr);
|
||||||
|
|
@ -117,6 +157,10 @@ int FsParser::parseHeader()
|
||||||
break;
|
break;
|
||||||
case 0x3B: /* last header line with crc and cfg data length */
|
case 0x3B: /* last header line with crc and cfg data length */
|
||||||
/* documentation issue */
|
/* documentation issue */
|
||||||
|
if (line_length != 32) {
|
||||||
|
printError("FsParser: length too short for key 0x3B");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
in_header = false;
|
in_header = false;
|
||||||
uint8_t crc;
|
uint8_t crc;
|
||||||
crc = 0x01 & (val >> 23);
|
crc = 0x01 & (val >> 23);
|
||||||
|
|
@ -148,8 +192,14 @@ int FsParser::parse()
|
||||||
* if true 0 -> 0, 1 -> 1
|
* if true 0 -> 0, 1 -> 1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
_bit_data.reserve(_raw_data.size() / 8);
|
||||||
for (auto &&line : _lstRawData) {
|
for (auto &&line : _lstRawData) {
|
||||||
for (size_t i = 0; i < line.size(); i += 8) {
|
const size_t line_length = line.size();
|
||||||
|
if ((line_length % 8) != 0) {
|
||||||
|
printError("FsParser: truncated line in bitstream data");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < line_length; i += 8) {
|
||||||
uint8_t data = bitToVal(&line[i], 8);
|
uint8_t data = bitToVal(&line[i], 8);
|
||||||
_bit_data.push_back((_reverseByte) ? reverseByte(data) : data);
|
_bit_data.push_back((_reverseByte) ? reverseByte(data) : data);
|
||||||
}
|
}
|
||||||
|
|
@ -236,9 +286,20 @@ int FsParser::parse()
|
||||||
for (auto &&ll = _lstRawData.begin();
|
for (auto &&ll = _lstRawData.begin();
|
||||||
ll != _lstRawData.end(); ll++) {
|
ll != _lstRawData.end(); ll++) {
|
||||||
std::string l = "";
|
std::string l = "";
|
||||||
std::string line = *ll;
|
const std::string &line = *ll;
|
||||||
|
const size_t line_length = line.size();
|
||||||
|
if (line_length < static_cast<size_t>(drop)) {
|
||||||
|
printError("FsParser: truncated configuration line");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
if (_compressed) {
|
if (_compressed) {
|
||||||
for (size_t i = 0; i < line.size()-drop; i+=8) {
|
const size_t payload_len = line_length - drop;
|
||||||
|
if ((payload_len % 8) != 0) {
|
||||||
|
printError("FsParser: compressed line is not byte aligned");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
l.reserve(payload_len * 8);
|
||||||
|
for (size_t i = 0; i < payload_len; i += 8) {
|
||||||
uint8_t c = bitToVal((const char *)&line[i], 8);
|
uint8_t c = bitToVal((const char *)&line[i], 8);
|
||||||
if (c == _8Zero)
|
if (c == _8Zero)
|
||||||
l += std::string(8*8, '0');
|
l += std::string(8*8, '0');
|
||||||
|
|
@ -250,15 +311,24 @@ int FsParser::parse()
|
||||||
l += line.substr(i, 8);
|
l += line.substr(i, 8);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
l = line.substr(0, line.size() - drop);
|
l = line.substr(0, line_length - drop);
|
||||||
}
|
}
|
||||||
|
const size_t l_length = l.size();
|
||||||
|
|
||||||
/* store bit for checksum */
|
/* store bit for checksum */
|
||||||
tmp += l.substr(padding, l.size() - padding);
|
if (static_cast<size_t>(padding) > l_length) {
|
||||||
|
printError("FsParser: invalid padding for configuration line");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
tmp += l.substr(padding, l_length - padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* checksum */
|
/* checksum */
|
||||||
_checksum = 0;
|
_checksum = 0;
|
||||||
|
if ((tmp.size() % 16) != 0) {
|
||||||
|
printError("FsParser: checksum data is truncated");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
for (uint32_t pos = 0; pos < tmp.size(); pos+=16)
|
for (uint32_t pos = 0; pos < tmp.size(); pos+=16)
|
||||||
_checksum += (uint16_t)bitToVal(&tmp[pos], 16);
|
_checksum += (uint16_t)bitToVal(&tmp[pos], 16);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue