From 487f6fa9224aaa51de1b91bfeae9e52e0e9136ea Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Thu, 3 Apr 2025 14:15:22 +0200 Subject: [PATCH] Clear warning suppression Code analysis got quite good and we'd better keep warnings on our radar. Either: 1. Research and resolve the reason for the warning. 2. Remove silencing and let code analysis complain. 3. Comment why some warning silencing is there. Signed-off-by: Simon Rozman --- include/stdex/base64.hpp | 11 ++--- include/stdex/hash.hpp | 96 +++++++++++++++++++-------------------- include/stdex/html.hpp | 4 ++ include/stdex/parser.hpp | 2 +- include/stdex/ring.hpp | 5 +- include/stdex/stream.hpp | 2 +- include/stdex/string.hpp | 19 ++++---- include/stdex/unicode.hpp | 6 +-- 8 files changed, 74 insertions(+), 71 deletions(-) diff --git a/include/stdex/base64.hpp b/include/stdex/base64.hpp index eed4cd679..5586287ce 100644 --- a/include/stdex/base64.hpp +++ b/include/stdex/base64.hpp @@ -370,9 +370,6 @@ namespace stdex size_t m_num; ///< Number of bytes used in `m_buf` }; -#pragma warning(push) -#pragma warning(disable: 26495) - /// /// Converts from Base64 when reading from a stream /// @@ -383,7 +380,11 @@ namespace stdex stdex::stream::converter(source), m_temp_off(0), m_temp_len(0) - {} + { + m_temp[0] = 0; + m_temp[1] = 0; + m_temp[2] = 0; + } #pragma warning(suppress: 6101) // See [1] below virtual _Success_(return != 0 || length == 0) size_t read( @@ -455,8 +456,6 @@ namespace stdex m_temp_off, ///< Index of data start in `m_temp` m_temp_len; ///< Number of bytes of data in `m_temp` }; - -#pragma warning(pop) } #if defined(__GNUC__) diff --git a/include/stdex/hash.hpp b/include/stdex/hash.hpp index b254fdc6d..02d5ea6c3 100644 --- a/include/stdex/hash.hpp +++ b/include/stdex/hash.hpp @@ -7,7 +7,8 @@ #include "assert.hpp" #include "compat.hpp" -#include "math.h" +#include "endian.hpp" +#include "math.hpp" #include "stream.hpp" #include @@ -18,9 +19,6 @@ namespace stdex { -#pragma warning(push) -#pragma warning(disable: 26495) - /// /// Basic hashing operations /// @@ -28,6 +26,7 @@ namespace stdex class basic_hash { public: + basic_hash() : m_value() {} virtual ~basic_hash() {} /// @@ -61,7 +60,7 @@ namespace stdex /// /// Returns hash value /// - operator const T&() const { return m_value; }; + operator const T& () const { return m_value; }; protected: T m_value; @@ -74,62 +73,46 @@ namespace stdex class block_hash : public basic_hash { public: + block_hash() + { + m_counter = 0; + memset(m_queue, 0, sizeof(m_queue)); + } + virtual void clear() { - m_counter[0] = m_counter[1] = 0; + m_counter = 0; } virtual void hash(_In_reads_bytes_opt_(length) const void* data, _In_ size_t length) { stdex_assert(data || !length); - - // Compute number of bytes mod 64. - size_t j = static_cast((m_counter[0] >> 3) & 63); - - // Update number of m_counter[1]. - if ((m_counter[0] += (static_cast(length) << 3)) < (static_cast(length) << 3)) - m_counter[1]++; - m_counter[1] += static_cast(length) >> 29; - - // Transform as many times as possible. - size_t i, remainder = 64 - j; - if (length >= remainder) { - stdex_assert(j < 64 && j + remainder <= 64); - stdex_assert(remainder <= length); - memcpy(m_queue + j, data, remainder); - hash_block(); - for (i = remainder; i + 64 <= length; i += 64) { -#pragma warning(push) -#pragma warning(disable: 6385) - memcpy(m_queue, reinterpret_cast(data) + i, 64); -#pragma warning(pop) + size_t j = static_cast(m_counter & 63); + m_counter += length; + while (length) { + size_t n = std::min(64 - j, length); + memcpy(&m_queue[j], data, n); + j += n; + if (j >= 64) { hash_block(); + j = 0; } - - j = 0; + reinterpret_cast(data) += n; + length -= n; } - else - i = 0; - - // Buffer remaining input. - stdex_assert(j < 64 && j + length - i <= 64); - stdex_assert(i <= length); - memcpy(m_queue + j, reinterpret_cast(data) + i, length - i); } protected: virtual void hash_block() = 0; protected: - uint32_t m_counter[2]; + uint64_t m_counter; // Number of bytes hashed union { uint8_t m_queue[64]; uint32_t m_temp[16]; }; }; -#pragma warning(pop) - /// /// Hashes read to or write from data of the stream /// @@ -324,12 +307,20 @@ namespace stdex 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - // Save number of final. - uint8_t final[8]; - memcpy(final, m_counter, sizeof(m_counter)); + // Save number of bits. + uint8_t final[] = { + static_cast((m_counter << 3) & 0xff), + static_cast((m_counter >> 5) & 0xff), + static_cast((m_counter >> 13) & 0xff), + static_cast((m_counter >> 21) & 0xff), + static_cast((m_counter >> 29) & 0xff), + static_cast((m_counter >> 37) & 0xff), + static_cast((m_counter >> 45) & 0xff), + static_cast((m_counter >> 53) & 0xff), + }; // Pad out to 56 mod 64. - size_t index = (m_counter[0] >> 3) & 0x3f; + size_t index = m_counter & 0x3f; size_t remainder = index < 56 ? 56 - index : 120 - index; hash(md5_padding, remainder); @@ -522,19 +513,26 @@ namespace stdex virtual void finalize() { - // Save number of final. - uint8_t final[8]; - for (size_t i = 0; i < 8; i++) - final[i] = static_cast((m_counter[((i >= 4) ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255); // Endian independent + // Save number of bits. + uint8_t final[] = { + static_cast((m_counter >> 53) & 0xff), + static_cast((m_counter >> 45) & 0xff), + static_cast((m_counter >> 37) & 0xff), + static_cast((m_counter >> 29) & 0xff), + static_cast((m_counter >> 21) & 0xff), + static_cast((m_counter >> 13) & 0xff), + static_cast((m_counter >> 5) & 0xff), + static_cast((m_counter << 3) & 0xff), + }; hash("\200", 1); - while ((m_counter[0] & 504) != 448) + while ((m_counter & 63) != 56) hash("\0", 1); hash(final, 8); // Cause a SHA1Transform() // Store m_state in m_value. for (size_t i = 0; i < 20; i++) - m_value.data8[i] = static_cast((m_state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); + m_value.data8[i] = static_cast((m_state[i >> 2] >> ((3 - (i & 3)) * 8)) & 0xff); } protected: diff --git a/include/stdex/html.hpp b/include/stdex/html.hpp index a6c7c8cdf..b646fb288 100644 --- a/include/stdex/html.hpp +++ b/include/stdex/html.hpp @@ -2088,6 +2088,7 @@ namespace stdex _In_ uint32_t _text_type = 0, _In_opt_ stdex::html::sequence* sequence = nullptr, _In_ uintptr_t data = 0) : token(type, sequence, data), +#pragma warning(suppress: 6387) // Testing indicates _text may be NULL when num_chars is also 0. Is SAL of the basic_string::basic_string wrong? text(_text, num_chars), text_type(_text_type) {} @@ -2115,6 +2116,7 @@ namespace stdex _In_opt_ stdex::html::sequence* _end_sequence = nullptr, _In_ uintptr_t data = 0) : text_token(token_t::starting, _text, num_chars_text, text_type, sequence, data), +#pragma warning(suppress: 6387) // Testing indicates _name may be NULL when num_chars_name is also 0. Is SAL of the basic_string::basic_string wrong? name(_name, num_chars_name), end_sequence(_end_sequence) {} @@ -2147,6 +2149,7 @@ namespace stdex token_url_t _encoding = token_url_t::plain, _In_opt_ stdex::html::sequence* sequence = nullptr, _In_ uintptr_t data = 0) : token(token_t::url, sequence, data), +#pragma warning(suppress: 6387) // Testing indicates _url may be NULL when num_chars is also 0. Is SAL of the basic_string::basic_string wrong? url(_url, num_chars), encoding(_encoding) {} @@ -2179,6 +2182,7 @@ namespace stdex _In_reads_or_z_opt_(num_chars) const stdex::schar_t* url = nullptr, _In_ size_t num_chars = 0, _In_ bool parse_frames = false, _In_ stdex::progress* progress = nullptr) : m_document(document), +#pragma warning(suppress: 6387) // Testing indicates url may be NULL when stdex::strnlen(url, num_chars) is also 0. Is SAL of the basic_string::basic_string wrong? m_url(url, stdex::strnlen(url, num_chars)), m_parse_frames(parse_frames), m_progress(progress), diff --git a/include/stdex/parser.hpp b/include/stdex/parser.hpp index 45e859275..c9fcc1753 100644 --- a/include/stdex/parser.hpp +++ b/include/stdex/parser.hpp @@ -34,7 +34,7 @@ #if defined(_MSC_VER) #pragma warning(push) -#pragma warning(disable: 4100) +#pragma warning(disable: 4100) // Tolerate unreferenced parameters to keep the code as clean as possible. #elif defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunknown-pragmas" diff --git a/include/stdex/ring.hpp b/include/stdex/ring.hpp index 8e9a7a9d5..1969445dd 100644 --- a/include/stdex/ring.hpp +++ b/include/stdex/ring.hpp @@ -28,12 +28,13 @@ namespace stdex class ring { public: -#pragma warning(suppress:26495) // Don't bother to initialize m_data ring() : m_head(0), m_size(0), m_quit(false) - {} + { + m_data[0] = 0; + } /// /// Allocates the data after the ring tail. Use push() after the allocated data is populated. diff --git a/include/stdex/stream.hpp b/include/stdex/stream.hpp index 73617363e..72abce434 100644 --- a/include/stdex/stream.hpp +++ b/include/stdex/stream.hpp @@ -2712,7 +2712,7 @@ namespace stdex }; #pragma warning(push) -#pragma warning(disable: 4250) +#pragma warning(disable: 4250) // MSVC naggs but does the right job. /// /// File-system file /// diff --git a/include/stdex/string.hpp b/include/stdex/string.hpp index 32d31b0e1..5e9537af0 100644 --- a/include/stdex/string.hpp +++ b/include/stdex/string.hpp @@ -1701,9 +1701,9 @@ namespace stdex stdex_assert(dst); stdex_assert(src); for (size_t j = 0, i = 0; ; ++j, ++i) { +#ifdef _MSC_VER // strcpy has no knowledge, how big the dst buffer is, but we know, we won't be writing more than strlen(src) + 1 characters into it. // Code Analysis somehow doesn't work this out from the code and the dst SAL above, and reports a false-positive warning. -#ifdef _MSC_VER #pragma warning(suppress: 6386) #endif if ((dst[j] = (is_surrogate_pair(&src[i]) ? surrogate_pair_to_ucs4(&src[i++]) : static_cast(src[i]))) == 0) @@ -1932,13 +1932,14 @@ namespace stdex /// \return Pointer to duplicated string; or nullptr if str is nullptr. Use delete[] operator to free the memory. /// template - _Check_return_ _Ret_maybenull_z_ T* strdup(_In_opt_z_ const T* str) + _Ret_maybenull_z_ T* strdup(_In_opt_z_ const T* str) { if (!str) _Unlikely_ return nullptr; - size_t count = strlen(str) + 1; - T* dst = new T[count]; - strncpy(dst, count, str, SIZE_MAX); + size_t count = strlen(str); + T* dst = new T[count + 1]; + strncpy(dst, str, count); + dst[count] = 0; return dst; } @@ -1955,7 +1956,7 @@ namespace stdex /// \return Pointer to duplicated string. Use delete[] operator to free the memory. /// template - _Ret_z_ T* strndup( + _Ret_notnull_ _Post_maybez_ T* strndup( _In_reads_or_z_opt_(count) const T* str, _In_ size_t count) { @@ -1976,7 +1977,7 @@ namespace stdex /// \return Pointer to duplicated string; or nullptr if str is nullptr. Use delete[] operator to free the memory. /// template - _Check_return_ _Ret_maybenull_z_ T* strndup(_In_ const T(&str)[N]) + _Ret_notnull_ _Post_maybez_ T* strndup(_In_ const T(&str)[N]) { return strndup(str, N); } @@ -2723,7 +2724,7 @@ namespace stdex inline int vsnprintf(_Out_z_cap_(capacity) char* str, _In_ size_t capacity, _In_z_ _Printf_format_string_params_(2) const char* format, _In_opt_ locale_t locale, _In_ va_list arg) { #ifdef _WIN32 -#pragma warning(suppress: 4996) +#pragma warning(suppress: 4996) // We do our own zero-termination. return _vsnprintf_l(str, capacity, format, locale, arg); #else va_list arg_mutable; @@ -2735,7 +2736,7 @@ namespace stdex inline int vsnprintf(_Out_z_cap_(capacity) wchar_t* str, _In_ size_t capacity, _In_z_ _Printf_format_string_params_(2) const wchar_t* format, _In_opt_ locale_t locale, _In_ va_list arg) { #ifdef _WIN32 -#pragma warning(suppress: 4996) +#pragma warning(suppress: 4996) // We do our own zero-termination. return _vsnwprintf_l(str, capacity, format, locale, arg); #else va_list arg_mutable; diff --git a/include/stdex/unicode.hpp b/include/stdex/unicode.hpp index 1fb4f5fbb..34a4d5fef 100644 --- a/include/stdex/unicode.hpp +++ b/include/stdex/unicode.hpp @@ -192,7 +192,7 @@ namespace stdex return; } -#pragma warning(suppress: 4127) +#pragma warning(suppress: 4127) // Can't use precompiler #if on template arguments, using "if" makes MSVC warnings. if constexpr (sizeof(T_from) == sizeof(char) && sizeof(T_to) == sizeof(wchar_t)) { stdex_assert(count_src < INT_MAX || count_src == SIZE_MAX); @@ -218,7 +218,7 @@ namespace stdex throw std::system_error(dwResult, std::system_category(), "MultiByteToWideChar failed"); } -#pragma warning(suppress: 4127) +#pragma warning(suppress: 4127) // Can't use precompiler #if on template arguments, using "if" makes MSVC warnings. if constexpr (sizeof(T_from) == sizeof(wchar_t) && sizeof(T_to) == sizeof(char)) { stdex_assert(count_src < INT_MAX || count_src == SIZE_MAX); @@ -244,7 +244,7 @@ namespace stdex throw std::system_error(dwResult, std::system_category(), "WideCharToMultiByte failed"); } -#pragma warning(suppress: 4127) +#pragma warning(suppress: 4127) // Can't use precompiler #if on template arguments, using "if" makes MSVC warnings. if constexpr (sizeof(T_from) == sizeof(char) && sizeof(T_to) == sizeof(char)) { stdex_assert(count_src < INT_MAX || count_src == SIZE_MAX);