From 7eeaa363583def5f371bbb8eefe7985ce9442e35 Mon Sep 17 00:00:00 2001 From: TD-er Date: Sun, 23 Aug 2026 17:50:31 +0200 Subject: [PATCH] [Debug] Add runtime bounds checks for PCONFIG_xxx macro parameters --- src/_Plugin_Helper.cpp | 85 ++++++++++++++++++++++++ src/_Plugin_Helper.h | 39 +++++++++-- src/src/CustomBuild/define_plugin_sets.h | 11 +++ 3 files changed, 129 insertions(+), 6 deletions(-) diff --git a/src/_Plugin_Helper.cpp b/src/_Plugin_Helper.cpp index 5c720cc64..0b83c6956 100644 --- a/src/_Plugin_Helper.cpp +++ b/src/_Plugin_Helper.cpp @@ -15,6 +15,91 @@ PluginTaskData_base *Plugin_task_data[TASKS_MAX] = {}; +#if DEBUG_PCONFIG_RANGE_CHECK +int16_t& do_PCONFIG(struct EventStruct *event, uint8_t n) +{ + constexpr uint8_t max_n = NR_ELEMENTS(Settings.TaskDevicePluginConfig[0]); + if (validTaskIndex(event->TaskIndex) && n < max_n) + return Settings.TaskDevicePluginConfig[event->TaskIndex][(n)]; + + if (loglevelActiveFor(LOG_LEVEL_DEBUG)) + addLog(LOG_LEVEL_DEBUG, concat( + F("PCONFIG"), + strformat(F("(%u) out of range for taskIndex %u"), n, event->TaskIndex))); + + static int16_t invalid{}; + invalid = 0; + return invalid; +} + +float& do_PCONFIG_FLOAT(struct EventStruct *event, uint8_t n) +{ + constexpr uint8_t max_n = NR_ELEMENTS(Settings.TaskDevicePluginConfigFloat[0]); + if (validTaskIndex(event->TaskIndex) && n < max_n) + return Settings.TaskDevicePluginConfigFloat[event->TaskIndex][(n)]; + + if (loglevelActiveFor(LOG_LEVEL_DEBUG)) + addLog(LOG_LEVEL_DEBUG, concat( + F("PCONFIG_FLOAT"), + strformat(F("(%u) out of range for taskIndex %u"), n, event->TaskIndex))); + + static float invalid{}; + invalid = 0; + return invalid; +} + +int32_t& do_PCONFIG_LONG(struct EventStruct *event, uint8_t n) +{ + constexpr uint8_t max_n = NR_ELEMENTS(Settings.TaskDevicePluginConfigLong[0]); + if (validTaskIndex(event->TaskIndex) && n < max_n) + return Settings.TaskDevicePluginConfigLong[event->TaskIndex][(n)]; + + if (loglevelActiveFor(LOG_LEVEL_DEBUG)) + addLog(LOG_LEVEL_DEBUG, concat( + F("PCONFIG_LONG"), + strformat(F("(%u) out of range for taskIndex %u"), n, event->TaskIndex))); + + static int32_t invalid{}; + invalid = 0; + return invalid; +} + +uint32_t& do_PCONFIG_ULONG(struct EventStruct *event, uint8_t n) +{ + constexpr uint8_t max_n = NR_ELEMENTS(Settings.TaskDevicePluginConfigULong[0]); + if (validTaskIndex(event->TaskIndex) && n < max_n) + return Settings.TaskDevicePluginConfigULong[event->TaskIndex][(n)]; + + if (loglevelActiveFor(LOG_LEVEL_DEBUG)) + addLog(LOG_LEVEL_DEBUG, concat( + F("PCONFIG_ULONG"), + strformat(F("(%u) out of range for taskIndex %u"), n, event->TaskIndex))); + + + static uint32_t invalid{}; + invalid = 0; + return invalid; +} + + +int8_t& do_PIN(struct EventStruct *event, uint8_t n) +{ + // N.B. order of array indices taskIndex_t and n differs from the other PCONFIGxxx + constexpr uint8_t max_n = 3; + if (validTaskIndex(event->TaskIndex) && n < max_n) + return Settings.TaskDevicePin[n][event->TaskIndex]; + + if (loglevelActiveFor(LOG_LEVEL_DEBUG)) + addLog(LOG_LEVEL_DEBUG, concat( + F("PIN"), + strformat(F("(%u) out of range for taskIndex %u"), n, event->TaskIndex))); + + static int8_t invalid{}; + invalid = -1; + return invalid; +} + +#endif String PCONFIG_LABEL(int n) { if (n < PLUGIN_CONFIGVAR_MAX) { diff --git a/src/_Plugin_Helper.h b/src/_Plugin_Helper.h index 9848ab0ed..e71dfee96 100644 --- a/src/_Plugin_Helper.h +++ b/src/_Plugin_Helper.h @@ -62,25 +62,51 @@ #include "src/WebServer/Markup_Forms.h" #include "src/WebServer/ESPEasy_WebServer.h" +#if DEBUG_PCONFIG_RANGE_CHECK + int16_t& do_PCONFIG(struct EventStruct *event, uint8_t n); + float& do_PCONFIG_FLOAT(struct EventStruct *event, uint8_t n); + int32_t& do_PCONFIG_LONG(struct EventStruct *event, uint8_t n); + uint32_t& do_PCONFIG_ULONG(struct EventStruct *event, uint8_t n); + int8_t& do_PIN(struct EventStruct *event, uint8_t n); +#endif + // Defines to make plugins more readable. - #ifndef PCONFIG - # define PCONFIG(n) (Settings.TaskDevicePluginConfig[event->TaskIndex][(n)]) + #if DEBUG_PCONFIG_RANGE_CHECK + #define PCONFIG(n) do_PCONFIG(event, n) + #else + #define PCONFIG(n) (Settings.TaskDevicePluginConfig[event->TaskIndex][(n)]) + #endif #endif // ifndef PCONFIG #ifndef PCONFIG_FLOAT - # define PCONFIG_FLOAT(n) (Settings.TaskDevicePluginConfigFloat[event->TaskIndex][(n)]) + #if DEBUG_PCONFIG_RANGE_CHECK + #define PCONFIG_FLOAT(n) do_PCONFIG_FLOAT(event, n) + #else + # define PCONFIG_FLOAT(n) (Settings.TaskDevicePluginConfigFloat[event->TaskIndex][(n)]) + #endif #endif // ifndef PCONFIG_FLOAT #ifndef PCONFIG_LONG - # define PCONFIG_LONG(n) (Settings.TaskDevicePluginConfigLong[event->TaskIndex][(n)]) + #if DEBUG_PCONFIG_RANGE_CHECK + #define PCONFIG_LONG(n) do_PCONFIG_LONG(event, n) + #else + # define PCONFIG_LONG(n) (Settings.TaskDevicePluginConfigLong[event->TaskIndex][(n)]) + #endif #endif // ifndef PCONFIG_LONG #ifndef PCONFIG_ULONG - # define PCONFIG_ULONG(n) (Settings.TaskDevicePluginConfigULong[event->TaskIndex][(n)]) + #if DEBUG_PCONFIG_RANGE_CHECK + #define PCONFIG_ULONG(n) do_PCONFIG_ULONG(event, n) + #else + # define PCONFIG_ULONG(n) (Settings.TaskDevicePluginConfigULong[event->TaskIndex][(n)]) + #endif #endif // ifndef PCONFIG_ULONG #ifndef PIN - // Please note the 'offset' of N compared to normal pin numbering. + #if DEBUG_PCONFIG_RANGE_CHECK + #define PIN(n) do_PIN(event, n) + #else # define PIN(n) (Settings.TaskDevicePin[n][event->TaskIndex]) + #endif #endif // ifndef PIN #ifndef CONFIG_PIN1 # define CONFIG_PIN1 (Settings.TaskDevicePin1[event->TaskIndex]) @@ -95,6 +121,7 @@ # define CONFIG_PORT (Settings.TaskDevicePort[event->TaskIndex]) #endif // ifndef CONFIG_PORT + extern PluginTaskData_base *Plugin_task_data[TASKS_MAX]; // Try to allocate in PSRAM or 2nd heap if possible diff --git a/src/src/CustomBuild/define_plugin_sets.h b/src/src/CustomBuild/define_plugin_sets.h index 127a4cd24..6a0d095e7 100644 --- a/src/src/CustomBuild/define_plugin_sets.h +++ b/src/src/CustomBuild/define_plugin_sets.h @@ -4651,4 +4651,15 @@ To create/register a plugin, you have to : #endif #endif // if !FEATURE_SPI && !FEATURE_I2C && !FEATURE_MODBUS && !FEATURE_CAN && !FEATURE_WRMBUS && !FEATURE_WIMBUS + + +#ifndef DEBUG_PCONFIG_RANGE_CHECK +#ifndef BUILD_NO_DEBUG +#define DEBUG_PCONFIG_RANGE_CHECK 1 +#else +#define DEBUG_PCONFIG_RANGE_CHECK 0 +#endif +#endif + + #endif // CUSTOMBUILD_DEFINE_PLUGIN_SETS_H