Correctly error out on non-zero return values.

version0.2
Ryan 16 years ago
parent 900815228c
commit cc5c9b037c

@ -71,7 +71,7 @@ struct http_parser {
size_t chunk_size; size_t chunk_size;
unsigned eating:1; unsigned eating:1;
unsigned buffer_overflow:1; unsigned error:1;
size_t body_read; size_t body_read;
const char *header_field_mark; const char *header_field_mark;

@ -48,7 +48,7 @@ do { \
if (parser->FOR##_mark) { \ if (parser->FOR##_mark) { \
parser->FOR##_size += p - parser->FOR##_mark; \ parser->FOR##_size += p - parser->FOR##_mark; \
if (parser->FOR##_size > MAX_FIELD_SIZE) { \ if (parser->FOR##_size > MAX_FIELD_SIZE) { \
parser->buffer_overflow = TRUE; \ parser->error = TRUE; \
return 0; \ return 0; \
} \ } \
if (parser->on_##FOR) { \ if (parser->on_##FOR) { \
@ -142,42 +142,60 @@ do { \
action header_field { action header_field {
CALLBACK(header_field); CALLBACK(header_field);
if (callback_return_value != 0) fbreak; if (callback_return_value != 0) {
parser->error = TRUE;
return 0;
}
parser->header_field_mark = NULL; parser->header_field_mark = NULL;
parser->header_field_size = 0; parser->header_field_size = 0;
} }
action header_value { action header_value {
CALLBACK(header_value); CALLBACK(header_value);
if (callback_return_value != 0) fbreak; if (callback_return_value != 0) {
parser->error = TRUE;
return 0;
}
parser->header_value_mark = NULL; parser->header_value_mark = NULL;
parser->header_value_size = 0; parser->header_value_size = 0;
} }
action request_uri { action request_uri {
CALLBACK(uri); CALLBACK(uri);
if (callback_return_value != 0) fbreak; if (callback_return_value != 0) {
parser->error = TRUE;
return 0;
}
parser->uri_mark = NULL; parser->uri_mark = NULL;
parser->uri_size = 0; parser->uri_size = 0;
} }
action fragment { action fragment {
CALLBACK(fragment); CALLBACK(fragment);
if (callback_return_value != 0) fbreak; if (callback_return_value != 0) {
parser->error = TRUE;
return 0;
}
parser->fragment_mark = NULL; parser->fragment_mark = NULL;
parser->fragment_size = 0; parser->fragment_size = 0;
} }
action query_string { action query_string {
CALLBACK(query_string); CALLBACK(query_string);
if (callback_return_value != 0) fbreak; if (callback_return_value != 0) {
parser->error = TRUE;
return 0;
}
parser->query_string_mark = NULL; parser->query_string_mark = NULL;
parser->query_string_size = 0; parser->query_string_size = 0;
} }
action request_path { action request_path {
CALLBACK(path); CALLBACK(path);
if (callback_return_value != 0) fbreak; if (callback_return_value != 0) {
parser->error = TRUE;
return 0;
}
parser->path_mark = NULL; parser->path_mark = NULL;
parser->path_size = 0; parser->path_size = 0;
} }
@ -185,20 +203,26 @@ do { \
action headers_complete { action headers_complete {
if(parser->on_headers_complete) { if(parser->on_headers_complete) {
callback_return_value = parser->on_headers_complete(parser); callback_return_value = parser->on_headers_complete(parser);
if (callback_return_value != 0) fbreak; if (callback_return_value != 0) {
parser->error = TRUE;
return 0;
}
} }
} }
action begin_message { action begin_message {
if(parser->on_message_begin) { if(parser->on_message_begin) {
callback_return_value = parser->on_message_begin(parser); callback_return_value = parser->on_message_begin(parser);
if (callback_return_value != 0) fbreak; if (callback_return_value != 0) {
parser->error = TRUE;
return 0;
}
} }
} }
action content_length { action content_length {
if (parser->content_length > INT_MAX) { if (parser->content_length > INT_MAX) {
parser->buffer_overflow = TRUE; parser->error = TRUE;
return 0; return 0;
} }
parser->content_length *= 10; parser->content_length *= 10;
@ -233,7 +257,10 @@ do { \
action skip_chunk_data { action skip_chunk_data {
SKIP_BODY(MIN(parser->chunk_size, REMAINING)); SKIP_BODY(MIN(parser->chunk_size, REMAINING));
if (callback_return_value != 0) fbreak; if (callback_return_value != 0) {
parser->error = TRUE;
return 0;
}
fhold; fhold;
if (parser->chunk_size > REMAINING) { if (parser->chunk_size > REMAINING) {
@ -261,7 +288,11 @@ do { \
p += 1; p += 1;
SKIP_BODY(MIN(REMAINING, parser->content_length)); SKIP_BODY(MIN(REMAINING, parser->content_length));
if (callback_return_value != 0) fbreak;
if (callback_return_value != 0) {
parser->error = TRUE;
return 0;
}
fhold; fhold;
if(parser->chunk_size > REMAINING) { if(parser->chunk_size > REMAINING) {
@ -390,7 +421,7 @@ http_parser_init (http_parser *parser, enum http_parser_type type)
%% write init; %% write init;
parser->cs = cs; parser->cs = cs;
parser->type = type; parser->type = type;
parser->buffer_overflow = 0; parser->error = 0;
parser->on_message_begin = NULL; parser->on_message_begin = NULL;
parser->on_path = NULL; parser->on_path = NULL;
@ -420,7 +451,10 @@ http_parser_execute (http_parser *parser, const char *buffer, size_t len)
if (0 < parser->chunk_size && parser->eating) { if (0 < parser->chunk_size && parser->eating) {
/* eat body */ /* eat body */
SKIP_BODY(MIN(len, parser->chunk_size)); SKIP_BODY(MIN(len, parser->chunk_size));
if (callback_return_value != 0) goto out; if (callback_return_value != 0) {
parser->error = TRUE;
return 0;
}
} }
if (parser->header_field_mark) parser->header_field_mark = buffer; if (parser->header_field_mark) parser->header_field_mark = buffer;
@ -441,7 +475,6 @@ http_parser_execute (http_parser *parser, const char *buffer, size_t len)
CALLBACK(path); CALLBACK(path);
CALLBACK(uri); CALLBACK(uri);
out:
assert(p <= pe && "buffer overflow after parsing execute"); assert(p <= pe && "buffer overflow after parsing execute");
return(p - buffer); return(p - buffer);
} }
@ -449,7 +482,7 @@ out:
int int
http_parser_has_error (http_parser *parser) http_parser_has_error (http_parser *parser)
{ {
if (parser->buffer_overflow) return TRUE; if (parser->error) return TRUE;
return parser->cs == http_parser_error; return parser->cs == http_parser_error;
} }

Loading…
Cancel
Save