xref: /openbmc/telemetry/src/utils/dbus_path_utils.cpp (revision 32305f14d8a7560980735c04fbb2067d633e08d8)
1 #include "utils/dbus_path_utils.hpp"
2 
3 namespace utils
4 {
5 sdbusplus::message::object_path pathAppend(sdbusplus::message::object_path path,
6                                            const std::string& appended)
7 {
8     if (appended.starts_with('/') || !isValidDbusPath(appended))
9     {
10         throw sdbusplus::exception::SdBusError(
11             static_cast<int>(std::errc::invalid_argument),
12             "Invalid appended string");
13     }
14 
15     size_t pos_start = 0;
16     size_t pos_end = 0;
17     while ((pos_end = appended.find('/', pos_start)) != std::string::npos)
18     {
19         if (pos_start == pos_end)
20         {
21             throw sdbusplus::exception::SdBusError(
22                 static_cast<int>(std::errc::invalid_argument),
23                 "Invalid appended string");
24         }
25         path /= std::string_view(appended.begin() + pos_start,
26                                  appended.begin() + pos_end);
27         pos_start = pos_end + 1;
28     }
29     path /= std::string_view(appended.begin() + pos_start, appended.end());
30     return path;
31 }
32 
33 std::string reportPathToId(const sdbusplus::message::object_path& path)
34 {
35     if (path.str.starts_with(constants::reportDirStr))
36     {
37         auto id = path.str.substr(constants::reportDirStr.length());
38         verifyIdPrefixes(id);
39         return id;
40     }
41     throw sdbusplus::exception::SdBusError(
42         static_cast<int>(std::errc::invalid_argument), "Invalid path prefix");
43 }
44 
45 void verifyIdPrefixes(std::string_view id)
46 {
47     size_t pos_start = 0;
48     size_t pos_end = 0;
49     size_t prefix_cnt = 0;
50     while ((pos_end = id.find('/', pos_start)) != std::string::npos)
51     {
52         if (pos_start == pos_end)
53         {
54             throw sdbusplus::exception::SdBusError(
55                 static_cast<int>(std::errc::invalid_argument),
56                 "Invalid prefixes in id");
57         }
58 
59         if (++prefix_cnt > constants::maxPrefixesInId)
60         {
61             throw sdbusplus::exception::SdBusError(
62                 static_cast<int>(std::errc::invalid_argument),
63                 "Too many prefixes");
64         }
65 
66         if (pos_end - pos_start > constants::maxPrefixLength)
67         {
68             throw sdbusplus::exception::SdBusError(
69                 static_cast<int>(std::errc::invalid_argument),
70                 "Prefix too long");
71         }
72 
73         pos_start = pos_end + 1;
74     }
75 
76     if (id.length() - pos_start > constants::maxIdNameLength)
77     {
78         throw sdbusplus::exception::SdBusError(
79             static_cast<int>(std::errc::invalid_argument), "Id too long");
80     }
81 }
82 } // namespace utils
83