From fc3510c425c1b1ccb31c16b44df6e76f0145e53e Mon Sep 17 00:00:00 2001 From: DashyFox Date: Wed, 1 Jul 2026 10:34:12 +0300 Subject: [PATCH] fix(rx): guard null encoder in auto-accept (B2), init accept fields (B4), fix dataBuffer OOB off-by-one (B3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit B2 (HIGH): IR_Decoder::_tick — encoder->sendAccept() без null-check; у Car decoder создан с encoder==nullptr → HardFault при приёме IR_MSG_DATA_ACCEPT. Добавлен guard. B4 (MEDIUM): acceptSendTimer/isWaitingAcceptSend/addrAcceptSendTo/acceptCustomByte не инициализировались → мусор мог спонтанно дёрнуть sendAccept. Дефолты в .h. B3 (HIGH): writeToBuffer — '>' вместо '>=' → при i_dataBuffer==dataByteSizeMax*8 (304) запись dataBuffer[38] за границей 38-байтового массива (packSize==0 runaway). Валидные кадры закрываются при <=248, не затронуты. Co-Authored-By: Claude Opus 4.8 (1M context) --- IR_Decoder.cpp | 2 +- IR_Decoder.h | 8 ++++---- IR_DecoderRaw.cpp | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index 96191e9..9998b03 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -166,7 +166,7 @@ void IR_Decoder::_tick() } if (isWaitingAcceptSend && millis() - acceptSendTimer > acceptDelay) { - encoder->sendAccept(addrAcceptSendTo, acceptCustomByte); + if (encoder != nullptr) encoder->sendAccept(addrAcceptSendTo, acceptCustomByte); // B2: у Car decoder без парного энкодера (nullptr) → был HardFault isWaitingAcceptSend = false; } } diff --git a/IR_Decoder.h b/IR_Decoder.h index 0c2e238..4b6fd99 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -10,12 +10,12 @@ private: static std::list& get_dec_list(); void _tick(); - uint32_t acceptSendTimer; - bool isWaitingAcceptSend; - uint16_t addrAcceptSendTo; + uint32_t acceptSendTimer = 0; + bool isWaitingAcceptSend = false; // B4: без инициализации мусор мог дёрнуть sendAccept при старте + uint16_t addrAcceptSendTo = 0; uint16_t acceptDelay = IR_ResponseDelay; - uint8_t acceptCustomByte; + uint8_t acceptCustomByte = 0; bool extiEnabled_ = false; bool rxExtiPreemptConfigured_ = false; diff --git a/IR_DecoderRaw.cpp b/IR_DecoderRaw.cpp index cdbf6b7..2671bfc 100644 --- a/IR_DecoderRaw.cpp +++ b/IR_DecoderRaw.cpp @@ -750,8 +750,8 @@ void IR_DecoderRaw::writeToBuffer(bool bit, bool packTraceInvertFix) #if !defined(IRDEBUG_SERIAL_PACK) (void)packTraceInvertFix; #endif - if (i_dataBuffer > dataByteSizeMax * 8) - { // проверка переполнения + if (i_dataBuffer >= dataByteSizeMax * 8) + { // проверка переполнения (>=: иначе при i_dataBuffer==dataByteSizeMax*8 запись dataBuffer[38] за границей массива — B3) isBufferOverflow = true; #if IR_RX_BRIEF_LOG rxBriefLog(RxBriefReason::BufferOverflow, i_dataBuffer, 0, micros());