On 03/02/12 21:44, Ángel González wrote:
> On 03/02/12 15:01, Gustavo Lopes wrote:
>> I've committed a different version that also forbids \0 (since, as
>> Stefan says, a NUL byte can result in the truncation of the rest of
>> the header) and that accepts a CRLF:
>>
>> http://svn.php.net/viewvc/php/php-src/trunk/main/SAPI.c?r1=323043&r2=323042&pathrev=323043
>>
> Looks good. But given that the goal is to make this robust, I would go
> further:
> a) Replace any CRLF + [ \r] with SP
> (rfc2616 allows us "A recipient MAY replace any linear white space
> with a single SP before forwarding the message downstream.", and
> this also protects UAs not following the spec)
>
> b) Bail out on any header_line[i] < ' ' (ie. fail on any special char)
I've gone ahead and written code for that feature. Comments welcome.
Index: main/SAPI.c
===================================================================
--- main/SAPI.c (revision 323049)
+++ main/SAPI.c (working copy)
@@ -710,27 +710,30 @@
efree(header_line);
return SUCCESS;
} else {
- /* new line/NUL character safety check */
- int i;
- for (i = 0; i < header_line_len; i++) {
- /* RFC 2616 allows new lines if followed by SP or HT */
- int illegal_break =
- (header_line[i+1] != ' ' && header_line[i+1] != '\t')
- && (
- header_line[i] == '\n'
- || (header_line[i] == '\r' && header_line[i+1] != '\n'));
- if (illegal_break) {
- efree(header_line);
- sapi_module.sapi_error(E_WARNING, "Header may not contain "
- "more than a single header, new line detected");
- return FAILURE;
+ /* Forbid new lines or control characters in the headers */
+ int i, j;
+ for (i = 0, j = 0; i < header_line_len; i++, j++) {
+ header[i] = header[j];
+ if (i < header_line_len - 2 &&
+ header_line[i] == '\r' && header_line[i+1] == '\n' &&
+ (header_line[i+2] == ' ' || header_line[i+2] == '\t')) {
+
+ /* This is a line continuation. Collapse this little-known
+ * feature into a single SP, as allowed by RFC 2616
+ */
+ header_line[i] = ' ';
+ j = i + 2;
}
- if (header_line[i] == '\0') {
+
+ if (header_line[i] < 32) {
efree(header_line);
- sapi_module.sapi_error(E_WARNING, "Header may not contain NUL bytes");
+ sapi_module.sapi_error(E_WARNING, "header() accepts only a single header, "
+ "new lines and control characters are forbidden");
return FAILURE;
}
}
+ header_line[j] = '\0';
+ header_line_len = j;
}
sapi_header.header = header_line;
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php