https://github.com/php/php-src/commit/3d9c02364db62a6d8e2794...
They also fixed the whitespace handling that let something like "RandomHeader: hello host:8080" mistakenly set the flag.
https://github.com/php/php-src/commit/56cdbe63c24b86c2f1d60b...
Otherwise, it looks like it will call strstr() one extra time, even though you may have already determined that the specific header is present.
[1] https://github.com/php/php-src/commit/3d9c02364db62a6d8e2794...
while ((s = strstr(s, "host:"))) {
if (s == t || *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' ') {
have_header |= HTTP_HEADER_HOST;
}
s++;
}
This s++ could be s + sizeof "host:" - 1.Reason being: if you have just found "host:" at address s, you will not find another one at s+1, s+2, s+3, s+4 or s+4; "host:" supports no overlapped matches.
Actually since, we are really looking for "host:" preceded by whitespace, we can skip by just sizeof "host", (five bytes). Because if s points at "host:host:", the second "host:" is not of interest; it is not preceded by a whitespace character; we won't be setting the HTTP_HEADER_HOST bit for that one.
Also, once we set the HTTP_HEADER_HOST bit, we can break out of the loop; there is no value in continuing it. The point of the loop is not to have a false negative: not to stop on a false match on "host:" which doesn't meet the HTTP_HEADER_HOST conditions, and thereby fail to find the real one later in the string. If we find the real one, we are done.
By the way, this test shows how verbose of a language C is:
*(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' '
If we could use Javascript, look how nice it would be: strchr("\r\n\t ", s[-1])[1] https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4....
There is no other RFC compliant way to end headers.