Fix `WebQuery response buffer corruption and format character %` (#20111)

This commit is contained in:
Theo Arends 2023-11-27 15:22:30 +01:00
parent 3273aaa9f9
commit 07031d5ebf
3 changed files with 26 additions and 14 deletions

View File

@ -31,6 +31,7 @@ All notable changes to this project will be documented in this file.
- Berry parser error in specific cases (#20059) - Berry parser error in specific cases (#20059)
- ``changeUIntScale`` for linearity when expanding range (#20089) - ``changeUIntScale`` for linearity when expanding range (#20089)
- ESP32 remove restart energy logging if no energy monitoring is selected - ESP32 remove restart energy logging if no energy monitoring is selected
- ``WebQuery`` response buffer corruption and format character ``%`` (#20111)
### Removed ### Removed

View File

@ -165,6 +165,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasm
- NeoPool filtration mode display [#19801](https://github.com/arendst/Tasmota/issues/19801) - NeoPool filtration mode display [#19801](https://github.com/arendst/Tasmota/issues/19801)
- Zero-Cross Dimmer for ESP32 with Core3 [#19929](https://github.com/arendst/Tasmota/issues/19929) - Zero-Cross Dimmer for ESP32 with Core3 [#19929](https://github.com/arendst/Tasmota/issues/19929)
- ``changeUIntScale`` for linearity when expanding range [#20089](https://github.com/arendst/Tasmota/issues/20089) - ``changeUIntScale`` for linearity when expanding range [#20089](https://github.com/arendst/Tasmota/issues/20089)
- ``WebQuery`` response buffer corruption and format character ``%`` [#20111](https://github.com/arendst/Tasmota/issues/20111)
- ESP32 I2C allow bus2 support when bus1 is not enabled - ESP32 I2C allow bus2 support when bus1 is not enabled
- ESP32 remove restart energy logging if no energy monitoring is selected - ESP32 remove restart energy logging if no energy monitoring is selected
- ESP32 IR receive with Arduino Core 3 [#19904](https://github.com/arendst/Tasmota/issues/19904) - ESP32 IR receive with Arduino Core 3 [#19904](https://github.com/arendst/Tasmota/issues/19904)

View File

@ -447,9 +447,9 @@ const char kUploadErrors[] PROGMEM =
const uint16_t DNS_PORT = 53; const uint16_t DNS_PORT = 53;
enum HttpOptions { HTTP_OFF, HTTP_USER, HTTP_ADMIN, HTTP_MANAGER, HTTP_MANAGER_RESET_ONLY }; enum HttpOptions { HTTP_OFF, HTTP_USER, HTTP_ADMIN, HTTP_MANAGER, HTTP_MANAGER_RESET_ONLY };
enum WebCmndStatus { WEBCMND_DONE=0, WEBCMND_WRONG_PARAMETERS, WEBCMND_CONNECT_FAILED, WEBCMND_HOST_NOT_FOUND, WEBCMND_MEMORY_ERROR enum WebCmndStatus { WEBCMND_DONE, WEBCMND_WRONG_PARAMETERS, WEBCMND_CONNECT_FAILED, WEBCMND_HOST_NOT_FOUND, WEBCMND_MEMORY_ERROR, WEBCMND_VALID_RESPONSE
#ifdef USE_WEBGETCONFIG #ifdef USE_WEBGETCONFIG
, WEBCMND_FILE_NOT_FOUND, WEBCMND_OTHER_HTTP_ERROR, WEBCMND_CONNECTION_LOST, WEBCMND_INVALID_FILE ,WEBCMND_FILE_NOT_FOUND, WEBCMND_OTHER_HTTP_ERROR, WEBCMND_CONNECTION_LOST, WEBCMND_INVALID_FILE
#endif // USE_WEBGETCONFIG #endif // USE_WEBGETCONFIG
}; };
@ -3353,19 +3353,25 @@ int WebQuery(char *buffer) {
else return status; else return status;
if (http_code > 0) { // http_code will be negative on error if (http_code > 0) { // http_code will be negative on error
if (http_code == HTTP_CODE_OK || http_code == HTTP_CODE_MOVED_PERMANENTLY) {
#ifdef USE_WEBSEND_RESPONSE #ifdef USE_WEBSEND_RESPONSE
if (http_code == HTTP_CODE_OK || http_code == HTTP_CODE_MOVED_PERMANENTLY) {
// Return received data to the user - Adds 900+ bytes to the code // Return received data to the user - Adds 900+ bytes to the code
String response = http.getString(); // File found at server - may need lot of ram or trigger out of memory! String response = http.getString(); // File found at server - may need lot of ram or trigger out of memory!
const char* read = response.c_str(); const char* read = response.c_str();
ResponseClear();
// uint32_t len = response.length() + 1;
// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: Response '%*_H' = %s"), len, (uint8_t*)read, read);
Response_P(PSTR("{\"" D_CMND_WEBQUERY "\":")); Response_P(PSTR("{\"" D_CMND_WEBQUERY "\":"));
char text[2] = { 0 }; char text[3] = { 0 }; // Make room foor double %
text[0] = *read++; text[0] = *read++;
bool assume_json = (text[0] == '{') || (text[0] == '['); bool assume_json = (text[0] == '{') || (text[0] == '[');
if (!assume_json) { ResponseAppend_P(PSTR("\"")); } if (!assume_json) { ResponseAppend_P(PSTR("\"")); }
while (text[0] != '\0') { while (text[0] != '\0') {
if (text[0] > 31) { // Remove control characters like linefeed if (text[0] > 31) { // Remove control characters like linefeed
if ('%' == text[0]) { // Fix char string expansion for %
text[1] = '%';
}
if (assume_json) { if (assume_json) {
if (ResponseAppend_P(text) == ResponseSize()) { break; }; if (ResponseAppend_P(text) == ResponseSize()) { break; };
} else { } else {
@ -3373,6 +3379,7 @@ int WebQuery(char *buffer) {
} }
} }
text[0] = *read++; text[0] = *read++;
text[1] = '\0';
} }
if (!assume_json) { ResponseAppend_P(PSTR("\"")); } if (!assume_json) { ResponseAppend_P(PSTR("\"")); }
ResponseJsonEnd(); ResponseJsonEnd();
@ -3381,9 +3388,9 @@ int WebQuery(char *buffer) {
// recursive call must be possible in this case // recursive call must be possible in this case
tasm_cmd_activ = 0; tasm_cmd_activ = 0;
#endif // USE_SCRIPT #endif // USE_SCRIPT
MqttPublishPrefixTopicRulesProcess_P(RESULT_OR_STAT, PSTR(D_CMND_WEBQUERY)); status = WEBCMND_VALID_RESPONSE;
} else
#endif // USE_WEBSEND_RESPONSE #endif // USE_WEBSEND_RESPONSE
}
status = WEBCMND_DONE; status = WEBCMND_DONE;
} else { } else {
status = WEBCMND_CONNECT_FAILED; status = WEBCMND_CONNECT_FAILED;
@ -3490,7 +3497,7 @@ bool JsonWebColor(const char* dataBuf)
return true; return true;
} }
const char kWebCmndStatus[] PROGMEM = D_JSON_DONE "|" D_JSON_WRONG_PARAMETERS "|" D_JSON_CONNECT_FAILED "|" D_JSON_HOST_NOT_FOUND "|" D_JSON_MEMORY_ERROR const char kWebCmndStatus[] PROGMEM = D_JSON_DONE "|" D_JSON_WRONG_PARAMETERS "|" D_JSON_CONNECT_FAILED "|" D_JSON_HOST_NOT_FOUND "|" D_JSON_MEMORY_ERROR "|"
#ifdef USE_WEBGETCONFIG #ifdef USE_WEBGETCONFIG
"|" D_JSON_FILE_NOT_FOUND "|" D_JSON_OTHER_HTTP_ERROR "|" D_JSON_CONNECTION_LOST "|" D_JSON_INVALID_FILE_TYPE "|" D_JSON_FILE_NOT_FOUND "|" D_JSON_OTHER_HTTP_ERROR "|" D_JSON_CONNECTION_LOST "|" D_JSON_INVALID_FILE_TYPE
#endif // USE_WEBGETCONFIG #endif // USE_WEBGETCONFIG
@ -3642,17 +3649,20 @@ void CmndWebSend(void)
{ {
if (XdrvMailbox.data_len > 0) { if (XdrvMailbox.data_len > 0) {
uint32_t result = WebSend(XdrvMailbox.data); uint32_t result = WebSend(XdrvMailbox.data);
char stemp1[20]; if (result != WEBCMND_VALID_RESPONSE) {
ResponseCmndChar(GetTextIndexed(stemp1, sizeof(stemp1), result, kWebCmndStatus)); char stemp1[20];
ResponseCmndChar(GetTextIndexed(stemp1, sizeof(stemp1), result, kWebCmndStatus));
}
} }
} }
void CmndWebQuery(void) void CmndWebQuery(void) {
{
if (XdrvMailbox.data_len > 0) { if (XdrvMailbox.data_len > 0) {
uint32_t result = WebQuery(XdrvMailbox.data); uint32_t result = WebQuery(XdrvMailbox.data);
char stemp1[20]; if (result != WEBCMND_VALID_RESPONSE) {
ResponseCmndChar(GetTextIndexed(stemp1, sizeof(stemp1), result, kWebCmndStatus)); char stemp1[20];
ResponseCmndChar(GetTextIndexed(stemp1, sizeof(stemp1), result, kWebCmndStatus));
}
} }
} }