From e7c9e3f0801bad234b25a6f04b76d9ceaa2a381a Mon Sep 17 00:00:00 2001 From: Sveninndh <32936592+Sveninndh@users.noreply.github.com> Date: Tue, 3 Jan 2023 18:05:26 +0100 Subject: [PATCH] Improvement template processing (see issues #1232 and #1249) AsyncAbstractResponse::_fillBufferAndProcessTemplates() 1.) A parameter is enclosed by the % delimiter. 2.) Parameter names can have a maximum of 32 characters. 3.) Parameter names cannot contain illegal characters. (\ .:<>{}',;"/) A parameter is only recognized and replaced if all of these conditions are met. Otherwise the text source code is not changed. Using double % is no longer necessary. Nevertheless, this mechanism will continue to be supported for reasons of compatibility. --- src/WebResponses.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/WebResponses.cpp b/src/WebResponses.cpp index a22e991aa..3ccca54cf 100644 --- a/src/WebResponses.cpp +++ b/src/WebResponses.cpp @@ -383,6 +383,7 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size if(!_callback) return _fillBuffer(data, len); + const char* illegalChars = " .:<>{}/',;\"\\"; const size_t originalLen = len; len = _readDataFromCacheOrContent(data, len); // Now we've read 'len' bytes, either from cache or from file @@ -396,11 +397,14 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size // If closing placeholder is found: if(pTemplateEnd) { // prepare argument to callback - const size_t paramNameLength = std::min(sizeof(buf) - 1, (unsigned int)(pTemplateEnd - pTemplateStart - 1)); + const size_t paramNameLength = (unsigned int)(pTemplateEnd - pTemplateStart - 1); if(paramNameLength) { - memcpy(buf, pTemplateStart + 1, paramNameLength); - buf[paramNameLength] = 0; - paramName = String(reinterpret_cast(buf)); + if(paramNameLength <= TEMPLATE_PARAM_NAME_LENGTH) { + memcpy(buf, pTemplateStart + 1, paramNameLength); + buf[paramNameLength] = 0; + if (strcspn((char*)buf, illegalChars) < paramNameLength) ++pTemplateStart; // invalid paramName, includes illagal characters, store found percent symbol as is and advance to the next position + else paramName = String(reinterpret_cast(buf)); + } else ++pTemplateStart; // invalid paramName, it is too long, store found percent symbol as is and advance to the next position } else { // double percent sign encountered, this is single percent sign escaped. // remove the 2nd percent sign memmove(pTemplateEnd, pTemplateEnd + 1, &data[len] - pTemplateEnd - 1); @@ -415,10 +419,13 @@ size_t AsyncAbstractResponse::_fillBufferAndProcessTemplates(uint8_t* data, size if(pTemplateEnd) { // prepare argument to callback *pTemplateEnd = 0; - paramName = String(reinterpret_cast(buf)); - // Copy remaining read-ahead data into cache - _cache.insert(_cache.begin(), pTemplateEnd + 1, buf + (&data[len - 1] - pTemplateStart) + readFromCacheOrContent); - pTemplateEnd = &data[len - 1]; + if (strcspn((char*)buf, illegalChars) < (pTemplateEnd - pTemplateStart - 1)) ++pTemplateStart; // invalid paramName, includes illagal characters, store found percent symbol as is and advance to the next position + else { + paramName = String(reinterpret_cast(buf)); + // Copy remaining read-ahead data into cache + _cache.insert(_cache.begin(), pTemplateEnd + 1, buf + (&data[len - 1] - pTemplateStart) + readFromCacheOrContent); + pTemplateEnd = &data[len - 1]; + } } else // closing placeholder not found in file data, store found percent symbol as is and advance to the next position {