@@ -170,6 +170,20 @@ static uint64_t decode_uint64(const char *p, int base, char **end = nullptr,
170170 return addr;
171171}
172172
173+ // / Attempts to parse a prefix of `number_str` as a uint64_t. If
174+ // / successful, the number is returned and the prefix is dropped from
175+ // / `number_str`.
176+ static std::optional<uint64_t > extract_u64 (std::string_view &number_str) {
177+ char *str_end = nullptr ;
178+ errno = 0 ;
179+ uint64_t number = strtoull (number_str.data (), &str_end, 16 );
180+ if (errno != 0 )
181+ return std::nullopt ;
182+ assert (str_end);
183+ number_str.remove_prefix (str_end - number_str.data ());
184+ return number;
185+ }
186+
173187static void append_hex_value (std::ostream &ostrm, const void *buf,
174188 size_t buf_size, bool swap) {
175189 int i;
@@ -204,6 +218,25 @@ static void append_hexified_string(std::ostream &ostrm,
204218 }
205219}
206220
221+ // / Returns true if `str` starts with `prefix`.
222+ static bool starts_with (std::string_view str, std::string_view prefix) {
223+ return str.substr (0 , prefix.size ()) == prefix;
224+ }
225+
226+ // / Splits `list_str` into multiple string_views separated by `,`.
227+ static std::vector<std::string_view>
228+ parse_comma_separated_list (std::string_view list_str) {
229+ std::vector<std::string_view> list;
230+ while (!list_str.empty ()) {
231+ auto pos = list_str.find (' ,' );
232+ list.push_back (list_str.substr (0 , pos));
233+ if (pos == list_str.npos )
234+ break ;
235+ list_str.remove_prefix (pos + 1 );
236+ }
237+ return list;
238+ }
239+
207240// from System.framework/Versions/B/PrivateHeaders/sys/codesign.h
208241extern " C" {
209242#define CS_OPS_STATUS 0 /* return status */
@@ -3155,42 +3188,6 @@ rnb_err_t RNBRemote::HandlePacket_m(const char *p) {
31553188 return SendPacket (ostrm.str ());
31563189}
31573190
3158- // / Returns true if `str` starts with `prefix`.
3159- static bool starts_with (std::string_view str, std::string_view prefix) {
3160- return str.size () >= prefix.size () &&
3161- str.compare (0 , prefix.size (), prefix) == 0 ;
3162- }
3163-
3164- // / Attempts to parse a prefix of `number_str` as a number of type `T`. If
3165- // / successful, the number is returned and the prefix is dropped from
3166- // / `number_str`.
3167- template <typename T>
3168- static std::optional<T> extract_number (std::string_view &number_str) {
3169- static_assert (std::is_integral<T>());
3170- char *str_end = nullptr ;
3171- errno = 0 ;
3172- nub_addr_t number = strtoull (number_str.data (), &str_end, 16 );
3173- if (errno != 0 )
3174- return std::nullopt ;
3175- assert (str_end);
3176- number_str.remove_prefix (str_end - number_str.data ());
3177- return number;
3178- }
3179-
3180- // / Splits `list_str` into multiple string_views separated by `,`.
3181- static std::vector<std::string_view>
3182- parse_comma_separated_list (std::string_view list_str) {
3183- std::vector<std::string_view> list;
3184- while (!list_str.empty ()) {
3185- auto pos = list_str.find (' ,' );
3186- list.push_back (list_str.substr (0 , pos));
3187- if (pos == list_str.npos )
3188- break ;
3189- list_str.remove_prefix (pos + 1 );
3190- }
3191- return list;
3192- }
3193-
31943191rnb_err_t RNBRemote::HandlePacket_MultiMemRead (const char *p) {
31953192 const std::string_view packet_name (" MultiMemRead:" );
31963193 std::string_view packet (p);
@@ -3227,10 +3224,8 @@ rnb_err_t RNBRemote::HandlePacket_MultiMemRead(const char *p) {
32273224 " MultiMemRead has an odd number of numbers for the ranges" );
32283225
32293226 for (unsigned idx = 0 ; idx < numbers_list.size (); idx += 2 ) {
3230- std::optional<nub_addr_t > maybe_addr =
3231- extract_number<nub_addr_t >(numbers_list[idx]);
3232- std::optional<size_t > maybe_length =
3233- extract_number<size_t >(numbers_list[idx + 1 ]);
3227+ std::optional<uint64_t > maybe_addr = extract_u64 (numbers_list[idx]);
3228+ std::optional<uint64_t > maybe_length = extract_u64 (numbers_list[idx + 1 ]);
32343229 if (!maybe_addr || !maybe_length)
32353230 return HandlePacket_ILLFORMED (__FILE__, __LINE__, packet.data (),
32363231 " Invalid MultiMemRead range" );
@@ -3248,28 +3243,14 @@ rnb_err_t RNBRemote::HandlePacket_MultiMemRead(const char *p) {
32483243 return HandlePacket_ILLFORMED (__FILE__, __LINE__, p,
32493244 " MultiMemRead has an empty range list" );
32503245
3251- // If 'options:' is present, ensure it's empty.
3252- const std::string_view options_prefix (" options:" );
3253- if (starts_with (packet, options_prefix)) {
3254- packet.remove_prefix (options_prefix.size ());
3255- if (packet.empty ())
3256- return HandlePacket_ILLFORMED (
3257- __FILE__, __LINE__, packet.data (),
3258- " Too short 'options' in MultiMemRead packet" );
3259- if (packet[0 ] != ' ;' )
3260- return HandlePacket_ILLFORMED (__FILE__, __LINE__, packet.data (),
3261- " Unimplemented 'options' in MultiMemRead" );
3262- packet.remove_prefix (1 );
3263- }
3264-
32653246 if (!packet.empty ())
3266- return HandlePacket_ILLFORMED (__FILE__, __LINE__, p,
3267- " Invalid MultiMemRead address_range " );
3247+ return HandlePacket_ILLFORMED (
3248+ __FILE__, __LINE__, p, " MultiMemRead packet has unrecognized fields " );
32683249
32693250 std::vector<std::vector<uint8_t >> buffers;
32703251 buffers.reserve (ranges.size ());
32713252 for (auto [base_addr, length] : ranges) {
3272- buffers.emplace_back (length, ' \0 ' );
3253+ buffers.emplace_back (length, 0 );
32733254 nub_size_t bytes_read = DNBProcessMemoryRead (m_ctx.ProcessID (), base_addr,
32743255 length, buffers.back ().data ());
32753256 buffers.back ().resize (bytes_read);
0 commit comments