Start using sdbusplus::message::filename()

Lots of code gets checked in that does this path checking incorrectly.
So much so, that we have it documented in COMMON_ERRORS.md, yet, we
persist.  This patchset starts using the new object_path::filename()
method that was added recently to sdbusplus.  Overall, it deletes code,
and makes for a much better developer experience.

Tested:
Pulled down several endpoints and verified that filename() method works
properly, and the collections are returned as expected.

curl -vvvv --insecure --user root:0penBmc https://192.168.7.2/redfish/v1/AccountService/Accounts

Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: Ief1e0584394fb139678d3453265f7011bc931f3c
diff --git a/redfish-core/include/utils/collection.hpp b/redfish-core/include/utils/collection.hpp
index bcf5c16..f1b7f21 100644
--- a/redfish-core/include/utils/collection.hpp
+++ b/redfish-core/include/utils/collection.hpp
@@ -44,13 +44,16 @@
 
             for (const auto& object : objects)
             {
-                auto pos = object.rfind('/');
-                if ((pos != std::string::npos) && (pos < (object.size() - 1)))
+                sdbusplus::message::object_path path(object);
+                std::string leaf = path.filename();
+                if (leaf.empty())
                 {
-                    members.push_back(
-                        {{"@odata.id",
-                          collectionPath + "/" + object.substr(pos + 1)}});
+                    continue;
                 }
+                std::string newPath = collectionPath;
+                newPath += '/';
+                newPath += leaf;
+                members.push_back({{"@odata.id", std::move(newPath)}});
             }
             aResp->res.jsonValue["Members@odata.count"] = members.size();
         },
diff --git a/redfish-core/include/utils/fw_utils.hpp b/redfish-core/include/utils/fw_utils.hpp
index 0e46f17..1e29139 100644
--- a/redfish-core/include/utils/fw_utils.hpp
+++ b/redfish-core/include/utils/fw_utils.hpp
@@ -68,20 +68,14 @@
             //        "/xyz/openbmc_project/software/230fb078"
             for (auto& fw : *functionalFw)
             {
+                sdbusplus::message::object_path path(fw);
+                std::string leaf = path.filename();
+                if (leaf.empty())
+                {
+                    continue;
+                }
 
-                std::string::size_type idPos = fw.rfind('/');
-                if (idPos == std::string::npos)
-                {
-                    BMCWEB_LOG_DEBUG << "Can't parse firmware ID!";
-                    continue;
-                }
-                idPos++;
-                if (idPos >= fw.size())
-                {
-                    BMCWEB_LOG_DEBUG << "Invalid firmware ID";
-                    continue;
-                }
-                functionalFwIds.push_back(fw.substr(idPos));
+                functionalFwIds.push_back(leaf);
             }
 
             crow::connections::systemBus->async_method_call(
@@ -109,22 +103,16 @@
                                  std::string, std::vector<std::string>>>>& obj :
                          subtree)
                     {
-                        // if can't parse fw id then return
-                        std::string::size_type idPos = obj.first.rfind('/');
-                        if (idPos == std::string::npos)
-                        {
-                            messages::internalError(aResp->res);
-                            BMCWEB_LOG_ERROR << "Can't parse firmware ID!!";
-                            return;
-                        }
-                        idPos++;
-                        if (idPos >= obj.first.size())
+
+                        sdbusplus::message::object_path path(obj.first);
+                        std::string swId = path.filename();
+                        if (swId.empty())
                         {
                             messages::internalError(aResp->res);
                             BMCWEB_LOG_ERROR << "Invalid firmware ID";
+
                             return;
                         }
-                        std::string swId = obj.first.substr(idPos);
 
                         bool runningImage = false;
                         // Look at Ids from
diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp
index 0cf24ea..3b6062a 100644
--- a/redfish-core/lib/account_service.hpp
+++ b/redfish-core/lib/account_service.hpp
@@ -1395,31 +1395,27 @@
                     asyncResp->res.jsonValue["Members"];
                 memberArray = nlohmann::json::array();
 
-                for (auto& user : users)
+                for (auto& userpath : users)
                 {
-                    const std::string& path =
-                        static_cast<const std::string&>(user.first);
-                    std::size_t lastIndex = path.rfind('/');
-                    if (lastIndex == std::string::npos)
+                    std::string user = userpath.first.filename();
+                    if (user.empty())
                     {
-                        lastIndex = 0;
-                    }
-                    else
-                    {
-                        lastIndex += 1;
+                        messages::internalError(asyncResp->res);
+                        BMCWEB_LOG_ERROR << "Invalid firmware ID";
+
+                        return;
                     }
 
                     // As clarified by Redfish here:
                     // https://redfishforum.com/thread/281/manageraccountcollection-change-allows-account-enumeration
                     // Users without ConfigureUsers, only see their own account.
                     // Users with ConfigureUsers, see all accounts.
-                    if (req.session->username == path.substr(lastIndex) ||
+                    if (req.session->username == user ||
                         isAllowedWithoutConfigureSelf(req))
                     {
                         memberArray.push_back(
                             {{"@odata.id",
-                              "/redfish/v1/AccountService/Accounts/" +
-                                  path.substr(lastIndex)}});
+                              "/redfish/v1/AccountService/Accounts/" + user}});
                     }
                 }
                 asyncResp->res.jsonValue["Members@odata.count"] =
diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp
index e73d338..159eda2 100644
--- a/redfish-core/lib/ethernet.hpp
+++ b/redfish-core/lib/ethernet.hpp
@@ -968,14 +968,13 @@
                     if (interface.first ==
                         "xyz.openbmc_project.Network.EthernetInterface")
                     {
-                        // Cut out everything until last "/", ...
-                        const std::string& ifaceId = objpath.first.str;
-                        std::size_t lastPos = ifaceId.rfind('/');
-                        if (lastPos != std::string::npos)
+                        std::string ifaceId = objpath.first.filename();
+                        if (ifaceId.empty())
                         {
-                            // and put it into output vector.
-                            ifaceList.emplace(ifaceId.substr(lastPos + 1));
+                            continue;
                         }
+                        // and put it into output vector.
+                        ifaceList.emplace(ifaceId);
                     }
                 }
             }
diff --git a/redfish-core/lib/hypervisor_system.hpp b/redfish-core/lib/hypervisor_system.hpp
index eff9c3c..290bac7 100644
--- a/redfish-core/lib/hypervisor_system.hpp
+++ b/redfish-core/lib/hypervisor_system.hpp
@@ -123,14 +123,17 @@
                 ifaceArray = nlohmann::json::array();
                 for (const std::string& iface : ifaceList)
                 {
-                    std::size_t lastPos = iface.rfind('/');
-                    if (lastPos != std::string::npos)
+                    sdbusplus::message::object_path path(iface);
+                    std::string name = path.filename();
+                    if (name.empty())
                     {
-                        ifaceArray.push_back(
-                            {{"@odata.id", "/redfish/v1/Systems/hypervisor/"
-                                           "EthernetInterfaces/" +
-                                               iface.substr(lastPos + 1)}});
+                        continue;
                     }
+
+                    ifaceArray.push_back(
+                        {{"@odata.id", "/redfish/v1/Systems/hypervisor/"
+                                       "EthernetInterfaces/" +
+                                           name}});
                 }
                 asyncResp->res.jsonValue["Members@odata.count"] =
                     ifaceArray.size();
diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp
index 4975a37..98a0808 100644
--- a/redfish-core/lib/log_services.hpp
+++ b/redfish-core/lib/log_services.hpp
@@ -442,14 +442,12 @@
                 uint64_t size = 0;
                 entriesArray.push_back({});
                 nlohmann::json& thisEntry = entriesArray.back();
