From 2bbed8cc0698e946a084425d8762fb89685b80f7 Mon Sep 17 00:00:00 2001 From: elsid Date: Mon, 2 Jan 2023 17:03:03 +0100 Subject: [PATCH] =?UTF-8?q?Fix=20gcc=20warning:=20array=20subscript=205=20?= =?UTF-8?q?is=20outside=20array=20bounds=20of=20=E2=80=98const=20char=20[5?= =?UTF-8?q?]=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In function ‘bool ESM::operator==(const FixedString&, const T* const&) [with long unsigned int capacity = 5; T = char; = void]’, inlined from ‘testing::AssertionResult testing::internal::CmpHelperEQ(const char*, const char*, const T1&, const T2&) [with T1 = ESM::FixedString<5>; T2 = const char*]’ at /home/elsid/dev/googletest/build/gcc/release/install/include/gtest/gtest.h:1358:11, inlined from ‘static testing::AssertionResult testing::internal::EqHelper::Compare(const char*, const char*, const T1&, const T2&) [with T1 = ESM::FixedString<5>; T2 = const char*; typename std::enable_if<((! std::is_integral<_Tp>::value) || (! std::is_pointer<_Dp>::value))>::type* = 0]’ at /home/elsid/dev/googletest/build/gcc/release/install/include/gtest/gtest.h:1377:64, inlined from ‘virtual void {anonymous}::EsmFixedString_equality_operator_for_not_convertible_to_uint32_with_const_char_pointer_Test::TestBody()’ at apps/openmw_test_suite/esm/test_fixed_string.cpp:165:9: components/esm/esmcommon.hpp:134:19: warning: array subscript 5 is outside array bounds of ‘const char [5]’ [-Warray-bounds] 134 | return rhs[capacity] == '\0'; | ~~~^ apps/openmw_test_suite/esm/test_fixed_string.cpp: In member function ‘virtual void {anonymous}::EsmFixedString_equality_operator_for_not_convertible_to_uint32_with_const_char_pointer_Test::TestBody()’: apps/openmw_test_suite/esm/test_fixed_string.cpp:164:20: note: at offset 5 into object ‘other’ of size 5 164 | const char other[5] = { 'a', 'b', 'c', 'd', '\0' }; | ^~~~~ --- .../esm/test_fixed_string.cpp | 15 ++++++++++++++ components/esm/esmcommon.hpp | 20 ++++++++++++------- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/apps/openmw_test_suite/esm/test_fixed_string.cpp b/apps/openmw_test_suite/esm/test_fixed_string.cpp index f3d4071c28..76ed346daa 100644 --- a/apps/openmw_test_suite/esm/test_fixed_string.cpp +++ b/apps/openmw_test_suite/esm/test_fixed_string.cpp @@ -170,4 +170,19 @@ namespace const ESM::FixedString<5> value("abcd"); EXPECT_EQ(value, std::string("abcd")); } + + TEST(EsmFixedString, equality_operator_for_not_convertible_to_uint32_with_string_view) + { + const ESM::FixedString<5> value("abcd"); + const std::string other("abcd"); + EXPECT_EQ(value, std::string_view(other)); + } + + TEST(EsmFixedString, equality_operator_should_not_get_out_of_bounds) + { + ESM::FixedString<5> value; + const char other[5] = { 'a', 'b', 'c', 'd', 'e' }; + std::memcpy(value.mData, other, sizeof(other)); + EXPECT_EQ(value, static_cast(other)); + } } diff --git a/components/esm/esmcommon.hpp b/components/esm/esmcommon.hpp index f272fa553e..e12a4703ce 100644 --- a/components/esm/esmcommon.hpp +++ b/components/esm/esmcommon.hpp @@ -121,23 +121,23 @@ namespace ESM } }; - template >> - inline bool operator==(const FixedString& lhs, const T* const& rhs) noexcept + template + inline bool operator==(const FixedString& lhs, std::string_view rhs) noexcept { - for (std::size_t i = 0; i < capacity; ++i) + for (std::size_t i = 0, n = std::min(rhs.size(), capacity); i < n; ++i) { if (lhs.mData[i] != rhs[i]) return false; if (lhs.mData[i] == '\0') return true; } - return rhs[capacity] == '\0'; + return rhs.size() <= capacity || rhs[capacity] == '\0'; } - template - inline bool operator==(const FixedString& lhs, const std::string& rhs) noexcept + template >> + inline bool operator==(const FixedString& lhs, const T* const& rhs) noexcept { - return lhs == rhs.c_str(); + return lhs == std::string_view(rhs, capacity); } template @@ -156,6 +156,12 @@ namespace ESM return lhs.toInt() == rhs.toInt(); } + template >> + inline bool operator==(const FixedString<4>& lhs, const T* const& rhs) noexcept + { + return lhs == std::string_view(rhs, 5); + } + template inline bool operator!=(const FixedString& lhs, const Rhs& rhs) noexcept {