Skip to content

Commit

Permalink
Merge pull request letscontrolit#5245 from TD-er/bugfix/P123_crash
Browse files Browse the repository at this point in the history
Fix crash when using std::move on String objects.
  • Loading branch information
TD-er authored Feb 6, 2025
2 parents a952e41 + 7bdf013 commit f748569
Show file tree
Hide file tree
Showing 12 changed files with 103 additions and 56 deletions.
16 changes: 13 additions & 3 deletions src/src/ESPEasyCore/Controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -830,10 +830,20 @@ bool MQTTpublish(controllerIndex_t controller_idx,
if (MQTT_queueFull(controller_idx)) {
return false;
}
String topic_str;
String payload_str;
if (!reserve_special(topic_str, strlen_P(topic)) ||
!reserve_special(payload_str, strlen_P(payload))) {
return false;
}
topic_str = topic;
payload_str = payload;
const bool success =
MQTTDelayHandler->addToQueue(std::unique_ptr<MQTT_queue_element>(new (std::nothrow) MQTT_queue_element(controller_idx, taskIndex, topic,
payload, retained,
callbackTask)));
MQTTDelayHandler->addToQueue(std::unique_ptr<MQTT_queue_element>(new (std::nothrow) MQTT_queue_element(
controller_idx, taskIndex,
std::move(topic_str),
std::move(payload_str), retained,
callbackTask)));

scheduleNextMQTTdelayQueue();
return success;
Expand Down
4 changes: 2 additions & 2 deletions src/src/Helpers/ESPEasy_Storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1002,7 +1002,7 @@ String LoadStringArray(SettingsType::Enum settingsType,
#ifndef BUILD_NO_DEBUG
return F("Invalid index for custom settings");
#else // ifndef BUILD_NO_DEBUG
return F("Save error");
return F("Load error");
#endif // ifndef BUILD_NO_DEBUG
}

Expand Down Expand Up @@ -1967,7 +1967,7 @@ String LoadFromFile(const char *fname, String& data, int offset)
STOP_TIMER(LOADFILE_STATS);
delay(0);

return String();
return EMPTY_STRING;
}

