From e2589c0756ff0bbe7f1ec55928ef370dac688ec1 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Fri, 19 Dec 2014 09:56:35 +0100 Subject: [PATCH] Replace the code for handling line endings. The new implementation is similar to the already existing code for reading Intel HEX files. It can handle arbitrary line endings, and not just CRLF or LF. --- src/hw_ostc3.c | 67 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 19 deletions(-) diff --git a/src/hw_ostc3.c b/src/hw_ostc3.c index f63603b..a9a683b 100644 --- a/src/hw_ostc3.c +++ b/src/hw_ostc3.c @@ -794,32 +794,61 @@ hw_ostc3_firmware_checksum (hw_ostc3_firmware_t *firmware) } static dc_status_t -hw_ostc3_firmware_readline (FILE *fp, unsigned int addr, unsigned char data[], unsigned int size) +hw_ostc3_firmware_readline (FILE *fp, dc_context_t *context, unsigned int addr, unsigned char data[], unsigned int size) { - unsigned char ascii[40]; - // 1 byte :, 6 bytes addr, X*2 bytes hex -> X bytes data. - const unsigned line_size = size * 2 + 1 + 6 + 1; + unsigned char ascii[39]; unsigned char faddr_byte[3]; unsigned int faddr = 0; - if (line_size > sizeof (ascii)) + int n = 0; + + if (size > 16) { + ERROR (context, "Invalid arguments."); return DC_STATUS_INVALIDARGS; - if (fread (ascii, sizeof (unsigned char), line_size, fp) != line_size) - return DC_STATUS_IO; - if (ascii[0] != ':') - return DC_STATUS_DATAFORMAT; - // Is it a CRLF file? - // Read away that trailing LF - if (ascii[line_size - 1] == '\r') - if (fread (ascii + line_size - 1, sizeof (unsigned char), 1, fp) != 1) + } + + // Read the start code. + while (1) { + n = fread (ascii, 1, 1, fp); + if (n != 1) { + ERROR (context, "Failed to read the start code."); + return DC_STATUS_IO; + } + + if (ascii[0] == ':') + break; + + // Ignore CR and LF characters. + if (ascii[0] != '\n' && ascii[0] != '\r') { + ERROR (context, "Unexpected character (0x%02x).", ascii[0]); return DC_STATUS_DATAFORMAT; - if (array_convert_hex2bin (ascii + 1, 6, faddr_byte, sizeof (faddr_byte)) != 0) { + } + } + + // Read the payload. + n = fread (ascii + 1, 1, 6 + size * 2, fp); + if (n != 6 + size * 2) { + ERROR (context, "Failed to read the data."); + return DC_STATUS_IO; + } + + // Convert the address to binary representation. + if (array_convert_hex2bin(ascii + 1, 6, faddr_byte, sizeof(faddr_byte)) != 0) { + ERROR (context, "Invalid hexadecimal character."); return DC_STATUS_DATAFORMAT; } + + // Get the address. faddr = array_uint24_be (faddr_byte); - if (faddr != addr) + if (faddr != addr) { + ERROR (context, "Unexpected address (0x%06x, 0x%06x).", faddr, addr); return DC_STATUS_DATAFORMAT; - if (array_convert_hex2bin (ascii + 1 + 6, size*2, data, size) != 0) + } + + // Convert the payload to binary representation. + if (array_convert_hex2bin (ascii + 1 + 6, size * 2, data, size) != 0) { + ERROR (context, "Invalid hexadecimal character."); return DC_STATUS_DATAFORMAT; + } return DC_STATUS_SUCCESS; } @@ -851,7 +880,7 @@ hw_ostc3_firmware_readfile (hw_ostc3_firmware_t *firmware, dc_context_t *context return DC_STATUS_IO; } - rc = hw_ostc3_firmware_readline (fp, 0, iv, sizeof (iv)); + rc = hw_ostc3_firmware_readline (fp, context, 0, iv, sizeof(iv)); if (rc != DC_STATUS_SUCCESS) { ERROR (context, "Failed to parse header."); fclose (fp); @@ -863,7 +892,7 @@ hw_ostc3_firmware_readfile (hw_ostc3_firmware_t *firmware, dc_context_t *context AES128_ECB_encrypt (iv, ostc3_key, tmpbuf); for (addr = 0; addr < SZ_FIRMWARE; addr += 16, bytes += 16) { - rc = hw_ostc3_firmware_readline (fp, bytes, encrypted, sizeof (encrypted)); + rc = hw_ostc3_firmware_readline (fp, context, bytes, encrypted, sizeof(encrypted)); if (rc != DC_STATUS_SUCCESS) { ERROR (context, "Failed to parse file data."); fclose (fp); @@ -879,7 +908,7 @@ hw_ostc3_firmware_readfile (hw_ostc3_firmware_t *firmware, dc_context_t *context } // This file format contains a tail with the checksum in - rc = hw_ostc3_firmware_readline (fp, bytes, checksum, sizeof (checksum)); + rc = hw_ostc3_firmware_readline (fp, context, bytes, checksum, sizeof(checksum)); if (rc != DC_STATUS_SUCCESS) { ERROR (context, "Failed to parse file tail."); fclose (fp);