Skip to content

Commit ac1a0f1

Browse files
authored
Merge pull request eclipse-iceoryx#1915 from ApexAI/iox-1394-fix-axivion-warnings-in-string
iox-eclipse-iceoryx#1394 Fix Axivion warnings in 'string'
2 parents 0487837 + fc94ecd commit ac1a0f1

File tree

3 files changed

+43
-36
lines changed

3 files changed

+43
-36
lines changed

iceoryx_hoofs/vocabulary/include/iox/detail/string.inl

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ inline string<Capacity>::string(const char (&other)[N]) noexcept
106106
template <uint64_t Capacity>
107107
// NOLINTNEXTLINE(hicpp-named-parameter, readability-named-parameter) justification in header
108108
inline string<Capacity>::string(TruncateToCapacity_t, const char* const other) noexcept
109-
: string(TruncateToCapacity, other, [&other]() -> uint64_t {
109+
: string(TruncateToCapacity, other, [&other]() noexcept -> uint64_t {
110110
return (other != nullptr) ? strnlen(other, Capacity) : 0U;
111111
}())
112112
{
@@ -123,13 +123,13 @@ inline string<Capacity>::string(TruncateToCapacity_t, const char* const other, c
123123
}
124124
else if (Capacity < count)
125125
{
126-
// AXIVION DISABLE STYLE AutosarC++19_03-A16.0.1: conditional compilation is required for setting gcc diagnostics, since
126+
// AXIVION DISABLE STYLE AutosarC++19_03-A16.0.1, AutosarC++19_03-A16.7.1: conditional compilation is required for setting gcc diagnostics, since
127127
// gcc 8 incorrectly warns here about out of bounds array access
128128
#if (defined(__GNUC__) && (__GNUC__ == 8)) && (__GNUC_MINOR__ >= 3)
129129
#pragma GCC diagnostic push
130130
#pragma GCC diagnostic ignored "-Warray-bounds"
131131
#endif
132-
std::memcpy(&(m_rawstring[0]), other, Capacity);
132+
std::memcpy(m_rawstring, other, Capacity);
133133
#if (defined(__GNUC__) && (__GNUC__ == 8)) && (__GNUC_MINOR__ >= 3)
134134
#pragma GCC diagnostic pop
135135
#endif
@@ -142,7 +142,7 @@ inline string<Capacity>::string(TruncateToCapacity_t, const char* const other, c
142142
}
143143
else
144144
{
145-
std::memcpy(&(m_rawstring[0]), other, count);
145+
std::memcpy(m_rawstring, other, count);
146146
m_rawstring[count] = '\0';
147147
m_rawstringSize = count;
148148
}
@@ -162,9 +162,9 @@ inline string<Capacity>& string<Capacity>::operator=(const char (&rhs)[N]) noexc
162162
return *this;
163163
}
164164

165-
std::memcpy(&(m_rawstring[0]), rhs, N);
165+
std::memcpy(m_rawstring, rhs, N);
166166

167-
m_rawstringSize = std::min(Capacity, static_cast<uint64_t>(strnlen(rhs, N)));
167+
m_rawstringSize = std::min(Capacity, static_cast<uint64_t>(strnlen(&rhs[0], N)));
168168
m_rawstring[m_rawstringSize] = '\0';
169169

170170
if (rhs[m_rawstringSize] != '\0')
@@ -209,7 +209,7 @@ inline bool string<Capacity>::unsafe_assign(const char* const str) noexcept
209209
<< Capacity << ") of the fixed string.";
210210
return false;
211211
}
212-
std::memcpy(&(m_rawstring[0]), str, strSize);
212+
std::memcpy(m_rawstring, str, strSize);
213213
m_rawstring[strSize] = '\0';
214214
m_rawstringSize = strSize;
215215
return true;
@@ -219,23 +219,24 @@ template <uint64_t Capacity>
219219
template <typename T>
220220
inline IsStringOrCharArray<T, int64_t> string<Capacity>::compare(const T& other) const noexcept
221221
{
222-
uint64_t otherSize{internal::GetSize<T>::call(other)};
223-
auto result = memcmp(c_str(), internal::GetData<T>::call(other), std::min(m_rawstringSize, otherSize));
222+
const uint64_t otherSize{internal::GetSize<T>::call(other)};
223+
const auto result = memcmp(c_str(), internal::GetData<T>::call(other), std::min(m_rawstringSize, otherSize));
224224
if (result == 0)
225225
{
226226
if (m_rawstringSize < otherSize)
227227
{
228228
return -1;
229229
}
230-
return ((m_rawstringSize > otherSize) ? 1 : 0);
230+
const int64_t isLargerThanOther{(m_rawstringSize > otherSize) ? 1L : 0L};
231+
return isLargerThanOther;
231232
}
232233
return result;
233234
}
234235

235236
template <uint64_t Capacity>
236237
inline int64_t string<Capacity>::compare(char other) const noexcept
237238
{
238-
auto result = memcmp(c_str(), &other, 1U);
239+
const auto result = memcmp(c_str(), &other, 1U);
239240
if (result == 0)
240241
{
241242
if (empty())
@@ -250,7 +251,7 @@ inline int64_t string<Capacity>::compare(char other) const noexcept
250251
template <uint64_t Capacity>
251252
inline const char* string<Capacity>::c_str() const noexcept
252253
{
253-
return &m_rawstring[0];
254+
return m_rawstring;
254255
}
255256

256257
template <uint64_t Capacity>
@@ -284,8 +285,8 @@ inline string<Capacity>& string<Capacity>::copy(const string<N>& rhs) noexcept
284285
{
285286
static_assert(N <= Capacity,
286287
"Assignment failed. The capacity of the given fixed string is larger than the capacity of this.");
287-
uint64_t strSize{rhs.size()};
288-
std::memcpy(&(m_rawstring[0]), rhs.c_str(), strSize);
288+
const uint64_t strSize{rhs.size()};
289+
std::memcpy(m_rawstring, rhs.c_str(), strSize);
289290
m_rawstring[strSize] = '\0';
290291
m_rawstringSize = strSize;
291292
return *this;
@@ -298,7 +299,7 @@ inline string<Capacity>& string<Capacity>::move(string<N>&& rhs) noexcept
298299
static_assert(N <= Capacity,
299300
"Assignment failed. The capacity of the given fixed string is larger than the capacity of this.");
300301
const uint64_t strSize{rhs.size()};
301-
std::memcpy(&(m_rawstring[0]), rhs.c_str(), strSize);
302+
std::memcpy(m_rawstring, rhs.c_str(), strSize);
302303
m_rawstring[strSize] = '\0';
303304
m_rawstringSize = strSize;
304305
rhs.clear();
@@ -341,8 +342,8 @@ concatenate(const T1& str1, const T2& str2) noexcept
341342
uint64_t size2{internal::GetSize<T2>::call(str2)};
342343
using NewStringType = string<internal::SumCapa<T1, T2>::value>;
343344
NewStringType newString;
344-
std::memcpy(&(newString.m_rawstring[0]), internal::GetData<T1>::call(str1), size1);
345-
std::memcpy(&(newString.m_rawstring[0]) + size1, internal::GetData<T2>::call(str2), size2);
345+
std::memcpy(newString.m_rawstring, internal::GetData<T1>::call(str1), size1);
346+
std::memcpy(&newString.m_rawstring[size1], internal::GetData<T2>::call(str2), size2);
346347
newString.m_rawstring[size1 + size2] = '\0';
347348
newString.m_rawstringSize = size1 + size2;
348349

@@ -369,9 +370,9 @@ template <uint64_t Capacity>
369370
template <typename T>
370371
inline IsStringOrCharArrayOrChar<T, bool> string<Capacity>::unsafe_append(const T& str) noexcept
371372
{
372-
uint64_t tSize{internal::GetSize<T>::call(str)};
373-
const char* tData{internal::GetData<T>::call(str)};
374-
uint64_t clampedTSize{std::min(Capacity - m_rawstringSize, tSize)};
373+
const uint64_t tSize{internal::GetSize<T>::call(str)};
374+
const char* const tData{internal::GetData<T>::call(str)};
375+
const uint64_t clampedTSize{std::min(Capacity - m_rawstringSize, tSize)};
375376

376377
if (tSize > clampedTSize)
377378
{
@@ -392,14 +393,14 @@ template <typename T>
392393
inline IsStringOrCharArrayOrChar<T, string<Capacity>&> string<Capacity>::append(TruncateToCapacity_t,
393394
const T& str) noexcept
394395
{
395-
uint64_t tSize{internal::GetSize<T>::call(str)};
396-
const char* tData{internal::GetData<T>::call(str)};
397-
uint64_t clampedTSize{std::min(Capacity - m_rawstringSize, tSize)};
396+
const uint64_t tSize{internal::GetSize<T>::call(str)};
397+
const char* const tData{internal::GetData<T>::call(str)};
398+
uint64_t const clampedTSize{std::min(Capacity - m_rawstringSize, tSize)};
398399

399400
std::memcpy(&(m_rawstring[m_rawstringSize]), tData, clampedTSize);
400401
if (tSize > clampedTSize)
401402
{
402-
IOX_LOG(WARN) << "The last " << (tSize - Capacity) + m_rawstringSize << " characters of " << tData
403+
IOX_LOG(WARN) << "The last " << (tSize - clampedTSize) << " characters of " << tData
403404
<< " are truncated, because the length is larger than the capacity.";
404405
}
405406

@@ -430,6 +431,7 @@ template <typename T>
430431
inline IsCxxStringOrCharArray<T, bool>
431432
string<Capacity>::insert(const uint64_t pos, const T& str, const uint64_t count) noexcept
432433
{
434+
// AXIVION Next Construct AutosarC++19_03-M0.1.2, AutosarC++19_03-M0.1.9, FaultDetection-DeadBranches : False positive! Branching depends on input parameter
433435
if (count > internal::GetSize<T>::call(str))
434436
{
435437
return false;
@@ -441,6 +443,7 @@ string<Capacity>::insert(const uint64_t pos, const T& str, const uint64_t count)
441443
return false;
442444
}
443445

446+
// AXIVION Next Construct AutosarC++19_03-M0.1.2, AutosarC++19_03-M0.1.9, FaultDetection-DeadBranches : False positive! Branching depends on input parameter
444447
if (pos > m_rawstringSize)
445448
{
446449
return false;
@@ -462,9 +465,9 @@ inline optional<string<Capacity>> string<Capacity>::substr(const uint64_t pos, c
462465
return nullopt;
463466
}
464467

465-
uint64_t length{std::min(count, m_rawstringSize - pos)};
468+
const uint64_t length{std::min(count, m_rawstringSize - pos)};
466469
string subString;
467-
std::memcpy(&(subString.m_rawstring[0]), &m_rawstring[pos], length);
470+
std::memcpy(subString.m_rawstring, &m_rawstring[pos], length);
468471
subString.m_rawstring[length] = '\0';
469472
subString.m_rawstringSize = length;
470473
return subString;
@@ -498,15 +501,16 @@ template <typename T>
498501
inline IsStringOrCharArray<T, optional<uint64_t>> string<Capacity>::find_first_of(const T& str,
499502
const uint64_t pos) const noexcept
500503
{
504+
// AXIVION Next Construct AutosarC++19_03-M0.1.2, AutosarC++19_03-M0.1.9, FaultDetection-DeadBranches : False positive! Branching depends on input parameter
501505
if (pos > m_rawstringSize)
502506
{
503507
return nullopt;
504508
}
505-
const char* found{nullptr};
506-
const char* data{internal::GetData<T>::call(str)};
509+
const char* const data{internal::GetData<T>::call(str)};
510+
const uint64_t dataSize{internal::GetSize<T>::call(str)};
507511
for (auto p = pos; p < m_rawstringSize; ++p)
508512
{
509-
found = std::strchr(data, m_rawstring[p]);
513+
const void* const found{memchr(data, m_rawstring[p], dataSize)};
510514
if (found != nullptr)
511515
{
512516
return p;
@@ -530,17 +534,17 @@ inline IsStringOrCharArray<T, optional<uint64_t>> string<Capacity>::find_last_of
530534
{
531535
p = m_rawstringSize - 1U;
532536
}
533-
const char* found{nullptr};
534-
const char* data{internal::GetData<T>::call(str)};
537+
const char* const data{internal::GetData<T>::call(str)};
538+
const uint64_t dataSize{internal::GetSize<T>::call(str)};
535539
for (; p > 0U; --p)
536540
{
537-
found = std::strchr(data, m_rawstring[p]);
541+
const void* const found{memchr(data, m_rawstring[p], dataSize)};
538542
if (found != nullptr)
539543
{
540544
return p;
541545
}
542546
}
543-
found = std::strchr(data, m_rawstring[p]);
547+
const void* const found{memchr(data, m_rawstring[p], dataSize)};
544548
if (found != nullptr)
545549
{
546550
return 0U;
@@ -614,12 +618,14 @@ inline IsStdStringOrCharArrayOrChar<T, bool> operator>=(const T& lhs, const stri
614618
return (rhs.compare(lhs) <= 0);
615619
}
616620

621+
// AXIVION Next Construct AutosarC++19_03-A13.5.4 : Code reuse is established by a helper function
617622
template <typename T, uint64_t Capacity>
618623
inline IsStringOrCharArrayOrChar<T, bool> operator==(const string<Capacity>& lhs, const T& rhs) noexcept
619624
{
620625
return (lhs.compare(rhs) == 0);
621626
}
622627

628+
// AXIVION Next Construct AutosarC++19_03-A13.5.4 : Code reuse is established by a helper function
623629
template <typename T, uint64_t Capacity>
624630
inline IsStringOrCharArrayOrChar<T, bool> operator!=(const string<Capacity>& lhs, const T& rhs) noexcept
625631
{

iceoryx_hoofs/vocabulary/include/iox/detail/string_internal.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,10 @@ template <uint64_t N>
8686
// NOLINTNEXTLINE(hicpp-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays)
8787
struct GetSize<char[N]>
8888
{
89+
// AXIVION Next Construct FaultDetection-TaintAnalysis : False positive! The size of the type is deduced
8990
static uint64_t call(const charArray<N>& data) noexcept
9091
{
91-
return strnlen(data, N);
92+
return strnlen(&data[0], N);
9293
}
9394
};
9495

iceoryx_hoofs/vocabulary/include/iox/string.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -532,8 +532,8 @@ class string final
532532
template <uint64_t N>
533533
string& move(string<N>&& rhs) noexcept;
534534

535-
// safe access is guaranteed since the char array is wrapped inside the string class
536-
// NOLINTNEXTLINE(hicpp-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays)
535+
// AXIVION Next Construct FaultDetection-IndirectAssignmentOverflow : False positive. Overflow checks are done before assigning and the data will be truncated if necessary
536+
// NOLINTNEXTLINE(hicpp-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays) safe access is guaranteed since the char array is wrapped inside the string class
537537
char m_rawstring[Capacity + 1]{};
538538
uint64_t m_rawstringSize{0U};
539539
};

0 commit comments

Comments
 (0)