[GH-ISSUE #1116] WiFiManagerParameters without ID sometimes get a length of 0 #954

Open
opened 2026-02-28 01:27:50 +03:00 by kerem · 3 comments
Owner

Originally created by @Lithimlin on GitHub (Aug 27, 2020).
Original GitHub issue: https://github.com/tzapu/WiFiManager/issues/1116

Basic Infos

Hardware

WiFimanager Branch/Release:

  • Master
  • Development

Esp8266/Esp32:

  • ESP8266
  • ESP32

Hardware: ESP-12e, esp01, esp25

  • ESP01
  • ESP12 E/F/S (nodemcu, wemos, feather)
  • Other: TTGO T8

ESP Core Version: 2.4.0, staging

  • 2.3.0
  • 2.4.0
  • staging (master/dev)

Description

When creating WiFiManagerParameters without an ID, the length sometimes becomes 0, causing it and following parameters to not render. Is it necessary to check if the length is 0 and then skip all following parameters in getParamOut()? Maybe a continue instead of a break would be better in general.

I also don't know why this only occurs sometimes. I haven't found a place where the _length of a parameter is ever overwritten and it is never 0 when I assign it. It only occurs with parameters that have no ID, like the SeparatorParameter below.

If you need more code, I'll try to provide it, but I'm trying to keep it simple here and my code has gotten quite complex. I hope the provided code is enough to pin down where the problem occurs.

In the particular example below, the first three parameters are rendered (three checkboxes). The fourth has a length of 0 and thus the fifth (another checkbox with the ID "use_mqtt") and following parameters are not rendered.

EDIT:

To be clear: When I say sometimes, I mean that I can compile the code and it may work. If I compile the same code again, it doesn't anymore.

Sketch


#include <WiFiManager.h>

class SeparatorParameter : public WiFiManagerParameter {
public:
  SeparatorParameter(const char *label)
    : WiFiManagerParameter() {
    char *custom = new char[55];
    strcpy(custom, "<div class=\"separator\">");
    strcat(custom, label);
    strcat(custom, "</div>");
    init(NULL, NULL, NULL, 4, custom, WFM_LABEL_BEFORE);
  }
};

WiFiManager wm;

void setup() {
  Serial.begin(115200);
  
  wm.setHostname("ConfigAP");

  std::vector<const char *> menu = {"wifi","info","param","sep","restart","exit"};
  wm.setMenu(menu);
  const char customHead[] = "<style>"
  ".separator {display: flex;align-items: center;text-align: center;}"
  ".separator::before, .separator::after {content:''; flex: 1; border-bottom: 1px solid #000;}"
  ".separator::before {margin-right: .25em;}"
  ".separator::after {margin-left: .25em;}"
  "body.invert .separator::before {border-bottom: 1px solid #FFF;}"
  "body.invert .separator::after {border-bottom: 1px solid #FFF;}"
  "</style>";
  wm.setCustomHeadElement(customHead);
  [...]
}

void loop() {

}

In WiFiManager.cpp:

[...]
String WiFiManager::getParamOut(){
  String page;

  if(_paramsCount > 0){

    String HTTP_PARAM_temp = FPSTR(HTTP_FORM_LABEL);
    HTTP_PARAM_temp += FPSTR(HTTP_FORM_PARAM);
    bool tok_I = HTTP_PARAM_temp.indexOf(FPSTR(T_I)) > 0;
    bool tok_i = HTTP_PARAM_temp.indexOf(FPSTR(T_i)) > 0;
    bool tok_n = HTTP_PARAM_temp.indexOf(FPSTR(T_n)) > 0;
    bool tok_p = HTTP_PARAM_temp.indexOf(FPSTR(T_p)) > 0;
    bool tok_t = HTTP_PARAM_temp.indexOf(FPSTR(T_t)) > 0;
    bool tok_l = HTTP_PARAM_temp.indexOf(FPSTR(T_l)) > 0;
    bool tok_v = HTTP_PARAM_temp.indexOf(FPSTR(T_v)) > 0;
    bool tok_c = HTTP_PARAM_temp.indexOf(FPSTR(T_c)) > 0;

    char valLength[5];
    // add the extra parameters to the form
    for (int i = 0; i < _paramsCount; i++) {
      if (_params[i] == NULL || _params[i]->_length == 0) {
        DEBUG_WM(DEBUG_ERROR,"[ERROR] WiFiManagerParameter is out of scope");
        if(_params[i]->_length == 0) {
          Serial.println("Length is 0");
        }
        if(i+1 < _paramsCount) {
          Serial.print("Next element: ");
          if(_params[i+1] == NULL) {
            Serial.println("NULL");
          } else {
            Serial.println(_params[i+1]->getID());
          }
        }
        break;
      }
[...]

Debug Messages

[...]
*WM: [3] setupConfigPortal 
*WM: [1] Starting Web Portal 
*WM: [3] dns server started with ip:  192.168.4.1
*WM: [2] HTTP server started 
*WM: [2] WiFi Scan completed in 3105 ms
*WM: [2] Config Portal Running, blocking, waiting for clients... 
*WM: [3] -> connectivitycheck.platform.hicloud.com 
*WM: [2] <- Request redirected to captive portal 
*WM: [3] -> connectivitycheck.platform.hicloud.com 
*WM: [2] <- Request redirected to captive portal 
*WM: [3] -> connectivitycheck.platform.hicloud.com 
*WM: [2] <- Request redirected to captive portal 
*WM: [3] -> connectivitycheck.platform.hicloud.com 
*WM: [2] <- Request redirected to captive portal 
*WM: [3] -> connectivitycheck.platform.hicloud.com 
*WM: [2] <- Request redirected to captive portal 
*WM: [2] <- HTTP Root 
*WM: [3] -> 192.168.4.1 
*WM: [3] lastconxresulttmp: WL_IDLE_STATUS
*WM: [3] lastconxresult: WL_DISCONNECTED
*WM: [2] Scan is cached 10214 ms ago
*WM: [3] -> 192.168.4.1 
*WM: [3] -> connectivitycheck.platform.hicloud.com 
*WM: [2] <- Request redirected to captive portal 
*WM: [3] -> connectivitycheck.platform.hicloud.com 
*WM: [2] <- Request redirected to captive portal 
*WM: [3] -> connectivitycheck.platform.hicloud.com 
*WM: [2] <- Request redirected to captive portal 
*WM: [2] <- HTTP Param 
*WM: [0] [ERROR] WiFiManagerParameter is out of scope 
Length is 0
Next element: use_mqtt
*WM: [3] lastconxresulttmp: WL_IDLE_STATUS
*WM: [3] lastconxresult: WL_DISCONNECTED
*WM: [3] Sent param page 
[...]
Originally created by @Lithimlin on GitHub (Aug 27, 2020). Original GitHub issue: https://github.com/tzapu/WiFiManager/issues/1116 ### Basic Infos #### Hardware **WiFimanager Branch/Release:** - [ ] Master - [x] Development **Esp8266/Esp32:** - [ ] ESP8266 - [x] ESP32 **Hardware: ESP-12e, esp01, esp25** - [ ] ESP01 - [ ] ESP12 E/F/S (nodemcu, wemos, feather) - [x] Other: TTGO T8 **ESP Core Version: 2.4.0, staging** - [ ] 2.3.0 - [x] 2.4.0 - [ ] staging (master/dev) ### Description When creating `WiFiManagerParameter`s without an ID, the length **sometimes** becomes 0, causing it and following parameters to not render. Is it necessary to check if the length is 0 and then skip all following parameters in `getParamOut()`? Maybe a `continue` instead of a `break` would be better in general. I also don't know why this only occurs sometimes. I haven't found a place where the `_length` of a parameter is ever overwritten and it is never 0 when I assign it. It only occurs with parameters that have no ID, like the `SeparatorParameter` below. If you need more code, I'll try to provide it, but I'm trying to keep it simple here and my code has gotten quite complex. I hope the provided code is enough to pin down where the problem occurs. In the particular example below, the first three parameters are rendered (three checkboxes). The fourth has a length of 0 and thus the fifth (another checkbox with the ID "use_mqtt") and following parameters are not rendered. **EDIT:** To be clear: When I say *sometimes*, I mean that I can compile the code and it may work. If I compile the same code again, it doesn't anymore. ### Sketch ```cpp #include <WiFiManager.h> class SeparatorParameter : public WiFiManagerParameter { public: SeparatorParameter(const char *label) : WiFiManagerParameter() { char *custom = new char[55]; strcpy(custom, "<div class=\"separator\">"); strcat(custom, label); strcat(custom, "</div>"); init(NULL, NULL, NULL, 4, custom, WFM_LABEL_BEFORE); } }; WiFiManager wm; void setup() { Serial.begin(115200); wm.setHostname("ConfigAP"); std::vector<const char *> menu = {"wifi","info","param","sep","restart","exit"}; wm.setMenu(menu); const char customHead[] = "<style>" ".separator {display: flex;align-items: center;text-align: center;}" ".separator::before, .separator::after {content:''; flex: 1; border-bottom: 1px solid #000;}" ".separator::before {margin-right: .25em;}" ".separator::after {margin-left: .25em;}" "body.invert .separator::before {border-bottom: 1px solid #FFF;}" "body.invert .separator::after {border-bottom: 1px solid #FFF;}" "</style>"; wm.setCustomHeadElement(customHead); [...] } void loop() { } ``` In `WiFiManager.cpp`: ```cpp [...] String WiFiManager::getParamOut(){ String page; if(_paramsCount > 0){ String HTTP_PARAM_temp = FPSTR(HTTP_FORM_LABEL); HTTP_PARAM_temp += FPSTR(HTTP_FORM_PARAM); bool tok_I = HTTP_PARAM_temp.indexOf(FPSTR(T_I)) > 0; bool tok_i = HTTP_PARAM_temp.indexOf(FPSTR(T_i)) > 0; bool tok_n = HTTP_PARAM_temp.indexOf(FPSTR(T_n)) > 0; bool tok_p = HTTP_PARAM_temp.indexOf(FPSTR(T_p)) > 0; bool tok_t = HTTP_PARAM_temp.indexOf(FPSTR(T_t)) > 0; bool tok_l = HTTP_PARAM_temp.indexOf(FPSTR(T_l)) > 0; bool tok_v = HTTP_PARAM_temp.indexOf(FPSTR(T_v)) > 0; bool tok_c = HTTP_PARAM_temp.indexOf(FPSTR(T_c)) > 0; char valLength[5]; // add the extra parameters to the form for (int i = 0; i < _paramsCount; i++) { if (_params[i] == NULL || _params[i]->_length == 0) { DEBUG_WM(DEBUG_ERROR,"[ERROR] WiFiManagerParameter is out of scope"); if(_params[i]->_length == 0) { Serial.println("Length is 0"); } if(i+1 < _paramsCount) { Serial.print("Next element: "); if(_params[i+1] == NULL) { Serial.println("NULL"); } else { Serial.println(_params[i+1]->getID()); } } break; } [...] ``` ### Debug Messages ``` [...] *WM: [3] setupConfigPortal *WM: [1] Starting Web Portal *WM: [3] dns server started with ip: 192.168.4.1 *WM: [2] HTTP server started *WM: [2] WiFi Scan completed in 3105 ms *WM: [2] Config Portal Running, blocking, waiting for clients... *WM: [3] -> connectivitycheck.platform.hicloud.com *WM: [2] <- Request redirected to captive portal *WM: [3] -> connectivitycheck.platform.hicloud.com *WM: [2] <- Request redirected to captive portal *WM: [3] -> connectivitycheck.platform.hicloud.com *WM: [2] <- Request redirected to captive portal *WM: [3] -> connectivitycheck.platform.hicloud.com *WM: [2] <- Request redirected to captive portal *WM: [3] -> connectivitycheck.platform.hicloud.com *WM: [2] <- Request redirected to captive portal *WM: [2] <- HTTP Root *WM: [3] -> 192.168.4.1 *WM: [3] lastconxresulttmp: WL_IDLE_STATUS *WM: [3] lastconxresult: WL_DISCONNECTED *WM: [2] Scan is cached 10214 ms ago *WM: [3] -> 192.168.4.1 *WM: [3] -> connectivitycheck.platform.hicloud.com *WM: [2] <- Request redirected to captive portal *WM: [3] -> connectivitycheck.platform.hicloud.com *WM: [2] <- Request redirected to captive portal *WM: [3] -> connectivitycheck.platform.hicloud.com *WM: [2] <- Request redirected to captive portal *WM: [2] <- HTTP Param *WM: [0] [ERROR] WiFiManagerParameter is out of scope Length is 0 Next element: use_mqtt *WM: [3] lastconxresulttmp: WL_IDLE_STATUS *WM: [3] lastconxresult: WL_DISCONNECTED *WM: [3] Sent param page [...] ```
Author
Owner

@Lithimlin commented on GitHub (Aug 27, 2020):

I just removed the length check and everything is working perfectly fine. Is that check even necessary?

<!-- gh-comment-id:681792384 --> @Lithimlin commented on GitHub (Aug 27, 2020): I just removed the length check and everything is working perfectly fine. Is that check even necessary?
Author
Owner

@tablatronix commented on GitHub (Aug 27, 2020):

I had a feeling this was the cause, what kind of parameter has a length of 0?

This is not necessary but it was keeping some code from blowing up if users were trying to use params out of scope.

Are you sure you are not losing scope of your params ? If you are using callbacks make sure they are icache, and make sure you are not in some other interrupt etc.

<!-- gh-comment-id:681960336 --> @tablatronix commented on GitHub (Aug 27, 2020): I had a feeling this was the cause, what kind of parameter has a length of 0? This is not necessary but it was keeping some code from blowing up if users were trying to use params out of scope. Are you sure you are not losing scope of your params ? If you are using callbacks make sure they are icache, and make sure you are not in some other interrupt etc.
Author
Owner

@Lithimlin commented on GitHub (Aug 27, 2020):

As I said, no parameters of mine actually have a length of 0. It's always at least 1.

I'm pretty sure I'm not losing their scope since I can access the _length field just fine and correctly work with them. It's just that the _length is being set to 0 somewhere in the code. I tried to find all occurrences if the _length field but it's not set to anything anywhere except when it's deconstructed. But I'm never actively deconstructing any of my parameters.

<!-- gh-comment-id:681963853 --> @Lithimlin commented on GitHub (Aug 27, 2020): As I said, no parameters of mine actually have a length of 0. It's always at least 1. I'm pretty sure I'm not losing their scope since I can access the `_length` field just fine and correctly work with them. It's just that the `_length` is being set to 0 somewhere in the code. I tried to find all occurrences if the `_length` field but it's not set to anything anywhere except when it's deconstructed. But I'm never actively deconstructing any of my parameters.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/WiFiManager#954
No description provided.