mirror of
https://github.com/esphome/esphome.git
synced 2025-10-09 21:33:48 +01:00
Fix parsing numbers from null-terminated buffers (#2755)
This commit is contained in:
@@ -364,45 +364,47 @@ std::string str_sanitize(const std::string &str);
|
||||
/// @name Parsing & formatting
|
||||
///@{
|
||||
|
||||
/// Parse a unsigned decimal number.
|
||||
/// Parse an unsigned decimal number (requires null-terminated string).
|
||||
template<typename T, enable_if_t<(std::is_integral<T>::value && std::is_unsigned<T>::value), int> = 0>
|
||||
optional<T> parse_number(const char *str, size_t len) {
|
||||
char *end = nullptr;
|
||||
unsigned long value = ::strtoul(str, &end, 10); // NOLINT(google-runtime-int)
|
||||
if (end == nullptr || end != str + len || value > std::numeric_limits<T>::max())
|
||||
if (end == str || *end != '\0' || value > std::numeric_limits<T>::max())
|
||||
return {};
|
||||
return value;
|
||||
}
|
||||
/// Parse an unsigned decimal number.
|
||||
template<typename T, enable_if_t<(std::is_integral<T>::value && std::is_unsigned<T>::value), int> = 0>
|
||||
optional<T> parse_number(const std::string &str) {
|
||||
return parse_number<T>(str.c_str(), str.length());
|
||||
return parse_number<T>(str.c_str(), str.length() + 1);
|
||||
}
|
||||
/// Parse a signed decimal number.
|
||||
/// Parse a signed decimal number (requires null-terminated string).
|
||||
template<typename T, enable_if_t<(std::is_integral<T>::value && std::is_signed<T>::value), int> = 0>
|
||||
optional<T> parse_number(const char *str, size_t len) {
|
||||
char *end = nullptr;
|
||||
signed long value = ::strtol(str, &end, 10); // NOLINT(google-runtime-int)
|
||||
if (end == nullptr || end != str + len || value < std::numeric_limits<T>::min() ||
|
||||
value > std::numeric_limits<T>::max())
|
||||
if (end == str || *end != '\0' || value < std::numeric_limits<T>::min() || value > std::numeric_limits<T>::max())
|
||||
return {};
|
||||
return value;
|
||||
}
|
||||
/// Parse a signed decimal number.
|
||||
template<typename T, enable_if_t<(std::is_integral<T>::value && std::is_signed<T>::value), int> = 0>
|
||||
optional<T> parse_number(const std::string &str) {
|
||||
return parse_number<T>(str.c_str(), str.length());
|
||||
return parse_number<T>(str.c_str(), str.length() + 1);
|
||||
}
|
||||
/// Parse a decimal floating-point number.
|
||||
/// Parse a decimal floating-point number (requires null-terminated string).
|
||||
template<typename T, enable_if_t<(std::is_same<T, float>::value), int> = 0>
|
||||
optional<T> parse_number(const char *str, size_t len) {
|
||||
char *end = nullptr;
|
||||
float value = ::strtof(str, &end);
|
||||
if (end == nullptr || end != str + len || value == HUGE_VALF)
|
||||
if (end == str || *end != '\0' || value == HUGE_VALF)
|
||||
return {};
|
||||
return value;
|
||||
}
|
||||
/// Parse a decimal floating-point number.
|
||||
template<typename T, enable_if_t<(std::is_same<T, float>::value), int> = 0>
|
||||
optional<T> parse_number(const std::string &str) {
|
||||
return parse_number<T>(str.c_str(), str.length());
|
||||
return parse_number<T>(str.c_str(), str.length() + 1);
|
||||
}
|
||||
|
||||
///@}
|
||||
|
Reference in New Issue
Block a user