comparison src/http/modules/ngx_http_limit_req_module.c @ 4417:9e9d2e06f933

Limit req: improved error handling when parsing "zone" parameter of "limit_req_zone" directive; minimum size of zone is increased. Previously an unsigned variable was used to keep the return value of ngx_parse_size() function, which led to an incorrect zone size if NGX_ERROR was returned. The new code has been taken from the "limit_conn_zone" directive.
author Valentin Bartenev <vbart@nginx.com>
date Mon, 30 Jan 2012 09:26:08 +0000
parents 8156a9bfc044
children aac79fc948cc
comparison
equal deleted inserted replaced
4416:8156a9bfc044 4417:9e9d2e06f933
587 587
588 static char * 588 static char *
589 ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) 589 ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
590 { 590 {
591 u_char *p; 591 u_char *p;
592 size_t size, len; 592 size_t len;
593 ssize_t size;
593 ngx_str_t *value, name, s; 594 ngx_str_t *value, name, s;
594 ngx_int_t rate, scale; 595 ngx_int_t rate, scale;
595 ngx_uint_t i; 596 ngx_uint_t i;
596 ngx_shm_zone_t *shm_zone; 597 ngx_shm_zone_t *shm_zone;
597 ngx_http_limit_req_ctx_t *ctx; 598 ngx_http_limit_req_ctx_t *ctx;
610 611
611 name.data = value[i].data + 5; 612 name.data = value[i].data + 5;
612 613
613 p = (u_char *) ngx_strchr(name.data, ':'); 614 p = (u_char *) ngx_strchr(name.data, ':');
614 615
615 if (p) { 616 if (p == NULL) {
616 *p = '\0'; 617 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
617 618 "invalid zone size \"%V\"", &value[i]);
618 name.len = p - name.data; 619 return NGX_CONF_ERROR;
619 620 }
620 p++; 621
621 622 name.len = p - name.data;
622 s.len = value[i].data + value[i].len - p; 623
623 s.data = p; 624 s.data = p + 1;
624 625 s.len = value[i].data + value[i].len - s.data;
625 size = ngx_parse_size(&s); 626
626 if (size > 8191) { 627 size = ngx_parse_size(&s);
627 continue; 628
628 } 629 if (size == NGX_ERROR) {
629 } 630 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
630 631 "invalid zone size \"%V\"", &value[i]);
631 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 632 return NGX_CONF_ERROR;
632 "invalid zone size \"%V\"", &value[i]); 633 }
633 return NGX_CONF_ERROR; 634
635 if (size < (ssize_t) (8 * ngx_pagesize)) {
636 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
637 "zone \"%V\" is too small", &value[i]);
638 return NGX_CONF_ERROR;
639 }
640
641 continue;
634 } 642 }
635 643
636 if (ngx_strncmp(value[i].data, "rate=", 5) == 0) { 644 if (ngx_strncmp(value[i].data, "rate=", 5) == 0) {
637 645
638 len = value[i].len; 646 len = value[i].len;
680 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 688 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
681 "invalid parameter \"%V\"", &value[i]); 689 "invalid parameter \"%V\"", &value[i]);
682 return NGX_CONF_ERROR; 690 return NGX_CONF_ERROR;
683 } 691 }
684 692
685 if (name.len == 0 || size == 0) { 693 if (name.len == 0) {
686 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, 694 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
687 "\"%V\" must have \"zone\" parameter", 695 "\"%V\" must have \"zone\" parameter",
688 &cmd->name); 696 &cmd->name);
689 return NGX_CONF_ERROR; 697 return NGX_CONF_ERROR;
690 } 698 }