summaryrefslogtreecommitdiff
path: root/redfish-core
diff options
context:
space:
mode:
authorEd Tanous <ed@tanous.net>2024-04-01 23:23:11 +0300
committerEd Tanous <ed@tanous.net>2024-04-07 04:21:05 +0300
commit099984c12e9bfcc76299fc3046d03b2c3118060e (patch)
treed9f00ef1f39ef541f1dcfd68991ab58e7544ac98 /redfish-core
parent7ac13cc939beaf9a2a7af870ba9b5650c98e409e (diff)
downloadbmcweb-099984c12e9bfcc76299fc3046d03b2c3118060e.tar.xz
Fix undefined behavior in getUniqueEntryID
Changing static bool getUniqueEntryID to inline bool getUniqueEntryID Exposes the fact that there's some undefined behavior here, and unit tests start failing, likely due to stack being reused where it previously wasn't. This commit cleans up the code to simplify it, and remove the problem. Tested: Unit tests pass. Good coverage. Change-Id: I5b9b8e8bb83c656560193e680d246c8513ed6c02 Signed-off-by: Ed Tanous <ed@tanous.net>
Diffstat (limited to 'redfish-core')
-rw-r--r--redfish-core/lib/log_services.hpp63
1 files changed, 30 insertions, 33 deletions
diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp
index d2b834a26e..609ff2c11c 100644
--- a/redfish-core/lib/log_services.hpp
+++ b/redfish-core/lib/log_services.hpp
@@ -271,21 +271,15 @@ static bool getUniqueEntryID(const std::string& logEntry, std::string& entryID,
// Entry is formed like "BootID_timestamp" or "BootID_timestamp_index"
inline static bool
getTimestampFromID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& entryID, sd_id128_t& bootID,
+ std::string_view entryIDStrView, sd_id128_t& bootID,
uint64_t& timestamp, uint64_t& index)
{
- if (entryID.empty())
- {
- return false;
- }
-
// Convert the unique ID back to a bootID + timestamp to find the entry
- std::string_view entryIDStrView(entryID);
auto underscore1Pos = entryIDStrView.find('_');
if (underscore1Pos == std::string_view::npos)
{
// EntryID has no bootID or timestamp
- messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
+ messages::resourceNotFound(asyncResp->res, "LogEntry", entryIDStrView);
return false;
}
@@ -294,41 +288,44 @@ inline static bool
// Convert entryIDViewString to BootID
// NOTE: bootID string which needs to be null-terminated for
// sd_id128_from_string()
- std::string bootIDStr(entryID, 0, underscore1Pos);
+ std::string bootIDStr(entryIDStrView.substr(0, underscore1Pos));
if (sd_id128_from_string(bootIDStr.c_str(), &bootID) < 0)
{
- messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
+ messages::resourceNotFound(asyncResp->res, "LogEntry", entryIDStrView);
return false;
}
// Get the timestamp from entryID
- std::string_view timestampStrView = entryIDStrView;
- timestampStrView.remove_prefix(underscore1Pos + 1);
+ entryIDStrView.remove_prefix(underscore1Pos + 1);
- // Check the index in timestamp
- auto underscore2Pos = timestampStrView.find('_');
- if (underscore2Pos != std::string_view::npos)
+ auto [timestampEnd, tstampEc] = std::from_chars(
+ entryIDStrView.begin(), entryIDStrView.end(), timestamp);
+ if (tstampEc != std::errc())
{
- // Timestamp has an index
- timestampStrView.remove_suffix(timestampStrView.size() -
- underscore2Pos);
- std::string_view indexStr(timestampStrView);
- indexStr.remove_prefix(underscore2Pos + 1);
- auto [ptr, ec] = std::from_chars(indexStr.begin(), indexStr.end(),
- index);
- if (ec != std::errc())
- {
- messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
- return false;
- }
+ messages::resourceNotFound(asyncResp->res, "LogEntry", entryIDStrView);
+ return false;
}
-
- // Now timestamp has no index
- auto [ptr, ec] = std::from_chars(timestampStrView.begin(),
- timestampStrView.end(), timestamp);
- if (ec != std::errc())
+ entryIDStrView = std::string_view(
+ timestampEnd,
+ static_cast<size_t>(std::distance(timestampEnd, entryIDStrView.end())));
+ if (entryIDStrView.empty())
+ {
+ index = 0U;
+ return true;
+ }
+ // Timestamp might include optional index, if two events happened at the
+ // same "time".
+ if (entryIDStrView[0] != '_')
+ {
+ messages::resourceNotFound(asyncResp->res, "LogEntry", entryIDStrView);
+ return false;
+ }
+ entryIDStrView.remove_prefix(1);
+ auto [ptr, indexEc] = std::from_chars(entryIDStrView.begin(),
+ entryIDStrView.end(), index);
+ if (indexEc != std::errc() || ptr != entryIDStrView.end())
{
- messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
+ messages::resourceNotFound(asyncResp->res, "LogEntry", entryIDStrView);
return false;
}
return true;