Mercurial > hg > nginx-vendor-0-7
comparison src/http/ngx_http_parse.c @ 500:ed3d382670c7 NGINX_0_7_62
nginx 0.7.62
*) Security: a segmentation fault might occur in worker process while
specially crafted request handling.
Thanks to Chris Ries.
*) Feature: the $upstream_cache_status variable.
*) Bugfix: an expired cached response might stick in the "UPDATING"
state.
*) Bugfix: a segmentation fault might occur in worker process, if
error_log was set to info or debug level.
Thanks to Sergey Bochenkov.
*) Bugfix: in handling FastCGI headers split in records.
*) Bugfix: XSLT filter may fail with message "not well formed XML
document" for valid XML document.
Thanks to Kuramoto Eiji.
*) Bugfix: now in MacOSX, Cygwin, and nginx/Windows locations given by
a regular expression are always tested in case insensitive mode.
*) Bugfix: now nginx/Windows ignores trailing dots in URI.
Thanks to Hugo Leisink.
*) Bugfix: name of file specified in --conf-path was not honored during
installation; the bug had appeared in 0.6.6.
Thanks to Maxim Dounin.
*) Bugfix: a 500 error code was returned for invalid login/password
while HTTP Basic authentication on Windows.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 14 Sep 2009 00:00:00 +0400 |
parents | 392c16f2d858 |
children | 89dc5654117c |
comparison
equal
deleted
inserted
replaced
499:f2c782e5161f | 500:ed3d382670c7 |
---|---|
737 | 737 |
738 switch (state) { | 738 switch (state) { |
739 | 739 |
740 /* first char */ | 740 /* first char */ |
741 case sw_start: | 741 case sw_start: |
742 r->header_name_start = p; | |
742 r->invalid_header = 0; | 743 r->invalid_header = 0; |
743 | 744 |
744 switch (ch) { | 745 switch (ch) { |
745 case CR: | 746 case CR: |
746 r->header_end = p; | 747 r->header_end = p; |
749 case LF: | 750 case LF: |
750 r->header_end = p; | 751 r->header_end = p; |
751 goto header_done; | 752 goto header_done; |
752 default: | 753 default: |
753 state = sw_name; | 754 state = sw_name; |
754 r->header_name_start = p; | |
755 | 755 |
756 c = lowcase[ch]; | 756 c = lowcase[ch]; |
757 | 757 |
758 if (c) { | 758 if (c) { |
759 hash = ngx_hash(0, c); | 759 hash = ngx_hash(0, c); |
948 enum { | 948 enum { |
949 sw_usual = 0, | 949 sw_usual = 0, |
950 sw_slash, | 950 sw_slash, |
951 sw_dot, | 951 sw_dot, |
952 sw_dot_dot, | 952 sw_dot_dot, |
953 #if (NGX_WIN32) | |
954 sw_dot_dot_dot, | |
955 #endif | |
956 sw_quoted, | 953 sw_quoted, |
957 sw_quoted_second | 954 sw_quoted_second |
958 } state, quoted_state; | 955 } state, quoted_state; |
959 | 956 |
960 #if (NGX_SUPPRESS_WARN) | 957 #if (NGX_SUPPRESS_WARN) |
1135 #if (NGX_WIN32) | 1132 #if (NGX_WIN32) |
1136 case '\\': | 1133 case '\\': |
1137 #endif | 1134 #endif |
1138 case '/': | 1135 case '/': |
1139 state = sw_slash; | 1136 state = sw_slash; |
1140 u -= 4; | 1137 u -= 5; |
1141 if (u < r->uri.data) { | 1138 for ( ;; ) { |
1142 return NGX_HTTP_PARSE_INVALID_REQUEST; | 1139 if (u < r->uri.data) { |
1143 } | 1140 return NGX_HTTP_PARSE_INVALID_REQUEST; |
1144 while (*(u - 1) != '/') { | 1141 } |
1142 if (*u == '/') { | |
1143 u++; | |
1144 break; | |
1145 } | |
1145 u--; | 1146 u--; |
1146 } | 1147 } |
1147 break; | 1148 break; |
1148 case '%': | 1149 case '%': |
1149 quoted_state = state; | 1150 quoted_state = state; |
1152 case '?': | 1153 case '?': |
1153 r->args_start = p; | 1154 r->args_start = p; |
1154 goto args; | 1155 goto args; |
1155 case '#': | 1156 case '#': |
1156 goto done; | 1157 goto done; |
1157 #if (NGX_WIN32) | |
1158 case '.': | |
1159 state = sw_dot_dot_dot; | |
1160 *u++ = ch; | |
1161 break; | |
1162 #endif | |
1163 case '+': | 1158 case '+': |
1164 r->plus_in_uri = 1; | 1159 r->plus_in_uri = 1; |
1165 default: | 1160 default: |
1166 state = sw_usual; | 1161 state = sw_usual; |
1167 *u++ = ch; | 1162 *u++ = ch; |
1168 break; | 1163 break; |
1169 } | 1164 } |
1170 | 1165 |
1171 ch = *p++; | 1166 ch = *p++; |
1172 break; | 1167 break; |
1173 | |
1174 #if (NGX_WIN32) | |
1175 case sw_dot_dot_dot: | |
1176 | |
1177 if (usual[ch >> 5] & (1 << (ch & 0x1f))) { | |
1178 state = sw_usual; | |
1179 *u++ = ch; | |
1180 ch = *p++; | |
1181 break; | |
1182 } | |
1183 | |
1184 switch(ch) { | |
1185 case '\\': | |
1186 case '/': | |
1187 state = sw_slash; | |
1188 u -= 5; | |
1189 if (u < r->uri.data) { | |
1190 return NGX_HTTP_PARSE_INVALID_REQUEST; | |
1191 } | |
1192 while (*u != '/') { | |
1193 u--; | |
1194 } | |
1195 if (u < r->uri.data) { | |
1196 return NGX_HTTP_PARSE_INVALID_REQUEST; | |
1197 } | |
1198 while (*(u - 1) != '/') { | |
1199 u--; | |
1200 } | |
1201 break; | |
1202 case '%': | |
1203 quoted_state = state; | |
1204 state = sw_quoted; | |
1205 break; | |
1206 case '?': | |
1207 r->args_start = p; | |
1208 goto args; | |
1209 case '#': | |
1210 goto done; | |
1211 case '+': | |
1212 r->plus_in_uri = 1; | |
1213 default: | |
1214 state = sw_usual; | |
1215 *u++ = ch; | |
1216 break; | |
1217 } | |
1218 | |
1219 ch = *p++; | |
1220 break; | |
1221 #endif | |
1222 | 1168 |
1223 case sw_quoted: | 1169 case sw_quoted: |
1224 r->quoted_uri = 1; | 1170 r->quoted_uri = 1; |
1225 | 1171 |
1226 if (ch >= '0' && ch <= '9') { | 1172 if (ch >= '0' && ch <= '9') { |
1367 /* detect "/../" */ | 1313 /* detect "/../" */ |
1368 | 1314 |
1369 if (p[0] == '.' && p[1] == '.' && ngx_path_separator(p[2])) { | 1315 if (p[0] == '.' && p[1] == '.' && ngx_path_separator(p[2])) { |
1370 goto unsafe; | 1316 goto unsafe; |
1371 } | 1317 } |
1372 | |
1373 #if (NGX_WIN32) | |
1374 | |
1375 if (len > 3) { | |
1376 | |
1377 /* detect "/.../" */ | |
1378 | |
1379 if (p[0] == '.' && p[1] == '.' && p[2] == '.' | |
1380 && ngx_path_separator(p[3])) | |
1381 { | |
1382 goto unsafe; | |
1383 } | |
1384 } | |
1385 #endif | |
1386 } | 1318 } |
1387 } | 1319 } |
1388 | 1320 |
1389 return NGX_OK; | 1321 return NGX_OK; |
1390 | 1322 |