@@ -403,7 +403,8 @@ static void push_uint16(std::vector<char> &buf, uint16_t value) {
403403}
404404
405405static uint16_t get_uint16 (const std::vector<char > &buf, size_t idx) {
406- return ((uint16_t )buf[idx] << 0 ) | ((uint16_t )buf[idx + 1 ] << 8 );
406+ // at() will check index and throw std::out_of_range
407+ return ((uint16_t )buf.at (idx) << 0 ) | ((uint16_t )buf.at (idx + 1 ) << 8 );
407408}
408409
409410static bool recv_args (int fd, std::vector<std::string> &args) {
@@ -437,18 +438,29 @@ static bool recv_args(int fd, std::vector<std::string> &args) {
437438 }
438439
439440 // Deserialize
440- size_t idx = 0 ;
441- size_t n_args = get_uint16 (buf, idx);
442- args.resize (n_args);
443- idx += sizeof (uint16_t );
444- for (size_t i = 0 ; i < n_args; i++) {
445- size_t arg_size = get_uint16 (buf, idx);
441+ try {
442+ size_t idx = 0 ;
443+ size_t n_args = get_uint16 (buf, idx);
444+ args.resize (n_args);
446445 idx += sizeof (uint16_t );
447- args[i] = std::string (buf.begin () + idx, buf.begin () + idx + arg_size);
448- idx += arg_size;
449- }
450- if (idx != buff_size) {
451- rtapi_print_msg (RTAPI_MSG_ERR , " rtapi_app: Bug recv_args: idx %li != buff_size %li\n " , idx, buff_size);
446+ for (size_t i = 0 ; i < n_args; i++) {
447+ size_t arg_size = get_uint16 (buf, idx);
448+ idx += sizeof (uint16_t );
449+ // Bound checked, unpack argument
450+ auto start = buf.begin () + idx;
451+ auto end = start + arg_size;
452+ if (end > buf.end ()) {
453+ throw std::out_of_range (" recv_args: arg size not in buffer range" );
454+ }
455+ args[i] = std::string (start, end);
456+ idx += arg_size;
457+ }
458+ if (idx != buff_size) {
459+ rtapi_print_msg (RTAPI_MSG_ERR , " rtapi_app: Bug recv_args: idx %li != buff_size %li\n " , idx, buff_size);
460+ return false ;
461+ }
462+ } catch (std::out_of_range &e) {
463+ rtapi_print_msg (RTAPI_MSG_ERR , " rtapi_app: Bug recv_args: %s\n " , e.what ());
452464 return false ;
453465 }
454466
@@ -561,7 +573,7 @@ static bool master_process_socket_command(int fd) {
561573 struct timeval timeout;
562574 timeout.tv_sec = 10 ;
563575 timeout.tv_usec = 0 ;
564- if (setsockopt (fd1, SOL_SOCKET , SO_RCVTIMEO , &timeout, sizeof (timeout)) < 0 ){
576+ if (setsockopt (fd1, SOL_SOCKET , SO_RCVTIMEO , &timeout, sizeof (timeout)) < 0 ) {
565577 rtapi_print_msg (RTAPI_MSG_ERR , " rtapi_app: setsockopt timeout failed: %s\n " , strerror (errno));
566578 close (fd1);
567579 return true ; // If there is a socket error, just continue
0 commit comments