AP_FETtecOneWire: avoid variable-length array in update()

update() declared a stack buffer sized by the runtime _esc_count.
clang-scan-build's core.VLASize flagged it as a possible zero-size VLA
because it cannot see that init() bounds _esc_count.

Introduce a named MAX_ESC_COUNT for the OneWire protocol maximum, use it
in place of the bare 24 in the init bounds check, and size the buffer to
it.  We do not size from NUM_SERVO_CHANNELS: it is board-dependent and
can be zero (e.g. AP_Periph), which would give a zero-length array.

init() rejects a motor mask which would leave _esc_count outside
[1, esc_count_limit], and that limit never exceeds MAX_ESC_COUNT, so the
buffer is large enough and is fully populated by the loop.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Peter Barker
2026-08-27 14:01:54 +10:00
committed by Peter Barker
co-authored by Claude Opus 4.8
parent 14f70f1028
commit 3946b90b41
2 changed files with 3 additions and 3 deletions
@@ -127,7 +127,7 @@ void AP_FETtecOneWire::init()
const auto esc_count_limit = MIN(15, ESC_TELEM_MAX_ESCS);
#else
// OneWire supports at most 24 ESCs without telemetry
const auto esc_count_limit = MIN(24, NUM_SERVO_CHANNELS);
const auto esc_count_limit = MIN(MAX_ESC_COUNT, NUM_SERVO_CHANNELS);
#endif
if (_esc_count == 0 || _motor_mask >= (1U << esc_count_limit)) {
_invalid_mask = true;
@@ -821,8 +821,7 @@ void AP_FETtecOneWire::update()
}
#endif
// get ESC set points
uint16_t motor_pwm[_esc_count];
uint16_t motor_pwm[MAX_ESC_COUNT];
for (uint8_t i = 0; i < _esc_count; i++) {
const ESC &esc = _escs[i];
const SRV_Channel* c = SRV_Channels::srv_channel(esc.servo_ofs);
@@ -112,6 +112,7 @@ private:
static constexpr uint8_t FRAME_OVERHEAD = 6; ///< OneWire message frame overhead (header+tail bytes)
static constexpr uint8_t MAX_RECEIVE_LENGTH = 12; ///< OneWire max receive message payload length in bytes
static constexpr uint8_t MAX_ESC_COUNT = 24; ///< Max ESCs supported (will be fewer with telemetry)
#if HAL_AP_FETTEC_ONEWIRE_GET_STATIC_INFO
static constexpr uint8_t SERIAL_NUMBER_LENGTH = 12; ///< ESC serial number length in bytes
#endif