diff --git a/esphome/core/helpers.cpp b/esphome/core/helpers.cpp index 77102c8db2..6a4894419c 100644 --- a/esphome/core/helpers.cpp +++ b/esphome/core/helpers.cpp @@ -266,19 +266,12 @@ std::string make_name_with_suffix(const std::string &name, char sep, const char // Parsing & formatting size_t parse_hex(const char *str, size_t length, uint8_t *data, size_t count) { - uint8_t val; size_t chars = std::min(length, 2 * count); for (size_t i = 2 * count - chars; i < 2 * count; i++, str++) { - if (*str >= '0' && *str <= '9') { - val = *str - '0'; - } else if (*str >= 'A' && *str <= 'F') { - val = 10 + (*str - 'A'); - } else if (*str >= 'a' && *str <= 'f') { - val = 10 + (*str - 'a'); - } else { + uint8_t val = parse_hex_char(*str); + if (val > 15) return 0; - } - data[i >> 1] = !(i & 1) ? val << 4 : data[i >> 1] | val; + data[i >> 1] = (i & 1) ? data[i >> 1] | val : val << 4; } return chars; } diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index 6054f03353..3e44e08dd4 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -624,6 +624,17 @@ template::value, int> = 0> optional< return parse_hex(str.c_str(), str.length()); } +/// Parse a hex character to its nibble value (0-15), returns 255 on invalid input +constexpr uint8_t parse_hex_char(char c) { + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + return 255; +} + /// Convert a nibble (0-15) to lowercase hex char inline char format_hex_char(uint8_t v) { return v >= 10 ? 'a' + (v - 10) : '0' + v; }