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;