diff --git a/Drivers/Super/driver_super.c b/Drivers/Super/driver_super.c index 1c6cfb17a..7e0a440be 100644 --- a/Drivers/Super/driver_super.c +++ b/Drivers/Super/driver_super.c @@ -853,8 +853,8 @@ static void DS_analyze_rx_buffer_variable_pickup_with_rx_frame_size_(DS_StreamCo { rx_frame_size = DS_analyze_rx_buffer_get_framelength_(p_stream_config); - // バッファー超えはエラーを出す! - if (rx_frame_size > buffer->capacity) + // バッファー超え or 上限値超えはエラーを出す! + if (rx_frame_size > buffer->capacity || rx_frame_size > p->settings.max_rx_frame_size_) { p->info.rec_status_.status_code = DS_STREAM_REC_STATUS_RX_FRAME_TOO_LONG; #ifdef DS_DEBUG @@ -953,12 +953,28 @@ static void DS_analyze_rx_buffer_variable_pickup_with_footer_(DS_StreamConfig* p // まだまだ受信する DS_confirm_stream_rec_buffer_(buffer, unprocessed_data_len); // unprocessed_data_len byte 確定 p->info.rec_status_.status_code = DS_STREAM_REC_STATUS_RECEIVING_DATA; + + if (buffer->confirmed_frame_len > p->settings.max_rx_frame_size_) + { + p->info.rec_status_.status_code = DS_STREAM_REC_STATUS_RX_FRAME_TOO_LONG; +#ifdef DS_DEBUG + Printf("DS: RX frame size is too long\n"); +#endif + } return; } processed_data_len = (uint16_t)(p_footer_last - &(buffer->buffer[memchr_offset]) + 1); // buffer->confirmed_frame_len が更新されることに注意! DS_confirm_stream_rec_buffer_(buffer, processed_data_len); // processed_data_len byte 確定 + if (buffer->confirmed_frame_len > p->settings.max_rx_frame_size_) + { + p->info.rec_status_.status_code = DS_STREAM_REC_STATUS_RX_FRAME_TOO_LONG; +#ifdef DS_DEBUG + Printf("DS: RX frame size is too long\n"); +#endif + return; + } body_data_len = buffer->confirmed_frame_len - p->settings.rx_header_size_ - p->settings.rx_footer_size_; if (body_data_len < 0) @@ -1174,6 +1190,7 @@ static DS_ERR_CODE DS_reset_stream_config_(DS_StreamConfig* p_stream_config) p->settings.rx_footer_ = NULL; p->settings.rx_footer_size_ = 0; p->settings.rx_frame_size_ = 0; + p->settings.max_rx_frame_size_ = 0xffff; p->settings.rx_framelength_pos_ = -1; p->settings.rx_framelength_type_size_ = 0; @@ -1488,6 +1505,18 @@ void DSSC_set_rx_frame_size(DS_StreamConfig* p_stream_config, p_stream_config->internal.is_validation_needed_for_rec_ = 1; } +uint16_t DSSC_get_max_rx_frame_size(const DS_StreamConfig* p_stream_config) +{ + return (uint16_t)p_stream_config->settings.max_rx_frame_size_; +} + +void DSSC_set_max_rx_frame_size(DS_StreamConfig* p_stream_config, + const uint16_t max_rx_frame_size) +{ + p_stream_config->settings.max_rx_frame_size_ = max_rx_frame_size; + p_stream_config->internal.is_validation_needed_for_rec_ = 1; +} + void DSSC_set_rx_framelength_pos(DS_StreamConfig* p_stream_config, const int16_t rx_framelength_pos) { diff --git a/Drivers/Super/driver_super.h b/Drivers/Super/driver_super.h index 419588721..2f81b6405 100644 --- a/Drivers/Super/driver_super.h +++ b/Drivers/Super/driver_super.h @@ -327,9 +327,14 @@ struct DS_StreamConfig ヘッダがない場合は0に設定 初期値: 0 */ int16_t rx_frame_size_; /*!< 受信データ(テレメトリ)フレームサイズ - 受信データがない場合は0に設定 + 受信データがない場合は 0 に設定 受信データが可変の場合は負数に設定 初期値: 0 */ + uint16_t max_rx_frame_size_; /*!< 受信データ(テレメトリ)の想定される最大フレームサイズ + これよりも長いフレームが来た(来そうな)場合は,そのフレーム(候補)は破棄される + これにより,ヘッダ内部のフレーム長が巨大な値に化けていた場合などに永遠に受信してしまうことを防ぐことができる + rx_frame_size_ が固定長の場合は無視される + 初期値: 0xffff */ int16_t rx_framelength_pos_; /*!< 受信データ内のフレームサイズデータの存在する場所(先頭から数えて何 byte 目に位置するか.0 起算) 受信データが可変長の場合のみ使用される. フレームサイズデータがない場合には負に設定する. @@ -589,6 +594,9 @@ uint16_t DSSC_get_rx_footer_size(const DS_StreamConfig* p_stream_config); int16_t DSSC_get_rx_frame_size(const DS_StreamConfig* p_stream_config); void DSSC_set_rx_frame_size(DS_StreamConfig* p_stream_config, const int16_t rx_frame_size); +uint16_t DSSC_get_max_rx_frame_size(const DS_StreamConfig* p_stream_config); +void DSSC_set_max_rx_frame_size(DS_StreamConfig* p_stream_config, + const uint16_t max_rx_frame_size); void DSSC_set_rx_framelength_pos(DS_StreamConfig* p_stream_config, const int16_t rx_framelength_pos);