Mercurial > hg > nginx
comparison src/core/ngx_parse.c @ 6009:15a15f6ae3a2
Core: overflow detection in number parsing functions.
author | Ruslan Ermilov <ru@nginx.com> |
---|---|
date | Tue, 17 Mar 2015 00:26:15 +0300 |
parents | d620f497c50f |
children | 040e2736e8dc |
comparison
equal
deleted
inserted
replaced
6008:b92d5a26d55f | 6009:15a15f6ae3a2 |
---|---|
10 | 10 |
11 | 11 |
12 ssize_t | 12 ssize_t |
13 ngx_parse_size(ngx_str_t *line) | 13 ngx_parse_size(ngx_str_t *line) |
14 { | 14 { |
15 u_char unit; | 15 u_char unit; |
16 size_t len; | 16 size_t len; |
17 ssize_t size; | 17 ssize_t size, scale, max; |
18 ngx_int_t scale; | |
19 | 18 |
20 len = line->len; | 19 len = line->len; |
21 unit = line->data[len - 1]; | 20 unit = line->data[len - 1]; |
22 | 21 |
23 switch (unit) { | 22 switch (unit) { |
24 case 'K': | 23 case 'K': |
25 case 'k': | 24 case 'k': |
26 len--; | 25 len--; |
26 max = NGX_MAX_SIZE_T_VALUE / 1024; | |
27 scale = 1024; | 27 scale = 1024; |
28 break; | 28 break; |
29 | 29 |
30 case 'M': | 30 case 'M': |
31 case 'm': | 31 case 'm': |
32 len--; | 32 len--; |
33 max = NGX_MAX_SIZE_T_VALUE / (1024 * 1024); | |
33 scale = 1024 * 1024; | 34 scale = 1024 * 1024; |
34 break; | 35 break; |
35 | 36 |
36 default: | 37 default: |
38 max = NGX_MAX_SIZE_T_VALUE; | |
37 scale = 1; | 39 scale = 1; |
38 } | 40 } |
39 | 41 |
40 size = ngx_atosz(line->data, len); | 42 size = ngx_atosz(line->data, len); |
41 if (size == NGX_ERROR) { | 43 if (size == NGX_ERROR || size > max) { |
42 return NGX_ERROR; | 44 return NGX_ERROR; |
43 } | 45 } |
44 | 46 |
45 size *= scale; | 47 size *= scale; |
46 | 48 |
49 | 51 |
50 | 52 |
51 off_t | 53 off_t |
52 ngx_parse_offset(ngx_str_t *line) | 54 ngx_parse_offset(ngx_str_t *line) |
53 { | 55 { |
54 u_char unit; | 56 u_char unit; |
55 off_t offset; | 57 off_t offset, scale, max; |
56 size_t len; | 58 size_t len; |
57 ngx_int_t scale; | |
58 | 59 |
59 len = line->len; | 60 len = line->len; |
60 unit = line->data[len - 1]; | 61 unit = line->data[len - 1]; |
61 | 62 |
62 switch (unit) { | 63 switch (unit) { |
63 case 'K': | 64 case 'K': |
64 case 'k': | 65 case 'k': |
65 len--; | 66 len--; |
67 max = NGX_MAX_OFF_T_VALUE / 1024; | |
66 scale = 1024; | 68 scale = 1024; |
67 break; | 69 break; |
68 | 70 |
69 case 'M': | 71 case 'M': |
70 case 'm': | 72 case 'm': |
71 len--; | 73 len--; |
74 max = NGX_MAX_OFF_T_VALUE / (1024 * 1024); | |
72 scale = 1024 * 1024; | 75 scale = 1024 * 1024; |
73 break; | 76 break; |
74 | 77 |
75 case 'G': | 78 case 'G': |
76 case 'g': | 79 case 'g': |
77 len--; | 80 len--; |
81 max = NGX_MAX_OFF_T_VALUE / (1024 * 1024 * 1024); | |
78 scale = 1024 * 1024 * 1024; | 82 scale = 1024 * 1024 * 1024; |
79 break; | 83 break; |
80 | 84 |
81 default: | 85 default: |
86 max = NGX_MAX_OFF_T_VALUE; | |
82 scale = 1; | 87 scale = 1; |
83 } | 88 } |
84 | 89 |
85 offset = ngx_atoof(line->data, len); | 90 offset = ngx_atoof(line->data, len); |
86 if (offset == NGX_ERROR) { | 91 if (offset == NGX_ERROR || offset > max) { |
87 return NGX_ERROR; | 92 return NGX_ERROR; |
88 } | 93 } |
89 | 94 |
90 offset *= scale; | 95 offset *= scale; |
91 | 96 |