diff --git a/quality/static_analysis/coding-standards.yaml b/quality/static_analysis/coding-standards.yaml index 58fe148688..7cc783e94f 100644 --- a/quality/static_analysis/coding-standards.yaml +++ b/quality/static_analysis/coding-standards.yaml @@ -24,6 +24,21 @@ deviations: code-identifier: "shared-memory-align-const-cast" scope: "Applies only to the specific const_cast marked with this code identifier in score/memory/shared/shared_memory_resource.cpp. This code-identifier must not be used anywhere else in the codebase." justification: "`do_allocation_algorithm` uses `std::align`, whose `void*&` out-parameter cannot bind to the `const void*` input pointer. `std::align` only reads and arithmetically adjusts the pointer value to compute an aligned address within the given buffer; it never writes through the pointer to modify the pointee (https://timsong-cpp.github.io/cppwp/n4659/ptr.align#lib:align). The const qualification of `alloc_start` is therefore not violated at runtime, and the `const_cast` is required purely to satisfy `std::align`'s non-const parameter type." + - rule-id: "RULE-7-0-5" + query-id: "cpp/misra/no-signedness-change-from-promotion" + code-identifier: "switch-enum-underlying-type-discriminant" + scope: "Applies only to the `switch` statement conditions and `case` labels marked with this code identifier in score/message_passing/client_connection.cpp, score/message_passing/unix_domain/unix_domain_server.cpp, and score/mw/com/impl/bindings/lola/messaging/message_passing_service_instance.cpp. This code-identifier must not be used anywhere else in the codebase." + justification: "These `switch` statements dispatch on a message/protocol byte (an unsigned narrow integral type, e.g. `std::uint8_t`) against `case` labels built from `score::cpp::to_underlying(EnumType::Value)`. The C++ language unconditionally applies integral promotion to a `switch` statement's controlling expression, and separately converts every `case` label's constant expression to that same promoted type, before the dispatch comparison is performed. This conversion is a fixed part of the `switch`/`case` language mechanism itself: it cannot be intercepted, wrapped, or replaced by any function call (including safe-comparison helpers such as `score::safe_math::CmpEqual`), because a `case` label must be an integer constant expression usable directly in the statement, not a function call result. The dispatch is not a source of misbehavior: it is a straightforward point-wise comparison for equality between the promoted controlling value and each promoted case constant, which cannot be affected by the promotion's signedness change (both sides undergo the exact same conversion, so equality is preserved)." + - rule-id: "RULE-7-0-5" + query-id: "cpp/misra/no-signedness-change-from-promotion" + code-identifier: "ctype-function-argument-promotion" + scope: "Applies only to the argument-conversion of an `unsigned char` value passed to a `` classification/conversion function (e.g. `std::isalpha`, `std::isalnum`), marked with this code identifier in score/mw/com/impl/instance_specifier.cpp. This code-identifier must not be used anywhere else in the codebase." + justification: "The C++ standard library's `` functions take an `int` parameter that must hold either `EOF` or the value of an `unsigned char` (https://eel.is/c++draft/character.seq#classification.functions). Passing an `unsigned char` value to such a function unavoidably requires the compiler to implicitly convert it to `int`, which is exactly what the marked line does (`static_cast(curent_char)` immediately followed by `std::isalpha`/`std::isalnum`). This conversion is mandated by the standard library's own API contract; it is not a signedness defect in this code, and there is no function-level wrapper that can avoid it, since the conversion happens at the call boundary of a fixed, non-overloadable standard library signature." + - rule-id: "RULE-7-0-5" + query-id: "cpp/misra/no-signedness-change-from-promotion" + code-identifier: "compile-time-static-assert-limit-check" + scope: "Applies only to the `static_assert` size-limit check marked with this code identifier in score/mw/com/impl/bindings/lola/tracing/tracing_runtime.cpp." + justification: "The marked expression appears solely inside a `static_assert` condition, evaluated entirely at compile time against `std::numeric_limits<...>::max()` constants; it never executes at runtime and can never observe or propagate a runtime value. Its only purpose is to fail the build if a future change to the underlying typedefs would allow the sum of the two maxima to exceed `TraceContextId`'s range. There is no runtime signedness-change defect for this rule to prevent, and using a `score::safe_math` runtime helper is neither necessary (the check is compile-time only) nor possible (safe_math's checked operations are not usable in this `static_assert`'s constant-expression context in a way that would improve on the existing explicit compile-time check)." guideline-recategorizations: - rule-id: "RULE-0-1-1" category: "disapplied" diff --git a/score/memory/shared/memory_region_map.cpp b/score/memory/shared/memory_region_map.cpp index 3ec01acc8b..aee4b807ac 100644 --- a/score/memory/shared/memory_region_map.cpp +++ b/score/memory/shared/memory_region_map.cpp @@ -303,8 +303,8 @@ auto MemoryRegionMapImpl::AcquireLatestRegionVersionForRea // It would actually need an insane number of threads, which concurrently try to increment the refcount! // We are using this bounded number here instead of a while(true) construct as we are then able to return // std::nullopt and leave it to the layer above to react e.g. with a std::terminate()! - constexpr std::uint8_t max_retries = 255U; - for (std::uint8_t retry_count = 0U; retry_count < max_retries; retry_count++) + constexpr std::uint32_t max_retries = 255U; + for (std::uint32_t retry_count = 0U; retry_count < max_retries; retry_count++) { const uint8_t region_index = latest_known_region_version_.load(std::memory_order_relaxed); const std::uint32_t previous_refcount = AtomicIndirectorType::fetch_add( @@ -340,16 +340,16 @@ std::optional MemoryRegionMapImpl::AcquireRe { // Arbitrary retry value here. It is expected, that when checking all known regions versions, the writer // will find one being unused! Because readers are accessing only the latest for a very short time ... - constexpr std::uint8_t max_retries = 10U; - for (std::uint8_t retry_count = 0U; retry_count < max_retries; retry_count++) + constexpr std::uint32_t max_retries = 10U; + for (std::uint32_t retry_count = 0U; retry_count < max_retries; retry_count++) { // Iterate over version indices starting with the version directly after the current // latest_known_region_version_. That way we are checking the oldest version first, to have the lowest // probability of clashes with readers. - for (std::uint8_t loop_idx = 1U; loop_idx < VERSION_COUNT; loop_idx++) + for (std::uint32_t loop_idx = 1U; loop_idx < VERSION_COUNT; loop_idx++) { - const auto version_idx = static_cast( - (loop_idx + latest_known_region_version_.load(std::memory_order_relaxed)) % VERSION_COUNT); + const std::uint32_t current_version = latest_known_region_version_.load(std::memory_order_relaxed); + const auto version_idx = static_cast((loop_idx + current_version) % VERSION_COUNT); RegionVersionRefCountType cur_ref_count = known_regions_versions_refcounts_.at(static_cast(version_idx)).load(); if (cur_ref_count == 0U) diff --git a/score/memory/shared/memory_region_map.h b/score/memory/shared/memory_region_map.h index 64bc973062..4477213130 100644 --- a/score/memory/shared/memory_region_map.h +++ b/score/memory/shared/memory_region_map.h @@ -138,7 +138,7 @@ class MemoryRegionMapImpl final // being given values that are not subsequently used.". // Rationale: False positive - variable is used below. // coverity[autosar_cpp14_a0_1_1_violation : FALSE] - static constexpr const std::uint8_t VERSION_COUNT{10U}; + static constexpr const std::uint32_t VERSION_COUNT{10U}; static_assert( VERSION_COUNT <= 255U, "VERSION_COUNT needs to be smaller than 255 as our latest_known_region_version_ tracker is an uint8 "); diff --git a/score/memory/shared/shared_memory_resource.cpp b/score/memory/shared/shared_memory_resource.cpp index 8f39e09fef..4546f64cb5 100644 --- a/score/memory/shared/shared_memory_resource.cpp +++ b/score/memory/shared/shared_memory_resource.cpp @@ -211,7 +211,7 @@ ShmObjectStatInfo GetShmObjectStatInfo(const ISharedMemoryResource::FileDescript if (typed_memory_ptr != nullptr) { const auto typedmemd_uid = AcquireTypedMemoryDaemonUid(); - if (is_named_shm && (typedmemd_uid.has_value() && (typedmemd_uid.value() == owner_uid))) + if (is_named_shm && (typedmemd_uid.has_value() && safe_math::CmpEqual(typedmemd_uid.value(), owner_uid))) { // Suppress "AUTOSAR C++14 A0-1-1", The rule states: "A project shall not contain instances of non-volatile // variables being given values that are not subsequently used" diff --git a/score/message_passing/client_connection.cpp b/score/message_passing/client_connection.cpp index c1f6184a90..f6c3d96af0 100644 --- a/score/message_passing/client_connection.cpp +++ b/score/message_passing/client_connection.cpp @@ -468,8 +468,10 @@ IClientConnection::StopReason ClientConnection::ProcessInputEvent() noexcept // This switch statement is considered not well-formed due to early exits, i.e. return statements. // New Misra rule 9.4.2 allows terminating switch statements with a return statement // coverity[autosar_cpp14_m6_4_3_violation] + // Deviation of MISRA RULE-7-0-5: codeql::misra_deviation_next_line(switch-enum-underlying-type-discriminant) switch (code) { + // Deviation of MISRA RULE-7-0-5: codeql::misra_deviation_next_line(switch-enum-underlying-type-discriminant) case score::cpp::to_underlying(ServerToClient::REPLY): { std::unique_lock lock{send_mutex_}; @@ -487,6 +489,7 @@ IClientConnection::StopReason ClientConnection::ProcessInputEvent() noexcept } break; } + // Deviation of MISRA RULE-7-0-5: codeql::misra_deviation_next_line(switch-enum-underlying-type-discriminant) case score::cpp::to_underlying(ServerToClient::NOTIFY): { if (!notify_callback_.empty()) diff --git a/score/message_passing/unix_domain/unix_domain_engine.cpp b/score/message_passing/unix_domain/unix_domain_engine.cpp index c01611a257..7e065b5e58 100644 --- a/score/message_passing/unix_domain/unix_domain_engine.cpp +++ b/score/message_passing/unix_domain/unix_domain_engine.cpp @@ -247,17 +247,23 @@ score::cpp::expected, score::os::Error> Uni // other side disconnected return score::cpp::make_unexpected(score::os::Error::createFromErrno(EPIPE)); } - if (size == 0) + // size itself must stay std::uint16_t: it is read directly into raw memory via the iovec above + // (io[1].iov_len = sizeof(size)), matching the exact 2-byte wire field written by SendProtocolMessage. + // Widening it (e.g. to std::size_t, whose width is even platform/bitness-dependent) would change the + // number of bytes read off the wire and break the protocol. Instead, widen only a local copy used for + // the comparisons below -- size's full range (0..65535) is always exactly representable in std::size_t. + const std::size_t message_size = size; + if (message_size == 0U) { return {}; } - if (size > static_cast(posix_receive_buffer_.size())) + if (message_size > posix_receive_buffer_.size()) { return score::cpp::make_unexpected(score::os::Error::createFromErrno(EMSGSIZE)); } io[0].iov_base = posix_receive_buffer_.data(); - io[0].iov_len = static_cast(size); + io[0].iov_len = message_size; msg.msg_iovlen = 1UL; using MessageFlag = ::score::os::Socket::MessageFlag; @@ -266,7 +272,11 @@ score::cpp::expected, score::os::Error> Uni { return score::cpp::make_unexpected(size_expected.error()); } - if (size_expected.value() != size) + // size_expected.value() is a recvmsg() byte count, which is guaranteed non-negative whenever has_value() + // is true (already checked above), so the signed-to-unsigned cast below never reinterprets a negative + // value. + // coverity[autosar_cpp14_a4_7_1_violation] + if (static_cast(size_expected.value()) != message_size) { return score::cpp::make_unexpected(score::os::Error::createFromErrno(EIO)); } diff --git a/score/message_passing/unix_domain/unix_domain_server.cpp b/score/message_passing/unix_domain/unix_domain_server.cpp index eb87c2d187..e61bed50de 100644 --- a/score/message_passing/unix_domain/unix_domain_server.cpp +++ b/score/message_passing/unix_domain/unix_domain_server.cpp @@ -109,14 +109,17 @@ bool UnixDomainServer::ServerConnection::ProcessInput() return false; } auto message = message_expected.value(); + // Deviation of MISRA RULE-7-0-5: codeql::misra_deviation_next_line(switch-enum-underlying-type-discriminant) switch (code) { + // Deviation of MISRA RULE-7-0-5: codeql::misra_deviation_next_line(switch-enum-underlying-type-discriminant) case score::cpp::to_underlying(ClientToServer::REQUEST): return (std::holds_alternative(user_data) ? std::get(user_data)->OnMessageSentWithReply(*this, message) : server_.sent_with_reply_callback_(*this, message)) .has_value(); + // Deviation of MISRA RULE-7-0-5: codeql::misra_deviation_next_line(switch-enum-underlying-type-discriminant) case score::cpp::to_underlying(ClientToServer::SEND): return (std::holds_alternative(user_data) ? std::get(user_data)->OnMessageSent(*this, message) diff --git a/score/mw/com/impl/bindings/lola/BUILD b/score/mw/com/impl/bindings/lola/BUILD index 66ed7c89fc..689402ea2f 100644 --- a/score/mw/com/impl/bindings/lola/BUILD +++ b/score/mw/com/impl/bindings/lola/BUILD @@ -434,6 +434,7 @@ cc_library( "//score/mw/com/impl:runtime", "//score/mw/com/impl/bindings/lola:partial_restart_path_builder", "@score_baselibs//score/language/safecpp/safe_atomics:try_atomic_add", + "@score_baselibs//score/language/safecpp/safe_math", "@score_baselibs//score/os:errno_logging", ], tags = ["FFI"], @@ -491,6 +492,7 @@ cc_library( deps = [ "//score/mw/com/impl:service_element_type", "//score/mw/com/impl/configuration", + "@score_baselibs//score/language/safecpp/safe_math", "@score_baselibs//score/mw/log", ], ) @@ -560,6 +562,7 @@ cc_library( "//score/mw/com/impl:subscription_state", "//score/mw/com/impl:subscription_state_change_handler", "//score/mw/com/impl/bindings/lola/messaging:i_message_passing_service", + "@score_baselibs//score/language/safecpp/safe_math", ], ) @@ -642,6 +645,7 @@ cc_library( ":event_data_control", ":event_slot_status", "@score_baselibs//score/concurrency:atomic_indirector", + "@score_baselibs//score/language/safecpp/safe_math", ], ) @@ -764,6 +768,7 @@ cc_library( deps = [ ":control_slot_types", ":event_data_control_composite", + "@score_baselibs//score/language/safecpp/safe_math", ], ) @@ -872,6 +877,7 @@ cc_library( "//score/mw/com/impl/configuration", "//score/mw/com/impl/util:copyable_atomic", "@score_baselibs//score/containers:dynamic_array", + "@score_baselibs//score/language/safecpp/safe_math", "@score_baselibs//score/result", "@score_baselibs//score/scope_exit", ], @@ -933,6 +939,7 @@ cc_library( ], deps = [ "//score/mw/com/impl/configuration", + "@score_baselibs//score/language/safecpp/safe_math", "@score_baselibs//score/mw/log", ], ) @@ -948,6 +955,7 @@ cc_library( ], deps = [ "//score/mw/com/impl/configuration", + "@score_baselibs//score/language/safecpp/safe_math", "@score_baselibs//score/mw/log", ], ) diff --git a/score/mw/com/impl/bindings/lola/element_fq_id.cpp b/score/mw/com/impl/bindings/lola/element_fq_id.cpp index e196e3c677..d97bbf1334 100644 --- a/score/mw/com/impl/bindings/lola/element_fq_id.cpp +++ b/score/mw/com/impl/bindings/lola/element_fq_id.cpp @@ -12,6 +12,7 @@ ********************************************************************************/ #include "score/mw/com/impl/bindings/lola/element_fq_id.h" +#include "score/language/safecpp/safe_math/safe_math.h" #include "score/mw/log/logging.h" #include @@ -40,7 +41,7 @@ ElementFqId::ElementFqId(const ServiceId service_id, // range coverity[autosar_cpp14_a7_2_1_violation] : ElementFqId(service_id, element_id, instance_id, static_cast(element_type)) { - if (element_type > static_cast(ServiceElementType::FIELD)) + if (safe_math::CmpGreater(element_type, static_cast(ServiceElementType::FIELD))) { score::mw::log::LogFatal("lola") << "ElementFqId::ElementFqId failed: Invalid ServiceElementType:" << element_type; @@ -83,21 +84,22 @@ bool operator==(const ElementFqId& lhs, const ElementFqId& rhs) noexcept // This a false-positive, all operands are parenthesized. // A bug ticket has been created to track this: [Ticket-165315](broken_link_j/Ticket-165315) // coverity[autosar_cpp14_a5_2_6_violation : FALSE] - return ((lhs.service_id_ == rhs.service_id_) && (lhs.element_id_ == rhs.element_id_) && - (lhs.instance_id_ == rhs.instance_id_)); + return (safe_math::CmpEqual(lhs.service_id_, rhs.service_id_) && + safe_math::CmpEqual(lhs.element_id_, rhs.element_id_) && + safe_math::CmpEqual(lhs.instance_id_, rhs.instance_id_)); } bool operator<(const ElementFqId& lhs, const ElementFqId& rhs) noexcept { - if (lhs.service_id_ == rhs.service_id_) + if (safe_math::CmpEqual(lhs.service_id_, rhs.service_id_)) { - if (lhs.instance_id_ == rhs.instance_id_) + if (safe_math::CmpEqual(lhs.instance_id_, rhs.instance_id_)) { - return lhs.element_id_ < rhs.element_id_; + return safe_math::CmpLess(lhs.element_id_, rhs.element_id_); } - return lhs.instance_id_ < rhs.instance_id_; + return safe_math::CmpLess(lhs.instance_id_, rhs.instance_id_); } - return lhs.service_id_ < rhs.service_id_; + return safe_math::CmpLess(lhs.service_id_, rhs.service_id_); } // Suppress "AUTOSAR C++14 A13-2-2" rule finding: "A binary arithmetic operator and a bitwise operator shall return diff --git a/score/mw/com/impl/bindings/lola/event_subscription_control.cpp b/score/mw/com/impl/bindings/lola/event_subscription_control.cpp index 7bf0af3150..ddf96c17b8 100644 --- a/score/mw/com/impl/bindings/lola/event_subscription_control.cpp +++ b/score/mw/com/impl/bindings/lola/event_subscription_control.cpp @@ -79,27 +79,31 @@ auto EventSubscriptionControl::Subscribe(SlotNumberType sl auto current_state = current_subscription_state_.load(); const auto current_subscribers = GetSubscribersFromState(current_state); - if (current_subscribers >= max_subscribers_) + if (safe_math::CmpGreaterEqual(current_subscribers, max_subscribers_)) { mw::log::LogInfo("lola") << "EventSubscriptionControl<>::Subscribe() rejected as already max_subscribers_ are subscribed."; return SubscribeResult::kMaxSubscribersOverflow; } SlotNumberType current_subscribed_slots = GetSubscribedSamplesFromState(current_state); - if ((enforce_max_samples_) && ((current_subscribed_slots + slot_count) > max_subscribable_slots_)) + if ((enforce_max_samples_) && safe_math::CmpGreater(safe_math::Add( + current_subscribed_slots, slot_count), + max_subscribable_slots_)) { mw::log::LogInfo("lola") << "EventSubscriptionControl<>::Subscribe() rejected as max_subscribable_slots_ would overflow."; return SubscribeResult::kSlotOverflow; } - std::uint32_t new_state = CreateState(static_cast(current_subscribers + 1U), - // Suppress "AUTOSAR C++14 A4-7-1" rule finding. This rule states: "An - // integer expression shall not lead to data loss.". The check above - // ensures that the addition result will not exceed its maximum value for - // std::uint16_t type. - // coverity[autosar_cpp14_a4_7_1_violation] - static_cast(current_subscribed_slots + slot_count)); + std::uint32_t new_state = + CreateState(static_cast(current_subscribers + 1U), + // Suppress "AUTOSAR C++14 A4-7-1" rule finding. This rule states: "An + // integer expression shall not lead to data loss.". The check above + // ensures that the addition result will not exceed its maximum value for + // std::uint16_t type. + // coverity[autosar_cpp14_a4_7_1_violation] + static_cast(safe_math::Add( + current_subscribed_slots, slot_count))); auto success = AtomicIndirectorType::compare_exchange_weak( current_subscription_state_, current_state, new_state, std::memory_order_acq_rel); if (success) @@ -138,7 +142,7 @@ auto EventSubscriptionControl::Unsubscribe(SlotNumberType std::terminate(); } SlotNumberType current_subscribed_slots = GetSubscribedSamplesFromState(current_state); - if (current_subscribed_slots < slot_count) + if (safe_math::CmpLess(current_subscribed_slots, slot_count)) { mw::log::LogFatal("lola") << "EventSubscriptionControl<>::Unsubscribe() rejected as currently subscribed slots " @@ -146,8 +150,10 @@ auto EventSubscriptionControl::Unsubscribe(SlotNumberType std::terminate(); } - std::uint32_t new_state = CreateState(static_cast(current_subscribers - 1U), - static_cast(current_subscribed_slots - slot_count)); + std::uint32_t new_state = + CreateState(static_cast(current_subscribers - 1U), + static_cast(safe_math::Subtract( + current_subscribed_slots, slot_count))); auto success = AtomicIndirectorType::compare_exchange_weak( current_subscription_state_, current_state, new_state, std::memory_order_acq_rel); if (success) diff --git a/score/mw/com/impl/bindings/lola/messaging/message_passing_service_instance.cpp b/score/mw/com/impl/bindings/lola/messaging/message_passing_service_instance.cpp index b5d2a7410b..843fd32de0 100644 --- a/score/mw/com/impl/bindings/lola/messaging/message_passing_service_instance.cpp +++ b/score/mw/com/impl/bindings/lola/messaging/message_passing_service_instance.cpp @@ -384,17 +384,22 @@ void MessagePassingServiceInstance::MessageCallback(const pid_t sender_pid, return; } const auto payload = message.subspan(1U); + // Deviation of MISRA RULE-7-0-5: codeql::misra_deviation_next_line(switch-enum-underlying-type-discriminant) switch (message.front()) { + // Deviation of MISRA RULE-7-0-5: codeql::misra_deviation_next_line(switch-enum-underlying-type-discriminant) case score::cpp::to_underlying(MessageType::kRegisterEventNotifier): HandleRegisterNotificationMsg(payload, sender_pid); break; + // Deviation of MISRA RULE-7-0-5: codeql::misra_deviation_next_line(switch-enum-underlying-type-discriminant) case score::cpp::to_underlying(MessageType::kUnregisterEventNotifier): HandleUnregisterNotificationMsg(payload, sender_pid); break; + // Deviation of MISRA RULE-7-0-5: codeql::misra_deviation_next_line(switch-enum-underlying-type-discriminant) case score::cpp::to_underlying(MessageType::kNotifyEvent): HandleNotifyEventMsg(payload, sender_pid); break; + // Deviation of MISRA RULE-7-0-5: codeql::misra_deviation_next_line(switch-enum-underlying-type-discriminant) case score::cpp::to_underlying(MessageType::kOutdatedNodeId): HandleOutdatedNodeIdMsg(payload, sender_pid); break; @@ -416,16 +421,20 @@ score::Result MessagePassingServiceInstance::MessageCallbackWithReply( return MakeUnexpected(MethodErrc::kUnexpectedMessageSize); } const auto payload = message.subspan(1U); + // Deviation of MISRA RULE-7-0-5: codeql::misra_deviation_next_line(switch-enum-underlying-type-discriminant) switch (message.front()) { + // Deviation of MISRA RULE-7-0-5: codeql::misra_deviation_next_line(switch-enum-underlying-type-discriminant) case score::cpp::to_underlying(MessageWithReplyType::kSubscribeServiceMethod): { return HandleSubscribeServiceMethodMsg(payload, sender_uid, sender_pid); } + // Deviation of MISRA RULE-7-0-5: codeql::misra_deviation_next_line(switch-enum-underlying-type-discriminant) case score::cpp::to_underlying(MessageWithReplyType::kUnsubscribeServiceMethod): { return HandleUnsubscribeServiceMethodMsg(payload, sender_pid); } + // Deviation of MISRA RULE-7-0-5: codeql::misra_deviation_next_line(switch-enum-underlying-type-discriminant) case score::cpp::to_underlying(MessageWithReplyType::kCallMethod): { return HandleCallMethodMsg(payload, sender_uid); @@ -899,7 +908,7 @@ void MessagePassingServiceInstance::NotifyEventRemote(const ElementFqId event_id nodeIdentifiersTmp, start_node_id); // send NotifyEventUpdateMessage to each node_id in nodeIdentifiersTmp - for (std::uint8_t i = 0U; i < num_ids_copied.first; i++) + for (std::uint8_t i = 0U; score::safe_math::CmpLess(i, num_ids_copied.first); i++) { // Suppress "AUTOSAR C++14 M5-0-3" rule findings. This rule states: "A cvalue expression shall // not be implicitly converted to a different underlying type" @@ -962,7 +971,7 @@ std::uint32_t MessagePassingServiceInstance::NotifyEventLocally(const ElementFqI // tmp-storage for all handlers (weak_ptrs), which will get filled under read-lock std::array, kMaxReceiveHandlersPerEvent> handler_weak_ptrs{ {{}, {}, {}, {}, {}}}; - std::uint8_t number_weak_ptrs_copied{0U}; + std::uint32_t number_weak_ptrs_copied{0U}; auto& handlers_for_event = search->second; auto handler_it = handlers_for_event.cbegin(); // LCOV_EXCL_START: decision couldn't be analyzed; considered normal under 100% line coverage @@ -988,7 +997,7 @@ std::uint32_t MessagePassingServiceInstance::NotifyEventLocally(const ElementFqI } // Call the handlers outside the read-lock - for (std::uint8_t i = 0U; i < number_weak_ptrs_copied; i++) + for (std::uint32_t i = 0U; i < number_weak_ptrs_copied; i++) { // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index): "i" is assured to be within array bounds. if (auto current_handler = handler_weak_ptrs[i].lock()) diff --git a/score/mw/com/impl/bindings/lola/messaging/message_passing_service_instance.h b/score/mw/com/impl/bindings/lola/messaging/message_passing_service_instance.h index f2e124784b..2487737623 100644 --- a/score/mw/com/impl/bindings/lola/messaging/message_passing_service_instance.h +++ b/score/mw/com/impl/bindings/lola/messaging/message_passing_service_instance.h @@ -172,7 +172,7 @@ class MessagePassingServiceInstance : public IMessagePassingServiceInstance // false-positive: is used to define the size of buffer for handlers // coverity[autosar_cpp14_a0_1_1_violation] - static constexpr std::uint8_t kMaxReceiveHandlersPerEvent{5U}; + static constexpr std::uint32_t kMaxReceiveHandlersPerEvent{5U}; // false-positive: is used to define the size of tmp array for node IDs // coverity[autosar_cpp14_a0_1_1_violation] diff --git a/score/mw/com/impl/bindings/lola/messaging/message_passing_service_instance_test.cpp b/score/mw/com/impl/bindings/lola/messaging/message_passing_service_instance_test.cpp index e7e241628d..2218c097d2 100644 --- a/score/mw/com/impl/bindings/lola/messaging/message_passing_service_instance_test.cpp +++ b/score/mw/com/impl/bindings/lola/messaging/message_passing_service_instance_test.cpp @@ -345,7 +345,7 @@ TEST_F(MessagePassingServiceInstanceTest, NotifyEventLocallyCallsNoMoreThanMaxPo }); // and handler being registered for event (max_receive_handlers_per_event + 2) times - for (auto i = 0; i < MessagePassingServiceInstanceAttorney::max_receive_handlers_per_event + 2; ++i) + for (auto i = 0U; i < MessagePassingServiceInstanceAttorney::max_receive_handlers_per_event + 2U; ++i) { instance.RegisterEventNotification(event_id_, handler, local_pid_); } diff --git a/score/mw/com/impl/bindings/lola/methods/BUILD b/score/mw/com/impl/bindings/lola/methods/BUILD index 3bfeba5080..105521c865 100644 --- a/score/mw/com/impl/bindings/lola/methods/BUILD +++ b/score/mw/com/impl/bindings/lola/methods/BUILD @@ -135,6 +135,7 @@ cc_library( "//score/mw/com/impl/configuration:lola_field_id", "//score/mw/com/impl/configuration:lola_method_id", "//score/mw/com/impl/configuration:lola_service_element_id", + "@score_baselibs//score/language/safecpp/safe_math", "@score_baselibs//score/mw/log", ], ) diff --git a/score/mw/com/impl/bindings/lola/methods/unique_method_identifier.cpp b/score/mw/com/impl/bindings/lola/methods/unique_method_identifier.cpp index 96fa0655a3..7dd5eb5018 100644 --- a/score/mw/com/impl/bindings/lola/methods/unique_method_identifier.cpp +++ b/score/mw/com/impl/bindings/lola/methods/unique_method_identifier.cpp @@ -12,12 +12,15 @@ ********************************************************************************/ #include "score/mw/com/impl/bindings/lola/methods/unique_method_identifier.h" +#include "score/language/safecpp/safe_math/safe_math.h" + namespace score::mw::com::impl::lola { bool operator==(const UniqueMethodIdentifier& lhs, const UniqueMethodIdentifier& rhs) noexcept { - return ((lhs.method_or_field_id == rhs.method_or_field_id) && (lhs.method_type == rhs.method_type)); + return (safe_math::CmpEqual(lhs.method_or_field_id, rhs.method_or_field_id) && + (lhs.method_type == rhs.method_type)); } bool operator!=(const UniqueMethodIdentifier& lhs, const UniqueMethodIdentifier& rhs) noexcept diff --git a/score/mw/com/impl/bindings/lola/provider_event_data_control_local_view.cpp b/score/mw/com/impl/bindings/lola/provider_event_data_control_local_view.cpp index d6d5fd660c..ed7c435e8c 100644 --- a/score/mw/com/impl/bindings/lola/provider_event_data_control_local_view.cpp +++ b/score/mw/com/impl/bindings/lola/provider_event_data_control_local_view.cpp @@ -12,6 +12,7 @@ ********************************************************************************/ #include "score/mw/com/impl/bindings/lola/provider_event_data_control_local_view.h" +#include "score/language/safecpp/safe_math/safe_math.h" #include "score/mw/com/impl/bindings/lola/control_slot_types.h" #include "score/mw/com/impl/bindings/lola/event_slot_status.h" @@ -79,7 +80,7 @@ auto ProviderEventDataControlLocalView::FindOldestUnusedSl // Suppress "AUTOSAR C++14 A4-7-1" rule finding. This rule states: "An integer expression shall not lead to // loss.". As the maximum number of slots is std::uint16_t, so there is no case for a data loss here. // coverity[autosar_cpp14_a4_7_1_violation] - slot_index < static_cast(state_slots_.size()); + safe_math::CmpLess(slot_index, static_cast(state_slots_.size())); ++slot_index) { // coverity[autosar_cpp14_a5_3_2_violation] diff --git a/score/mw/com/impl/bindings/lola/proxy.cpp b/score/mw/com/impl/bindings/lola/proxy.cpp index 4675b3327d..62c9314c97 100644 --- a/score/mw/com/impl/bindings/lola/proxy.cpp +++ b/score/mw/com/impl/bindings/lola/proxy.cpp @@ -114,13 +114,13 @@ using memory::DataTypeSizeInfo; std::unique_ptr> PlaceSharedLockOnUsageMarkerFileWithRetry(memory::shared::LockFile& service_instance_usage_marker_file, std::string_view file_path, - std::uint8_t max_retries) + std::uint32_t max_retries) { auto service_instance_usage_mutex_and_lock = std::make_unique>( service_instance_usage_marker_file); constexpr std::chrono::milliseconds kRetryBackoffTime{200U}; - std::uint8_t retry_counter{0U}; + std::uint32_t retry_counter{0U}; // We use while true and manually break within the loop to prevent sleeping an additional time in case retry_counter // exceeds max_retries. @@ -369,7 +369,7 @@ std::unique_ptr Proxy::Create(const HandleType handle) return nullptr; } - constexpr std::uint8_t kMaxFlockRetries{3U}; + constexpr std::uint32_t kMaxFlockRetries{3U}; auto service_instance_usage_mutex_and_lock = PlaceSharedLockOnUsageMarkerFileWithRetry(service_instance_usage_marker_file.value(), std::string_view(service_instance_usage_marker_file_path), diff --git a/score/mw/com/impl/bindings/lola/proxy_instance_identifier.cpp b/score/mw/com/impl/bindings/lola/proxy_instance_identifier.cpp index 4f54779b9a..60f3405483 100644 --- a/score/mw/com/impl/bindings/lola/proxy_instance_identifier.cpp +++ b/score/mw/com/impl/bindings/lola/proxy_instance_identifier.cpp @@ -12,12 +12,15 @@ ********************************************************************************/ #include "score/mw/com/impl/bindings/lola/proxy_instance_identifier.h" +#include "score/language/safecpp/safe_math/safe_math.h" + namespace score::mw::com::impl::lola { bool operator==(const ProxyInstanceIdentifier& lhs, const ProxyInstanceIdentifier& rhs) noexcept { - return ((lhs.application_id == rhs.application_id) && (lhs.proxy_instance_counter == rhs.proxy_instance_counter)); + return (safe_math::CmpEqual(lhs.application_id, rhs.application_id) && + safe_math::CmpEqual(lhs.proxy_instance_counter, rhs.proxy_instance_counter)); } std::ostream& operator<<(std::ostream& stream, const ProxyInstanceIdentifier& value) diff --git a/score/mw/com/impl/bindings/lola/sample_allocatee_ptr.h b/score/mw/com/impl/bindings/lola/sample_allocatee_ptr.h index 0bd96465a9..8da17c7a1b 100644 --- a/score/mw/com/impl/bindings/lola/sample_allocatee_ptr.h +++ b/score/mw/com/impl/bindings/lola/sample_allocatee_ptr.h @@ -17,6 +17,8 @@ #include "score/mw/com/impl/bindings/lola/control_slot_types.h" #include "score/mw/com/impl/bindings/lola/event_data_control_composite.h" +#include "score/language/safecpp/safe_math/safe_math.h" + #include #include #include @@ -181,7 +183,7 @@ class SampleAllocateePtr void internal_delete() { managed_object_ = nullptr; - if (event_slot_index_ < kUninitialisedEventSlotIndex) + if (safe_math::CmpLess(event_slot_index_, kUninitialisedEventSlotIndex)) { SCORE_LANGUAGE_FUTURECPP_PRECONDITION_PRD_MESSAGE( event_data_control_ptr_ != nullptr, diff --git a/score/mw/com/impl/bindings/lola/service_discovery/BUILD b/score/mw/com/impl/bindings/lola/service_discovery/BUILD index 6f3333d73c..c8ad2fb354 100644 --- a/score/mw/com/impl/bindings/lola/service_discovery/BUILD +++ b/score/mw/com/impl/bindings/lola/service_discovery/BUILD @@ -112,6 +112,7 @@ cc_library( deps = [ "//score/mw/com/impl:enriched_instance_identifier", "//score/mw/com/impl/configuration", + "@score_baselibs//score/language/safecpp/safe_math", ], ) diff --git a/score/mw/com/impl/bindings/lola/service_discovery/flag_file_crawler.cpp b/score/mw/com/impl/bindings/lola/service_discovery/flag_file_crawler.cpp index b6acdb60f1..16084ab33c 100644 --- a/score/mw/com/impl/bindings/lola/service_discovery/flag_file_crawler.cpp +++ b/score/mw/com/impl/bindings/lola/service_discovery/flag_file_crawler.cpp @@ -212,13 +212,13 @@ auto FlagFileCrawler::CrawlAndWatchImpl(const EnrichedInstanceIdentifier& enrich // [Ticket-173043](broken_link_j/Ticket-173043) // coverity[autosar_cpp14_a15_5_3_violation : FALSE] auto FlagFileCrawler::CrawlAndWatchWithRetry(const EnrichedInstanceIdentifier& enriched_instance_identifier, - const std::uint8_t max_number_of_retries) + const std::uint32_t max_number_of_retries) -> score::Result, QualityAwareContainer>> { constexpr std::chrono::milliseconds wait_between_retries{50U}; - std::uint8_t current_retry_count{0U}; + std::uint32_t current_retry_count{0U}; std::optional crawl_and_watch_error{}; while (current_retry_count < max_number_of_retries) { diff --git a/score/mw/com/impl/bindings/lola/service_discovery/flag_file_crawler.h b/score/mw/com/impl/bindings/lola/service_discovery/flag_file_crawler.h index 6390441deb..1382082ffa 100644 --- a/score/mw/com/impl/bindings/lola/service_discovery/flag_file_crawler.h +++ b/score/mw/com/impl/bindings/lola/service_discovery/flag_file_crawler.h @@ -44,7 +44,7 @@ class FlagFileCrawler QualityAwareContainer>>; auto CrawlAndWatchWithRetry(const EnrichedInstanceIdentifier& enriched_instance_identifier, - const std::uint8_t max_number_of_retries) + const std::uint32_t max_number_of_retries) -> score::Result, QualityAwareContainer>>; diff --git a/score/mw/com/impl/bindings/lola/service_discovery/lola_service_instance_identifier.cpp b/score/mw/com/impl/bindings/lola/service_discovery/lola_service_instance_identifier.cpp index 14bcd61bb7..4ad5f5e9b6 100644 --- a/score/mw/com/impl/bindings/lola/service_discovery/lola_service_instance_identifier.cpp +++ b/score/mw/com/impl/bindings/lola/service_discovery/lola_service_instance_identifier.cpp @@ -11,6 +11,7 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ #include "score/mw/com/impl/bindings/lola/service_discovery/lola_service_instance_identifier.h" +#include "score/language/safecpp/safe_math/safe_math.h" #include "score/mw/com/impl/configuration/lola_service_type_deployment.h" namespace score::mw::com::impl::lola @@ -51,7 +52,7 @@ std::optional LolaServiceInstanceIdentifier:: bool operator==(const LolaServiceInstanceIdentifier& lhs, const LolaServiceInstanceIdentifier& rhs) noexcept { - return (lhs.GetServiceId() == rhs.GetServiceId()) && (lhs.GetInstanceId() == rhs.GetInstanceId()); + return safe_math::CmpEqual(lhs.GetServiceId(), rhs.GetServiceId()) && (lhs.GetInstanceId() == rhs.GetInstanceId()); } } // namespace score::mw::com::impl::lola diff --git a/score/mw/com/impl/bindings/lola/skeleton_instance_identifier.cpp b/score/mw/com/impl/bindings/lola/skeleton_instance_identifier.cpp index dc29c66379..dbde5202d4 100644 --- a/score/mw/com/impl/bindings/lola/skeleton_instance_identifier.cpp +++ b/score/mw/com/impl/bindings/lola/skeleton_instance_identifier.cpp @@ -12,12 +12,15 @@ ********************************************************************************/ #include "score/mw/com/impl/bindings/lola/skeleton_instance_identifier.h" +#include "score/language/safecpp/safe_math/safe_math.h" + namespace score::mw::com::impl::lola { bool operator==(const SkeletonInstanceIdentifier& lhs, const SkeletonInstanceIdentifier& rhs) noexcept { - return ((lhs.service_id == rhs.service_id) && (lhs.instance_id == rhs.instance_id)); + return (safe_math::CmpEqual(lhs.service_id, rhs.service_id) && + safe_math::CmpEqual(lhs.instance_id, rhs.instance_id)); } mw::log::LogStream& operator<<(score::mw::log::LogStream& stream, const SkeletonInstanceIdentifier& value) noexcept diff --git a/score/mw/com/impl/bindings/lola/subscription_subscribed_states.cpp b/score/mw/com/impl/bindings/lola/subscription_subscribed_states.cpp index 86d1ef10eb..2c39ecd1f4 100644 --- a/score/mw/com/impl/bindings/lola/subscription_subscribed_states.cpp +++ b/score/mw/com/impl/bindings/lola/subscription_subscribed_states.cpp @@ -11,6 +11,7 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ #include "score/mw/com/impl/bindings/lola/subscription_subscribed_states.h" +#include "score/language/safecpp/safe_math/safe_math.h" #include "score/mw/com/impl/bindings/lola/subscription_helpers.h" #include "score/mw/com/impl/bindings/lola/subscription_state_machine.h" #include "score/mw/com/impl/bindings/lola/subscription_state_machine_states.h" @@ -34,7 +35,7 @@ Result SubscribedState::SubscribeEvent(const std::size_t max_sample_count) // different max_sample_count. // coverity[autosar_cpp14_a4_7_1_violation] const auto max_sample_count_uint16 = static_cast(max_sample_count); - if (state_machine_.subscription_data_.max_sample_count_.value() == max_sample_count_uint16) + if (safe_math::CmpEqual(state_machine_.subscription_data_.max_sample_count_.value(), max_sample_count_uint16)) { ::score::mw::log::LogWarn("lola") << CreateLoggingString("Calling SubscribeEvent() while already subscribed has no effect.", diff --git a/score/mw/com/impl/bindings/lola/subscription_subscription_pending_states.cpp b/score/mw/com/impl/bindings/lola/subscription_subscription_pending_states.cpp index 2fbdd4be79..695fa66444 100644 --- a/score/mw/com/impl/bindings/lola/subscription_subscription_pending_states.cpp +++ b/score/mw/com/impl/bindings/lola/subscription_subscription_pending_states.cpp @@ -30,13 +30,15 @@ namespace score::mw::com::impl::lola Result SubscriptionPendingState::SubscribeEvent(const std::size_t max_sample_count) { - // Suppress "AUTOSAR C++14 A4-7-1" rule finding. This rule states: "An integer expression shall - // not lead to data loss.". - // This is an in purpose casting and below we do check on the max_sample_count and an error reported in case of - // different max_sample_count. - // coverity[autosar_cpp14_a4_7_1_violation] - const auto max_sample_count_uint8 = static_cast(max_sample_count); - if (state_machine_.subscription_data_.max_sample_count_.value() == max_sample_count_uint8) + // Compare max_sample_count (std::size_t) directly against the stored max_sample_count_ (std::uint16_t), + // widening the latter to std::size_t for the comparison. This is always lossless (every std::uint16_t + // value fits in std::size_t) and avoids a signedness-changing promotion, since std::size_t already has + // rank >= int. Note: this intentionally no longer truncates max_sample_count down to std::uint8_t first -- + // that previous truncation silently corrupted the comparison for any max_sample_count above 255 (the + // stored max_sample_count_ can legitimately be up to 65535, per its std::uint16_t type), which would + // have caused SubscribeEvent() to spuriously report "different max_sample_count" for a legitimate + // resubscription with the same, larger count. + if (max_sample_count == static_cast(state_machine_.subscription_data_.max_sample_count_.value())) { ::score::mw::log::LogWarn("lola") << CreateLoggingString("Calling SubscribeEvent() while subscription is pending has no effect.", diff --git a/score/mw/com/impl/bindings/lola/tracing/tracing_runtime.cpp b/score/mw/com/impl/bindings/lola/tracing/tracing_runtime.cpp index 1b05ae213d..f3dad17e65 100644 --- a/score/mw/com/impl/bindings/lola/tracing/tracing_runtime.cpp +++ b/score/mw/com/impl/bindings/lola/tracing/tracing_runtime.cpp @@ -370,6 +370,7 @@ auto TracingRuntime::GetTraceContextIdRangeForServiceElement( // LCOV_EXCL_START (We don't have the infrastructure to test the failure case of this static assert at compile time. // This check is anyway defensive programming to prevent accidental changes that could be made to the code in // the future but currently has no way of failing in production. + // Deviation of MISRA RULE-7-0-5: codeql::misra_deviation_next_line(compile-time-static-assert-limit-check) static_assert( ((std::numeric_limits::max() + std::numeric_limits::max()) <= std::numeric_limits::max()), @@ -405,8 +406,8 @@ auto TracingRuntime::GetTraceContextId( TracingRuntime::EmplaceTypeErasedSamplePtr(impl::tracing::TypeErasedSamplePtr type_erased_sample_ptr, const impl::tracing::ServiceElementTracingData service_element_tracing_data) { - if (service_element_tracing_data.service_element_range_start >= - next_available_position_for_new_service_element_range_start_) + if (score::safe_math::CmpGreaterEqual(service_element_tracing_data.service_element_range_start, + next_available_position_for_new_service_element_range_start_)) { score::mw::log::LogFatal("lola") << "Cannot set type erased sample pointer as provided service element with range start at" diff --git a/score/mw/com/impl/bindings/lola/transaction_log_local_view.cpp b/score/mw/com/impl/bindings/lola/transaction_log_local_view.cpp index d5de47f758..5eb9419e13 100644 --- a/score/mw/com/impl/bindings/lola/transaction_log_local_view.cpp +++ b/score/mw/com/impl/bindings/lola/transaction_log_local_view.cpp @@ -31,9 +31,9 @@ namespace // This allows Thread A to complete its dereference transaction before proceeding. void WaitForTransactionEndToBecomeFalse(TransactionLogSlot& slot) noexcept { - constexpr std::uint8_t kRetryCount = 10U; + constexpr std::uint32_t kRetryCount = 10U; constexpr std::chrono::milliseconds kRetryInterval(10); - for (std::uint8_t retry = 0U; retry < kRetryCount; ++retry) + for (std::uint32_t retry = 0U; retry < kRetryCount; ++retry) { if (!slot.GetTransactionEnd()) { @@ -42,7 +42,8 @@ void WaitForTransactionEndToBecomeFalse(TransactionLogSlot& slot) noexcept std::this_thread::sleep_for(kRetryInterval); } score::mw::log::LogFatal("lola") << "ReferenceTransactionBegin: Transaction-END bit remains TRUE after " - << kRetryCount * kRetryInterval.count() << "ms; terminating"; + << static_cast(kRetryCount) * kRetryInterval.count() + << "ms; terminating"; std::terminate(); } diff --git a/score/mw/com/impl/bindings/lola/transaction_log_set.cpp b/score/mw/com/impl/bindings/lola/transaction_log_set.cpp index b7826bb682..0292258b12 100644 --- a/score/mw/com/impl/bindings/lola/transaction_log_set.cpp +++ b/score/mw/com/impl/bindings/lola/transaction_log_set.cpp @@ -12,6 +12,7 @@ ********************************************************************************/ #include "score/mw/com/impl/bindings/lola/transaction_log_set.h" +#include "score/language/safecpp/safe_math/safe_math.h" #include "score/mw/com/impl/bindings/lola/transaction_log_registration_guard.h" #include "score/mw/com/impl/com_error.h" #include "score/mw/log/logging.h" @@ -57,7 +58,7 @@ TransactionLogSet::TransactionLogSet(const TransactionLogIndex max_number_of_log skeleton_tracing_transaction_log_{number_of_slots, resource} { SCORE_LANGUAGE_FUTURECPP_PRECONDITION_PRD_MESSAGE( - max_number_of_logs != kSkeletonIndexSentinel, + safe_math::CmpNotEqual(max_number_of_logs, kSkeletonIndexSentinel), "kSkeletonIndexSentinel is a reserved sentinel value so the max_number_of_logs must be reduced."); } @@ -271,7 +272,7 @@ TransactionLogSet::AcquireNextAvailableSlot(TransactionLogId transaction_log_id) bool TransactionLogSet::IsSkeletonElementTransactionLogIndex(const TransactionLogIndex transaction_log_index) { - return transaction_log_index == TransactionLogSet::kSkeletonIndexSentinel; + return safe_math::CmpEqual(transaction_log_index, TransactionLogSet::kSkeletonIndexSentinel); } } // namespace score::mw::com::impl::lola diff --git a/score/mw/com/impl/configuration/BUILD b/score/mw/com/impl/configuration/BUILD index 331f38cfe0..db11aa60af 100644 --- a/score/mw/com/impl/configuration/BUILD +++ b/score/mw/com/impl/configuration/BUILD @@ -199,6 +199,7 @@ cc_library( features = COMPILER_WARNING_FEATURES, implementation_deps = [ ":configuration_common_resources", + "@score_baselibs//score/language/safecpp/safe_math", "@score_baselibs//score/mw/log", ], tags = ["FFI"], @@ -320,7 +321,10 @@ cc_library( srcs = ["lola_service_instance_id.cpp"], hdrs = ["lola_service_instance_id.h"], features = COMPILER_WARNING_FEATURES, - implementation_deps = [":configuration_common_resources"], + implementation_deps = [ + ":configuration_common_resources", + "@score_baselibs//score/language/safecpp/safe_math", + ], tags = ["FFI"], visibility = ["//score/mw/com/impl/bindings/lola:__pkg__"], deps = ["@score_baselibs//score/json"], @@ -417,6 +421,7 @@ cc_library( ":configuration_common_resources", "//score/mw/com/impl:service_element_type", "@score_baselibs//score/json", + "@score_baselibs//score/language/safecpp/safe_math", ], ) diff --git a/score/mw/com/impl/configuration/binding_service_type_deployment_impl.h b/score/mw/com/impl/configuration/binding_service_type_deployment_impl.h index 982b5305df..14576f96e0 100644 --- a/score/mw/com/impl/configuration/binding_service_type_deployment_impl.h +++ b/score/mw/com/impl/configuration/binding_service_type_deployment_impl.h @@ -15,6 +15,7 @@ #include "score/json/json_parser.h" +#include "score/language/safecpp/safe_math/safe_math.h" #include "score/mw/com/impl/configuration/configuration_common_resources.h" #include "score/mw/com/impl/service_element_type.h" @@ -156,8 +157,8 @@ template & lhs, const BindingServiceTypeDeployment& rhs) noexcept { - return ((lhs.service_id_ == rhs.service_id_) && (lhs.events_ == rhs.events_) && (lhs.fields_ == rhs.fields_) && - (lhs.methods_ == rhs.methods_)); + return (safe_math::CmpEqual(lhs.service_id_, rhs.service_id_) && (lhs.events_ == rhs.events_) && + (lhs.fields_ == rhs.fields_) && (lhs.methods_ == rhs.methods_)); } template @@ -151,7 +152,8 @@ void LolaEventInstanceDeployment::SetNumberOfSampleSlots(SampleSlotCountType num bool operator==(const LolaEventInstanceDeployment& lhs, const LolaEventInstanceDeployment& rhs) noexcept { const bool number_of_sample_slots_equal = (lhs.number_of_sample_slots_ == rhs.number_of_sample_slots_); - const bool number_of_tracing_slots_equal = (lhs.number_of_tracing_slots_ == rhs.number_of_tracing_slots_); + const bool number_of_tracing_slots_equal = + safe_math::CmpEqual(lhs.number_of_tracing_slots_, rhs.number_of_tracing_slots_); const bool max_subscribers_equal = (lhs.max_subscribers_ == rhs.max_subscribers_); const bool max_concurrent_allocations_equal = (lhs.max_concurrent_allocations_ == rhs.max_concurrent_allocations_); const bool enforce_max_samples_equal = (lhs.enforce_max_samples_ == rhs.enforce_max_samples_); diff --git a/score/mw/com/impl/configuration/lola_service_instance_id.cpp b/score/mw/com/impl/configuration/lola_service_instance_id.cpp index db5214bb37..0bdde77769 100644 --- a/score/mw/com/impl/configuration/lola_service_instance_id.cpp +++ b/score/mw/com/impl/configuration/lola_service_instance_id.cpp @@ -15,6 +15,7 @@ #include "score/mw/com/impl/configuration/configuration_common_resources.h" #include "score/json/json_parser.h" +#include "score/language/safecpp/safe_math/safe_math.h" #include @@ -70,12 +71,12 @@ std::string_view LolaServiceInstanceId::ToHashString() const noexcept bool operator==(const LolaServiceInstanceId& lhs, const LolaServiceInstanceId& rhs) noexcept { - return lhs.GetId() == rhs.GetId(); + return safe_math::CmpEqual(lhs.GetId(), rhs.GetId()); } bool operator<(const LolaServiceInstanceId& lhs, const LolaServiceInstanceId& rhs) noexcept { - return lhs.GetId() < rhs.GetId(); + return safe_math::CmpLess(lhs.GetId(), rhs.GetId()); } } // namespace score::mw::com::impl diff --git a/score/mw/com/impl/instance_specifier.cpp b/score/mw/com/impl/instance_specifier.cpp index f88b706edf..21868b21d7 100644 --- a/score/mw/com/impl/instance_specifier.cpp +++ b/score/mw/com/impl/instance_specifier.cpp @@ -51,6 +51,7 @@ bool IsShortNameValid(const std::string_view shortname) noexcept // static_cast from int to bool will not change the signedness and the type convertion is intended // coverity[autosar_cpp14_m5_0_3_violation] // coverity[autosar_cpp14_m5_0_4_violation] + // Deviation of MISRA RULE-7-0-5: codeql::misra_deviation_next_line(ctype-function-argument-promotion) const auto is_alpha_or_num = first_char ? std::isalpha(u_ch) : std::isalnum(u_ch); // coverity[autosar_cpp14_a5_2_6_violation: FALSE] False positive: each operand is parenthesized return ((static_cast(is_alpha_or_num)) || (curent_char == '_') || (curent_char == '/')); diff --git a/score/mw/com/impl/tracing/BUILD b/score/mw/com/impl/tracing/BUILD index 795f94ec30..d41134810d 100644 --- a/score/mw/com/impl/tracing/BUILD +++ b/score/mw/com/impl/tracing/BUILD @@ -72,6 +72,7 @@ cc_library( visibility = ["//score/mw/com/impl:__subpackages__"], deps = [ "//score/mw/com/impl/configuration:lola_event_instance_deployment", + "@score_baselibs//score/language/safecpp/safe_math", ], ) diff --git a/score/mw/com/impl/tracing/configuration/BUILD b/score/mw/com/impl/tracing/configuration/BUILD index 05f7ef4789..7480491b70 100644 --- a/score/mw/com/impl/tracing/configuration/BUILD +++ b/score/mw/com/impl/tracing/configuration/BUILD @@ -177,6 +177,7 @@ cc_library( deps = [ ":hash_helper_utility", ":service_element_identifier_view", + "@score_baselibs//score/language/safecpp/safe_math", "@score_baselibs//score/mw/log", ], ) diff --git a/score/mw/com/impl/tracing/configuration/trace_point_key.cpp b/score/mw/com/impl/tracing/configuration/trace_point_key.cpp index 6173321212..b3dd8ff706 100644 --- a/score/mw/com/impl/tracing/configuration/trace_point_key.cpp +++ b/score/mw/com/impl/tracing/configuration/trace_point_key.cpp @@ -12,12 +12,15 @@ ********************************************************************************/ #include "score/mw/com/impl/tracing/configuration/trace_point_key.h" +#include "score/language/safecpp/safe_math/safe_math.h" + namespace score::mw::com::impl::tracing { bool operator==(const TracePointKey& lhs, const TracePointKey& rhs) noexcept { - return ((lhs.service_element == rhs.service_element) && (lhs.trace_point_type == rhs.trace_point_type)); + return ((lhs.service_element == rhs.service_element) && + safe_math::CmpEqual(lhs.trace_point_type, rhs.trace_point_type)); } } // namespace score::mw::com::impl::tracing diff --git a/score/mw/com/impl/tracing/service_element_tracing_data.h b/score/mw/com/impl/tracing/service_element_tracing_data.h index 5eaee2833b..63a3c98913 100644 --- a/score/mw/com/impl/tracing/service_element_tracing_data.h +++ b/score/mw/com/impl/tracing/service_element_tracing_data.h @@ -15,6 +15,8 @@ #include "score/mw/com/impl/configuration/lola_event_instance_deployment.h" +#include "score/language/safecpp/safe_math/safe_math.h" + #include namespace score::mw::com::impl::tracing { @@ -30,8 +32,9 @@ struct ServiceElementTracingData inline bool operator==(const ServiceElementTracingData& lhs, const ServiceElementTracingData& rhs) noexcept { - return ((lhs.number_of_service_element_tracing_slots == rhs.number_of_service_element_tracing_slots) && - (lhs.service_element_range_start == rhs.service_element_range_start)); + return ( + safe_math::CmpEqual(lhs.number_of_service_element_tracing_slots, rhs.number_of_service_element_tracing_slots) && + safe_math::CmpEqual(lhs.service_element_range_start, rhs.service_element_range_start)); } } // namespace score::mw::com::impl::tracing diff --git a/score/mw/com/impl/tracing/tracing_runtime.cpp b/score/mw/com/impl/tracing/tracing_runtime.cpp index ea3bb45c3c..6224d479f3 100644 --- a/score/mw/com/impl/tracing/tracing_runtime.cpp +++ b/score/mw/com/impl/tracing/tracing_runtime.cpp @@ -555,7 +555,7 @@ Result TracingRuntime::Trace(const BindingType binding_type, // Handle debounced logging for no available tracing slots // Log first 10 failures at LogInfo level, then switch to LogDebug to reduce DLT bandwidth. ++debounce_counter_; - const bool debouncing_active = (debounce_counter_ >= kDebounceAfter); + const bool debouncing_active = debounce_counter_ >= kDebounceAfter; if (!debouncing_active) { diff --git a/score/mw/com/impl/tracing/tracing_runtime.h b/score/mw/com/impl/tracing/tracing_runtime.h index 0048bb1b48..93e479433e 100644 --- a/score/mw/com/impl/tracing/tracing_runtime.h +++ b/score/mw/com/impl/tracing/tracing_runtime.h @@ -180,13 +180,13 @@ class TracingRuntime : public ITracingRuntime /// \details After this many consecutive (limited by 10 for the moment) "no tracing slot available" failures, /// subsequent failure messages will be logged at LogDebug level instead of LogInfo to reduce DLT /// bandwidth. - static constexpr std::uint8_t kDebounceAfter{10U}; + static constexpr std::uint32_t kDebounceAfter{10U}; /// \brief Counter for consecutive "no tracing slot available" failures /// \details Tracks consecutive getting available slots failures. Incremented on each failure, reset to 0 when /// tracing slot becomes available again. Used with kDebounceAfter threshold to determine when to switch /// log levels from LogInfo to LogDebug. - std::uint8_t debounce_counter_; + std::uint32_t debounce_counter_; /// \brief Flag to track if this is the first time debouncing becomes active /// \details Initially true. Set to false when debounce_counter_ first exceeds kDebounceAfter threshold. Used to log