Mercurial > hg > nginx
comparison src/http/ngx_http_spdy.c @ 5323:2be1a9ce9d8e
SPDY: fixed corruption of headers with names longer than 255.
It is a bad idea to put zero byte in position where the length of
the next header name can be stored before it was parsed.
author | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Thu, 15 Aug 2013 19:14:58 +0400 |
parents | 7542b72fe4b1 |
children | 8ef1722143dc |
comparison
equal
deleted
inserted
replaced
5322:bdb3588681c9 | 5323:2be1a9ce9d8e |
---|---|
807 buf = r->header_in; | 807 buf = r->header_in; |
808 | 808 |
809 sc->zstream_in.next_in = pos; | 809 sc->zstream_in.next_in = pos; |
810 sc->zstream_in.avail_in = size; | 810 sc->zstream_in.avail_in = size; |
811 sc->zstream_in.next_out = buf->last; | 811 sc->zstream_in.next_out = buf->last; |
812 | |
813 /* one byte is reserved for null-termination of the last header value */ | |
812 sc->zstream_in.avail_out = buf->end - buf->last - 1; | 814 sc->zstream_in.avail_out = buf->end - buf->last - 1; |
813 | 815 |
814 z = inflate(&sc->zstream_in, Z_NO_FLUSH); | 816 z = inflate(&sc->zstream_in, Z_NO_FLUSH); |
815 | 817 |
816 if (z == Z_NEED_DICT) { | 818 if (z == Z_NEED_DICT) { |
910 ngx_http_spdy_close_stream(sc->stream, | 912 ngx_http_spdy_close_stream(sc->stream, |
911 NGX_HTTP_INTERNAL_SERVER_ERROR); | 913 NGX_HTTP_INTERNAL_SERVER_ERROR); |
912 return ngx_http_spdy_state_headers_error(sc, pos, end); | 914 return ngx_http_spdy_state_headers_error(sc, pos, end); |
913 } | 915 } |
914 | 916 |
917 /* null-terminate the last processed header name or value */ | |
918 *buf->pos = '\0'; | |
919 | |
915 buf = r->header_in; | 920 buf = r->header_in; |
916 | 921 |
917 sc->zstream_in.next_out = buf->last; | 922 sc->zstream_in.next_out = buf->last; |
923 | |
924 /* one byte is reserved for null-termination */ | |
918 sc->zstream_in.avail_out = buf->end - buf->last - 1; | 925 sc->zstream_in.avail_out = buf->end - buf->last - 1; |
919 | 926 |
920 z = inflate(&sc->zstream_in, Z_NO_FLUSH); | 927 z = inflate(&sc->zstream_in, Z_NO_FLUSH); |
921 | 928 |
922 if (z != Z_OK) { | 929 if (z != Z_OK) { |
993 | 1000 |
994 if (!complete) { | 1001 if (!complete) { |
995 return ngx_http_spdy_state_save(sc, pos, end, | 1002 return ngx_http_spdy_state_save(sc, pos, end, |
996 ngx_http_spdy_state_headers); | 1003 ngx_http_spdy_state_headers); |
997 } | 1004 } |
1005 | |
1006 /* null-terminate the last header value */ | |
1007 *buf->pos = '\0'; | |
998 | 1008 |
999 ngx_http_spdy_run_request(r); | 1009 ngx_http_spdy_run_request(r); |
1000 | 1010 |
1001 return ngx_http_spdy_state_complete(sc, pos, end); | 1011 return ngx_http_spdy_state_complete(sc, pos, end); |
1002 } | 1012 } |
1934 | 1944 |
1935 if (!len) { | 1945 if (!len) { |
1936 return NGX_HTTP_PARSE_INVALID_HEADER; | 1946 return NGX_HTTP_PARSE_INVALID_HEADER; |
1937 } | 1947 } |
1938 | 1948 |
1949 /* null-terminate the previous header value */ | |
1950 *p = '\0'; | |
1951 | |
1939 p += NGX_SPDY_NV_NLEN_SIZE; | 1952 p += NGX_SPDY_NV_NLEN_SIZE; |
1940 | 1953 |
1941 r->header_name_end = p + len; | 1954 r->header_name_end = p + len; |
1942 r->lowcase_index = len; | 1955 r->lowcase_index = len; |
1943 r->invalid_header = 0; | 1956 r->invalid_header = 0; |
2002 len = ngx_spdy_frame_parse_uint16(p); | 2015 len = ngx_spdy_frame_parse_uint16(p); |
2003 | 2016 |
2004 if (!len) { | 2017 if (!len) { |
2005 return NGX_ERROR; | 2018 return NGX_ERROR; |
2006 } | 2019 } |
2020 | |
2021 /* null-terminate header name */ | |
2022 *p = '\0'; | |
2007 | 2023 |
2008 p += NGX_SPDY_NV_VLEN_SIZE; | 2024 p += NGX_SPDY_NV_VLEN_SIZE; |
2009 | 2025 |
2010 r->header_end = p + len; | 2026 r->header_end = p + len; |
2011 | 2027 |
2161 | 2177 |
2162 h->hash = r->header_hash; | 2178 h->hash = r->header_hash; |
2163 | 2179 |
2164 h->key.len = r->lowcase_index; | 2180 h->key.len = r->lowcase_index; |
2165 h->key.data = r->header_name_start; | 2181 h->key.data = r->header_name_start; |
2166 h->key.data[h->key.len] = '\0'; | |
2167 | 2182 |
2168 h->value.len = r->header_size; | 2183 h->value.len = r->header_size; |
2169 h->value.data = r->header_start; | 2184 h->value.data = r->header_start; |
2170 h->value.data[h->value.len] = '\0'; | |
2171 | 2185 |
2172 h->lowcase_key = h->key.data; | 2186 h->lowcase_key = h->key.data; |
2173 | 2187 |
2174 return NGX_OK; | 2188 return NGX_OK; |
2175 } | 2189 } |