rc522: fix buffer overflow in UID/buffer formatting helpers (#9375)

This commit is contained in:
@RubenKelevra 2025-07-24 14:43:44 +02:00 committed by GitHub
parent 73f58dfe80
commit 27119ef7ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,4 +1,5 @@
#include "rc522.h" #include "rc522.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
// Based on: // Based on:
@ -13,30 +14,6 @@ static const char *const TAG = "rc522";
static const uint8_t RESET_COUNT = 5; static const uint8_t RESET_COUNT = 5;
std::string format_buffer(uint8_t *b, uint8_t len) {
char buf[32];
int offset = 0;
for (uint8_t i = 0; i < len; i++) {
const char *format = "%02X";
if (i + 1 < len)
format = "%02X-";
offset += sprintf(buf + offset, format, b[i]);
}
return std::string(buf);
}
std::string format_uid(std::vector<uint8_t> &uid) {
char buf[32];
int offset = 0;
for (size_t i = 0; i < uid.size(); i++) {
const char *format = "%02X";
if (i + 1 < uid.size())
format = "%02X-";
offset += sprintf(buf + offset, format, uid[i]);
}
return std::string(buf);
}
void RC522::setup() { void RC522::setup() {
state_ = STATE_SETUP; state_ = STATE_SETUP;
// Pull device out of power down / reset state. // Pull device out of power down / reset state.
@ -215,7 +192,7 @@ void RC522::loop() {
ESP_LOGV(TAG, "STATE_READ_SERIAL_DONE -> TIMEOUT (no tag present) %d", status); ESP_LOGV(TAG, "STATE_READ_SERIAL_DONE -> TIMEOUT (no tag present) %d", status);
} else { } else {
ESP_LOGW(TAG, "Unexpected response. Read status is %d. Read bytes: %d (%s)", status, back_length_, ESP_LOGW(TAG, "Unexpected response. Read status is %d. Read bytes: %d (%s)", status, back_length_,
format_buffer(buffer_, 9).c_str()); format_hex_pretty(buffer_, back_length_, '-', false).c_str());
} }
state_ = STATE_DONE; state_ = STATE_DONE;
@ -239,7 +216,7 @@ void RC522::loop() {
std::vector<uint8_t> rfid_uid(std::begin(uid_buffer_), std::begin(uid_buffer_) + uid_idx_); std::vector<uint8_t> rfid_uid(std::begin(uid_buffer_), std::begin(uid_buffer_) + uid_idx_);
uid_idx_ = 0; uid_idx_ = 0;
// ESP_LOGD(TAG, "Processing '%s'", format_uid(rfid_uid).c_str()); // ESP_LOGD(TAG, "Processing '%s'", format_hex_pretty(rfid_uid, '-', false).c_str());
pcd_antenna_off_(); pcd_antenna_off_();
state_ = STATE_INIT; // scan again on next update state_ = STATE_INIT; // scan again on next update
bool report = true; bool report = true;
@ -260,13 +237,13 @@ void RC522::loop() {
trigger->process(rfid_uid); trigger->process(rfid_uid);
if (report) { if (report) {
ESP_LOGD(TAG, "Found new tag '%s'", format_uid(rfid_uid).c_str()); ESP_LOGD(TAG, "Found new tag '%s'", format_hex_pretty(rfid_uid, '-', false).c_str());
} }
break; break;
} }
case STATE_DONE: { case STATE_DONE: {
if (!this->current_uid_.empty()) { if (!this->current_uid_.empty()) {
ESP_LOGV(TAG, "Tag '%s' removed", format_uid(this->current_uid_).c_str()); ESP_LOGV(TAG, "Tag '%s' removed", format_hex_pretty(this->current_uid_, '-', false).c_str());
for (auto *trigger : this->triggers_ontagremoved_) for (auto *trigger : this->triggers_ontagremoved_)
trigger->process(this->current_uid_); trigger->process(this->current_uid_);
} }
@ -361,7 +338,7 @@ void RC522::pcd_clear_register_bit_mask_(PcdRegister reg, ///< The register to
* @return STATUS_OK on success, STATUS_??? otherwise. * @return STATUS_OK on success, STATUS_??? otherwise.
*/ */
void RC522::pcd_transceive_data_(uint8_t send_len) { void RC522::pcd_transceive_data_(uint8_t send_len) {
ESP_LOGV(TAG, "PCD TRANSCEIVE: RX: %s", format_buffer(buffer_, send_len).c_str()); ESP_LOGV(TAG, "PCD TRANSCEIVE: RX: %s", format_hex_pretty(buffer_, send_len, '-', false).c_str());
delayMicroseconds(1000); // we need 1 ms delay between antenna on and those communication commands delayMicroseconds(1000); // we need 1 ms delay between antenna on and those communication commands
send_len_ = send_len; send_len_ = send_len;
// Prepare values for BitFramingReg // Prepare values for BitFramingReg
@ -435,7 +412,8 @@ RC522::StatusCode RC522::await_transceive_() {
error_reg_value); // TODO: is this always due to collissions? error_reg_value); // TODO: is this always due to collissions?
return STATUS_ERROR; return STATUS_ERROR;
} }
ESP_LOGV(TAG, "received %d bytes: %s", back_length_, format_buffer(buffer_ + send_len_, back_length_).c_str()); ESP_LOGV(TAG, "received %d bytes: %s", back_length_,
format_hex_pretty(buffer_ + send_len_, back_length_, '-', false).c_str());
return STATUS_OK; return STATUS_OK;
} }
@ -499,7 +477,7 @@ bool RC522BinarySensor::process(std::vector<uint8_t> &data) {
this->found_ = result; this->found_ = result;
return result; return result;
} }
void RC522Trigger::process(std::vector<uint8_t> &data) { this->trigger(format_uid(data)); } void RC522Trigger::process(std::vector<uint8_t> &data) { this->trigger(format_hex_pretty(data, '-', false)); }
} // namespace rc522 } // namespace rc522
} // namespace esphome } // namespace esphome