Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESP8266WebServer::authenticate() makes the sketch crash. #1790

Closed
dancol90 opened this issue Mar 17, 2016 · 2 comments
Closed

ESP8266WebServer::authenticate() makes the sketch crash. #1790

dancol90 opened this issue Mar 17, 2016 · 2 comments

Comments

@dancol90
Copy link

Hardware

Hardware: ESP-12E (NodeMCU)
Core Version: 2.1.0

Description

When ESP8266WebServer::authenticate() is called, the program crashes. By analyzing the stack, it seems related to sprintf and delete[] commands inside the web server library code.

The sketch loads fine, it connects to wifi, but after connecting with a browser and entering auth info (right or wrong, doesn't matter), the program crashes. A stack dump is provided below.

Looking at ESP8266WebServer::authenticate() code, and after some experiments, it seems that the program breaks when calling delete[] toencode. Removing the sprintf call inside the function avoids the crash (obviously the function will return always false, but whatever).

Also, rewriting the function using Arduino's String objects instead of char buffer formatting makes the crash disappear.

Sometimes the program crashes before the browser asks for a username and a password.

Settings in IDE

Same problem is observed using PlatformIO.

Module: Generic ESP8266 Module
Flash Size: 4MB/1MB
CPU Frequency: 80Mhz
Flash Mode: qio
Flash Frequency: 40Mhz
Upload Using: SERIAL
Reset Method: nodemcu

Sketch

Every time HTTP authentication is used as is intended to be used. The simplest example is the HttpBasicAuth example, provided with the ESPWebServer lib.

server.on("/", [](){
  if(!server.authenticate(www_username, www_password))
    return server.requestAuthentication();
    server.send(200, "text/plain", "Login OK");
});

Stack dump

0x40101daa: pp_post at ?? line ?
0x40101daa: pp_post at ?? line ?
0x40107080: printf at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/cores/esp8266/libc_replacements.c line 206
0x40102c4c: trc_NeedRTS at ?? line ?
0x40227be2: ets_vsnprintf at ?? line ?
0x402093f6: String::copy(char const*, unsigned int) at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/cores/esp8266/WString.cpp line 177
0x4010031d: check_poison at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/cores/esp8266/umm_malloc/umm_malloc.c line 817
0x40100426: check_poison_block at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/cores/esp8266/umm_malloc/umm_malloc.c line 851
0x40100466: get_unpoisoned at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/cores/esp8266/umm_malloc/umm_malloc.c line 936
0x401008bc: free at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/cores/esp8266/umm_malloc/umm_malloc.c line 1714
0x40207dec: operator delete[](void*) at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/cores/esp8266/abi.cpp line 84
0x40205732: ESP8266WebServer::authenticate(char const*, char const*) at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h line 53
0x401006d8: malloc at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/cores/esp8266/umm_malloc/umm_malloc.c line 1658
0x4020936e: String::changeBuffer(unsigned int) at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/cores/esp8266/WString.cpp line 156
0x40205d48: FunctionRequestHandler::handle(ESP8266WebServer&, HTTPMethod, String) at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h line 53
0x402026b1: operator() at /Users/daniele/Progetti/Arduino/HttpBasicAuth/HttpBasicAuth.ino line 26
:  (inlined by) _M_invoke at /Users/daniele/Library/Arduino15/packages/esp8266/tools/xtensa-lx106-elf-gcc/1.20.0-26-gb404fb9-2/xtensa-lx106-elf/include/c++/4.8.2/functional line 2071
0x401008c8: free at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/cores/esp8266/umm_malloc/umm_malloc.c line 1727
0x40205d3e: std::function ::operator()() const at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h line 53
0x40205d7a: FunctionRequestHandler::handle(ESP8266WebServer&, HTTPMethod, String) at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h line 53
0x4020951c: String::String(String const&) at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/cores/esp8266/WString.cpp line 46
0x40205e0d: ESP8266WebServer::_handleRequest() at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h line 53
0x402030a0: WiFiClient::~WiFiClient() at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/libraries/ESP8266WiFi/src/WiFiClient.cpp line 362
0x40207e8c: esp_yield at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/cores/esp8266/core_esp8266_main.cpp line 43
0x4020603b: ESP8266WebServer::handleClient() at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/libraries/ESP8266WebServer/src/detail/RequestHandlersImpl.h line 53
0x40208a74: Print::println(char const*) at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/cores/esp8266/Print.cpp line 156
0x40202800: setup at /Users/daniele/Progetti/Arduino/HttpBasicAuth/HttpBasicAuth.ino line 35
0x40202822: loop at /Users/daniele/Progetti/Arduino/HttpBasicAuth/HttpBasicAuth.ino line 40
0x40207ed8: loop_wrapper at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/cores/esp8266/core_esp8266_main.cpp line 43
0x40100958: cont_norm at /Users/daniele/Library/Arduino15/packages/esp8266/hardware/esp8266/2.1.0/cores/esp8266/cont.S line 109
@igrr
Copy link
Member

igrr commented Mar 18, 2016

My guess is that there is an error in this line:
char toencodeLen = strlen(username)+strlen(password)+1;
That should probably be +2, because we have username, colon, password, and zero terminator.
Could you please try replacing +1 with +2 in that line and see if that will work?

@dancol90
Copy link
Author

Thanks! You are right, the buffer is one byte shorter than expected!
The solution you suggest it's not the best because makes the function always return false, as toencodeLen is meant to be the exact string length, without the termination character.
I solved the issue adding a +1 to the buffer allocation:

char toencodeLen = strlen(username)+strlen(password)+1;
char *toencode = new char[toencodeLen+1];

Now it works like a charm!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants