fix: validate sensor IDs before narrowing

This commit is contained in:
Yurii committed 2026-10-19 05:22:30 +03:00
1 parent ab5b96c970
commit 63aeb2fa25
3 files changed
+41 -25

No files matched your search

+6 -18
View File
@@ -227,12 +227,8 @@ protected:
// restore sensors settings // restore sensors settings
if (!requestDoc[FPSTR(S_SENSORS)].isNull()) { if (!requestDoc[FPSTR(S_SENSORS)].isNull()) {
for (auto sensor : requestDoc[FPSTR(S_SENSORS)].as<JsonObject>()) { for (auto sensor : requestDoc[FPSTR(S_SENSORS)].as<JsonObject>()) {
if (!isDigit(sensor.key().c_str())) { uint8_t sensorId;
continue; if (!Sensors::parseId(sensor.key().c_str(), sensorId)) {
}
int sensorId = atoi(sensor.key().c_str());
if (sensorId < 0 || sensorId > 255 || !Sensors::isValidSensorId(sensorId)) {
continue; continue;
} }
@@ -420,12 +416,8 @@ protected:
} }
const auto& id = request->getParam("id")->value(); const auto& id = request->getParam("id")->value();
if (!isDigit(id.c_str())) { uint8_t sensorId;
return request->send(400); if (!Sensors::parseId(id.c_str(), sensorId)) {
}
uint8_t sensorId = id.toInt();
if (!Sensors::isValidSensorId(sensorId)) {
return request->send(404); return request->send(404);
} }
@@ -451,12 +443,8 @@ protected:
} }
auto& id = request->getParam("id")->value(); auto& id = request->getParam("id")->value();
if (!isDigit(id.c_str())) { uint8_t sensorId;
return request->send(400); if (!Sensors::parseId(id.c_str(), sensorId)) {
}
uint8_t sensorId = id.toInt();
if (!Sensors::isValidSensorId(sensorId)) {
return request->send(404); return request->send(404);
} }
+35 -1
View File
@@ -1,4 +1,6 @@
#pragma once #pragma once
#include <errno.h>
#include <stdlib.h>
class Sensors { class Sensors {
protected: protected:
@@ -121,10 +123,26 @@ public:
return maxSensors > 1 ? (maxSensors - 1) : 0; return maxSensors > 1 ? (maxSensors - 1) : 0;
} }
static inline bool isValidSensorId(const uint8_t id) { template <class T>
static bool isValidSensorId(const T id) {
return id >= 0 && id <= getMaxSensorId(); return id >= 0 && id <= getMaxSensorId();
} }
static bool parseId(const char* value, uint8_t& sensorId) {
if (!isDigit(value)) {
return false;
}
errno = 0;
const unsigned long parsed = strtoul(value, nullptr, 10);
if (errno == ERANGE || !isValidSensorId(parsed)) {
return false;
}
sensorId = static_cast<uint8_t>(parsed);
return true;
}
static inline bool isValidValueId(const uint8_t id) { static inline bool isValidValueId(const uint8_t id) {
return id >= (uint8_t) ValueType::TEMPERATURE && id <= (uint8_t) ValueType::RSSI; return id >= (uint8_t) ValueType::TEMPERATURE && id <= (uint8_t) ValueType::RSSI;
} }
@@ -499,6 +517,22 @@ public:
static uint8_t bluetoothRssiToQuality(int rssi) { static uint8_t bluetoothRssiToQuality(int rssi) {
return constrain(map(rssi, -110, -50, 0, 100), 0, 100);; return constrain(map(rssi, -110, -50, 0, 100), 0, 100);;
} }
private:
static constexpr bool isDigit(const char* value) {
if (value == nullptr || *value == '\0') {
return false;
}
while (*value != '\0') {
if (*value < '0' || *value > '9') {
return false;
}
value++;
}
return true;
}
}; };
uint8_t Sensors::maxSensors = 0; uint8_t Sensors::maxSensors = 0;
-6
View File
@@ -70,12 +70,6 @@ time_t mkgmtime(const struct tm *ptm) {
return secs; return secs;
} }
inline bool isDigit(const char* ptr) {
char* endPtr;
auto tmp = strtol(ptr, &endPtr, 10);
return *endPtr == 0;
}
inline float liter2gallon(float value) { inline float liter2gallon(float value) {
return value / 4.546091879f; return value / 4.546091879f;
} }