From 9c448019fb4007ae3155f89ce8f7a5da3f2f817e Mon Sep 17 00:00:00 2001 From: Anthony Fishbeck Date: Wed, 29 Nov 2023 18:38:04 -0500 Subject: [PATCH] HPCC-30942 Fix SOAPCALL handling of lowercase HTTP headers in response Signed-off-by: Anthony Fishbeck --- common/thorhelper/thorsoapcall.cpp | 10 ++--- system/jlib/jstring.cpp | 60 ++++++++++++++++++++++++++++++ system/jlib/jstring.hpp | 2 + 3 files changed, 67 insertions(+), 5 deletions(-) diff --git a/common/thorhelper/thorsoapcall.cpp b/common/thorhelper/thorsoapcall.cpp index 085f0e18d91..513d6bb0f17 100644 --- a/common/thorhelper/thorsoapcall.cpp +++ b/common/thorhelper/thorsoapcall.cpp @@ -1609,9 +1609,9 @@ bool httpHeaderBlockContainsHeader(const char *httpheaders, const char *header) return false; VStringBuffer match("\n%s:", header); const char *matchStart = match.str()+1; - if (!strncmp(httpheaders, matchStart, strlen(matchStart))) + if (!strnicmp(httpheaders, matchStart, strlen(matchStart))) return true; - if (strstr(httpheaders, match)) + if (stristr(httpheaders, match)) return true; return false; } @@ -1621,7 +1621,7 @@ bool getHTTPHeader(const char *httpheaders, const char *header, StringBuffer& va if (!httpheaders || !*httpheaders || !header || !*header) return false; - const char* pHeader = strstr(httpheaders, header); + const char* pHeader = stristr(httpheaders, header); if (!pHeader) return false; @@ -1947,10 +1947,10 @@ class CWSCAsyncFor : implements IWSCAsyncFor, public CInterface, public CAsyncFo s = strstr(buffer, " "); if (s) rval = atoi(s+1); - if (!strstr(buffer,"Transfer-Encoding: chunked")) + if (!stristr(buffer,"Transfer-Encoding: chunked")) { chunked = false; - s = strstr(buffer,CONTENT_LENGTH); + s = stristr(buffer,CONTENT_LENGTH); if (s) { s += strlen(CONTENT_LENGTH); if ((size32_t)(s-buffer) < payloadofs) diff --git a/system/jlib/jstring.cpp b/system/jlib/jstring.cpp index b54d30e4838..930ded8801e 100644 --- a/system/jlib/jstring.cpp +++ b/system/jlib/jstring.cpp @@ -2842,3 +2842,63 @@ void processOptionString(const char * options, optionCallback callback) options = comma+1; } } + +/** + * stristr - Case insensitive strstr() + * @haystack: Where we will search for our @needle + * @needle: Search pattern. + * + * Description: + * This function is an ANSI version of strstr() with case insensitivity. + * + * It is a commodity funciton found on the web, cut'd, 'n', pasted.. + * URL: http://www.brokersys.com/snippets/STRISTR.C + * + * Hereby donated to public domain. + * + * Returns: char *pointer if needle is found in haystack, otherwise NULL. + * + * Rev History: 11/30/23 JLibify + * 01/20/05 Joachim Nilsson Cleanups + * 07/04/95 Bob Stout ANSI-fy + * 02/03/94 Fred Cole Original + */ + +const char * stristr (const char *haystack, const char *needle) +{ + if (isEmptyString(haystack) || isEmptyString(needle)) + return nullptr; + + const char *pptr = needle; /* Pattern to search for */ + const char *start = haystack; /* Start with a bowl of hay */ + const char *sptr; /* Substring pointer */ + int slen = strlen(haystack); /* Total size of haystack */ + int plen = strlen(needle); /* Length of our needle */ + + /* while string length not shorter than pattern length */ + for (; slen >= plen; start++, slen--) + { + /* find start of pattern in string */ + while (tolower(*start) != tolower(*needle)) + { + start++; + slen--; + /* if pattern longer than string */ + if (slen < plen) + return nullptr; + } + + sptr = start; + pptr = (char *) needle; + while (tolower(*sptr) == tolower(*pptr)) + { + sptr++; + pptr++; + /* if end of pattern then pattern was found */ + if (!*pptr) + return start; + } + } + + return nullptr; +} diff --git a/system/jlib/jstring.hpp b/system/jlib/jstring.hpp index 8acec63a83a..162679a9e13 100644 --- a/system/jlib/jstring.hpp +++ b/system/jlib/jstring.hpp @@ -639,4 +639,6 @@ void processLines(const StringBuffer & content, LineProcessor process) using optionCallback = std::function; extern jlib_decl void processOptionString(const char * options, optionCallback callback); +extern jlib_decl const char * stristr(const char *haystack, const char *needle); + #endif