Hi there, There is an easy-to-reproduce exception which is luckily caught triggered from cache_manager.cc: If the page 'cache_object://0/io?&' is accessed, CacheManager::ParseUrl() will parse the URL as follows: t = sscanf(url, "cache_object://%[^/]/%[^?]%n?%s", host, request, &pos, params); This 'params' variable will then be passed: Mgr::QueryParams::Parse(params, cmd->params.queryParams). At this stage, 'params' contains only a single character, '&'. As the function goes on, it is picked up here: for (size_t i = n; i < len; ++i) { if (aParamsStr[i] == '&') { if (!ParseParam(aParamsStr.substr(n, i), param)) here, both 'n' and 'i' are 0. aParamsStr.substr(n, i) thus causes an exception: Breakpoint 8, String::substr (this=0x7fffffff3860, from=0, to=0) at String.cc:226 226 Must(from < size()); (gdb) n 227 Must(to > 0 && to <= size()); (gdb) n 2021/03/03 16:58:58.743| 0,3| String.cc(227) substr: check failed: to > 0 && to <= size() exception location: String.cc(227) substr 2021/03/03 16:58:58.761| 33,3| ../../src/base/AsyncJobCalls.h(178) dial: Server::doClientRead threw exception: check failed: to > 0 && to <= size() exception location: String.cc(227) substr 2021/03/03 16:58:58.761| 93,2| AsyncJob.cc(129) callException: check failed: to > 0 && to <= size() exception location: String.cc(227) substr A one-line reproducer: printf "GET cache_object://0/io?&\n" | nc localhost 3128
I can reproduce in v4-based code.
FTR, there is no longer any need for this logic to be parsing the full URI. There is a pre-parsed and validated representation available at HttpRequest::url which shoudl be the argument passed to this function. At most the Uri::path string may need parsing to identify the command and params segments.
Since AnyP::Uri is my project I will pick this up and make a PR shortly.
https://github.com/squid-cache/squid/pull/788
.