Notably, the bugfix made PHP maintainers realize that the header handler had additional behaviors that they did not understand nor had a rationale for, so those behaviors were removed as well:<p><a href="https://github.com/php/php-src/pull/5201" rel="nofollow">https://github.com/php/php-src/pull/5201</a>
Looking at lines 460-521 in the modified file (<a href="https://github.com/miguelxpn/php-src/blob/f4b2089b642d504be358b06bbae81fa688d8bf0e/ext/standard/http_fopen_wrapper.c#L460" rel="nofollow">https://github.com/miguelxpn/php-src/blob/f4b2089b642d504be3...</a>), is there not a benefit to `break` out of the while loop in the nested if statements?<p>Otherwise, it looks like it will call strstr() one extra time, even though you may have already determined that the specific header is present.
Interesting bug, but even better it's nice to see encouragement of people to get involved in open source. The walk through of the process was great.
<p><pre><code> 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++;
}
</code></pre>
This s++ could be s + sizeof "host:" - 1.<p>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.<p>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.<p>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.<p>By the way, this test shows how verbose of a language C is:<p><pre><code> *(s-1) == '\r' || *(s-1) == '\n' ||
*(s-1) == '\t' || *(s-1) == ' '
</code></pre>
If we could use Javascript, look how nice it would be:<p><pre><code> strchr("\r\n\t ", s[-1])</code></pre>