khoih-prog / WiFiWebServer

This is simple yet complete WebServer library for AVR, Portenta_H7, Teensy, SAM DUE, SAMD, STM32, RP2040-based, etc. boards running WiFi modules/shields (WiFiNINA, CYW43439, U-Blox W101, W102, etc.). The functions are similar and compatible to ESP8266/ESP32 WebServer libraries to make life much easier to port sketches from ESP8266/ESP32. Now using WiFiMulti_Generic library
MIT License
104 stars 21 forks source link

send_P sends corrupted data with large char arrays #15

Closed r-p-d closed 2 years ago

r-p-d commented 2 years ago

I have a quite straightforward implementation:

  char content[sizeof(INDEX_HTML1)];
  memcpy_P(content, INDEX_HTML1, sizeof(INDEX_HTML1));
  server.send_P(200, "text/html", content, sizeof(content));

with INDEX_HTML being an ~7kb string with HTML content

const char INDEX_HTML1[] PROGMEM = R"====(

    <html>
<head>
<script>

...

$("#btn_min").click(function() {
                if (timeVal > 0) {
                    timeVal = timeVal - 0.05;
                }

                $("#val").text(Number(timeVal).toFixed(2));

                $.ajax({
                    url: "/setTime?time=" + timeVal,
                    success: function(result) {

...

Running this yields the following data corruption:


            $("#btn_min").click(function() {
                if (timeVal > 0) {
                    timeVal = timeVal - 0.05;
                }

              p��?umber(timeVal).toFixed(2));

                $.ajax({
                    url: "/setTime?time=" + timeVal,
                    success: function(result) {

Tried to go down the source code, but couldn't find a thing. Would you kindly be able to confirm the bug?

khoih-prog commented 2 years ago

HI @r-p-d

Thanks for your interest in the library and your effort to post the issue.

Please also follow the instructions to post the MRE so that anybody can easily duplicate the issue then fix, if the issue is real.

Your post even has no info about the board, WiFi hardware / library, etc.

Next time, the similar info-lacking post will be deleted right away


Anyway, the send_P() is prototyped as

void send_P(int code, PGM_P content_type, PGM_P content, size_t contentLength);

where : content is PGM_P (PROGMEM pointer)

You already badly copy (without the terminating NULL character) to

char content[sizeof(INDEX_HTML1)]; <====== Bad Bad. must be sizeof(INDEX_HTML1) + 1

so you can't use send_P() anymore, just use send(), such as

char content[sizeof(INDEX_HTML1) + 1];
memcpy_P(content, INDEX_HTML1, sizeof(INDEX_HTML1));
server.send(200, "text/html", content, sizeof(content));

It's better to use original PROGMEM-stored INDEX_HTML1 (if not, why use PROGMEM anyway ???), such as

server.send_P(200, "text/html", INDEX_HTML1, sizeof(INDEX_HTML1));