mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 23:53:32 +01:00
Add pullup-free version of fetch_from_evbuffer_http
This commit is contained in:
parent
4af6887d20
commit
698085d56e
@ -1013,8 +1013,10 @@ fetch_var_cell_from_buf(buf_t *buf, var_cell_t **out, int linkproto)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_BUFFEREVENTS
|
#ifdef USE_BUFFEREVENTS
|
||||||
|
/* DOCDOC */
|
||||||
static size_t
|
static size_t
|
||||||
inspect_evbuffer(struct evbuffer *buf, char **data, size_t n, int *free_out)
|
inspect_evbuffer(struct evbuffer *buf, char **data, size_t n, int *free_out,
|
||||||
|
struct evbuffer_ptr *pos)
|
||||||
{
|
{
|
||||||
int n_vecs, i;
|
int n_vecs, i;
|
||||||
|
|
||||||
@ -1022,12 +1024,12 @@ inspect_evbuffer(struct evbuffer *buf, char **data, size_t n, int *free_out)
|
|||||||
n = evbuffer_get_length(buf);
|
n = evbuffer_get_length(buf);
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
return 0;
|
return 0;
|
||||||
n_vecs = evbuffer_peek(buf, n, NULL, NULL, 0);
|
n_vecs = evbuffer_peek(buf, n, pos, NULL, 0);
|
||||||
if (n_vecs <= 0)
|
if (n_vecs <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (n_vecs == 1) {
|
if (n_vecs == 1) {
|
||||||
struct evbuffer_iovec v;
|
struct evbuffer_iovec v;
|
||||||
i = evbuffer_peek(buf, n, NULL, &v, 1);
|
i = evbuffer_peek(buf, n, pos, &v, 1);
|
||||||
tor_assert(i == 1);
|
tor_assert(i == 1);
|
||||||
*data = v.iov_base;
|
*data = v.iov_base;
|
||||||
*free_out = 0;
|
*free_out = 0;
|
||||||
@ -1074,7 +1076,7 @@ fetch_var_cell_from_evbuffer(struct evbuffer *buf, var_cell_t **out,
|
|||||||
result = 0;
|
result = 0;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
n = inspect_evbuffer(buf, &hdr, VAR_CELL_HEADER_SIZE, &free_hdr);
|
n = inspect_evbuffer(buf, &hdr, VAR_CELL_HEADER_SIZE, &free_hdr, NULL);
|
||||||
tor_assert(n == VAR_CELL_HEADER_SIZE);
|
tor_assert(n == VAR_CELL_HEADER_SIZE);
|
||||||
|
|
||||||
command = get_uint8(hdr+2);
|
command = get_uint8(hdr+2);
|
||||||
@ -1354,10 +1356,8 @@ fetch_from_evbuffer_http(struct evbuffer *buf,
|
|||||||
char **body_out, size_t *body_used, size_t max_bodylen,
|
char **body_out, size_t *body_used, size_t max_bodylen,
|
||||||
int force_complete)
|
int force_complete)
|
||||||
{
|
{
|
||||||
struct evbuffer_ptr crlf;
|
struct evbuffer_ptr crlf, content_length;
|
||||||
unsigned char *headers;
|
|
||||||
size_t headerlen, bodylen, contentlen;
|
size_t headerlen, bodylen, contentlen;
|
||||||
char *p;
|
|
||||||
|
|
||||||
crlf = evbuffer_search(buf, "\r\n\r\n", 4, NULL);
|
crlf = evbuffer_search(buf, "\r\n\r\n", 4, NULL);
|
||||||
if (crlf.pos < 0) {
|
if (crlf.pos < 0) {
|
||||||
@ -1367,19 +1367,31 @@ fetch_from_evbuffer_http(struct evbuffer *buf,
|
|||||||
} else if (crlf.pos > (int)max_headerlen)
|
} else if (crlf.pos > (int)max_headerlen)
|
||||||
return -1; /* Headers too long. */
|
return -1; /* Headers too long. */
|
||||||
|
|
||||||
/* Okay, we've found the end of the headers. Pull them into the first
|
|
||||||
* chunk. */
|
|
||||||
/* XXXX Or don't! It would be better to scan for the Content-Length as-is.*/
|
|
||||||
headerlen = crlf.pos + 4;
|
headerlen = crlf.pos + 4;
|
||||||
bodylen = evbuffer_get_length(buf) - headerlen;
|
bodylen = evbuffer_get_length(buf) - headerlen;
|
||||||
if (bodylen > max_bodylen)
|
if (bodylen > max_bodylen)
|
||||||
return -1; /* body too long */
|
return -1; /* body too long */
|
||||||
|
|
||||||
headers = evbuffer_pullup(buf, headerlen);
|
content_length = evbuffer_search_range(buf, CONTENT_LENGTH,
|
||||||
tor_assert(headers && evbuffer_get_contiguous_space(buf) >= headerlen);
|
strlen(CONTENT_LENGTH), NULL, &crlf);
|
||||||
p = (char*) tor_memstr(headers, headerlen, CONTENT_LENGTH);
|
|
||||||
if (p) {
|
if (content_length.pos >= 0) {
|
||||||
int i = atoi(p+strlen(CONTENT_LENGTH));
|
struct evbuffer_ptr eol;
|
||||||
|
char *data = NULL;
|
||||||
|
int free_data = 0;
|
||||||
|
int n, i;
|
||||||
|
n = evbuffer_ptr_set(buf, &content_length, strlen(CONTENT_LENGTH),
|
||||||
|
EVBUFFER_PTR_ADD);
|
||||||
|
tor_assert(n == 0);
|
||||||
|
eol = evbuffer_search_eol(buf, &content_length, NULL, EVBUFFER_EOL_CRLF);
|
||||||
|
tor_assert(eol.pos > content_length.pos);
|
||||||
|
tor_assert(eol.pos <= crlf.pos);
|
||||||
|
inspect_evbuffer(buf, &data, eol.pos - content_length.pos, &free_data,
|
||||||
|
&content_length);
|
||||||
|
|
||||||
|
i = atoi(data);
|
||||||
|
if (free_data)
|
||||||
|
tor_free(data);
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
log_warn(LD_PROTOCOL, "Content-Length is less than zero; it looks like "
|
log_warn(LD_PROTOCOL, "Content-Length is less than zero; it looks like "
|
||||||
"someone is trying to crash us.");
|
"someone is trying to crash us.");
|
||||||
@ -1996,7 +2008,7 @@ peek_evbuffer_has_control0_command(struct evbuffer *buf)
|
|||||||
if (evbuffer_get_length(buf) >= 4) {
|
if (evbuffer_get_length(buf) >= 4) {
|
||||||
int free_out = 0;
|
int free_out = 0;
|
||||||
char *data = NULL;
|
char *data = NULL;
|
||||||
size_t n = inspect_evbuffer(buf, &data, 4, &free_out);
|
size_t n = inspect_evbuffer(buf, &data, 4, &free_out, NULL);
|
||||||
uint16_t cmd;
|
uint16_t cmd;
|
||||||
tor_assert(n >= 4);
|
tor_assert(n >= 4);
|
||||||
cmd = ntohs(get_uint16(data+2));
|
cmd = ntohs(get_uint16(data+2));
|
||||||
|
Loading…
Reference in New Issue
Block a user