clang-tidy-21: fix cppcoreguidelines-pro-bounds-pointer-arithmetic

Fix various pro-bounds-pointer-arithmetic warnings that started being
reported with clang-tidy-21.

```
error: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic,-warnings-as-errors]
```

Forked this change from [1]

References:
[1] https://gerrit.openbmc.org/c/openbmc/entity-manager/+/84049

Tested: Inspection only.

Change-Id: I535802825e68d7f5fe01ed2428d127f7a18ab4f8
Signed-off-by: Alexander Hansen <alexander.hansen@9elements.com>
diff --git a/src/entity_manager/utils.cpp b/src/entity_manager/utils.cpp
index 7528117..28e6d11 100644
--- a/src/entity_manager/utils.cpp
+++ b/src/entity_manager/utils.cpp
@@ -1,5 +1,6 @@
 #include "utils.hpp"
 
+#include "../utils.hpp"
 #include "../variant_visitors.hpp"
 #include "expression.hpp"
 #include "phosphor-logging/lg2.hpp"
@@ -281,10 +282,10 @@
     }
 
     uint64_t temp = 0;
-    const char* strDataEndPtr = strView.data() + strView.size();
+    bool fullMatch = false;
     const std::from_chars_result res =
-        std::from_chars(strView.data(), strDataEndPtr, temp, base);
-    if (res.ec == std::errc{} && res.ptr == strDataEndPtr)
+        fromCharsWrapper(strView, temp, fullMatch, base);
+    if (res.ec == std::errc{} && fullMatch)
     {
         keyPair.value() = temp;
     }
diff --git a/src/fru_device/fru_device.cpp b/src/fru_device/fru_device.cpp
index d508896..4bb9418 100644
--- a/src/fru_device/fru_device.cpp
+++ b/src/fru_device/fru_device.cpp
@@ -129,7 +129,8 @@
     }
     std::string_view num = busName.substr(findBus + 1);
     int val = 0;
-    std::from_chars(num.data(), num.data() + num.size(), val);
+    bool fullMatch = false;
+    fromCharsWrapper(num, val, fullMatch);
     return val;
 }
 
@@ -667,8 +668,9 @@
                     for (const auto& address : addresses)
                     {
                         size_t addressInt = 0;
-                        std::from_chars(address.begin() + 2, address.end(),
-                                        addressInt, 16);
+                        bool fullMatch = false;
+                        fromCharsWrapper(address.substr(2), addressInt,
+                                         fullMatch, 16);
                         block.insert(addressInt);
                     }
                 }
diff --git a/src/fru_device/fru_utils.cpp b/src/fru_device/fru_utils.cpp
index 13e619f..14ec8c1 100644
--- a/src/fru_device/fru_utils.cpp
+++ b/src/fru_device/fru_utils.cpp
@@ -781,7 +781,8 @@
     }
 
     std::vector<uint8_t> device;
-    device.insert(device.end(), blockData.begin(), blockData.begin() + 8);
+    device.insert(device.end(), blockData.begin(),
+                  std::next(blockData.begin(), 8));
 
     bool hasMultiRecords = false;
     size_t fruLength = fruBlockSize; // At least FRU header is present
@@ -889,7 +890,7 @@
         }
 
         device.insert(device.end(), blockData.begin(),
-                      blockData.begin() + requestLength);
+                      std::next(blockData.begin(), requestLength));
 
         readOffset += requestLength;
         fruLength -= std::min(requestLength, fruLength);
diff --git a/src/utils.hpp b/src/utils.hpp
index 123a316..3a3a083 100644
--- a/src/utils.hpp
+++ b/src/utils.hpp
@@ -8,6 +8,7 @@
 #include <sdbusplus/asio/connection.hpp>
 #include <sdbusplus/exception.hpp>
 
+#include <charconv>
 #include <filesystem>
 
 using DBusValueVariant =
@@ -73,3 +74,15 @@
 /// \param dbusValue the property value being matched to a probe.
 /// \return true if the dbusValue matched the probe otherwise false.
 bool matchProbe(const nlohmann::json& probe, const DBusValueVariant& dbusValue);
+
+template <typename T>
+std::from_chars_result fromCharsWrapper(const std::string_view& str, T& out,
+                                        bool& fullMatch, int base = 10)
+{
+    auto result = std::from_chars(
+        str.data(), std::next(str.begin(), str.size()), out, base);
+
+    fullMatch = result.ptr == std::next(str.begin(), str.size());
+
+    return result;
+}