Removed shitty sodium fromHex parse function
This commit is contained in:
@ -23,11 +23,6 @@ constexpr const char * const TAG = "ESPCPPUTILS";
|
|||||||
tl::expected<char *, std::string> sodium_bin2hex(char * const hex, const size_t hex_maxlen,
|
tl::expected<char *, std::string> sodium_bin2hex(char * const hex, const size_t hex_maxlen,
|
||||||
const unsigned char * const bin, const size_t bin_len)
|
const unsigned char * const bin, const size_t bin_len)
|
||||||
__attribute__ ((nonnull(1)));
|
__attribute__ ((nonnull(1)));
|
||||||
tl::expected<void, std::string> sodium_hex2bin(unsigned char * const bin, const size_t bin_maxlen,
|
|
||||||
const char * const hex, const size_t hex_len,
|
|
||||||
const char * const ignore, size_t * const bin_len,
|
|
||||||
const char ** const hex_end)
|
|
||||||
__attribute__ ((nonnull(1)));
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
std::string toString(sntp_sync_mode_t val)
|
std::string toString(sntp_sync_mode_t val)
|
||||||
@ -110,28 +105,50 @@ std::string toHexString(std::basic_string_view<unsigned char> buf)
|
|||||||
return hex;
|
return hex;
|
||||||
}
|
}
|
||||||
|
|
||||||
tl::expected<std::basic_string_view<unsigned char>, std::string> fromHexString(std::string_view str)
|
tl::expected<std::basic_string<unsigned char>, std::string> fromHexString(std::string_view hex)
|
||||||
{
|
{
|
||||||
const auto binMaxLen = (str.size()+1)/2;
|
if (hex.size() % 2 != 0)
|
||||||
uint8_t binBuf[binMaxLen];
|
return tl::make_unexpected("hex length not even");
|
||||||
|
|
||||||
size_t binLen;
|
std::basic_string<unsigned char> result;
|
||||||
if (const auto result = sodium_hex2bin(binBuf, binMaxLen, str.data(), str.size(), NULL, &binLen, NULL); !result)
|
result.reserve(hex.size() / 2);
|
||||||
|
|
||||||
|
for (auto iter = std::cbegin(hex); iter != std::cend(hex); )
|
||||||
{
|
{
|
||||||
auto msg = fmt::format("sodium_hex2bin() failed with {}", result.error());
|
union {
|
||||||
ESP_LOGW(TAG, "%.*s", msg.size(), msg.data());
|
unsigned char c;
|
||||||
return tl::make_unexpected(std::move(msg));
|
struct {
|
||||||
|
unsigned char nibble1:4;
|
||||||
|
unsigned char nibble0:4;
|
||||||
|
} nibbles;
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (const auto c = *iter)
|
||||||
|
{
|
||||||
|
case '0'...'9': nibbles.nibble0 = c - '0'; break;
|
||||||
|
case 'A'...'F': nibbles.nibble0 = c - 'A' + 10; break;
|
||||||
|
case 'a'...'f': nibbles.nibble0 = c - 'a' + 10; break;
|
||||||
|
default:
|
||||||
|
return tl::make_unexpected(fmt::format("invalid character {} at pos {}", c, std::distance(std::begin(hex), iter)));
|
||||||
|
}
|
||||||
|
|
||||||
|
iter++;
|
||||||
|
|
||||||
|
switch (const auto c = *iter)
|
||||||
|
{
|
||||||
|
case '0'...'9': nibbles.nibble1 = c - '0'; break;
|
||||||
|
case 'A'...'F': nibbles.nibble1 = c - 'A' + 10; break;
|
||||||
|
case 'a'...'f': nibbles.nibble1 = c - 'a' + 10; break;
|
||||||
|
default:
|
||||||
|
return tl::make_unexpected(fmt::format("invalid character {} at pos {}", c, std::distance(std::begin(hex), iter)));
|
||||||
|
}
|
||||||
|
|
||||||
|
iter++;
|
||||||
|
|
||||||
|
result.push_back(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (binLen != str.size() / 2)
|
return result;
|
||||||
{
|
|
||||||
ESP_LOGW(TAG, "invalid hex");
|
|
||||||
return tl::make_unexpected("invalid hex");
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::basic_string_view<unsigned char> bin{binBuf, binLen};
|
|
||||||
|
|
||||||
return bin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -162,65 +179,5 @@ sodium_bin2hex(char *const hex, const size_t hex_maxlen,
|
|||||||
|
|
||||||
return hex;
|
return hex;
|
||||||
}
|
}
|
||||||
|
|
||||||
tl::expected<void, std::string>
|
|
||||||
sodium_hex2bin(unsigned char *const bin, const size_t bin_maxlen,
|
|
||||||
const char *const hex, const size_t hex_len,
|
|
||||||
const char *const ignore, size_t *const bin_len,
|
|
||||||
const char **const hex_end)
|
|
||||||
{
|
|
||||||
size_t bin_pos = (size_t) 0U;
|
|
||||||
size_t hex_pos = (size_t) 0U;
|
|
||||||
tl::expected<void, std::string> ret;
|
|
||||||
unsigned char c;
|
|
||||||
unsigned char c_acc = 0U;
|
|
||||||
unsigned char c_alpha0, c_alpha;
|
|
||||||
unsigned char c_num0, c_num;
|
|
||||||
unsigned char c_val;
|
|
||||||
unsigned char state = 0U;
|
|
||||||
|
|
||||||
while (hex_pos < hex_len) {
|
|
||||||
c = (unsigned char) hex[hex_pos];
|
|
||||||
c_num = c ^ 48U;
|
|
||||||
c_num0 = (c_num - 10U) >> 8;
|
|
||||||
c_alpha = (c & ~32U) - 55U;
|
|
||||||
c_alpha0 = ((c_alpha - 10U) ^ (c_alpha - 16U)) >> 8;
|
|
||||||
if ((c_num0 | c_alpha0) == 0U) {
|
|
||||||
if (ignore != NULL && state == 0U && strchr(ignore, c) != NULL) {
|
|
||||||
hex_pos++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
c_val = (c_num0 & c_num) | (c_alpha0 & c_alpha);
|
|
||||||
if (bin_pos >= bin_maxlen) {
|
|
||||||
ret = tl::make_unexpected("ERANGE because bin_pos >= bin_maxlen"s);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (state == 0U) {
|
|
||||||
c_acc = c_val * 16U;
|
|
||||||
} else {
|
|
||||||
bin[bin_pos++] = c_acc | c_val;
|
|
||||||
}
|
|
||||||
state = ~state;
|
|
||||||
hex_pos++;
|
|
||||||
}
|
|
||||||
if (state != 0U) {
|
|
||||||
hex_pos--;
|
|
||||||
ret = tl::make_unexpected("EINVAL because state != 0U"s);
|
|
||||||
}
|
|
||||||
if (!ret) {
|
|
||||||
bin_pos = (size_t) 0U;
|
|
||||||
}
|
|
||||||
if (hex_end != NULL) {
|
|
||||||
*hex_end = &hex[hex_pos];
|
|
||||||
} else if (hex_pos != hex_len) {
|
|
||||||
ret = tl::make_unexpected("EINVAL because hex_pos != hex_len"s);
|
|
||||||
}
|
|
||||||
if (bin_len != NULL) {
|
|
||||||
*bin_len = bin_pos;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace espcpputils
|
} // namespace espcpputils
|
||||||
|
@ -24,10 +24,6 @@ inline std::string toHexString(std::string_view str)
|
|||||||
return toHexString(std::basic_string_view<unsigned char>{reinterpret_cast<const unsigned char *>(str.data()), str.size()});
|
return toHexString(std::basic_string_view<unsigned char>{reinterpret_cast<const unsigned char *>(str.data()), str.size()});
|
||||||
}
|
}
|
||||||
|
|
||||||
tl::expected<std::basic_string_view<unsigned char>, std::string> fromHexString(std::string_view str);
|
tl::expected<std::basic_string<unsigned char>, std::string> fromHexString(std::string_view hex);
|
||||||
inline tl::expected<std::basic_string_view<unsigned char>, std::string> fromHexString(std::basic_string_view<unsigned char> str)
|
|
||||||
{
|
|
||||||
return fromHexString(std::string_view{reinterpret_cast<const char *>(str.data()), str.size()});
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace espcpputils
|
} // namespace espcpputils
|
||||||
|
Reference in New Issue
Block a user