Mercurial > hg > nginx
comparison src/http/modules/ngx_http_autoindex_module.c @ 7435:a91b93f3f3e7
Autoindex: fixed possible integer overflow on 32-bit systems.
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Tue, 25 Dec 2018 12:59:24 +0300 |
parents | 061ec464813f |
children |
comparison
equal
deleted
inserted
replaced
7434:e3b262e7fc88 | 7435:a91b93f3f3e7 |
---|---|
432 static ngx_buf_t * | 432 static ngx_buf_t * |
433 ngx_http_autoindex_html(ngx_http_request_t *r, ngx_array_t *entries) | 433 ngx_http_autoindex_html(ngx_http_request_t *r, ngx_array_t *entries) |
434 { | 434 { |
435 u_char *last, scale; | 435 u_char *last, scale; |
436 off_t length; | 436 off_t length; |
437 size_t len, char_len, escape_html; | 437 size_t len, entry_len, char_len, escape_html; |
438 ngx_tm_t tm; | 438 ngx_tm_t tm; |
439 ngx_buf_t *b; | 439 ngx_buf_t *b; |
440 ngx_int_t size; | 440 ngx_int_t size; |
441 ngx_uint_t i, utf8; | 441 ngx_uint_t i, utf8; |
442 ngx_time_t *tp; | 442 ngx_time_t *tp; |
497 entry[i].name.len); | 497 entry[i].name.len); |
498 } else { | 498 } else { |
499 entry[i].utf_len = entry[i].name.len; | 499 entry[i].utf_len = entry[i].name.len; |
500 } | 500 } |
501 | 501 |
502 len += sizeof("<a href=\"") - 1 | 502 entry_len = sizeof("<a href=\"") - 1 |
503 + entry[i].name.len + entry[i].escape | 503 + entry[i].name.len + entry[i].escape |
504 + 1 /* 1 is for "/" */ | 504 + 1 /* 1 is for "/" */ |
505 + sizeof("\">") - 1 | 505 + sizeof("\">") - 1 |
506 + entry[i].name.len - entry[i].utf_len | 506 + entry[i].name.len - entry[i].utf_len |
507 + entry[i].escape_html | 507 + entry[i].escape_html |
508 + NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof(">") - 2 | 508 + NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof(">") - 2 |
509 + sizeof("</a>") - 1 | 509 + sizeof("</a>") - 1 |
510 + sizeof(" 28-Sep-1970 12:00 ") - 1 | 510 + sizeof(" 28-Sep-1970 12:00 ") - 1 |
511 + 20 /* the file size */ | 511 + 20 /* the file size */ |
512 + 2; | 512 + 2; |
513 | |
514 if (len > NGX_MAX_SIZE_T_VALUE - entry_len) { | |
515 return NULL; | |
516 } | |
517 | |
518 len += entry_len; | |
513 } | 519 } |
514 | 520 |
515 b = ngx_create_temp_buf(r->pool, len); | 521 b = ngx_create_temp_buf(r->pool, len); |
516 if (b == NULL) { | 522 if (b == NULL) { |
517 return NULL; | 523 return NULL; |
695 | 701 |
696 static ngx_buf_t * | 702 static ngx_buf_t * |
697 ngx_http_autoindex_json(ngx_http_request_t *r, ngx_array_t *entries, | 703 ngx_http_autoindex_json(ngx_http_request_t *r, ngx_array_t *entries, |
698 ngx_str_t *callback) | 704 ngx_str_t *callback) |
699 { | 705 { |
700 size_t len; | 706 size_t len, entry_len; |
701 ngx_buf_t *b; | 707 ngx_buf_t *b; |
702 ngx_uint_t i; | 708 ngx_uint_t i; |
703 ngx_http_autoindex_entry_t *entry; | 709 ngx_http_autoindex_entry_t *entry; |
704 | 710 |
705 len = sizeof("[" CRLF CRLF "]") - 1; | 711 len = sizeof("[" CRLF CRLF "]") - 1; |
712 | 718 |
713 for (i = 0; i < entries->nelts; i++) { | 719 for (i = 0; i < entries->nelts; i++) { |
714 entry[i].escape = ngx_escape_json(NULL, entry[i].name.data, | 720 entry[i].escape = ngx_escape_json(NULL, entry[i].name.data, |
715 entry[i].name.len); | 721 entry[i].name.len); |
716 | 722 |
717 len += sizeof("{ }," CRLF) - 1 | 723 entry_len = sizeof("{ }," CRLF) - 1 |
718 + sizeof("\"name\":\"\"") - 1 | 724 + sizeof("\"name\":\"\"") - 1 |
719 + entry[i].name.len + entry[i].escape | 725 + entry[i].name.len + entry[i].escape |
720 + sizeof(", \"type\":\"directory\"") - 1 | 726 + sizeof(", \"type\":\"directory\"") - 1 |
721 + sizeof(", \"mtime\":\"Wed, 31 Dec 1986 10:00:00 GMT\"") - 1; | 727 + sizeof(", \"mtime\":\"Wed, 31 Dec 1986 10:00:00 GMT\"") - 1; |
722 | 728 |
723 if (entry[i].file) { | 729 if (entry[i].file) { |
724 len += sizeof(", \"size\":") - 1 + NGX_OFF_T_LEN; | 730 entry_len += sizeof(", \"size\":") - 1 + NGX_OFF_T_LEN; |
725 } | 731 } |
732 | |
733 if (len > NGX_MAX_SIZE_T_VALUE - entry_len) { | |
734 return NULL; | |
735 } | |
736 | |
737 len += entry_len; | |
726 } | 738 } |
727 | 739 |
728 b = ngx_create_temp_buf(r->pool, len); | 740 b = ngx_create_temp_buf(r->pool, len); |
729 if (b == NULL) { | 741 if (b == NULL) { |
730 return NULL; | 742 return NULL; |
839 | 851 |
840 | 852 |
841 static ngx_buf_t * | 853 static ngx_buf_t * |
842 ngx_http_autoindex_xml(ngx_http_request_t *r, ngx_array_t *entries) | 854 ngx_http_autoindex_xml(ngx_http_request_t *r, ngx_array_t *entries) |
843 { | 855 { |
844 size_t len; | 856 size_t len, entry_len; |
845 ngx_tm_t tm; | 857 ngx_tm_t tm; |
846 ngx_buf_t *b; | 858 ngx_buf_t *b; |
847 ngx_str_t type; | 859 ngx_str_t type; |
848 ngx_uint_t i; | 860 ngx_uint_t i; |
849 ngx_http_autoindex_entry_t *entry; | 861 ngx_http_autoindex_entry_t *entry; |
857 | 869 |
858 for (i = 0; i < entries->nelts; i++) { | 870 for (i = 0; i < entries->nelts; i++) { |
859 entry[i].escape = ngx_escape_html(NULL, entry[i].name.data, | 871 entry[i].escape = ngx_escape_html(NULL, entry[i].name.data, |
860 entry[i].name.len); | 872 entry[i].name.len); |
861 | 873 |
862 len += sizeof("<directory></directory>" CRLF) - 1 | 874 entry_len = sizeof("<directory></directory>" CRLF) - 1 |
863 + entry[i].name.len + entry[i].escape | 875 + entry[i].name.len + entry[i].escape |
864 + sizeof(" mtime=\"1986-12-31T10:00:00Z\"") - 1; | 876 + sizeof(" mtime=\"1986-12-31T10:00:00Z\"") - 1; |
865 | 877 |
866 if (entry[i].file) { | 878 if (entry[i].file) { |
867 len += sizeof(" size=\"\"") - 1 + NGX_OFF_T_LEN; | 879 entry_len += sizeof(" size=\"\"") - 1 + NGX_OFF_T_LEN; |
868 } | 880 } |
881 | |
882 if (len > NGX_MAX_SIZE_T_VALUE - entry_len) { | |
883 return NULL; | |
884 } | |
885 | |
886 len += entry_len; | |
869 } | 887 } |
870 | 888 |
871 b = ngx_create_temp_buf(r->pool, len); | 889 b = ngx_create_temp_buf(r->pool, len); |
872 if (b == NULL) { | 890 if (b == NULL) { |
873 return NULL; | 891 return NULL; |