Commit 6aef05cf7f75a53bab2b4107b5ba06a16e834275

Authored by Georg Hopp
1 parent 4a075de8

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.
  1 +2012-02-10 06:22:39 +0100 Georg Hopp
  2 +
  3 + * fix rather nasty reentrance bug (HEAD, master)
  4 +
1 5 2012-02-10 05:52:50 +0100 Georg Hopp
2 6
3   - * 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)
  7 + * 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
4 8
5 9 2012-02-10 00:27:51 +0100 Georg Hopp
6 10
... ...
... ... @@ -17,10 +17,14 @@ typedef enum e_HttpRequestState {
17 17
18 18 CLASS(HttpRequestParser) {
19 19 char * buffer;
  20 + char * cur_data;
  21 +
20 22 size_t buffer_used;
21 23 size_t buffer_size;
22 24
23 25 HttpRequestQueue request_queue;
  26 + HttpRequest cur_request;
  27 +
24 28 HttpRequestState state;
25 29 };
26 30
... ...
... ... @@ -7,8 +7,8 @@
7 7 #include "interface/class.h"
8 8
9 9
10   -#define REMAINS(pars,done) \
11   - ((pars)->buffer_used - ((done) - (pars)->buffer))
  10 +#define REMAINS(pars) \
  11 + ((pars)->buffer_used - ((pars)->cur_data - (pars)->buffer))
12 12
13 13
14 14 static
... ... @@ -43,34 +43,32 @@ void httpRequestParserGetHeader(HttpRequest, char *);
43 43 void
44 44 httpRequestParserParse(HttpRequestParser this)
45 45 {
46   - static HttpRequest request = NULL;
47   - static char * data; // static pointer to unprocessed data
48 46 char * line;
49 47 int cont = 1;
50 48
51 49 while(cont) {
52 50 switch(this->state) {
53 51 case HTTP_REQUEST_GARBAGE:
54   - data = this->buffer; // initialize static pointer
55   - httpRequestSkip(&data);
56   - request = new(HttpRequest);
  52 + this->cur_data = this->buffer; // initialize static pointer
  53 + httpRequestSkip(&(this->cur_data));
  54 + this->cur_request = new(HttpRequest);
57 55
58 56 this->state = HTTP_REQUEST_START;
59 57 break;
60 58
61 59 case HTTP_REQUEST_START:
62   - if (NULL == (line = httpRequestParserGetLine(&data))) {
  60 + if (NULL == (line = httpRequestParserGetLine(&(this->cur_data)))) {
63 61 cont = 0;
64 62 break;
65 63 }
66 64
67   - httpRequestParserGetRequestLine(request, line);
  65 + httpRequestParserGetRequestLine(this->cur_request, line);
68 66
69 67 this->state = HTTP_REQUEST_REQUEST_LINE_DONE;
70 68 break;
71 69
72 70 case HTTP_REQUEST_REQUEST_LINE_DONE:
73   - if (NULL == (line = httpRequestParserGetLine(&data))) {
  71 + if (NULL == (line = httpRequestParserGetLine(&(this->cur_data)))) {
74 72 cont = 0;
75 73 break;
76 74 }
... ... @@ -80,19 +78,19 @@ httpRequestParserParse(HttpRequestParser this)
80 78 break;
81 79 }
82 80
83   - httpRequestParserGetHeader(request, line);
  81 + httpRequestParserGetHeader(this->cur_request, line);
84 82 break;
85 83
86 84 case HTTP_REQUEST_HEADERS_DONE:
87   - httpHeaderSort(request->header, request->nheader);
  85 + httpHeaderSort(this->cur_request->header, this->cur_request->nheader);
88 86
89 87 {
90 88 char * nbody;
91 89
92   - if (0 == request->nbody) {
  90 + if (0 == this->cur_request->nbody) {
93 91 nbody = httpHeaderGet(
94   - request->header,
95   - request->nheader,
  92 + this->cur_request->header,
  93 + this->cur_request->nheader,
96 94 "Content-Length");
97 95
98 96 if (NULL == nbody) {
... ... @@ -100,14 +98,16 @@ httpRequestParserParse(HttpRequestParser this)
100 98 break;
101 99 }
102 100 else {
103   - request->nbody = atoi(nbody);
  101 + this->cur_request->nbody = atoi(nbody);
104 102 }
105 103 }
106 104
107   - if (REMAINS(this, data) >= request->nbody) {
108   - request->body = calloc(1, request->nbody + 1);
109   - memcpy(request->body, data, request->nbody);
110   - data += request->nbody;
  105 + if (REMAINS(this) >= this->cur_request->nbody) {
  106 + this->cur_request->body = calloc(1, this->cur_request->nbody + 1);
  107 + memcpy(this->cur_request->body,
  108 + this->cur_data,
  109 + this->cur_request->nbody);
  110 + this->cur_data += this->cur_request->nbody;
111 111 this->state = HTTP_REQUEST_DONE;
112 112 }
113 113 }
... ... @@ -119,14 +119,14 @@ httpRequestParserParse(HttpRequestParser this)
119 119 * enqueue current request
120 120 */
121 121 this->request_queue->requests[(this->request_queue->nrequests)++] =
122   - request;
  122 + this->cur_request;
123 123
124 124 /**
125 125 * remove processed stuff from input buffer.
126 126 */
127   - memmove(this->buffer, data, REMAINS(this, data));
  127 + memmove(this->buffer, this->cur_data, REMAINS(this));
128 128
129   - this->buffer_used -= data - this->buffer;
  129 + this->buffer_used -= this->cur_data - this->buffer;
130 130
131 131 /**
132 132 * dont continue loop if input buffer is empty
... ...
Please register or login to post a comment