@@ -147,6 +147,20 @@ uint64_t decode_uint64(const char *p, int base, char **end = nullptr,
147147 return addr;
148148}
149149
150+ // / Attempts to parse a prefix of `number_str` as a uint64_t. If
151+ // / successful, the number is returned and the prefix is dropped from
152+ // / `number_str`.
153+ static std::optional<uint64_t > extract_u64 (std::string_view &number_str) {
154+ char *str_end = nullptr ;
155+ errno = 0 ;
156+ uint64_t number = strtoull (number_str.data (), &str_end, 16 );
157+ if (errno != 0 )
158+ return std::nullopt ;
159+ assert (str_end);
160+ number_str.remove_prefix (str_end - number_str.data ());
161+ return number;
162+ }
163+
150164void append_hex_value (std::ostream &ostrm, const void *buf, size_t buf_size,
151165 bool swap) {
152166 int i;
@@ -180,6 +194,25 @@ void append_hexified_string(std::ostream &ostrm, const std::string &string) {
180194 }
181195}
182196
197+ // / Returns true if `str` starts with `prefix`.
198+ static bool starts_with (std::string_view str, std::string_view prefix) {
199+ return str.substr (0 , prefix.size ()) == prefix;
200+ }
201+
202+ // / Splits `list_str` into multiple string_views separated by `,`.
203+ static std::vector<std::string_view>
204+ parse_comma_separated_list (std::string_view list_str) {
205+ std::vector<std::string_view> list;
206+ while (!list_str.empty ()) {
207+ auto pos = list_str.find (' ,' );
208+ list.push_back (list_str.substr (0 , pos));
209+ if (pos == list_str.npos )
210+ break ;
211+ list_str.remove_prefix (pos + 1 );
212+ }
213+ return list;
214+ }
215+
183216// from System.framework/Versions/B/PrivateHeaders/sys/codesign.h
184217extern " C" {
185218#define CS_OPS_STATUS 0 /* return status */
@@ -3165,42 +3198,6 @@ rnb_err_t RNBRemote::HandlePacket_m(const char *p) {
31653198 return SendPacket (ostrm.str ());
31663199}
31673200
3168- // / Returns true if `str` starts with `prefix`.
3169- static bool starts_with (std::string_view str, std::string_view prefix) {
3170- return str.size () >= prefix.size () &&
3171- str.compare (0 , prefix.size (), prefix) == 0 ;
3172- }
3173-
3174- // / Attempts to parse a prefix of `number_str` as a number of type `T`. If
3175- // / successful, the number is returned and the prefix is dropped from
3176- // / `number_str`.
3177- template <typename T>
3178- static std::optional<T> extract_number (std::string_view &number_str) {
3179- static_assert (std::is_integral<T>());
3180- char *str_end = nullptr ;
3181- errno = 0 ;
3182- nub_addr_t number = strtoull (number_str.data (), &str_end, 16 );
3183- if (errno != 0 )
3184- return std::nullopt ;
3185- assert (str_end);
3186- number_str.remove_prefix (str_end - number_str.data ());
3187- return number;
3188- }
3189-
3190- // / Splits `list_str` into multiple string_views separated by `,`.
3191- static std::vector<std::string_view>
3192- parse_comma_separated_list (std::string_view list_str) {
3193- std::vector<std::string_view> list;
3194- while (!list_str.empty ()) {
3195- auto pos = list_str.find (' ,' );
3196- list.push_back (list_str.substr (0 , pos));
3197- if (pos == list_str.npos )
3198- break ;
3199- list_str.remove_prefix (pos + 1 );
3200- }
3201- return list;
3202- }
3203-
32043201rnb_err_t RNBRemote::HandlePacket_MultiMemRead (const char *p) {
32053202 const std::string_view packet_name (" MultiMemRead:" );
32063203 std::string_view packet (p);
@@ -3237,10 +3234,8 @@ rnb_err_t RNBRemote::HandlePacket_MultiMemRead(const char *p) {
32373234 " MultiMemRead has an odd number of numbers for the ranges" );
32383235
32393236 for (unsigned idx = 0 ; idx < numbers_list.size (); idx += 2 ) {
3240- std::optional<nub_addr_t > maybe_addr =
3241- extract_number<nub_addr_t >(numbers_list[idx]);
3242- std::optional<size_t > maybe_length =
3243- extract_number<size_t >(numbers_list[idx + 1 ]);
3237+ std::optional<uint64_t > maybe_addr = extract_u64 (numbers_list[idx]);
3238+ std::optional<uint64_t > maybe_length = extract_u64 (numbers_list[idx + 1 ]);
32443239 if (!maybe_addr || !maybe_length)
32453240 return HandlePacket_ILLFORMED (__FILE__, __LINE__, packet.data (),
32463241 " Invalid MultiMemRead range" );
@@ -3258,28 +3253,14 @@ rnb_err_t RNBRemote::HandlePacket_MultiMemRead(const char *p) {
32583253 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p,
32593254 " MultiMemRead has an empty range list" );
32603255
3261- // If 'options:' is present, ensure it's empty.
3262- const std::string_view options_prefix (" options:" );
3263- if (starts_with (packet, options_prefix)) {
3264- packet.remove_prefix (options_prefix.size ());
3265- if (packet.empty ())
3266- return HandlePacket_ILLFORMED (
3267- __FILE__, __LINE__, packet.data (),
3268- " Too short 'options' in MultiMemRead packet" );
3269- if (packet[0 ] != ' ;' )
3270- return HandlePacket_ILLFORMED (__FILE__, __LINE__, packet.data (),
3271- " Unimplemented 'options' in MultiMemRead" );
3272- packet.remove_prefix (1 );
3273- }
3274-
32753256 if (!packet.empty ())
3276- return HandlePacket_ILLFORMED (__FILE__, __LINE__, p,
3277- " Invalid MultiMemRead address_range " );
3257+ return HandlePacket_ILLFORMED (
3258+ __FILE__, __LINE__, p, " MultiMemRead packet has unrecognized fields " );
32783259
32793260 std::vector<std::vector<uint8_t >> buffers;
32803261 buffers.reserve (ranges.size ());
32813262 for (auto [base_addr, length] : ranges) {
3282- buffers.emplace_back (length, ' \0 ' );
3263+ buffers.emplace_back (length, 0 );
32833264 nub_size_t bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID (), base_addr,
32843265 length, buffers.back ().data ());
32853266 buffers.back ().resize (bytes_read);
0 commit comments