-                const std::string& path =
-                    static_cast<const std::string&>(object.first);
-                std::size_t lastPos = path.rfind('/');
-                if (lastPos == std::string::npos)
+
+                std::string entryID = object.first.filename();
+                if (entryID.empty())
                 {
                     continue;
                 }
-                std::string entryID = path.substr(lastPos + 1);
 
                 for (auto& interfaceMap : object.second)
                 {
@@ -842,12 +840,13 @@
 
             for (const std::string& path : subTreePaths)
             {
-                std::size_t pos = path.rfind('/');
-                if (pos != std::string::npos)
+                sdbusplus::message::object_path objPath(path);
+                std::string logID = objPath.filename();
+                if (logID.empty())
                 {
-                    std::string logID = path.substr(pos + 1);
-                    deleteDumpEntry(asyncResp, logID, dumpType);
+                    continue;
                 }
+                deleteDumpEntry(asyncResp, logID, dumpType);
             }
         },
         "xyz.openbmc_project.ObjectMapper",
diff --git a/redfish-core/lib/update_service.hpp b/redfish-core/lib/update_service.hpp
index 6d44171..18b2db0 100644
--- a/redfish-core/lib/update_service.hpp
+++ b/redfish-core/lib/update_service.hpp
@@ -733,15 +733,14 @@
 
                 for (auto& obj : subtree)
                 {
-                    // if can't parse fw id then return
-                    std::size_t idPos;
-                    if ((idPos = obj.first.rfind('/')) == std::string::npos)
+                    sdbusplus::message::object_path path(obj.first);
+                    std::string swId = path.filename();
+                    if (swId.empty())
                     {
                         messages::internalError(asyncResp->res);
                         BMCWEB_LOG_DEBUG << "Can't parse firmware ID!!";
                         return;
                     }
-                    std::string swId = obj.first.substr(idPos + 1);
 
                     nlohmann::json& members =
                         asyncResp->res.jsonValue["Members"];
diff --git a/redfish-core/lib/virtual_media.hpp b/redfish-core/lib/virtual_media.hpp
index 95a8881..b157867 100644
--- a/redfish-core/lib/virtual_media.hpp
+++ b/redfish-core/lib/virtual_media.hpp
@@ -203,18 +203,14 @@
             for (const auto& object : subtree)
             {
                 nlohmann::json item;
-                const std::string& path =
-                    static_cast<const std::string&>(object.first);
-                std::size_t lastIndex = path.rfind('/');
-                if (lastIndex == std::string::npos)
+                std::string path = object.first.filename();
+                if (path.empty())
                 {
                     continue;
                 }
 
-                lastIndex += 1;
-
-                item["@odata.id"] = "/redfish/v1/Managers/" + name +
-                                    "/VirtualMedia/" + path.substr(lastIndex);
+                item["@odata.id"] =
+                    "/redfish/v1/Managers/" + name + "/VirtualMedia/" + *path;
 
                 members.emplace_back(std::move(item));
             }
@@ -245,16 +241,13 @@
 
             for (auto& item : subtree)
             {
-                const std::string& path =
-                    static_cast<const std::string&>(item.first);
-
-                std::size_t lastItem = path.rfind('/');
-                if (lastItem == std::string::npos)
+                std::string thispath = item.first.filename();
+                if (thispath.empty())
                 {
                     continue;
                 }
 
-                if (path.substr(lastItem + 1) != resName)
+                if (thispath != resName)
                 {
                     continue;
                 }
@@ -262,7 +255,7 @@
                 aResp->res.jsonValue = vmItemTemplate(name, resName);
 
                 // Check if dbus path is Legacy type
-                if (path.find("VirtualMedia/Legacy") != std::string::npos)
+                if (thispath.find("VirtualMedia/Legacy") != std::string::npos)
                 {
                     aResp->res.jsonValue["Actions"]["#VirtualMedia.InsertMedia"]
                                         ["target"] =