diff options
author | 2023-04-13 05:49:05 +1000 | |
---|---|---|
committer | 2023-04-13 05:49:05 +1000 | |
commit | b6b6c9b15c34471fd3938bdb9715754f09f10e00 (patch) | |
tree | b77d63379d6fb1305ca64342f7e5ca7f9aff3d3c /src/lib/util/hashing.cpp | |
parent | 81dd75f7d7db2967d00075bd443c85e8b042251d (diff) |
Allow loading PNG/JPEG/MS DIB bitmaps from Lua, and cleanup.
Use VirtualAlloc rather than VirtualProtect on Windows to change page
protection, as the latter can cause severe performance issues with some
antivirus software.
Added noexcept to lots of hash- and bitmap-related things, and added a
little more error checking. Yes, I realise it will abort if an
allocation fails while printing a log message, but if you get to that
point, you're probably screwed already.
Diffstat (limited to 'src/lib/util/hashing.cpp')
-rw-r--r-- | src/lib/util/hashing.cpp | 98 |
1 files changed, 54 insertions, 44 deletions
diff --git a/src/lib/util/hashing.cpp b/src/lib/util/hashing.cpp index 62447c7b6c0..3410389fdc8 100644 --- a/src/lib/util/hashing.cpp +++ b/src/lib/util/hashing.cpp @@ -9,12 +9,14 @@ ***************************************************************************/ #include "hashing.h" + #include "strformat.h" #include "eminline.h" #include <zlib.h> +#include <algorithm> #include <iomanip> #include <sstream> @@ -42,7 +44,7 @@ constexpr int char_to_hex(char c) } -inline uint32_t sha1_b(uint32_t *data, unsigned i) +inline uint32_t sha1_b(uint32_t *data, unsigned i) noexcept { uint32_t r = data[(i + 13) & 15U]; r ^= data[(i + 8) & 15U]; @@ -53,37 +55,37 @@ inline uint32_t sha1_b(uint32_t *data, unsigned i) return r; } -inline void sha1_r0(const uint32_t *data, std::array<uint32_t, 5> &d, unsigned i) +inline void sha1_r0(const uint32_t *data, std::array<uint32_t, 5> &d, unsigned i) noexcept { d[i % 5] = d[i % 5] + ((d[(i + 3) % 5] & (d[(i + 2) % 5] ^ d[(i + 1) % 5])) ^ d[(i + 1) % 5]) + data[i] + 0x5a827999U + rotl_32(d[(i + 4) % 5], 5); d[(i + 3) % 5] = rotl_32(d[(i + 3) % 5], 30); } -inline void sha1_r1(uint32_t *data, std::array<uint32_t, 5> &d, unsigned i) +inline void sha1_r1(uint32_t *data, std::array<uint32_t, 5> &d, unsigned i) noexcept { d[i % 5] = d[i % 5] + ((d[(i + 3) % 5] & (d[(i + 2) % 5] ^ d[(i + 1) % 5])) ^ d[(i + 1) % 5])+ sha1_b(data, i) + 0x5a827999U + rotl_32(d[(i + 4) % 5], 5); d[(i + 3) % 5] = rotl_32(d[(i + 3) % 5], 30); } -inline void sha1_r2(uint32_t *data, std::array<uint32_t, 5> &d, unsigned i) +inline void sha1_r2(uint32_t *data, std::array<uint32_t, 5> &d, unsigned i) noexcept { d[i % 5] = d[i % 5] + (d[(i + 3) % 5] ^ d[(i + 2) % 5] ^ d[(i + 1) % 5]) + sha1_b(data, i) + 0x6ed9eba1U + rotl_32(d[(i + 4) % 5], 5); d[(i + 3) % 5] = rotl_32(d[(i + 3) % 5], 30); } -inline void sha1_r3(uint32_t *data, std::array<uint32_t, 5> &d, unsigned i) +inline void sha1_r3(uint32_t *data, std::array<uint32_t, 5> &d, unsigned i) noexcept { d[i % 5] = d[i % 5] + (((d[(i + 3) % 5] | d[(i + 2) % 5]) & d[(i + 1) % 5]) | (d[(i + 3) % 5] & d[(i + 2) % 5])) + sha1_b(data, i) + 0x8f1bbcdcU + rotl_32(d[(i + 4) % 5], 5); d[(i + 3) % 5] = rotl_32(d[(i + 3) % 5], 30); } -inline void sha1_r4(uint32_t *data, std::array<uint32_t, 5> &d, unsigned i) +inline void sha1_r4(uint32_t *data, std::array<uint32_t, 5> &d, unsigned i) noexcept { d[i % 5] = d[i % 5] + (d[(i + 3) % 5] ^ d[(i + 2) % 5] ^ d[(i + 1) % 5]) + sha1_b(data, i) + 0xca62c1d6U + rotl_32(d[(i + 4) % 5], 5); d[(i + 3) % 5] = rotl_32(d[(i + 3) % 5], 30); } -inline void sha1_process(std::array<uint32_t, 5> &st, uint32_t *data) +inline void sha1_process(std::array<uint32_t, 5> &st, uint32_t *data) noexcept { std::array<uint32_t, 5> d = st; unsigned i = 0U; @@ -125,18 +127,18 @@ const sum16_t sum16_t::null = { 0 }; // from_string - convert from a string //------------------------------------------------- -bool sha1_t::from_string(std::string_view string) +bool sha1_t::from_string(std::string_view string) noexcept { // must be at least long enough to hold everything - memset(m_raw, 0, sizeof(m_raw)); + std::fill(std::begin(m_raw), std::end(m_raw), 0); if (string.length() < 2 * sizeof(m_raw)) return false; // iterate through our raw buffer - for (auto & elem : m_raw) + for (auto &elem : m_raw) { - int upper = char_to_hex(string[0]); - int lower = char_to_hex(string[1]); + int const upper = char_to_hex(string[0]); + int const lower = char_to_hex(string[1]); if (upper == -1 || lower == -1) return false; elem = (upper << 4) | lower; @@ -152,12 +154,16 @@ bool sha1_t::from_string(std::string_view string) std::string sha1_t::as_string() const { - std::ostringstream buffer; - buffer.fill('0'); - buffer << std::hex; - for (auto & elem : m_raw) - buffer << std::setw(2) << unsigned(elem); - return buffer.str(); + std::string result(2 * std::size(m_raw), ' '); + auto it = result.begin(); + for (auto const &elem : m_raw) + { + auto const upper = elem >> 4; + auto const lower = elem & 0x0f; + *it++ = ((10 > upper) ? '0' : ('a' - 10)) + upper; + *it++ = ((10 > lower) ? '0' : ('a' - 10)) + lower; + } + return result; } @@ -165,7 +171,7 @@ std::string sha1_t::as_string() const // reset - prepare to digest a block of data //------------------------------------------------- -void sha1_creator::reset() +void sha1_creator::reset() noexcept { m_cnt = 0U; m_st[0] = 0xc3d2e1f0U; @@ -180,7 +186,7 @@ void sha1_creator::reset() // append - digest a block of data //------------------------------------------------- -void sha1_creator::append(const void *data, uint32_t length) +void sha1_creator::append(const void *data, uint32_t length) noexcept { #ifdef LSB_FIRST constexpr unsigned swizzle = 3U; @@ -215,7 +221,7 @@ void sha1_creator::append(const void *data, uint32_t length) // finish - compute final hash //------------------------------------------------- -sha1_t sha1_creator::finish() +sha1_t sha1_creator::finish() noexcept { const unsigned padlen = 64U - (63U & ((unsigned(m_cnt) >> 3) + 8U)); uint8_t padbuf[64]; @@ -243,18 +249,18 @@ sha1_t sha1_creator::finish() // from_string - convert from a string //------------------------------------------------- -bool md5_t::from_string(std::string_view string) +bool md5_t::from_string(std::string_view string) noexcept { // must be at least long enough to hold everything - memset(m_raw, 0, sizeof(m_raw)); + std::fill(std::begin(m_raw), std::end(m_raw), 0); if (string.length() < 2 * sizeof(m_raw)) return false; // iterate through our raw buffer - for (auto & elem : m_raw) + for (auto &elem : m_raw) { - int upper = char_to_hex(string[0]); - int lower = char_to_hex(string[1]); + int const upper = char_to_hex(string[0]); + int const lower = char_to_hex(string[1]); if (upper == -1 || lower == -1) return false; elem = (upper << 4) | lower; @@ -270,12 +276,16 @@ bool md5_t::from_string(std::string_view string) std::string md5_t::as_string() const { - std::ostringstream buffer; - buffer.fill('0'); - buffer << std::hex; - for (auto & elem : m_raw) - buffer << std::setw(2) << unsigned(elem); - return buffer.str(); + std::string result(2 * std::size(m_raw), ' '); + auto it = result.begin(); + for (auto const &elem : m_raw) + { + auto const upper = elem >> 4; + auto const lower = elem & 0x0f; + *it++ = ((10 > upper) ? '0' : ('a' - 10)) + upper; + *it++ = ((10 > lower) ? '0' : ('a' - 10)) + lower; + } + return result; } @@ -288,18 +298,18 @@ std::string md5_t::as_string() const // from_string - convert from a string //------------------------------------------------- -bool crc32_t::from_string(std::string_view string) +bool crc32_t::from_string(std::string_view string) noexcept { // must be at least long enough to hold everything m_raw = 0; - if (string.length() < 2 * sizeof(m_raw)) + if (string.length() < (2 * sizeof(m_raw))) return false; // iterate through our raw buffer m_raw = 0; for (int bytenum = 0; bytenum < sizeof(m_raw) * 2; bytenum++) { - int nibble = char_to_hex(string[0]); + int const nibble = char_to_hex(string[0]); if (nibble == -1) return false; m_raw = (m_raw << 4) | nibble; @@ -324,7 +334,7 @@ std::string crc32_t::as_string() const // the currently-accumulated value //------------------------------------------------- -void crc32_creator::append(const void *data, uint32_t length) +void crc32_creator::append(const void *data, uint32_t length) noexcept { m_accum.m_raw = crc32(m_accum, reinterpret_cast<const Bytef *>(data), length); } @@ -339,18 +349,18 @@ void crc32_creator::append(const void *data, uint32_t length) // from_string - convert from a string //------------------------------------------------- -bool crc16_t::from_string(std::string_view string) +bool crc16_t::from_string(std::string_view string) noexcept { // must be at least long enough to hold everything m_raw = 0; - if (string.length() < 2 * sizeof(m_raw)) + if (string.length() < (2 * sizeof(m_raw))) return false; // iterate through our raw buffer m_raw = 0; for (int bytenum = 0; bytenum < sizeof(m_raw) * 2; bytenum++) { - int nibble = char_to_hex(string[0]); + int const nibble = char_to_hex(string[0]); if (nibble == -1) return false; m_raw = (m_raw << 4) | nibble; @@ -385,7 +395,7 @@ std::string crc16_t::as_string() const * @param length The length. */ -void crc16_creator::append(const void *data, uint32_t length) +void crc16_creator::append(const void *data, uint32_t length) noexcept { static const uint16_t s_table[256] = { @@ -442,18 +452,18 @@ void crc16_creator::append(const void *data, uint32_t length) // from_string - convert from a string //------------------------------------------------- -bool sum16_t::from_string(std::string_view string) +bool sum16_t::from_string(std::string_view string) noexcept { // must be at least long enough to hold everything m_raw = 0; - if (string.length() < 2 * sizeof(m_raw)) + if (string.length() < (2 * sizeof(m_raw))) return false; // iterate through our raw buffer m_raw = 0; for (int bytenum = 0; bytenum < sizeof(m_raw) * 2; bytenum++) { - int nibble = char_to_hex(string[0]); + int const nibble = char_to_hex(string[0]); if (nibble == -1) return false; m_raw = (m_raw << 4) | nibble; @@ -488,7 +498,7 @@ std::string sum16_t::as_string() const * @param length The length. */ -void sum16_creator::append(const void *data, uint32_t length) +void sum16_creator::append(const void *data, uint32_t length) noexcept { const auto *src = reinterpret_cast<const uint8_t *>(data); |