What's Changed
Security fixes
- Reject bytes trailing an IPv6 host literal in
parse_url()instead of folding them into the path (#2536, thanks @metsw24-max).http://[::1]evil.com/previously parsed with host::1and pathevil.com/, silently dropping the extra bytes rather than rejecting the URL; a]not followed by:,/,?,#, or end-of-string is now a parse failure - Guard regex routes against stack overflow from long paths.
RegexMatcher::match()calledstd::regex_match()directly on the attacker-controlled request path; for quantified patterns such as(.*), libstdc++'s recursive backtracking implementation recurses roughly once per matched character, so a path of a couple thousand characters (well within the existing 8192-byte request URI limit) reliably crashed the process under the default thread stack size. AddCPPHTTPLIB_REGEX_ROUTE_PATH_MAX_LENGTH(default 256) and reject paths longer than it as a non-match before ever callingstd::regex_match() - Enforce
payload_max_lengthon the decompressed size for unframed requests. A non-SSL request with neitherContent-LengthnorTransfer-Encodingread raw wire bytes directly, bypassing the decompressor wrapper the length-framed and chunked paths already use, sopayload_max_lengthonly bounded the compressed bytes read off the socket rather than the decompressed size a handler could see. This path is now routed through the same decompressing helper as the others
Performance
- Match literal route patterns without building a
std::regex(#2538). Most registered route patterns are plain literals with no regex metacharacters, but every non-parameter pattern still went throughstd::regex_matchon every request.PathParamsMatcheralready does an exact literal comparison when it captures no parameter, so patterns are now routed there whenever they contain none of the 14 ECMAScript metacharacters. Measured with clang -O2 on macOS: scanning routes that all miss until the last one, throughput rises about 24% at 100 routes and roughly 3x at 1000; registering 5000 literal routes drops from about 3.0ms to about 0.9ms. This also confinesCPPHTTPLIB_REGEX_ROUTE_PATH_MAX_LENGTHto routes that actually use regex, since literal routes no longer go throughRegexMatcher. One visible behavior change: a literal route no longer populatesRequest::matches(path parameter routes have always behaved this way)
Full Changelog: v0.53.0...v0.53.1