Skip to content

Commit 7a69d83

Browse files
committed
fsparser: check lines length
1 parent 78ab322 commit 7a69d83

1 file changed

Lines changed: 80 additions & 10 deletions

File tree

src/fsparser.cpp

Lines changed: 80 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,30 +42,50 @@ int FsParser::parseHeader()
4242
std::istringstream lineStream(_raw_data);
4343

4444
while (std::getline(lineStream, buffer, '\n')) {
45+
/* store full/real file lenght */
4546
ret += buffer.size() + 1;
47+
48+
/* FIXME: a line can't be empty -> error */
49+
if (buffer.empty())
50+
break;
51+
/* dos file */
52+
if (buffer.back() == '\r')
53+
buffer.pop_back();
54+
55+
/* FIXME: a line can't be empty -> error */
4656
if (buffer.empty())
4757
break;
4858
/* drop all comment, base analyze on header */
4959
if (buffer[0] == '/')
5060
continue;
51-
if (buffer[buffer.size()-1] == '\r')
52-
buffer.pop_back();
5361

54-
/* store each line in dedicated buffer for future use
55-
*/
62+
const size_t line_length = buffer.size();
63+
64+
/* store each line in dedicated buffer for future use */
5665
_lstRawData.push_back(buffer);
5766

67+
/* only headers are parsed by next portion of code */
5868
if (!in_header)
5969
continue;
6070

71+
/* a line must have at least 8 1/0 for the key */
72+
if (line_length < 8) {
73+
printError("FsParser: Potential corrupted file");
74+
return 0;
75+
}
6176
uint8_t c = bitToVal(buffer.substr(0, 8).c_str(), 8);
6277
uint8_t key = c & 0x7F;
63-
uint64_t val = bitToVal(buffer.c_str(), buffer.size());
78+
/* the line length depends on key/information */
79+
uint64_t val = bitToVal(buffer.c_str(), line_length);
6480

6581
char __buf[10];
6682
int __buf_valid_bytes;
6783
switch (key) {
6884
case 0x06: /* idCode */
85+
if (line_length != 64) {
86+
printError("FsParser: length too short for key 0x06");
87+
return 0;
88+
}
6989
_idcode = (0xffffffff & val);
7090
__buf_valid_bytes = snprintf(__buf, 9, "%08x", _idcode);
7191
_hdr["idcode"] = std::string(__buf, __buf_valid_bytes);
@@ -77,9 +97,17 @@ int FsParser::parseHeader()
7797
_hdr["CheckSum"].resize(8, ' ');
7898
break;
7999
case 0x0B: /* only present when bit_security is set */
100+
if (line_length != 32) {
101+
printError("FsParser: length too short for key 0x0B");
102+
return 0;
103+
}
80104
_hdr["SecurityBit"] = "ON";
81105
break;
82106
case 0x10: {
107+
if (line_length != 64) {
108+
printError("FsParser: length too short for key 0x10");
109+
return 0;
110+
}
83111
unsigned rate = (val >> 16) & 0xff;
84112
if (rate) {
85113
rate &= 0x7f;
@@ -96,8 +124,16 @@ int FsParser::parseHeader()
96124
break;
97125
}
98126
case 0x12: /* unknown */
127+
if (line_length != 32) {
128+
printError("FsParser: length too short for key 0x12");
129+
return 0;
130+
}
99131
break;
100132
case 0x51:
133+
if (line_length != 64) {
134+
printError("FsParser: length too short for key 0x51");
135+
return 0;
136+
}
101137
/*
102138
[23:16] : a value used to replace 8x 0x00 in compress mode
103139
[15: 8] : a value used to replace 4x 0x00 in compress mode
@@ -108,6 +144,10 @@ int FsParser::parseHeader()
108144
_2Zero = 0xff & (val >> 0);
109145
break;
110146
case 0x52: /* documentation issue */
147+
if (line_length != 64) {
148+
printError("FsParser: length too short for key 0x52");
149+
return 0;
150+
}
111151
uint32_t flash_addr;
112152
flash_addr = val & 0xffffffff;
113153
__buf_valid_bytes = snprintf(__buf, 9, "%08x", flash_addr);
@@ -117,6 +157,10 @@ int FsParser::parseHeader()
117157
break;
118158
case 0x3B: /* last header line with crc and cfg data length */
119159
/* documentation issue */
160+
if (line_length != 32) {
161+
printError("FsParser: length too short for key 0x3B");
162+
return 0;
163+
}
120164
in_header = false;
121165
uint8_t crc;
122166
crc = 0x01 & (val >> 23);
@@ -148,8 +192,14 @@ int FsParser::parse()
148192
* if true 0 -> 0, 1 -> 1
149193
*/
150194

195+
_bit_data.reserve(_raw_data.size() / 8);
151196
for (auto &&line : _lstRawData) {
152-
for (size_t i = 0; i < line.size(); i += 8) {
197+
const size_t line_length = line.size();
198+
if ((line_length % 8) != 0) {
199+
printError("FsParser: truncated line in bitstream data");
200+
return EXIT_FAILURE;
201+
}
202+
for (size_t i = 0; i < line_length; i += 8) {
153203
uint8_t data = bitToVal(&line[i], 8);
154204
_bit_data.push_back((_reverseByte) ? reverseByte(data) : data);
155205
}
@@ -236,9 +286,20 @@ int FsParser::parse()
236286
for (auto &&ll = _lstRawData.begin();
237287
ll != _lstRawData.end(); ll++) {
238288
std::string l = "";
239-
std::string line = *ll;
289+
const std::string &line = *ll;
290+
const size_t line_length = line.size();
291+
if (line_length < static_cast<size_t>(drop)) {
292+
printError("FsParser: truncated configuration line");
293+
return EXIT_FAILURE;
294+
}
240295
if (_compressed) {
241-
for (size_t i = 0; i < line.size()-drop; i+=8) {
296+
const size_t payload_len = line_length - drop;
297+
if ((payload_len % 8) != 0) {
298+
printError("FsParser: compressed line is not byte aligned");
299+
return EXIT_FAILURE;
300+
}
301+
l.reserve(payload_len * 8);
302+
for (size_t i = 0; i < payload_len; i += 8) {
242303
uint8_t c = bitToVal((const char *)&line[i], 8);
243304
if (c == _8Zero)
244305
l += std::string(8*8, '0');
@@ -250,15 +311,24 @@ int FsParser::parse()
250311
l += line.substr(i, 8);
251312
}
252313
} else {
253-
l = line.substr(0, line.size() - drop);
314+
l = line.substr(0, line_length - drop);
254315
}
316+
const size_t l_length = l.size();
255317

256318
/* store bit for checksum */
257-
tmp += l.substr(padding, l.size() - padding);
319+
if (static_cast<size_t>(padding) > l_length) {
320+
printError("FsParser: invalid padding for configuration line");
321+
return EXIT_FAILURE;
322+
}
323+
tmp += l.substr(padding, l_length - padding);
258324
}
259325

260326
/* checksum */
261327
_checksum = 0;
328+
if ((tmp.size() % 16) != 0) {
329+
printError("FsParser: checksum data is truncated");
330+
return EXIT_FAILURE;
331+
}
262332
for (uint32_t pos = 0; pos < tmp.size(); pos+=16)
263333
_checksum += (uint16_t)bitToVal(&tmp[pos], 16);
264334

0 commit comments

Comments
 (0)