Fix layout / widget init buffer overflow

This commit is contained in:
Raphael Coeffic
2021-04-18 17:53:59 +02:00
parent 8c49a07242
commit 85da52db55
3 changed files with 38 additions and 23 deletions
@@ -25,8 +25,8 @@
#include "audio.h"
#include "translations.h"
#include "layout.h"
#include "widgets/widgets_container_impl.h"
#include "layout.h"
#define LAYOUT_COMMON_OPTIONS \
{ STR_TOP_BAR, ZoneOption::Bool }, \
@@ -133,6 +133,7 @@ class BaseLayoutFactory: public LayoutFactory
Layout * create(Layout::PersistentData * persistentData) const override
{
initPersistentData(persistentData);
Layout * layout = new T(this, persistentData);
if (layout) {
layout->create();
@@ -149,6 +150,20 @@ class BaseLayoutFactory: public LayoutFactory
return layout;
}
void initPersistentData(Layout::PersistentData * persistentData) const
{
memset(persistentData, 0, sizeof(Layout::PersistentData));
if (options) {
int i = 0;
for (const ZoneOption * option = options; option->name; option++, i++) {
TRACE("LayoutFactory::initPersistentData() setting option '%s'", option->name);
// TODO compiler bug? The CPU freezes ... persistentData->options[i++] = option->deflt;
memcpy(&persistentData->options[i].value, &option->deflt, sizeof(ZoneOptionValue));
persistentData->options[i].type = zoneValueEnumFromType(option->type);
}
}
}
protected:
const uint8_t * bitmap;
const ZoneOption * options;
+3 -22
View File
@@ -125,11 +125,11 @@ class WidgetFactory
memset(persistentData, 0, sizeof(Widget::PersistentData));
if (options) {
int i = 0;
for (const ZoneOption * option = options; option->name; option++) {
for (const ZoneOption * option = options; option->name; option++, i++) {
TRACE("WidgetFactory::initPersistentData() setting option '%s'", option->name);
// TODO compiler bug? The CPU freezes ... persistentData->options[i++] = option->deflt;
memcpy(&persistentData->options[i++].value, &option->deflt, sizeof(ZoneOptionValue));
persistentData->options[i++].type = zoneValueEnumFromType(option->type);
memcpy(&persistentData->options[i].value, &option->deflt, sizeof(ZoneOptionValue));
persistentData->options[i].type = zoneValueEnumFromType(option->type);
}
}
}
@@ -141,25 +141,6 @@ class WidgetFactory
const ZoneOption * options;
};
template<class T>
class BaseWidgetFactory: public WidgetFactory
{
public:
BaseWidgetFactory(const char * name, const ZoneOption * options):
WidgetFactory(name, options)
{
}
Widget * create(FormGroup * parent, const rect_t & rect, Widget::PersistentData * persistentData, bool init = true) const override
{
if (init) {
initPersistentData(persistentData);
}
return new T(this, parent, rect, persistentData);
}
};
inline const ZoneOption * Widget::getOptions() const
{
return getFactory()->getOptions();
@@ -145,3 +145,22 @@ class WidgetsContainerImpl: public WidgetsContainer
PersistentData * persistentData;
Widget * widgets[N] = {};
};
template<class T>
class BaseWidgetFactory: public WidgetFactory
{
public:
BaseWidgetFactory(const char * name, const ZoneOption * options):
WidgetFactory(name, options)
{
}
Widget * create(FormGroup * parent, const rect_t & rect, Widget::PersistentData * persistentData, bool init = true) const override
{
if (init) {
initPersistentData(persistentData);
}
return new T(this, parent, rect, persistentData);
}
};