/********************************************************************************************\
Expand Down
83 changes: 57 additions & 26 deletions src/src/Helpers/ESPEasy_TouchHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,32 @@

# include "../Commands/ExecuteCommand.h"

tTouchObjects::tTouchObjects() :
flags(0u),
SurfaceAreas(0u),
TouchTimers(0u),
#ifdef ESP32
top_left({0u, 0u}),
width_height({0u, 0u}),
#endif
TouchStates(0u)
# if TOUCH_FEATURE_EXTENDED_TOUCH
, groupFlags (0u)
, colorOn (0u)
, colorOff (0u)
, colorCaption (0u)
, colorBorder (0u)
, colorDisabled (0u)
, colorDisabledCaption (0u)
# endif // if TOUCH_FEATURE_EXTENDED_TOUCH
{
objectName.clear();
captionOn.clear();
captionOff.clear();
}



/****************************************************************************
* toString: Display-value for the touch action
***************************************************************************/
Expand Down Expand Up @@ -139,7 +165,7 @@ void ESPEasy_TouchHandler::loadTouchObjects(struct EventStruct *event) {
# endif // if TOUCH_FEATURE_SWIPE
# endif // if TOUCH_FEATURE_EXTENDED_TOUCH

settingsArray[TOUCH_CALIBRATION_START].clear(); // Free a little memory
free_string(settingsArray[TOUCH_CALIBRATION_START]); // Free a little memory

// Buffer some settings, mostly for readability, but also to be able to set from write command
_flipped = bitRead(Touch_Settings.flags, TOUCH_FLAGS_ROTATION_FLIPPED);
Expand All @@ -153,44 +179,47 @@ void ESPEasy_TouchHandler::loadTouchObjects(struct EventStruct *event) {

for (uint8_t i = TOUCH_OBJECT_INDEX_START; i <= lastObjectIndex; ++i) {
if (!settingsArray[i].isEmpty()) {
TouchObjects.push_back(tTouchObjects());
TouchObjects[t].flags = parseStringToInt(settingsArray[i], TOUCH_OBJECT_FLAGS, TOUCH_SETTINGS_SEPARATOR);
TouchObjects[t].objectName = parseStringKeepCase(settingsArray[i], TOUCH_OBJECT_NAME, TOUCH_SETTINGS_SEPARATOR);
TouchObjects[t].top_left.x = parseStringToInt(settingsArray[i], TOUCH_OBJECT_COORD_TOP_X, TOUCH_SETTINGS_SEPARATOR);
TouchObjects[t].top_left.y = parseStringToInt(settingsArray[i], TOUCH_OBJECT_COORD_TOP_Y, TOUCH_SETTINGS_SEPARATOR);
TouchObjects[t].width_height.x = parseStringToInt(settingsArray[i], TOUCH_OBJECT_COORD_WIDTH, TOUCH_SETTINGS_SEPARATOR);
TouchObjects[t].width_height.y = parseStringToInt(settingsArray[i], TOUCH_OBJECT_COORD_HEIGHT, TOUCH_SETTINGS_SEPARATOR);
tTouchObjects touchObject{};
touchObject.flags = parseStringToInt(settingsArray[i], TOUCH_OBJECT_FLAGS, TOUCH_SETTINGS_SEPARATOR);
String objectName = parseStringKeepCase(settingsArray[i], TOUCH_OBJECT_NAME, TOUCH_SETTINGS_SEPARATOR);
touchObject.objectName = objectName;
touchObject.top_left.x = parseStringToInt(settingsArray[i], TOUCH_OBJECT_COORD_TOP_X, TOUCH_SETTINGS_SEPARATOR);
touchObject.top_left.y = parseStringToInt(settingsArray[i], TOUCH_OBJECT_COORD_TOP_Y, TOUCH_SETTINGS_SEPARATOR);
touchObject.width_height.x = parseStringToInt(settingsArray[i], TOUCH_OBJECT_COORD_WIDTH, TOUCH_SETTINGS_SEPARATOR);
touchObject.width_height.y = parseStringToInt(settingsArray[i], TOUCH_OBJECT_COORD_HEIGHT, TOUCH_SETTINGS_SEPARATOR);
# if TOUCH_FEATURE_EXTENDED_TOUCH
TouchObjects[t].colorOn = parseStringToInt(settingsArray[i], TOUCH_OBJECT_COLOR_ON, TOUCH_SETTINGS_SEPARATOR);
TouchObjects[t].colorOff = parseStringToInt(settingsArray[i], TOUCH_OBJECT_COLOR_OFF, TOUCH_SETTINGS_SEPARATOR);
TouchObjects[t].colorCaption = parseStringToInt(settingsArray[i], TOUCH_OBJECT_COLOR_CAPTION, TOUCH_SETTINGS_SEPARATOR);
TouchObjects[t].captionOn = parseStringKeepCase(settingsArray[i], TOUCH_OBJECT_CAPTION_ON, TOUCH_SETTINGS_SEPARATOR);
TouchObjects[t].captionOff = parseStringKeepCase(settingsArray[i], TOUCH_OBJECT_CAPTION_OFF, TOUCH_SETTINGS_SEPARATOR);
TouchObjects[t].colorBorder = parseStringToInt(settingsArray[i], TOUCH_OBJECT_COLOR_BORDER, TOUCH_SETTINGS_SEPARATOR);
TouchObjects[t].colorDisabled = parseStringToInt(settingsArray[i], TOUCH_OBJECT_COLOR_DISABLED, TOUCH_SETTINGS_SEPARATOR);
TouchObjects[t].colorDisabledCaption = parseStringToInt(settingsArray[i], TOUCH_OBJECT_COLOR_DISABCAPT, TOUCH_SETTINGS_SEPARATOR);
TouchObjects[t].groupFlags = parseStringToInt(settingsArray[i], TOUCH_OBJECT_GROUPFLAGS, TOUCH_SETTINGS_SEPARATOR);

const uint8_t g = get8BitFromUL(TouchObjects[t].flags, TOUCH_OBJECT_FLAG_GROUP);
touchObject.colorOn = parseStringToInt(settingsArray[i], TOUCH_OBJECT_COLOR_ON, TOUCH_SETTINGS_SEPARATOR);
touchObject.colorOff = parseStringToInt(settingsArray[i], TOUCH_OBJECT_COLOR_OFF, TOUCH_SETTINGS_SEPARATOR);
touchObject.colorCaption = parseStringToInt(settingsArray[i], TOUCH_OBJECT_COLOR_CAPTION, TOUCH_SETTINGS_SEPARATOR);
String captionOn = parseStringKeepCase(settingsArray[i], TOUCH_OBJECT_CAPTION_ON, TOUCH_SETTINGS_SEPARATOR);
String captionOff = parseStringKeepCase(settingsArray[i], TOUCH_OBJECT_CAPTION_OFF, TOUCH_SETTINGS_SEPARATOR);
touchObject.captionOn = captionOn;
touchObject.captionOff = captionOff;
touchObject.colorBorder = parseStringToInt(settingsArray[i], TOUCH_OBJECT_COLOR_BORDER, TOUCH_SETTINGS_SEPARATOR);
touchObject.colorDisabled = parseStringToInt(settingsArray[i], TOUCH_OBJECT_COLOR_DISABLED, TOUCH_SETTINGS_SEPARATOR);
touchObject.colorDisabledCaption = parseStringToInt(settingsArray[i], TOUCH_OBJECT_COLOR_DISABCAPT, TOUCH_SETTINGS_SEPARATOR);
touchObject.groupFlags = parseStringToInt(settingsArray[i], TOUCH_OBJECT_GROUPFLAGS, TOUCH_SETTINGS_SEPARATOR);

const uint8_t g = get8BitFromUL(touchObject.flags, TOUCH_OBJECT_FLAG_GROUP);

if (!validButtonGroup(g)) {
_buttonGroups.insert(g);
}
# endif // if TOUCH_FEATURE_EXTENDED_TOUCH

TouchObjects[t].SurfaceAreas = 0u; // Reset runtime stuff
TouchObjects[t].TouchTimers = 0u;
TouchObjects[t].TouchStates = 0;
touchObject.SurfaceAreas = 0u; // Reset runtime stuff
touchObject.TouchTimers = 0u;
touchObject.TouchStates = 0;

# if TOUCH_FEATURE_EXTENDED_TOUCH && TOUCH_FEATURE_SWIPE

// Check if a slider/gauge with range not including 0 is used, then set starting value closest to 0
if (bitRead(TouchObjects[t].flags, TOUCH_OBJECT_FLAG_SLIDER) && !TouchObjects[t].captionOff.isEmpty()) {
if (bitRead(touchObject.flags, TOUCH_OBJECT_FLAG_SLIDER) && !touchObject.captionOff.isEmpty()) {
int16_t _value = 0;
int16_t lowRange = 0;
int16_t highRange = 100;

if (parseRangeToInt16(TouchObjects[t].captionOff, lowRange, highRange)) {
if (parseRangeToInt16(touchObject.captionOff, lowRange, highRange)) {
if (lowRange > highRange) {
if (_value < highRange) {
_value = highRange;
Expand All @@ -204,14 +233,16 @@ void ESPEasy_TouchHandler::loadTouchObjects(struct EventStruct *event) {
_value = highRange;
}
}
TouchObjects[t].TouchStates = _value;
touchObject.TouchStates = _value;
}
}
# endif // if TOUCH_FEATURE_EXTENDED_TOUCH && TOUCH_FEATURE_SWIPE

TouchObjects.push_back(std::move(touchObject));

t++;

settingsArray[i].clear(); // Free a little memory
free_string(settingsArray[i]); // Free a little memory
}
}
}
Expand Down
13 changes: 7 additions & 6 deletions src/src/Helpers/ESPEasy_TouchHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ struct tTouch_Point
// For touch objects we store a name, 2 coordinates, flags and other options
struct tTouchObjects
{
tTouchObjects();
uint32_t flags = 0u;
uint32_t SurfaceAreas = 0u;
uint32_t TouchTimers = 0u;
Expand Down Expand Up @@ -383,21 +384,21 @@ class ESPEasy_TouchHandler {
AdaGFXColorDepth _colorDepth = AdaGFXColorDepth::FullColor;
int16_t _buttonGroup = 0;

std::set<int16_t>_buttonGroups;
std::set<int16_t>_buttonGroups{};

bool _settingsLoaded = false;
bool _stillTouching = false;
bool _touchIgnored = false;

// Used to generate events on touch-release
int8_t _lastObjectIndex = -1;
String _lastObjectName;
String _lastObjectName{};
tTouch_Point _last_point;
tTouch_Point _last_point_z; // Only used to store z in the x member
# if TOUCH_FEATURE_EXTENDED_TOUCH && TOUCH_FEATURE_SWIPE
Swipe_action_e _lastSwipe = Swipe_action_e::None;
int16_t _last_delta_x;
int16_t _last_delta_y;
int16_t _last_delta_x{};
int16_t _last_delta_y{};
# endif // if TOUCH_FEATURE_EXTENDED_TOUCH && TOUCH_FEATURE_SWIPE

struct tTouch_Globals
Expand All @@ -420,7 +421,7 @@ class ESPEasy_TouchHandler {
bool logEnabled = false;
};

std::vector<tTouchObjects>TouchObjects;
std::vector<tTouchObjects>TouchObjects{};

public:

Expand All @@ -429,7 +430,7 @@ class ESPEasy_TouchHandler {

tTouch_Globals Touch_Settings;

String settingsArray[TOUCH_ARRAY_SIZE];
String settingsArray[TOUCH_ARRAY_SIZE]{};
uint8_t lastObjectIndex = 0u;
uint8_t objectCount = 0u;
};
Expand Down
8 changes: 6 additions & 2 deletions src/src/Helpers/Memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,8 @@ bool String_reserve_special(String& str, size_t size) {
class PSRAM_String : public String {
public:
PSRAM_String(size_t size) : String() {
if (size > capacity() && UsePSRAM()) {
init();
if (size != 0 && size > capacity() && UsePSRAM()) {
size_t newSize = (size + 16) & (~0xf);
void *ptr = special_calloc(1, newSize);
if (ptr != nullptr) {
Expand All @@ -242,7 +243,10 @@ class PSRAM_String : public String {


bool String_reserve_special(String& str, size_t size) {
if (str.length() < size) {
if (!UsePSRAM()) {
return str.reserve(size);
}
if (str.length() <= size) {
// As we like to move this to PSRAM, it also makes sense
// to do this when the length equals size
PSRAM_String psram_str(size);
Expand Down
2 changes: 1 addition & 1 deletion src/src/Helpers/Misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ void logMemUsageAfter(const __FlashStringHelper *function, int value) {
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
String log;

if (log.reserve(128)) {
if (reserve_special(log, 128)) {
log = F("After ");
log += function;

Expand Down
4 changes: 3 additions & 1 deletion src/src/Helpers/PortStatus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include "../DataStructs/PinMode.h"
#include "../Globals/GlobalMapPortStatus.h"

#include "../Helpers/StringConverter.h"

#include "../../ESPEasy-Globals.h"


Expand Down Expand Up @@ -208,7 +210,7 @@ String getPinStateJSON(bool search, uint32_t key, const String& log, int16_t noS
if (!search || found)
{
String reply;
reply.reserve(128);
reserve_special(reply, 128);
reply += F("{\n\"log\": \"");
{
// truncate to 25 chars, max MQTT message size = 128 including header...
Expand Down
16 changes: 7 additions & 9 deletions src/src/Helpers/RulesHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,11 @@ void RulesHelperClass::init()
#ifndef BUILD_NO_DEBUG

if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
String log = F("Cache rules event: ");
log += filename;
log += F(" pos: ");
log += pos_start_line;
log += ' ';
log += rulesLine;
addLogMove(LOG_LEVEL_DEBUG, log);
addLogMove(LOG_LEVEL_DEBUG, strformat(
F("Cache rules event: %s pos: %u %s"),
filename.c_str(),
pos_start_line,
rulesLine.c_str()));
}
#endif // ifndef BUILD_NO_DEBUG
}
Expand Down Expand Up @@ -296,7 +294,7 @@ String RulesHelperClass::readLn(const String& filename,

while (f.available()) {
if (addChar(char(f.read()), tmpStr, firstNonSpaceRead)) {
lines.push_back(tmpStr);
lines.push_back(move_special(std::move(tmpStr)));
++readPos;

firstNonSpaceRead = false;
Expand All @@ -307,7 +305,7 @@ String RulesHelperClass::readLn(const String& filename,
if (tmpStr.length() > 0) {
rules_strip_trailing_comments(tmpStr);
check_rules_line_user_errors(tmpStr);
lines.push_back(tmpStr);
lines.push_back(move_special(std::move(tmpStr)));
tmpStr.clear();
}
# ifndef BUILD_NO_DEBUG
Expand Down
4 changes: 2 additions & 2 deletions src/src/Helpers/Scheduler_SystemEventTimer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ void ESPEasy_Scheduler::schedule_mqtt_controller_event_timer(
const size_t topic_length = strlen_P(c_topic);

// This is being called from a callback function, so do not try to allocate this on the 2nd heap, but rather on the default heap.
if (!(event.String1.reserve(topic_length) &&
event.String2.reserve(length))) {
if (!(reserve_special(event.String1, topic_length) &&
reserve_special(event.String2, length))) {
addLog(LOG_LEVEL_ERROR, F("MQTT : Out of Memory! Cannot process MQTT message"));
return;
}
Expand Down
5 changes: 3 additions & 2 deletions src/src/Helpers/StringConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -854,12 +854,13 @@ String parseStringKeepCase(const String& string, uint8_t indexFind, char separat
String result;

if (!GetArgv(string.c_str(), result, indexFind, separator)) {
return EMPTY_STRING;
return String();
}
if (trimResult) {
result.trim();
}
return stripQuotes(result);
result = stripQuotes(result);
return result;
}

String parseStringToEnd(const String& string, uint8_t indexFind, char separator, bool trimResult) {
Expand Down
2 changes: 1 addition & 1 deletion src/src/PluginStructs/P028_data_struct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ bool P028_data_struct::updateMeasurements(taskIndex_t task_index) {
String log;

if (loglevelActiveFor(LOG_LEVEL_INFO)) {
log.reserve(120); // Prevent re-allocation
reserve_special(log, 120); // Prevent re-allocation
log = getDeviceName(sensorID);
log += ':';
}
Expand Down
2 changes: 1 addition & 1 deletion tools/pio/pre_custom_esp32.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
"-DUSES_P131", # NeoPixelMatrix

"-DUSES_P146", # Cache Reader
"-DUSES_P169", # AS3935 Lightning Detector
"-DUSES_P123", # AS3935 Lightning Detector

"-DUSES_C016", # Cache Controller
"-DUSES_C018", # TTN/RN2483
Expand Down

0 comments on commit f748569

Please sign in to comment.