Fix trouble with uniqu_ptr deleting reference content.

It is not necessary to use a unique_ptr (also always using .release shows
this), so there can be used a raw pointer instead.

Here we fix usage of _aux an also of back pointing _ac. Especially on _ac
it does not make any sense, since this pointer is stored in many locations.

refs #138
pull/141/head
Sven Steckmann 5 years ago
parent becd58ec63
commit 9e02f48f53
  1. 16
      src/AutoConnect.cpp
  2. 2
      src/AutoConnect.h
  3. 20
      src/AutoConnectAux.cpp
  4. 6
      src/AutoConnectAux.h

@ -57,7 +57,7 @@ void AutoConnect::_initialize(void) {
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
_disconnectEventId = -1; // The member available for ESP32 only _disconnectEventId = -1; // The member available for ESP32 only
#endif #endif
_aux.release(); _aux = nullptr;
_auxUri = String(""); _auxUri = String("");
} }
@ -367,11 +367,11 @@ WebServerClass& AutoConnect::host(void) {
* @return A pointer of AutoConnectAux instance. * @return A pointer of AutoConnectAux instance.
*/ */
AutoConnectAux* AutoConnect::aux(const String& uri) const { AutoConnectAux* AutoConnect::aux(const String& uri) const {
AutoConnectAux* aux_p = _aux.get(); AutoConnectAux* aux_p = _aux;
while (aux_p) { while (aux_p) {
if (!strcmp(aux_p->uri(), uri.c_str())) if (!strcmp(aux_p->uri(), uri.c_str()))
break; break;
aux_p = aux_p->_next.get(); aux_p = aux_p->_next;
} }
return aux_p; return aux_p;
} }
@ -385,7 +385,7 @@ void AutoConnect::join(AutoConnectAux& aux) {
if (_aux) if (_aux)
_aux->_concat(aux); _aux->_concat(aux);
else else
_aux.reset(&aux); _aux = &aux;
aux._join(*this); aux._join(*this);
AC_DBG("%s on hands\n", aux.uri()); AC_DBG("%s on hands\n", aux.uri());
} }
@ -563,13 +563,13 @@ void AutoConnect::handleRequest(void) {
* registered. * registered.
*/ */
bool AutoConnect::on(const String& uri, const AuxHandlerFunctionT handler, AutoConnectExitOrder_t order) { bool AutoConnect::on(const String& uri, const AuxHandlerFunctionT handler, AutoConnectExitOrder_t order) {
AutoConnectAux* aux = _aux.get(); AutoConnectAux* aux = _aux;
while (aux) { while (aux) {
if (!strcmp(uri.c_str(), aux->uri())) { if (!strcmp(uri.c_str(), aux->uri())) {
aux->on(handler, order); aux->on(handler, order);
return true; return true;
} }
aux = aux->_next.get(); aux = aux->_next;
} }
return false; return false;
} }
@ -865,13 +865,13 @@ bool AutoConnect::_classifyHandle(HTTPMethod method, String uri) {
* upload function of the AutoConnectAux which has a destination URI. * upload function of the AutoConnectAux which has a destination URI.
*/ */
void AutoConnect::_handleUpload(const String& requestUri, const HTTPUpload& upload) { void AutoConnect::_handleUpload(const String& requestUri, const HTTPUpload& upload) {
AutoConnectAux* aux = _aux.get(); AutoConnectAux* aux = _aux;
while (aux) { while (aux) {
if (aux->_uriStr == requestUri) { if (aux->_uriStr == requestUri) {
aux->upload(_prevUri, upload); aux->upload(_prevUri, upload);
break; break;
} }
aux = aux->_next.get(); aux = aux->_next;
} }
} }

@ -282,7 +282,7 @@ class AutoConnect {
PageElement* _currentPageElement; PageElement* _currentPageElement;
/** Extended pages made up with AutoConnectAux */ /** Extended pages made up with AutoConnectAux */
std::unique_ptr<AutoConnectAux> _aux; AutoConnectAux* _aux = nullptr;
String _auxUri; /**< Last accessed AutoConnectAux */ String _auxUri; /**< Last accessed AutoConnectAux */
String _prevUri; /**< Previous generated page uri */ String _prevUri; /**< Previous generated page uri */
/** Available updater, only reset by AutoConnectUpdate::attach is valid */ /** Available updater, only reset by AutoConnectUpdate::attach is valid */

@ -74,8 +74,6 @@ const char AutoConnectAux::_PAGE_AUX[] PROGMEM = {
AutoConnectAux::~AutoConnectAux() { AutoConnectAux::~AutoConnectAux() {
_addonElm.clear(); _addonElm.clear();
_addonElm.swap(_addonElm); _addonElm.swap(_addonElm);
if (_ac)
_ac.release();
} }
/** /**
@ -116,7 +114,7 @@ void AutoConnectAux::fetchElement(void) {
_ac->_auxUri = _webServer->arg(String(F(AUTOCONNECT_AUXURI_PARAM))); _ac->_auxUri = _webServer->arg(String(F(AUTOCONNECT_AUXURI_PARAM)));
_ac->_auxUri.replace("&#47;", "/"); _ac->_auxUri.replace("&#47;", "/");
AC_DBG("fetch %s", _ac->_auxUri.c_str()); AC_DBG("fetch %s", _ac->_auxUri.c_str());
AutoConnectAux* aux = _ac->_aux.get(); AutoConnectAux* aux = _ac->_aux;
while (aux) { while (aux) {
if (aux->_uriStr == _ac->_auxUri) { if (aux->_uriStr == _ac->_auxUri) {
// Save the value owned by each element contained in the POST body // Save the value owned by each element contained in the POST body
@ -124,7 +122,7 @@ void AutoConnectAux::fetchElement(void) {
aux->_storeElements(_webServer); aux->_storeElements(_webServer);
break; break;
} }
aux = aux->_next.get(); aux = aux->_next;
} }
} }
} }
@ -262,13 +260,13 @@ void AutoConnectAux::upload(const String& requestUri, const HTTPUpload& upload)
String logContext = "missing"; String logContext = "missing";
AutoConnectElementVT addons; AutoConnectElementVT addons;
AutoConnectAux* aux = _ac->_aux.get(); AutoConnectAux* aux = _ac->_aux;
while (aux) { while (aux) {
if (aux->_uriStr == requestUri) { if (aux->_uriStr == requestUri) {
addons = aux->_addonElm; addons = aux->_addonElm;
break; break;
} }
aux = aux->_next.get(); aux = aux->_next;
} }
_currentUpload = nullptr; _currentUpload = nullptr;
@ -337,7 +335,7 @@ void AutoConnectAux::_concat(AutoConnectAux& aux) {
if (_next) if (_next)
_next->_concat(aux); _next->_concat(aux);
else else
_next.reset(&aux); _next = &aux;
} }
/** /**
@ -348,7 +346,7 @@ void AutoConnectAux::_concat(AutoConnectAux& aux) {
* @param ac A reference of AutoConnect. * @param ac A reference of AutoConnect.
*/ */
void AutoConnectAux::_join(AutoConnect& ac) { void AutoConnectAux::_join(AutoConnect& ac) {
_ac.reset(&ac); _ac = &ac;
// Chain to subsequent AutoConnectAux in the list. // Chain to subsequent AutoConnectAux in the list.
if (_next) if (_next)
@ -486,7 +484,7 @@ PageElement* AutoConnectAux::_setupPage(const String& uri) {
elm = _next->_setupPage(uri); elm = _next->_setupPage(uri);
} }
} else { } else {
AutoConnect* mother = _ac.get(); AutoConnect* mother = _ac;
// Overwrite actual AutoConnectMenu title to the Aux. page title // Overwrite actual AutoConnectMenu title to the Aux. page title
if (_title.length()) if (_title.length())
mother->_menuTitle = _title; mother->_menuTitle = _title;
@ -548,11 +546,11 @@ void AutoConnectAux::_storeElements(WebServerClass* webServer) {
// Copy a value to other elements declared as global. // Copy a value to other elements declared as global.
if (elm.global) { if (elm.global) {
AutoConnectAux* aux = _ac->_aux.get(); AutoConnectAux* aux = _ac->_aux;
while (aux) { while (aux) {
if (aux != this) if (aux != this)
aux->setElementValue(elm.name, elmValue); aux->setElementValue(elm.name, elmValue);
aux = aux->_next.get(); aux = aux->_next;
} }
} }
} }

@ -48,7 +48,7 @@ typedef enum {
class AutoConnectAux : public PageBuilder { class AutoConnectAux : public PageBuilder {
public: public:
explicit AutoConnectAux(const String& uri = String(""), const String& title = String(""), const bool menu = true, const AutoConnectElementVT addons = AutoConnectElementVT()) : explicit AutoConnectAux(const String& uri = String(""), const String& title = String(""), const bool menu = true, const AutoConnectElementVT addons = AutoConnectElementVT()) :
chunk(PB_Chunk), _title(title), _menu(menu), _uriStr(String(uri)), _addonElm(addons), _handler(nullptr), _order(AC_EXIT_AHEAD), _uploadHandler(nullptr) { _uri = _uriStr.c_str(); _next.release(); _ac.release(); } chunk(PB_Chunk), _title(title), _menu(menu), _uriStr(String(uri)), _addonElm(addons), _handler(nullptr), _order(AC_EXIT_AHEAD), _uploadHandler(nullptr) { _uri = _uriStr.c_str(); }
~AutoConnectAux(); ~AutoConnectAux();
AutoConnectElement& operator[](const String& name) { return *getElement(name); } AutoConnectElement& operator[](const String& name) { return *getElement(name); }
void add(AutoConnectElement& addon); /**< Add an element to the auxiliary page */ void add(AutoConnectElement& addon); /**< Add an element to the auxiliary page */
@ -148,8 +148,8 @@ class AutoConnectAux : public PageBuilder {
bool _menu; /**< Switch for menu displaying */ bool _menu; /**< Switch for menu displaying */
String _uriStr; /**< uri as String */ String _uriStr; /**< uri as String */
AutoConnectElementVT _addonElm; /**< A vector set of AutoConnectElements placed on this auxiliary page */ AutoConnectElementVT _addonElm; /**< A vector set of AutoConnectElements placed on this auxiliary page */
std::unique_ptr<AutoConnectAux> _next; /**< Auxiliary pages chain list */ AutoConnectAux* _next = nullptr; /**< Auxiliary pages chain list */
std::unique_ptr<AutoConnect> _ac; /**< Hosted AutoConnect instance */ AutoConnect* _ac = nullptr; /**< Hosted AutoConnect instance */
AuxHandlerFunctionT _handler; /**< User sketch callback function when AutoConnectAux page requested. */ AuxHandlerFunctionT _handler; /**< User sketch callback function when AutoConnectAux page requested. */
AutoConnectExitOrder_t _order; /**< The order in which callback functions are called. */ AutoConnectExitOrder_t _order; /**< The order in which callback functions are called. */
PageBuilder::UploadFuncT _uploadHandler; /**< The AutoConnectFile corresponding to current upload */ PageBuilder::UploadFuncT _uploadHandler; /**< The AutoConnectFile corresponding to current upload */

Loading…
Cancel
Save