mirror of
https://git.proxmox.com/git/fwupd
synced 2025-07-27 06:10:13 +00:00
dfu: Fix the SREC parser to correctly parse 32 bit address values
This commit is contained in:
parent
849d841ca9
commit
38d064a7f3
@ -103,8 +103,8 @@ dfu_image_from_srec (DfuImage *image,
|
|||||||
while (offset < len_in) {
|
while (offset < len_in) {
|
||||||
DfuSrecClassType rec_class = DFU_SREC_RECORD_CLASS_UNKNOWN;
|
DfuSrecClassType rec_class = DFU_SREC_RECORD_CLASS_UNKNOWN;
|
||||||
guint32 rec_addr32;
|
guint32 rec_addr32;
|
||||||
guint8 rec_count;
|
guint8 rec_count; /* bytes */
|
||||||
guint8 rec_datalen;
|
guint8 rec_dataoffset; /* bytes */
|
||||||
guint8 rec_kind;
|
guint8 rec_kind;
|
||||||
|
|
||||||
/* check starting token */
|
/* check starting token */
|
||||||
@ -141,9 +141,6 @@ dfu_image_from_srec (DfuImage *image,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove the length of the checksum */
|
|
||||||
rec_datalen = rec_count - 1;
|
|
||||||
|
|
||||||
/* checksum check */
|
/* checksum check */
|
||||||
if ((flags & DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST) == 0) {
|
if ((flags & DFU_FIRMWARE_PARSE_FLAG_NO_CRC_TEST) == 0) {
|
||||||
guint8 rec_csum = 0;
|
guint8 rec_csum = 0;
|
||||||
@ -162,11 +159,14 @@ dfu_image_from_srec (DfuImage *image,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* record kind + record count (in bytes, not chars) */
|
||||||
|
rec_dataoffset = 2;
|
||||||
|
|
||||||
/* parse record */
|
/* parse record */
|
||||||
switch (rec_kind) {
|
switch (rec_kind) {
|
||||||
case '0':
|
case '0':
|
||||||
rec_class = DFU_SREC_RECORD_CLASS_HEADER;
|
rec_class = DFU_SREC_RECORD_CLASS_HEADER;
|
||||||
rec_datalen -= 2;
|
rec_dataoffset += 2;
|
||||||
rec_addr32 = dfu_utils_buffer_parse_uint16 (in_buffer + offset + 4);
|
rec_addr32 = dfu_utils_buffer_parse_uint16 (in_buffer + offset + 4);
|
||||||
if (rec_addr32 != 0x0) {
|
if (rec_addr32 != 0x0) {
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
@ -177,8 +177,8 @@ dfu_image_from_srec (DfuImage *image,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
/* could be anything, lets assume text */
|
/* could be anything, lets assume text */
|
||||||
for (guint i = 0; i < rec_datalen; i++) {
|
for (guint8 i = rec_dataoffset; i <= rec_count; i++) {
|
||||||
guint8 tmp = dfu_utils_buffer_parse_uint8 (in_buffer + offset + 8 + (i * 2));
|
guint8 tmp = dfu_utils_buffer_parse_uint8 (in_buffer + offset + (i * 2));
|
||||||
if (!g_ascii_isgraph (tmp))
|
if (!g_ascii_isgraph (tmp))
|
||||||
break;
|
break;
|
||||||
g_string_append_c (modname, tmp);
|
g_string_append_c (modname, tmp);
|
||||||
@ -188,40 +188,36 @@ dfu_image_from_srec (DfuImage *image,
|
|||||||
break;
|
break;
|
||||||
case '1':
|
case '1':
|
||||||
rec_class = DFU_SREC_RECORD_CLASS_DATA;
|
rec_class = DFU_SREC_RECORD_CLASS_DATA;
|
||||||
rec_datalen -= 2;
|
rec_dataoffset += 2;
|
||||||
rec_addr32 = dfu_utils_buffer_parse_uint16 (in_buffer + offset + 4);
|
rec_addr32 = dfu_utils_buffer_parse_uint16 (in_buffer + offset + 4);
|
||||||
break;
|
break;
|
||||||
case '2':
|
case '2':
|
||||||
rec_class = DFU_SREC_RECORD_CLASS_DATA;
|
rec_class = DFU_SREC_RECORD_CLASS_DATA;
|
||||||
rec_datalen -= 3;
|
rec_dataoffset += 3;
|
||||||
rec_addr32 = dfu_utils_buffer_parse_uint24 (in_buffer + offset + 4);
|
rec_addr32 = dfu_utils_buffer_parse_uint24 (in_buffer + offset + 4);
|
||||||
break;
|
break;
|
||||||
case '3':
|
case '3':
|
||||||
rec_class = DFU_SREC_RECORD_CLASS_DATA;
|
rec_class = DFU_SREC_RECORD_CLASS_DATA;
|
||||||
rec_datalen -= 4;
|
rec_dataoffset += 4;
|
||||||
rec_addr32 = dfu_utils_buffer_parse_uint32 (in_buffer + offset + 4);
|
rec_addr32 = dfu_utils_buffer_parse_uint32 (in_buffer + offset + 4);
|
||||||
break;
|
break;
|
||||||
case '9':
|
case '9':
|
||||||
rec_class = DFU_SREC_RECORD_CLASS_TERMINATION;
|
rec_class = DFU_SREC_RECORD_CLASS_TERMINATION;
|
||||||
rec_datalen -= 2;
|
|
||||||
rec_addr32 = dfu_utils_buffer_parse_uint16 (in_buffer + offset + 4);
|
rec_addr32 = dfu_utils_buffer_parse_uint16 (in_buffer + offset + 4);
|
||||||
got_eof = TRUE;
|
got_eof = TRUE;
|
||||||
break;
|
break;
|
||||||
case '8':
|
case '8':
|
||||||
rec_class = DFU_SREC_RECORD_CLASS_TERMINATION;
|
rec_class = DFU_SREC_RECORD_CLASS_TERMINATION;
|
||||||
rec_datalen -= 3;
|
|
||||||
rec_addr32 = dfu_utils_buffer_parse_uint24 (in_buffer + offset + 4);
|
rec_addr32 = dfu_utils_buffer_parse_uint24 (in_buffer + offset + 4);
|
||||||
got_eof = TRUE;
|
got_eof = TRUE;
|
||||||
break;
|
break;
|
||||||
case '7':
|
case '7':
|
||||||
rec_class = DFU_SREC_RECORD_CLASS_TERMINATION;
|
rec_class = DFU_SREC_RECORD_CLASS_TERMINATION;
|
||||||
rec_datalen -= 4;
|
|
||||||
rec_addr32 = dfu_utils_buffer_parse_uint32 (in_buffer + offset + 4);
|
rec_addr32 = dfu_utils_buffer_parse_uint32 (in_buffer + offset + 4);
|
||||||
got_eof = TRUE;
|
got_eof = TRUE;
|
||||||
break;
|
break;
|
||||||
case '5':
|
case '5':
|
||||||
rec_class = DFU_SREC_RECORD_CLASS_COUNT;
|
rec_class = DFU_SREC_RECORD_CLASS_COUNT;
|
||||||
rec_datalen -= 2;
|
|
||||||
rec_addr32 = dfu_utils_buffer_parse_uint16 (in_buffer + offset + 4);
|
rec_addr32 = dfu_utils_buffer_parse_uint16 (in_buffer + offset + 4);
|
||||||
if (rec_addr32 != class_data_cnt) {
|
if (rec_addr32 != class_data_cnt) {
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
@ -262,8 +258,8 @@ dfu_image_from_srec (DfuImage *image,
|
|||||||
g_debug ("ignoring data at 0x%x as before start address 0x%x",
|
g_debug ("ignoring data at 0x%x as before start address 0x%x",
|
||||||
(guint) rec_addr32, (guint) start_addr);
|
(guint) rec_addr32, (guint) start_addr);
|
||||||
} else {
|
} else {
|
||||||
for (guint i = 0; i < rec_datalen; i++) {
|
for (guint8 i = rec_dataoffset; i <= rec_count; i++) {
|
||||||
guint8 tmp = dfu_utils_buffer_parse_uint8 (in_buffer + offset + 8 + (i * 2));
|
guint8 tmp = dfu_utils_buffer_parse_uint8 (in_buffer + offset + (i * 2));
|
||||||
g_string_append_c (outbuf, tmp);
|
g_string_append_c (outbuf, tmp);
|
||||||
}
|
}
|
||||||
if (element_address == 0x0)
|
if (element_address == 0x0)
|
||||||
|
Loading…
Reference in New Issue
Block a user