mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-14 14:54:49 -04:00
from trunk: reject negative content-length headers
svn:r895
This commit is contained in:
parent
e7d5dfda49
commit
3add69df67
@ -3,6 +3,7 @@ Changes in 1.4.6-stable:
|
||||
o switch all uses of [v]snprintf over to evutil
|
||||
o Correct handling of trailing headers in chunked replies; from Scott Lamb.
|
||||
o Support multi-line HTTP headers; based on a patch from Moshe Litvin
|
||||
o Reject negative Content-Length headers; anonymous bug report
|
||||
|
||||
Changes in 1.4.5-stable:
|
||||
o Fix connection keep-alive behavior for HTTP/1.0
|
||||
|
19
http.c
19
http.c
@ -391,7 +391,7 @@ evhttp_make_header_request(struct evhttp_connection *evcon,
|
||||
evhttp_find_header(req->output_headers, "Content-Length") == NULL){
|
||||
char size[12];
|
||||
evutil_snprintf(size, sizeof(size), "%ld",
|
||||
(long)EVBUFFER_LENGTH(req->output_buffer));
|
||||
(long)EVBUFFER_LENGTH(req->output_buffer));
|
||||
evhttp_add_header(req->output_headers, "Content-Length", size);
|
||||
}
|
||||
}
|
||||
@ -791,6 +791,7 @@ evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
|
||||
while ((len = EVBUFFER_LENGTH(buf)) > 0) {
|
||||
if (req->ntoread < 0) {
|
||||
/* Read chunk size */
|
||||
ev_int64_t ntoread;
|
||||
char *p = evbuffer_readline(buf);
|
||||
char *endp;
|
||||
int error;
|
||||
@ -801,13 +802,16 @@ evhttp_handle_chunked_read(struct evhttp_request *req, struct evbuffer *buf)
|
||||
free(p);
|
||||
continue;
|
||||
}
|
||||
req->ntoread = evutil_strtoll(p, &endp, 16);
|
||||
error = *p == '\0' || (*endp != '\0' && *endp != ' ');
|
||||
ntoread = evutil_strtoll(p, &endp, 16);
|
||||
error = (*p == '\0' ||
|
||||
(*endp != '\0' && *endp != ' ') ||
|
||||
ntoread < 0);
|
||||
free(p);
|
||||
if (error) {
|
||||
/* could not get chunk size */
|
||||
return (DATA_CORRUPTED);
|
||||
}
|
||||
req->ntoread = ntoread;
|
||||
if (req->ntoread == 0) {
|
||||
/* Last chunk */
|
||||
return (ALL_DATA_READ);
|
||||
@ -1507,12 +1511,13 @@ evhttp_get_body_length(struct evhttp_request *req)
|
||||
req->ntoread = -1;
|
||||
} else {
|
||||
char *endp;
|
||||
req->ntoread = evutil_strtoll(content_length, &endp, 10);
|
||||
if (*content_length == '\0' || *endp != '\0') {
|
||||
event_warnx("%s: illegal content length: %s",
|
||||
__func__, content_length);
|
||||
ev_int64_t ntoread = evutil_strtoll(content_length, &endp, 10);
|
||||
if (*content_length == '\0' || *endp != '\0' || ntoread < 0) {
|
||||
event_debug(("%s: illegal content length: %s",
|
||||
__func__, content_length));
|
||||
return (-1);
|
||||
}
|
||||
req->ntoread = ntoread;
|
||||
}
|
||||
|
||||
event_debug(("%s: bytes to read: %lld (in buffer %ld)\n",
|
||||
|
@ -227,6 +227,12 @@ http_basic_cb(struct evhttp_request *req, void *arg)
|
||||
test_ok++;
|
||||
}
|
||||
}
|
||||
|
||||
/* injecting a bad content-length */
|
||||
if (evhttp_find_header(req->input_headers, "X-Negative"))
|
||||
evhttp_add_header(req->output_headers,
|
||||
"Content-Length", "-100");
|
||||
|
||||
/* allow sending of an empty reply */
|
||||
evhttp_send_reply(req, HTTP_OK, "Everything is fine",
|
||||
!empty ? evb : NULL);
|
||||
@ -1276,6 +1282,64 @@ http_multi_line_header_test(void)
|
||||
fprintf(stdout, "OK\n");
|
||||
}
|
||||
|
||||
static void
|
||||
http_request_bad(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
if (req != NULL) {
|
||||
fprintf(stderr, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
test_ok = 1;
|
||||
event_loopexit(NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
http_negative_content_length_test(void)
|
||||
{
|
||||
short port = -1;
|
||||
struct evhttp_connection *evcon = NULL;
|
||||
struct evhttp_request *req = NULL;
|
||||
|
||||
test_ok = 0;
|
||||
fprintf(stdout, "Testing HTTP Negative Content Length: ");
|
||||
|
||||
http = http_setup(&port, NULL);
|
||||
|
||||
evcon = evhttp_connection_new("127.0.0.1", port);
|
||||
if (evcon == NULL) {
|
||||
fprintf(stdout, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, we want to schedule a request to the HTTP
|
||||
* server using our make request method.
|
||||
*/
|
||||
|
||||
req = evhttp_request_new(http_request_bad, NULL);
|
||||
|
||||
/* Cause the response to have a negative content-length */
|
||||
evhttp_add_header(req->output_headers, "X-Negative", "makeitso");
|
||||
|
||||
/* We give ownership of the request to the connection */
|
||||
if (evhttp_make_request(evcon, req, EVHTTP_REQ_GET, "/test") == -1) {
|
||||
fprintf(stdout, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
event_dispatch();
|
||||
|
||||
evhttp_free(http);
|
||||
|
||||
if (test_ok != 1) {
|
||||
fprintf(stdout, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fprintf(stdout, "OK\n");
|
||||
}
|
||||
|
||||
void
|
||||
http_suite(void)
|
||||
{
|
||||
@ -1291,6 +1355,7 @@ http_suite(void)
|
||||
http_dispatcher_test();
|
||||
|
||||
http_multi_line_header_test();
|
||||
http_negative_content_length_test();
|
||||
|
||||
http_chunked_test();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user