mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2025-05-15 09:18:27 +00:00
Work around incompatibility in <regex> in libc++
libc++ (the implementation of the C++ standard library usually used by Clang) throws an exception for the regex used by parse_headers before this patch for certain strings. Work around this by simplifying the regex and parsing the header lines "by hand" partially. I have repro'd this problem with Xcode 11.1 which I believe uses libc++ version 8. This may be a bug in libc++ as I can't see why the regex would result in asymptotic run-time complexity for any strings. However, it may take a while for libc++ to be fixed and for everyone to migrate to it, so it makes sense to work around it in this codebase for now.
This commit is contained in:
parent
a9e942d755
commit
bc9251ea49
2 changed files with 73 additions and 22 deletions
20
httplib.h
20
httplib.h
|
@ -1566,7 +1566,7 @@ inline bool read_headers(Stream &strm, Headers &headers) {
|
|||
// the left or right side of the header value:
|
||||
// - https://stackoverflow.com/questions/50179659/
|
||||
// - https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html
|
||||
static std::regex re(R"((.+?):[\t ]*(.+?)[\t ]*\r\n)");
|
||||
static std::regex re(R"((.+?):[\t ]*(.+))");
|
||||
|
||||
const auto bufsiz = 2048;
|
||||
char buf[bufsiz];
|
||||
|
@ -1575,9 +1575,23 @@ inline bool read_headers(Stream &strm, Headers &headers) {
|
|||
|
||||
for (;;) {
|
||||
if (!line_reader.getline()) { return false; }
|
||||
if (!strcmp(line_reader.ptr(), "\r\n")) { break; }
|
||||
const char *end = line_reader.ptr() + line_reader.size();
|
||||
auto erase_last_char = [&](char c) {
|
||||
if (line_reader.ptr() == end || end[-1] != c) {
|
||||
return false;
|
||||
}
|
||||
end--;
|
||||
return true;
|
||||
};
|
||||
if (!erase_last_char('\n')) { continue; }
|
||||
if (!erase_last_char('\r')) { continue; }
|
||||
|
||||
// Blank line indicates end of headers.
|
||||
if (line_reader.ptr() == end) { break; }
|
||||
|
||||
while (erase_last_char(' ') || erase_last_char('\t')) {}
|
||||
std::cmatch m;
|
||||
if (std::regex_match(line_reader.ptr(), m, re)) {
|
||||
if (std::regex_match(line_reader.ptr(), end, m, re)) {
|
||||
auto key = std::string(m[1]);
|
||||
auto val = std::string(m[2]);
|
||||
headers.emplace(key, val);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue