# HG changeset patch # User Igor Sysoev # Date 1292274000 -10800 # Node ID e1f4748dc78ecb7a2e886e81933a590db25d76fa # Parent 647973d42a2a5f8d5a90877aa259ea41d91d56fd nginx 0.7.68 *) Bugfix: if there was a single server for given IPv6 address:port pair, then captures in regular expressions in a "server_name" directive did not work. *) Bugfix: a segmentation fault might occur in a worker process, if the "auth_basic" directive was used. Thanks to Michail Laletin. *) Bugfix: SSI response might be truncated after include with wait="yes"; the bug had appeared in 0.7.25. Thanks to Maxim Dounin. *) Bugfix: the "sub_filter" directive might change character case on partial match. *) Bugfix: nginx treated large SSLv2 packets as plain requests. Thanks to Miroslaw Jaworski. *) Bugfix: nginx might close IPv6 listen socket during reconfiguration. Thanks to Maxim Dounin. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,29 @@ +Changes with nginx 0.7.68 14 Dec 2010 + + *) Bugfix: if there was a single server for given IPv6 address:port + pair, then captures in regular expressions in a "server_name" + directive did not work. + + *) Bugfix: a segmentation fault might occur in a worker process, if the + "auth_basic" directive was used. + Thanks to Michail Laletin. + + *) Bugfix: SSI response might be truncated after include with + wait="yes"; the bug had appeared in 0.7.25. + Thanks to Maxim Dounin. + + *) Bugfix: the "sub_filter" directive might change character case on + partial match. + + *) Bugfix: nginx treated large SSLv2 packets as plain requests. + Thanks to Miroslaw Jaworski. + + *) Bugfix: nginx might close IPv6 listen socket during + reconfiguration. + Thanks to Maxim Dounin. + + Changes with nginx 0.7.67 15 Jun 2010 *) Security: nginx/Windows worker might be terminated abnormally if a @@ -697,7 +722,7 @@ Changes with nginx 0.7.44 *) Bugfix: the "try_files" directive might test incorrectly directories. - *) Bugfix: if there is the single server for given address:port pair, + *) Bugfix: if there was a single server for given address:port pair, then captures in regular expressions in a "server_name" directive did not work. @@ -1051,7 +1076,7 @@ Changes with nginx 0.7.18 *) Bugfix: the "http_503" parameter of the "proxy_next_upstream" or "fastcgi_next_upstream" directives did not work. - *) Bugfix: nginx might send a "Transfer-Encoding: chunked" heaer line + *) Bugfix: nginx might send a "Transfer-Encoding: chunked" header line for HEAD requests. *) Bugfix: now accept threshold depends on worker_connections. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,30 @@ +Изменения в nginx 0.7.68 14.12.2010 + + *) Исправление: если для пары IPv6-адрес:порт описан только один + сервер, то выделения в регулярных выражениях в директиве server_name + не работали. + + *) Исправление: при использовании директивы auth_basic в рабочем + процессе мог произойти segmentation fault. + Спасибо Михаилу Лалетину. + + *) Исправление: ответ SSI модуля мог передаваться не полностью после + команды include с параметром wait="yes"; ошибка появилась в 0.7.25. + Спасибо Максиму Дунину. + + *) Исправление: директива sub_filter могла изменять регистр букв при + частичном совпадении. + + *) Исправление: nginx считал большие пакеты SSLv2 как обычные текстовые + запросы. + Спасибо Miroslaw Jaworski. + + *) Исправление: nginx мог закрывать IPv6 listen сокет во время + переконфигурации. + Спасибо Максиму Дунину. + + Изменения в nginx 0.7.67 15.06.2010 *) Безопасность: рабочий процесс nginx/Windows мог завершаться аварийно @@ -1504,7 +1530,7 @@ *) Исправление: nginx неверно определял длину строки кэша на Pentium 4. - Спасибо Gena Makhomed. + Спасибо Геннадию Махомеду. *) Исправление: в проксированных подзапросах и подзапросах к FastCGI-серверу вместо метода GET использовался оригинальный метод diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,8 +8,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 7067 -#define NGINX_VERSION "0.7.67" +#define nginx_version 7068 +#define NGINX_VERSION "0.7.68" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -847,7 +847,7 @@ ngx_cmp_sockaddr(struct sockaddr *sa1, s sin61 = (struct sockaddr_in6 *) sa1; sin62 = (struct sockaddr_in6 *) sa2; - if (sin61->sin6_port != sin61->sin6_port) { + if (sin61->sin6_port != sin62->sin6_port) { return NGX_DECLINED; } diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c --- a/src/http/modules/ngx_http_ssi_filter_module.c +++ b/src/http/modules/ngx_http_ssi_filter_module.c @@ -70,6 +70,8 @@ typedef enum { static ngx_int_t ngx_http_ssi_output(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx); +static void ngx_http_ssi_buffered(ngx_http_request_t *r, + ngx_http_ssi_ctx_t *ctx); static ngx_int_t ngx_http_ssi_parse(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx); static ngx_str_t *ngx_http_ssi_get_variable(ngx_http_request_t *r, @@ -797,6 +799,7 @@ ngx_http_ssi_body_filter(ngx_http_reques } if (rc == NGX_DONE || rc == NGX_AGAIN || rc == NGX_ERROR) { + ngx_http_ssi_buffered(r, ctx); return rc; } } @@ -949,14 +952,21 @@ ngx_http_ssi_output(ngx_http_request_t * } } + ngx_http_ssi_buffered(r, ctx); + + return rc; +} + + +static void +ngx_http_ssi_buffered(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx) +{ if (ctx->in || ctx->buf) { r->buffered |= NGX_HTTP_SSI_BUFFERED; } else { r->buffered &= ~NGX_HTTP_SSI_BUFFERED; } - - return rc; } diff --git a/src/http/modules/ngx_http_sub_filter_module.c b/src/http/modules/ngx_http_sub_filter_module.c --- a/src/http/modules/ngx_http_sub_filter_module.c +++ b/src/http/modules/ngx_http_sub_filter_module.c @@ -29,6 +29,8 @@ typedef enum { typedef struct { ngx_str_t match; + ngx_str_t saved; + ngx_str_t looked; ngx_uint_t once; /* unsigned once:1 */ @@ -47,8 +49,6 @@ typedef struct { ngx_str_t sub; ngx_uint_t state; - size_t saved; - size_t looked; } ngx_http_sub_ctx_t; @@ -147,6 +147,16 @@ ngx_http_sub_header_filter(ngx_http_requ return NGX_ERROR; } + ctx->saved.data = ngx_pnalloc(r->pool, slcf->match.len); + if (ctx->saved.data == NULL) { + return NGX_ERROR; + } + + ctx->looked.data = ngx_pnalloc(r->pool, slcf->match.len); + if (ctx->looked.data == NULL) { + return NGX_ERROR; + } + ngx_http_set_ctx(r, ctx, ngx_http_sub_filter_module); ctx->match = slcf->match; @@ -226,13 +236,13 @@ ngx_http_sub_body_filter(ngx_http_reques while (ctx->pos < ctx->buf->last) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "saved: %d state: %d", ctx->saved, ctx->state); + "saved: \"%V\" state: %d", &ctx->saved, ctx->state); rc = ngx_http_sub_parse(r, ctx); ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "parse: %d, looked: %d %p-%p", - rc, ctx->looked, ctx->copy_start, ctx->copy_end); + "parse: %d, looked: \"%V\" %p-%p", + rc, &ctx->looked, ctx->copy_start, ctx->copy_end); if (rc == NGX_ERROR) { return rc; @@ -241,9 +251,9 @@ ngx_http_sub_body_filter(ngx_http_reques if (ctx->copy_start != ctx->copy_end) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "saved: %d", ctx->saved); + "saved: \"%V\"", &ctx->saved); - if (ctx->saved) { + if (ctx->saved.len) { if (ctx->free) { cl = ctx->free; @@ -265,14 +275,19 @@ ngx_http_sub_body_filter(ngx_http_reques cl->buf = b; } + b->pos = ngx_pnalloc(r->pool, ctx->saved.len); + if (b->pos == NULL) { + return NGX_ERROR; + } + + ngx_memcpy(b->pos, ctx->saved.data, ctx->saved.len); + b->last = b->pos + ctx->saved.len; b->memory = 1; - b->pos = ctx->match.data; - b->last = ctx->match.data + ctx->saved; *ctx->last_out = cl; ctx->last_out = &cl->next; - ctx->saved = 0; + ctx->saved.len = 0; } if (ctx->free) { @@ -405,7 +420,8 @@ ngx_http_sub_body_filter(ngx_http_reques ctx->buf = NULL; - ctx->saved = ctx->looked; + ctx->saved.len = ctx->looked.len; + ngx_memcpy(ctx->saved.data, ctx->looked.data, ctx->looked.len); } if (ctx->out == NULL && ctx->busy == NULL) { @@ -496,7 +512,7 @@ ngx_http_sub_parse(ngx_http_request_t *r ctx->copy_start = ctx->pos; ctx->copy_end = ctx->buf->last; ctx->pos = ctx->buf->last; - ctx->looked = 0; + ctx->looked.len = 0; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "once"); @@ -504,7 +520,7 @@ ngx_http_sub_parse(ngx_http_request_t *r } state = ctx->state; - looked = ctx->looked; + looked = ctx->looked.len; last = ctx->buf->last; copy_end = ctx->copy_end; @@ -522,6 +538,7 @@ ngx_http_sub_parse(ngx_http_request_t *r for ( ;; ) { if (ch == match) { copy_end = p; + ctx->looked.data[0] = *p; looked = 1; state = sub_match_state; @@ -538,7 +555,7 @@ ngx_http_sub_parse(ngx_http_request_t *r ctx->state = state; ctx->pos = p; - ctx->looked = looked; + ctx->looked.len = looked; ctx->copy_end = p; if (ctx->copy_start == NULL) { @@ -555,16 +572,17 @@ ngx_http_sub_parse(ngx_http_request_t *r /* state == sub_match_state */ if (ch == ctx->match.data[looked]) { + ctx->looked.data[looked] = *p; looked++; if (looked == ctx->match.len) { if ((size_t) (p - ctx->pos) < looked) { - ctx->saved = 0; + ctx->saved.len = 0; } ctx->state = sub_start_state; ctx->pos = p + 1; - ctx->looked = 0; + ctx->looked.len = 0; ctx->copy_end = copy_end; if (ctx->copy_start == NULL && copy_end) { @@ -576,6 +594,7 @@ ngx_http_sub_parse(ngx_http_request_t *r } else if (ch == ctx->match.data[0]) { copy_end = p; + ctx->looked.data[0] = *p; looked = 1; } else { @@ -587,7 +606,7 @@ ngx_http_sub_parse(ngx_http_request_t *r ctx->state = state; ctx->pos = p; - ctx->looked = looked; + ctx->looked.len = looked; ctx->copy_end = (state == sub_start_state) ? p : copy_end; diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm --- a/src/http/modules/perl/nginx.pm +++ b/src/http/modules/perl/nginx.pm @@ -47,7 +47,7 @@ our @EXPORT = qw( HTTP_INSUFFICIENT_STORAGE ); -our $VERSION = '0.7.67'; +our $VERSION = '0.7.68'; require XSLoader; XSLoader::load('nginx', $VERSION); diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -1831,8 +1831,12 @@ ngx_http_add_addrs6(ngx_conf_t *cf, ngx_ if (addr[i].hash.buckets == NULL && (addr[i].wc_head == NULL || addr[i].wc_head->hash.buckets == NULL) - && (addr[i].wc_head == NULL - || addr[i].wc_head->hash.buckets == NULL)) + && (addr[i].wc_tail == NULL + || addr[i].wc_tail->hash.buckets == NULL) +#if (NGX_PCRE) + && addr[i].nregex == 0 +#endif + ) { continue; } diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -785,10 +785,6 @@ ngx_http_handler(ngx_http_request_t *r) r->phase_handler = cmcf->phase_engine.server_rewrite_index; } - if (r->unparsed_uri.len) { - r->valid_unparsed_uri = 1; - } - r->valid_location = 1; #if (NGX_HTTP_GZIP) r->gzip_tested = 0; diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -551,7 +551,7 @@ ngx_http_ssl_handshake(ngx_event_t *rev) } if (n == 1) { - if (buf[0] == 0x80 /* SSLv2 */ || buf[0] == 0x16 /* SSLv3/TLSv1 */) { + if (buf[0] & 0x80 /* SSLv2 */ || buf[0] == 0x16 /* SSLv3/TLSv1 */) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "https ssl handshake: 0x%02Xd", buf[0]); @@ -752,6 +752,7 @@ ngx_http_process_request_line(ngx_event_ r->unparsed_uri.len = r->uri_end - r->uri_start; r->unparsed_uri.data = r->uri_start; + r->valid_unparsed_uri = 1; r->method_name.len = r->method_end - r->request_start + 1; r->method_name.data = r->request_line.data; diff --git a/src/os/unix/ngx_user.c b/src/os/unix/ngx_user.c --- a/src/os/unix/ngx_user.c +++ b/src/os/unix/ngx_user.c @@ -41,11 +41,11 @@ ngx_crypt(ngx_pool_t *pool, u_char *key, err = ngx_errno; if (err == 0) { - len = ngx_strlen(value); + len = ngx_strlen(value) + 1; *encrypted = ngx_pnalloc(pool, len); if (*encrypted) { - ngx_memcpy(*encrypted, value, len + 1); + ngx_memcpy(*encrypted, value, len); return NGX_OK; } } @@ -79,11 +79,11 @@ ngx_crypt(ngx_pool_t *pool, u_char *key, value = crypt((char *) key, (char *) salt); if (value) { - len = ngx_strlen(value); + len = ngx_strlen(value) + 1; *encrypted = ngx_pnalloc(pool, len); if (*encrypted) { - ngx_memcpy(*encrypted, value, len + 1); + ngx_memcpy(*encrypted, value, len); } #if (NGX_THREADS && NGX_NONREENTRANT_CRYPT)