From: Amos Jeffries Date: Fri, 20 May 2016 05:25:58 +0000 (+1200) Subject: squidclient: Improve shell-escape support in -H option X-Git-Tag: SQUID_4_0_11~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8798e209833f31da6f3f411e8d3cae4c879c478d;p=thirdparty%2Fsquid.git squidclient: Improve shell-escape support in -H option The -H parameter takes a string with some limited shell-escaped characters. Currently just \n was expanded to the CRLF sequence. Other shell escaped characters were left untouched. However, to properly test headers containing weird CR, LF and HTAB positioning it needs to be able to receive these special characters individually and thus unescape them. Add a new function similar to perform shell unescape with special characters \\, \r, \n, and \t. All other characters are un-escaped to themselves and a warning printed at verbosity level 1. --- diff --git a/tools/squidclient/squidclient.cc b/tools/squidclient/squidclient.cc index e084ee6193..e73ef2bf0e 100644 --- a/tools/squidclient/squidclient.cc +++ b/tools/squidclient/squidclient.cc @@ -111,7 +111,7 @@ usage(const char *progname) << "HTTP Options:" << std::endl << " -a Do NOT include Accept: header." << std::endl << " -A User-Agent: header. Use \"\" to omit." << std::endl - << " -H 'string' Extra headers to send. Use '\\n' for new lines." << std::endl + << " -H 'string' Extra headers to send. Supports '\\\\', '\\n', '\\r' and '\\t'." << std::endl << " -i IMS If-Modified-Since time (in Epoch seconds)." << std::endl << " -j hosthdr Host header content" << std::endl << " -k Keep the connection active. Default is to do only one request then close." << std::endl @@ -132,6 +132,56 @@ usage(const char *progname) exit(1); } +static void +shellUnescape(char *buf) +{ + if (!buf) + return; + + unsigned char *p, *d; + + d = p = reinterpret_cast(buf); + + while (auto ch = *p) { + + if (ch == '\\') { + ++p; + + switch (*p) { + case 'n': + ch = '\n'; + break; + case 'r': + ch = '\r'; + break; + case 't': + ch = '\t'; + break; + case '\\': + ch = '\\'; + break; + default: + ch = *p; + debugVerbose(1, "Warning: unsupported shell code '\\" << ch << "'"); + break; + } + + *d = ch; + + if (!ch) + continue; + + } else { + *d = *p; + } + + ++p; + ++d; + } + + *d = '\0'; +} + int main(int argc, char *argv[]) { @@ -262,10 +312,8 @@ main(int argc, char *argv[]) case 'H': if (strlen(optarg)) { - char *t; strncpy(extra_hdrs, optarg, sizeof(extra_hdrs)); - while ((t = strstr(extra_hdrs, "\\n"))) - *t = '\r', *(t + 1) = '\n'; + shellUnescape(extra_hdrs); } break;