| CODENOTIFIER | HelpYou are not signed inSign in |
Project: lighttpd
Revision: 2269
Author: stbuehler
Date: 01 Aug 2008 07:19:30
Changes:Fix #1555: HTTP Request/Response only accept complete headers, i.e. ended with double CRLF
Files:| ... | ...@@ -263,6 +263,11 @@ | |
| 263 | 263 | t.last_token_id = token_id; |
| 264 | 264 | } |
| 265 | 265 | |
| 266 | // Tokenizer failed | |
| 267 | if (parser_ret == PARSER_ERROR) { | |
| 268 | ret = PARSE_ERROR; | |
| 269 | } | |
| 270 | ||
| 266 | 271 | /* oops, the parser failed */ |
| 267 | 272 | if (context.ok == 0) { |
| 268 | 273 | ret = PARSE_ERROR; |
| ... | ...@@ -300,6 +305,8 @@ | |
| 300 | 305 | if (ret == PARSE_UNSET) { |
| 301 | 306 | ret = buffer_is_empty(context.errmsg) ? PARSE_NEED_MORE : PARSE_ERROR; |
| 302 | 307 | } |
| 308 | } else if (parser_ret == PARSER_EOF) { // didn't see CRLF CRLF, no other error till now | |
| 309 | ret = PARSE_NEED_MORE; | |
| 303 | 310 | } else { |
| 304 | 311 | chunk *c; |
| 305 | 312 |
| ... | ...@@ -94,8 +94,14 @@ | |
| 94 | 94 | return 0; |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | typedef enum { | |
| 98 | PARSER_UNSET, | |
| 99 | PARSER_OK, | |
| 100 | PARSER_ERROR, | |
| 101 | PARSER_EOF | |
| 102 | } http_resp_parser_t; | |
| 97 | 103 | |
| 98 | static int http_resp_tokenizer( | |
| 104 | static http_resp_parser_t http_resp_tokenizer( | |
| 99 | 105 | http_resp_tokenizer_t *t, |
| 100 | 106 | int *token_id, |
| 101 | 107 | buffer *token |
| ... | ...@@ -130,8 +136,8 @@ | |
| 130 | 136 | t->is_statusline = 0; |
| 131 | 137 | t->is_key = 1; |
| 132 | 138 | } else { |
| 133 | fprintf(stderr, "%s.%d: CR with out LF\r\n", __FILE__, __LINE__); | |
| 134 | return -1; | |
| 139 | ERROR("CR with out LF at pos: %zu", t->offset); | |
| 140 | return PARSER_ERROR; | |
| 135 | 141 | } |
| 136 | 142 | break; |
| 137 | 143 | case '\n': |
| ... | ...@@ -151,14 +157,14 @@ | |
| 151 | 157 | if (c == ':') break; /* the : is the splitter between key and value */ |
| 152 | 158 | } |
| 153 | 159 | } |
| 154 | if (0 != http_resp_lookup_next_char(t, &c)) return -1; | |
| 160 | if (0 != http_resp_lookup_next_char(t, &c)) return PARSER_EOF; | |
| 155 | 161 | } |
| 156 | 162 | |
| 157 | 163 | if (t->c == t->lookup_c && |
| 158 | 164 | t->offset == t->lookup_offset + 1) { |
| 159 | 165 | |
| 160 | fprintf(stderr, "%s.%d: invalid char in string\n", __FILE__, __LINE__); | |
| 161 | return -1; | |
| 166 | ERROR("invalid char (%d) at pos: %zu", c, t->offset); | |
| 167 | return PARSER_ERROR; | |
| 162 | 168 | } |
| 163 | 169 | |
| 164 | 170 | tid = TK_STRING; |
| ... | ...@@ -192,10 +198,10 @@ | |
| 192 | 198 | if (tid) { |
| 193 | 199 | *token_id = tid; |
| 194 | 200 | |
| 195 | return 1; | |
| 201 | return PARSER_OK; | |
| 196 | 202 | } |
| 197 | 203 | |
| 198 | return -1; | |
| 204 | return PARSER_EOF; | |
| 199 | 205 | } |
| 200 | 206 | |
| 201 | 207 | parse_status_t http_response_parse_cq(chunkqueue *cq, http_resp *resp) { |
| ... | ...@@ -205,6 +211,7 @@ | |
| 205 | 211 | buffer *token = NULL; |
| 206 | 212 | http_resp_ctx_t context; |
| 207 | 213 | parse_status_t ret = PARSE_UNSET; |
| 214 | http_resp_parser_t parser_ret; | |
| 208 | 215 | int last_token_id = 0; |
| 209 | 216 | |
| 210 | 217 | if(!cq->first) return PARSE_NEED_MORE; |
| ... | ...@@ -228,7 +235,7 @@ | |
| 228 | 235 | http_resp_parserTrace(stderr, "http-response: "); |
| 229 | 236 | #endif |
| 230 | 237 | |
| 231 | while((1 == http_resp_tokenizer(&t, &token_id, token)) && context.ok) { | |
| 238 | while((PARSER_OK == (parser_ret = http_resp_tokenizer(&t, &token_id, token))) && context.ok) { | |
| 232 | 239 | http_resp_parser(pParser, token_id, token, &context); |
| 233 | 240 | |
| 234 | 241 | token = buffer_pool_get(context.unused_buffers); |
| ... | ...@@ -240,6 +247,11 @@ | |
| 240 | 247 | last_token_id = token_id; |
| 241 | 248 | } |
| 242 | 249 | |
| 250 | // Tokenizer failed | |
| 251 | if (parser_ret == PARSER_ERROR) { | |
| 252 | ret = PARSE_ERROR; | |
| 253 | } | |
| 254 | ||
| 243 | 255 | /* oops, the parser failed */ |
| 244 | 256 | if (context.ok == 0) { |
| 245 | 257 | ret = PARSE_ERROR; |
| ... | ...@@ -267,6 +279,8 @@ | |
| 267 | 279 | if (ret == PARSE_UNSET) { |
| 268 | 280 | ret = buffer_is_empty(context.errmsg) ? PARSE_NEED_MORE : PARSE_ERROR; |
| 269 | 281 | } |
| 282 | } else if (parser_ret == PARSER_EOF) { // didn't see CRLF CRLF, no other error till now | |
| 283 | ret = PARSE_NEED_MORE; | |
| 270 | 284 | } else { |
| 271 | 285 | chunk *c; |
| 272 | 286 |
| ... | ...@@ -572,7 +572,7 @@ | |
| 572 | 572 | /* (re)initialize the parser, if necessary */ |
| 573 | 573 | yypParser = (yyParser*)yyp; |
| 574 | 574 | if( yypParser->yyidx<0 ){ |
| 575 | if( yymajor==0 ) return; | |
| 575 | if( yymajor==0 ) return; /* Accept empty input */ | |
| 576 | 576 | yypParser->yyidx = 0; |
| 577 | 577 | yypParser->yyerrcnt = -1; |
| 578 | 578 | yypParser->yystack[0].stateno = 0; |
| ... | ...@@ -51,6 +51,7 @@ | |
| 51 | 51 | * case insensitive match for secdownload md5 token (#1710) |
| 52 | 52 | * handle only HEAD, GET and POST in mod_dirlisting (same as in staticfile) (#1687) |
| 53 | 53 | * fixed mod_webdav, litmus now passes everything except locks (#1738) |
| 54 | * fixed #1555: HTTP Request/Response only accept complete headers, i.e. ended with double CRLF | |
| 54 | 55 | |
| 55 | 56 | - 1.5.0-r19.. - |
| 56 | 57 | * -F option added for spawn-fcgi |