- proper identification of header type, prior could mistakenly set the
type by matching the prefix of long header name
- GH #2572
(cherry picked from commit c0f5382bfbd2022896a9b206967977f827517700)
... | ... |
@@ -31,6 +31,16 @@ |
31 | 31 |
#define READ(val) \ |
32 | 32 |
(*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24)) |
33 | 33 |
|
34 |
+#define LW_HNAME_SET(_p, _end, _hnlen, _type, _htype) \ |
|
35 |
+ do { \ |
|
36 |
+ if(_end - _p > _hnlen) { \ |
|
37 |
+ if(_p[_hnlen] == ':' || _p[_hnlen] == ' ') { \ |
|
38 |
+ *_type = _htype; \ |
|
39 |
+ _p += _hnlen; \ |
|
40 |
+ } \ |
|
41 |
+ } \ |
|
42 |
+ } while(0) |
|
43 |
+ |
|
34 | 44 |
/* |
35 | 45 |
* lightweight header field name parser |
36 | 46 |
* used by build_local_reparse() function in order to construct ACK or CANCEL request |
... | ... |
@@ -50,122 +60,111 @@ char *lw_get_hf_name(char *begin, char *end, enum _hdr_types_t *type) |
50 | 60 |
|
51 | 61 |
p = begin; |
52 | 62 |
val = LOWER_DWORD(READ(p)); |
63 |
+ *type = HDR_OTHER_T; |
|
53 | 64 |
|
54 | 65 |
switch(val) { |
55 | 66 |
|
56 | 67 |
case _cseq_: /* Cseq */ |
57 |
- *type = HDR_CSEQ_T; |
|
58 |
- p += 4; |
|
68 |
+ LW_HNAME_SET(p, end, 4, type, HDR_CSEQ_T); |
|
59 | 69 |
break; |
60 | 70 |
|
61 | 71 |
case _via1_: /* Via */ |
62 | 72 |
case _via2_: |
63 |
- *type = HDR_VIA_T; |
|
64 |
- p += 3; |
|
73 |
+ LW_HNAME_SET(p, end, 3, type, HDR_VIA_T); |
|
65 | 74 |
break; |
66 | 75 |
|
67 | 76 |
case _from_: /* From */ |
68 |
- *type = HDR_FROM_T; |
|
69 |
- p += 4; |
|
77 |
+ LW_HNAME_SET(p, end, 4, type, HDR_FROM_T); |
|
70 | 78 |
break; |
71 | 79 |
|
72 | 80 |
case _to12_: /* To */ |
73 |
- *type = HDR_TO_T; |
|
74 |
- p += 2; |
|
81 |
+ LW_HNAME_SET(p, end, 2, type, HDR_TO_T); |
|
75 | 82 |
break; |
76 | 83 |
|
77 | 84 |
case _requ_: /* Require */ |
78 |
- p += 4; |
|
79 |
- val = LOWER_DWORD(READ(p)); |
|
85 |
+ if(end - begin < 8) { |
|
86 |
+ return begin; |
|
87 |
+ } |
|
88 |
+ |
|
89 |
+ val = LOWER_DWORD(READ(p + 4)); |
|
80 | 90 |
|
81 | 91 |
switch(val) { |
82 | 92 |
|
83 | 93 |
case _ire1_: |
84 | 94 |
case _ire2_: |
85 |
- p += 3; |
|
86 |
- *type = HDR_REQUIRE_T; |
|
95 |
+ LW_HNAME_SET(p, end, 7, type, HDR_REQUIRE_T); |
|
87 | 96 |
break; |
88 | 97 |
|
89 | 98 |
default: |
90 |
- p -= 4; |
|
91 | 99 |
*type = HDR_OTHER_T; |
92 | 100 |
break; |
93 | 101 |
} |
94 | 102 |
break; |
95 | 103 |
|
96 | 104 |
case _prox_: /* Proxy-Require */ |
105 |
+ if(end - begin < 14) { |
|
106 |
+ return begin; |
|
107 |
+ } |
|
97 | 108 |
|
98 | 109 |
if((LOWER_DWORD(READ(p + 4)) == _y_re_) |
99 | 110 |
&& (LOWER_DWORD(READ(p + 8)) == _quir_) |
100 | 111 |
&& (LOWER_BYTE(*(p + 12)) == 'e')) { |
101 |
- |
|
102 |
- p += 13; |
|
103 |
- *type = HDR_PROXYREQUIRE_T; |
|
104 |
- break; |
|
105 |
- |
|
106 |
- } else { |
|
107 |
- *type = HDR_OTHER_T; |
|
112 |
+ LW_HNAME_SET(p, end, 13, type, HDR_PROXYREQUIRE_T); |
|
108 | 113 |
break; |
109 | 114 |
} |
115 |
+ break; |
|
110 | 116 |
|
111 | 117 |
case _cont_: /* Content-Length */ |
118 |
+ if(end - begin < 15) { |
|
119 |
+ return begin; |
|
120 |
+ } |
|
112 | 121 |
|
113 | 122 |
if((LOWER_DWORD(READ(p + 4)) == _ent__) |
114 | 123 |
&& (LOWER_DWORD(READ(p + 8)) == _leng_) |
115 | 124 |
&& (LOWER_BYTE(*(p + 12)) == 't') |
116 | 125 |
&& (LOWER_BYTE(*(p + 13)) == 'h')) { |
117 |
- |
|
118 |
- p += 14; |
|
119 |
- *type = HDR_CONTENTLENGTH_T; |
|
120 |
- break; |
|
121 |
- } else { |
|
122 |
- *type = HDR_OTHER_T; |
|
126 |
+ LW_HNAME_SET(p, end, 14, type, HDR_CONTENTLENGTH_T); |
|
123 | 127 |
break; |
124 | 128 |
} |
129 |
+ break; |
|
125 | 130 |
|
126 | 131 |
case _call_: /* Call-Id */ |
132 |
+ if(end - begin < 8) { |
|
133 |
+ return begin; |
|
134 |
+ } |
|
127 | 135 |
|
128 |
- p += 4; |
|
129 |
- val = LOWER_DWORD(READ(p)); |
|
136 |
+ val = LOWER_DWORD(READ(p + 4)); |
|
130 | 137 |
|
131 | 138 |
switch(val) { |
132 |
- |
|
133 | 139 |
case __id1_: |
134 | 140 |
case __id2_: |
135 |
- p += 3; |
|
136 |
- *type = HDR_CALLID_T; |
|
137 |
- break; |
|
138 |
- |
|
139 |
- default: |
|
140 |
- p -= 4; |
|
141 |
- *type = HDR_OTHER_T; |
|
141 |
+ LW_HNAME_SET(p, end, 7, type, HDR_CALLID_T); |
|
142 | 142 |
break; |
143 | 143 |
} |
144 | 144 |
break; |
145 | 145 |
|
146 | 146 |
case _rout_: /* Route */ |
147 |
+ if(end - begin < 6) { |
|
148 |
+ return begin; |
|
149 |
+ } |
|
147 | 150 |
|
148 | 151 |
if(LOWER_BYTE(*(p + 4)) == 'e') { |
149 |
- p += 5; |
|
150 |
- *type = HDR_ROUTE_T; |
|
151 |
- break; |
|
152 |
- } else { |
|
153 |
- *type = HDR_OTHER_T; |
|
152 |
+ LW_HNAME_SET(p, end, 5, type, HDR_ROUTE_T); |
|
154 | 153 |
break; |
155 | 154 |
} |
155 |
+ break; |
|
156 | 156 |
|
157 | 157 |
case _max__: /* Max-Forwards */ |
158 |
+ if(end - begin < 13) { |
|
159 |
+ return begin; |
|
160 |
+ } |
|
158 | 161 |
|
159 | 162 |
if((LOWER_DWORD(READ(p + 4)) == _forw_) |
160 | 163 |
&& (LOWER_DWORD(READ(p + 8)) == _ards_)) { |
161 |
- |
|
162 |
- p += 12; |
|
163 |
- *type = HDR_MAXFORWARDS_T; |
|
164 |
- break; |
|
165 |
- } else { |
|
166 |
- *type = HDR_OTHER_T; |
|
164 |
+ LW_HNAME_SET(p, end, 12, type, HDR_MAXFORWARDS_T); |
|
167 | 165 |
break; |
168 | 166 |
} |
167 |
+ break; |
|
169 | 168 |
|
170 | 169 |
default: |
171 | 170 |
/* compact headers */ |
... | ... |
@@ -177,7 +176,6 @@ char *lw_get_hf_name(char *begin, char *end, enum _hdr_types_t *type) |
177 | 176 |
*type = HDR_VIA_T; |
178 | 177 |
break; |
179 | 178 |
} |
180 |
- *type = HDR_OTHER_T; |
|
181 | 179 |
break; |
182 | 180 |
|
183 | 181 |
case 'f': /* From */ |
... | ... |
@@ -186,7 +184,6 @@ char *lw_get_hf_name(char *begin, char *end, enum _hdr_types_t *type) |
186 | 184 |
*type = HDR_FROM_T; |
187 | 185 |
break; |
188 | 186 |
} |
189 |
- *type = HDR_OTHER_T; |
|
190 | 187 |
break; |
191 | 188 |
|
192 | 189 |
case 't': /* To */ |
... | ... |
@@ -200,7 +197,6 @@ char *lw_get_hf_name(char *begin, char *end, enum _hdr_types_t *type) |
200 | 197 |
*type = HDR_TO_T; |
201 | 198 |
break; |
202 | 199 |
} |
203 |
- *type = HDR_OTHER_T; |
|
204 | 200 |
break; |
205 | 201 |
|
206 | 202 |
case 'l': /* Content-Length */ |
... | ... |
@@ -209,7 +205,6 @@ char *lw_get_hf_name(char *begin, char *end, enum _hdr_types_t *type) |
209 | 205 |
*type = HDR_CONTENTLENGTH_T; |
210 | 206 |
break; |
211 | 207 |
} |
212 |
- *type = HDR_OTHER_T; |
|
213 | 208 |
break; |
214 | 209 |
|
215 | 210 |
case 'i': /* Call-Id */ |
... | ... |
@@ -218,11 +213,6 @@ char *lw_get_hf_name(char *begin, char *end, enum _hdr_types_t *type) |
218 | 213 |
*type = HDR_CALLID_T; |
219 | 214 |
break; |
220 | 215 |
} |
221 |
- *type = HDR_OTHER_T; |
|
222 |
- break; |
|
223 |
- |
|
224 |
- default: |
|
225 |
- *type = HDR_OTHER_T; |
|
226 | 216 |
break; |
227 | 217 |
} |
228 | 218 |
} |