From fedeeea9cb91f627d15a34779daed58fb01d2e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Fiedler?= Date: Sat, 7 Mar 2026 18:43:17 +0100 Subject: [PATCH] Refactor Config_Web to use heap-allocated JSON document and add stack usage check script --- scripts/check_config_web_stack_usage.sh | 12 ++++++++++++ src/Config_Web.cpp | 17 +++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) create mode 100755 scripts/check_config_web_stack_usage.sh diff --git a/scripts/check_config_web_stack_usage.sh b/scripts/check_config_web_stack_usage.sh new file mode 100755 index 0000000..896b630 --- /dev/null +++ b/scripts/check_config_web_stack_usage.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +set -euo pipefail + +cd "$(dirname "$0")/.." + +if rg -n '^[[:space:]]+StaticJsonDocument[[:space:]]+[A-Za-z_][A-Za-z0-9_]*;' src/Config_Web.cpp; then + echo "Config_Web.cpp still allocates kConfigJsonCapacity-sized StaticJsonDocument on the stack" >&2 + exit 1 +fi + +echo "Config_Web.cpp avoids stack-local kConfigJsonCapacity StaticJsonDocument allocations" diff --git a/src/Config_Web.cpp b/src/Config_Web.cpp index 6b1f7b1..181cb38 100644 --- a/src/Config_Web.cpp +++ b/src/Config_Web.cpp @@ -9,6 +9,7 @@ namespace const size_t kConfigJsonCapacity = 4096; const byte kDnsPort = 53; const unsigned long kWifiReconnectIntervalMs = 10000; + using ConfigJsonDocument = StaticJsonDocument; WebServer server(80); DNSServer dnsServer; @@ -17,6 +18,14 @@ namespace bool staReconnectEnabled = false; bool staConnectionKnown = false; unsigned long lastStaReconnectAttemptMs = 0; + ConfigJsonDocument g_configJsonScratch; + + ConfigJsonDocument &configJsonScratch() + { + // Keep the large config JSON buffer off ESP32 Arduino's 8 KB loopTask stack. + g_configJsonScratch.clear(); + return g_configJsonScratch; + } void redirectToRoot() { @@ -371,7 +380,7 @@ bool loadConfigFromFile() return saveConfigToFile(); } - StaticJsonDocument doc; + ConfigJsonDocument &doc = configJsonScratch(); DeserializationError err = deserializeJson(doc, file); file.close(); if (err) @@ -424,7 +433,7 @@ bool saveConfigToFile() return false; } - StaticJsonDocument doc; + ConfigJsonDocument &doc = configJsonScratch(); JsonArray params = doc.createNestedArray("parameters"); for (size_t i = 0; i < configParameterCount; ++i) { @@ -461,7 +470,7 @@ bool saveConfigToFile() String buildConfigJson() { - StaticJsonDocument doc; + ConfigJsonDocument &doc = configJsonScratch(); JsonArray params = doc.createNestedArray("parameters"); for (size_t i = 0; i < configParameterCount; ++i) { @@ -497,7 +506,7 @@ String buildConfigJson() bool applyConfigJson(const String &payload, String &errorMessage) { - StaticJsonDocument doc; + ConfigJsonDocument &doc = configJsonScratch(); DeserializationError err = deserializeJson(doc, payload); if (err) {