From 6aef05cf7f75a53bab2b4107b5ba06a16e834275 Mon Sep 17 00:00:00 2001 From: Georg Hopp Date: Fri, 10 Feb 2012 06:22:39 +0100 Subject: [PATCH] fix rather nasty reentrance bug as i first wrote the parser i used static valiables to hold the state of the currently parsed request. If a request would spread of multiple reads this would lead to one reqeust messing up the state of another. not those states are part of the parser object itself where they belong. --- ChangeLog | 6 ++++- include/http/request_parser.h | 4 +++ src/http/request/parser/parse.c | 46 ++++++++++++++++----------------- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/ChangeLog b/ChangeLog index d3ee9dc..8d19814 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,10 @@ +2012-02-10 06:22:39 +0100 Georg Hopp + + * fix rather nasty reentrance bug (HEAD, master) + 2012-02-10 05:52:50 +0100 Georg Hopp - * fix bug that arose in rewrite of header get and results in an ugly memory leak, as well as no headers would be found any more (HEAD, master) + * fix bug that arose in rewrite of header get and results in an ugly memory leak, as well as no headers would be found any more 2012-02-10 00:27:51 +0100 Georg Hopp diff --git a/include/http/request_parser.h b/include/http/request_parser.h index 089a9a4..ef24139 100644 --- a/include/http/request_parser.h +++ b/include/http/request_parser.h @@ -17,10 +17,14 @@ typedef enum e_HttpRequestState { CLASS(HttpRequestParser) { char * buffer; + char * cur_data; + size_t buffer_used; size_t buffer_size; HttpRequestQueue request_queue; + HttpRequest cur_request; + HttpRequestState state; }; diff --git a/src/http/request/parser/parse.c b/src/http/request/parser/parse.c index 8b5f39f..79884eb 100644 --- a/src/http/request/parser/parse.c +++ b/src/http/request/parser/parse.c @@ -7,8 +7,8 @@ #include "interface/class.h" -#define REMAINS(pars,done) \ - ((pars)->buffer_used - ((done) - (pars)->buffer)) +#define REMAINS(pars) \ + ((pars)->buffer_used - ((pars)->cur_data - (pars)->buffer)) static @@ -43,34 +43,32 @@ void httpRequestParserGetHeader(HttpRequest, char *); void httpRequestParserParse(HttpRequestParser this) { - static HttpRequest request = NULL; - static char * data; // static pointer to unprocessed data char * line; int cont = 1; while(cont) { switch(this->state) { case HTTP_REQUEST_GARBAGE: - data = this->buffer; // initialize static pointer - httpRequestSkip(&data); - request = new(HttpRequest); + this->cur_data = this->buffer; // initialize static pointer + httpRequestSkip(&(this->cur_data)); + this->cur_request = new(HttpRequest); this->state = HTTP_REQUEST_START; break; case HTTP_REQUEST_START: - if (NULL == (line = httpRequestParserGetLine(&data))) { + if (NULL == (line = httpRequestParserGetLine(&(this->cur_data)))) { cont = 0; break; } - httpRequestParserGetRequestLine(request, line); + httpRequestParserGetRequestLine(this->cur_request, line); this->state = HTTP_REQUEST_REQUEST_LINE_DONE; break; case HTTP_REQUEST_REQUEST_LINE_DONE: - if (NULL == (line = httpRequestParserGetLine(&data))) { + if (NULL == (line = httpRequestParserGetLine(&(this->cur_data)))) { cont = 0; break; } @@ -80,19 +78,19 @@ httpRequestParserParse(HttpRequestParser this) break; } - httpRequestParserGetHeader(request, line); + httpRequestParserGetHeader(this->cur_request, line); break; case HTTP_REQUEST_HEADERS_DONE: - httpHeaderSort(request->header, request->nheader); + httpHeaderSort(this->cur_request->header, this->cur_request->nheader); { char * nbody; - if (0 == request->nbody) { + if (0 == this->cur_request->nbody) { nbody = httpHeaderGet( - request->header, - request->nheader, + this->cur_request->header, + this->cur_request->nheader, "Content-Length"); if (NULL == nbody) { @@ -100,14 +98,16 @@ httpRequestParserParse(HttpRequestParser this) break; } else { - request->nbody = atoi(nbody); + this->cur_request->nbody = atoi(nbody); } } - if (REMAINS(this, data) >= request->nbody) { - request->body = calloc(1, request->nbody + 1); - memcpy(request->body, data, request->nbody); - data += request->nbody; + if (REMAINS(this) >= this->cur_request->nbody) { + this->cur_request->body = calloc(1, this->cur_request->nbody + 1); + memcpy(this->cur_request->body, + this->cur_data, + this->cur_request->nbody); + this->cur_data += this->cur_request->nbody; this->state = HTTP_REQUEST_DONE; } } @@ -119,14 +119,14 @@ httpRequestParserParse(HttpRequestParser this) * enqueue current request */ this->request_queue->requests[(this->request_queue->nrequests)++] = - request; + this->cur_request; /** * remove processed stuff from input buffer. */ - memmove(this->buffer, data, REMAINS(this, data)); + memmove(this->buffer, this->cur_data, REMAINS(this)); - this->buffer_used -= data - this->buffer; + this->buffer_used -= this->cur_data - this->buffer; /** * dont continue loop if input buffer is empty