mirror of
https://github.com/esphome/esphome.git
synced 2026-06-24 16:38:43 +00:00
[multiple] Fix crashes from malformed external input (batch 2) (#14651)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -514,6 +514,11 @@ void ESPBTDevice::parse_adv_(const uint8_t *payload, uint8_t len) {
|
||||
continue; // Possible zero padded advertisement data
|
||||
}
|
||||
|
||||
// Validate field fits in remaining payload
|
||||
if (offset + field_length > len) {
|
||||
break;
|
||||
}
|
||||
|
||||
// first byte of adv record is adv record type
|
||||
const uint8_t record_type = payload[offset++];
|
||||
const uint8_t *record = &payload[offset];
|
||||
|
||||
@@ -59,6 +59,10 @@ bool ModbusController::send_next_command_() {
|
||||
|
||||
// Queue incoming response
|
||||
void ModbusController::on_modbus_data(const std::vector<uint8_t> &data) {
|
||||
if (this->command_queue_.empty()) {
|
||||
ESP_LOGW(TAG, "Received modbus data but command queue is empty");
|
||||
return;
|
||||
}
|
||||
auto ¤t_command = this->command_queue_.front();
|
||||
if (current_command != nullptr) {
|
||||
if (this->module_offline_) {
|
||||
@@ -92,6 +96,9 @@ void ModbusController::process_modbus_data_(const ModbusCommandItem *response) {
|
||||
|
||||
void ModbusController::on_modbus_error(uint8_t function_code, uint8_t exception_code) {
|
||||
ESP_LOGE(TAG, "Modbus error function code: 0x%X exception: %d ", function_code, exception_code);
|
||||
if (this->command_queue_.empty()) {
|
||||
return;
|
||||
}
|
||||
// Remove pending command waiting for a response
|
||||
auto ¤t_command = this->command_queue_.front();
|
||||
if (current_command != nullptr) {
|
||||
@@ -175,6 +182,11 @@ void ModbusController::on_modbus_write_registers(uint8_t function_code, const st
|
||||
uint16_t payload_offset;
|
||||
|
||||
if (function_code == ModbusFunctionCode::WRITE_MULTIPLE_REGISTERS) {
|
||||
if (data.size() < 5) {
|
||||
ESP_LOGW(TAG, "Write multiple registers data too short (%zu bytes)", data.size());
|
||||
this->send_error(function_code, ModbusExceptionCode::ILLEGAL_DATA_VALUE);
|
||||
return;
|
||||
}
|
||||
number_of_registers = uint16_t(data[3]) | (uint16_t(data[2]) << 8);
|
||||
if (number_of_registers == 0 || number_of_registers > modbus::MAX_NUM_OF_REGISTERS_TO_WRITE) {
|
||||
ESP_LOGW(TAG, "Invalid number of registers %d. Sending exception response.", number_of_registers);
|
||||
@@ -188,8 +200,19 @@ void ModbusController::on_modbus_write_registers(uint8_t function_code, const st
|
||||
this->send_error(function_code, ModbusExceptionCode::ILLEGAL_DATA_VALUE);
|
||||
return;
|
||||
}
|
||||
if (data.size() < 5 + payload_size) {
|
||||
ESP_LOGW(TAG, "Write multiple registers payload truncated (%zu bytes, expected %u)", data.size(),
|
||||
5 + payload_size);
|
||||
this->send_error(function_code, ModbusExceptionCode::ILLEGAL_DATA_VALUE);
|
||||
return;
|
||||
}
|
||||
payload_offset = 5;
|
||||
} else if (function_code == ModbusFunctionCode::WRITE_SINGLE_REGISTER) {
|
||||
if (data.size() < 4) {
|
||||
ESP_LOGW(TAG, "Write single register data too short (%zu bytes)", data.size());
|
||||
this->send_error(function_code, ModbusExceptionCode::ILLEGAL_DATA_VALUE);
|
||||
return;
|
||||
}
|
||||
number_of_registers = 1;
|
||||
payload_offset = 2;
|
||||
} else {
|
||||
|
||||
@@ -86,6 +86,12 @@ int Nextion::upload_by_chunks_(HTTPClient &http_client, uint32_t &range_start) {
|
||||
ESP_LOGD(TAG, "Upload: %0.2f%% (%" PRIu32 " left, heap: %" PRIu32 ")", upload_percentage, this->content_length_,
|
||||
EspClass::getFreeHeap());
|
||||
upload_first_chunk_sent_ = true;
|
||||
if (recv_string.empty()) {
|
||||
ESP_LOGW(TAG, "No response from display during upload");
|
||||
allocator.deallocate(buffer, 4096);
|
||||
buffer = nullptr;
|
||||
return -1;
|
||||
}
|
||||
if (recv_string[0] == 0x08 && recv_string.size() == 5) { // handle partial upload request
|
||||
char hex_buf[format_hex_pretty_size(NEXTION_MAX_RESPONSE_LOG_BYTES)];
|
||||
ESP_LOGD(
|
||||
|
||||
@@ -108,6 +108,12 @@ int Nextion::upload_by_chunks_(esp_http_client_handle_t http_client, uint32_t &r
|
||||
static_cast<uint32_t>(esp_get_free_heap_size()));
|
||||
#endif
|
||||
upload_first_chunk_sent_ = true;
|
||||
if (recv_string.empty()) {
|
||||
ESP_LOGW(TAG, "No response from display during upload");
|
||||
allocator.deallocate(buffer, 4096);
|
||||
buffer = nullptr;
|
||||
return -1;
|
||||
}
|
||||
if (recv_string[0] == 0x08 && recv_string.size() == 5) { // handle partial upload request
|
||||
char hex_buf[format_hex_pretty_size(NEXTION_MAX_RESPONSE_LOG_BYTES)];
|
||||
ESP_LOGD(
|
||||
|
||||
@@ -199,7 +199,7 @@ void MR60BHA2Component::process_frame_(uint16_t frame_id, uint16_t frame_type, c
|
||||
}
|
||||
break;
|
||||
case DISTANCE_TYPE_BUFFER:
|
||||
if (data[0] != 0) {
|
||||
if (length >= 1 && data[0] != 0) {
|
||||
if (this->distance_sensor_ != nullptr && length >= 8) {
|
||||
uint32_t current_distance_int = encode_uint32(data[7], data[6], data[5], data[4]);
|
||||
float distance_float;
|
||||
|
||||
@@ -492,6 +492,11 @@ bool USBClient::transfer_in(uint8_t ep_address, const transfer_cb_t &callback, u
|
||||
ESP_LOGE(TAG, "Too many requests queued");
|
||||
return false;
|
||||
}
|
||||
if (length > trq->transfer->data_buffer_size) {
|
||||
ESP_LOGE(TAG, "transfer_in: data length %u exceeds buffer size %u", length, trq->transfer->data_buffer_size);
|
||||
this->release_trq(trq);
|
||||
return false;
|
||||
}
|
||||
trq->callback = callback;
|
||||
trq->transfer->callback = transfer_callback;
|
||||
trq->transfer->bEndpointAddress = ep_address | USB_DIR_IN;
|
||||
|
||||
Reference in New Issue
Block a user