Don't assert() on whitespace in URL.

Be lenient about tabs and form feeds in non-strict mode.
v0.10
Ben Noordhuis 13 years ago
parent 8bec3ea459
commit b97fdb0513

@ -184,11 +184,18 @@ static const int8_t unhex[256] =
}; };
#if HTTP_PARSER_STRICT
# define T 0
#else
# define T 1
#endif
static const uint8_t normal_url_char[256] = { static const uint8_t normal_url_char[256] = {
/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ /* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ /* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */
0, 0, 0, 0, 0, 0, 0, 0, 0, T, 0, 0, T, 0, 0, 0,
/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ /* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ /* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */
@ -218,6 +225,7 @@ static const uint8_t normal_url_char[256] = {
/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ /* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */
1, 1, 1, 1, 1, 1, 1, 0, }; 1, 1, 1, 1, 1, 1, 1, 0, };
#undef T
enum state enum state
{ s_dead = 1 /* important that this is > 0 */ { s_dead = 1 /* important that this is > 0 */
@ -396,7 +404,15 @@ int http_message_needs_eof(http_parser *parser);
static enum state static enum state
parse_url_char(enum state s, const char ch) parse_url_char(enum state s, const char ch)
{ {
assert(!isspace(ch)); if (ch == ' ' || ch == '\r' || ch == '\n') {
return s_dead;
}
#if HTTP_PARSER_STRICT
if (ch == '\t' || ch == '\f') {
return s_dead;
}
#endif
switch (s) { switch (s) {
case s_req_spaces_before_url: case s_req_spaces_before_url:

@ -2072,6 +2072,68 @@ const struct url_test url_tests[] =
,.is_connect=1 ,.is_connect=1
,.rv=1 ,.rv=1
} }
, {.name="space in URL"
,.url="/foo bar/"
,.rv=1 /* s_dead */
}
, {.name="carriage return in URL"
,.url="/foo\rbar/"
,.rv=1 /* s_dead */
}
, {.name="line feed in URL"
,.url="/foo\nbar/"
,.rv=1 /* s_dead */
}
#if HTTP_PARSER_STRICT
, {.name="tab in URL"
,.url="/foo\tbar/"
,.rv=1 /* s_dead */
}
, {.name="form feed in URL"
,.url="/foo\fbar/"
,.rv=1 /* s_dead */
}
#else /* !HTTP_PARSER_STRICT */
, {.name="tab in URL"
,.url="/foo\tbar/"
,.u=
{.field_set=(1 << UF_PATH)
,.field_data=
{{ 0, 0 } /* UF_SCHEMA */
,{ 0, 0 } /* UF_HOST */
,{ 0, 0 } /* UF_PORT */
,{ 0, 9 } /* UF_PATH */
,{ 0, 0 } /* UF_QUERY */
,{ 0, 0 } /* UF_FRAGMENT */
}
}
,.rv=0
}
, {.name="form feed in URL"
,.url="/foo\fbar/"
,.u=
{.field_set=(1 << UF_PATH)
,.field_data=
{{ 0, 0 } /* UF_SCHEMA */
,{ 0, 0 } /* UF_HOST */
,{ 0, 0 } /* UF_PORT */
,{ 0, 9 } /* UF_PATH */
,{ 0, 0 } /* UF_QUERY */
,{ 0, 0 } /* UF_FRAGMENT */
}
}
,.rv=0
}
#endif
}; };
void void

Loading…
Cancel
Save