Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.15.12 ]​[ nginx-1.16.0 ]​

0001 
0002 /*
0003  * Copyright (C) Igor Sysoev
0004  * Copyright (C) Nginx, Inc.
0005  */
0006 
0007 
0008 #include <ngx_config.h>
0009 #include <ngx_core.h>
0010 
0011 
0012 ssize_t
0013 ngx_parse_size(ngx_str_t *line)
0014 {
0015     u_char   unit;
0016     size_t   len;
0017     ssize_t  size, scale, max;
0018 
0019     len = line->len;
0020 
0021     if (len == 0) {
0022         return NGX_ERROR;
0023     }
0024 
0025     unit = line->data[len - 1];
0026 
0027     switch (unit) {
0028     case 'K':
0029     case 'k':
0030         len--;
0031         max = NGX_MAX_SIZE_T_VALUE / 1024;
0032         scale = 1024;
0033         break;
0034 
0035     case 'M':
0036     case 'm':
0037         len--;
0038         max = NGX_MAX_SIZE_T_VALUE / (1024 * 1024);
0039         scale = 1024 * 1024;
0040         break;
0041 
0042     default:
0043         max = NGX_MAX_SIZE_T_VALUE;
0044         scale = 1;
0045     }
0046 
0047     size = ngx_atosz(line->data, len);
0048     if (size == NGX_ERROR || size > max) {
0049         return NGX_ERROR;
0050     }
0051 
0052     size *= scale;
0053 
0054     return size;
0055 }
0056 
0057 
0058 off_t
0059 ngx_parse_offset(ngx_str_t *line)
0060 {
0061     u_char  unit;
0062     off_t   offset, scale, max;
0063     size_t  len;
0064 
0065     len = line->len;
0066 
0067     if (len == 0) {
0068         return NGX_ERROR;
0069     }
0070 
0071     unit = line->data[len - 1];
0072 
0073     switch (unit) {
0074     case 'K':
0075     case 'k':
0076         len--;
0077         max = NGX_MAX_OFF_T_VALUE / 1024;
0078         scale = 1024;
0079         break;
0080 
0081     case 'M':
0082     case 'm':
0083         len--;
0084         max = NGX_MAX_OFF_T_VALUE / (1024 * 1024);
0085         scale = 1024 * 1024;
0086         break;
0087 
0088     case 'G':
0089     case 'g':
0090         len--;
0091         max = NGX_MAX_OFF_T_VALUE / (1024 * 1024 * 1024);
0092         scale = 1024 * 1024 * 1024;
0093         break;
0094 
0095     default:
0096         max = NGX_MAX_OFF_T_VALUE;
0097         scale = 1;
0098     }
0099 
0100     offset = ngx_atoof(line->data, len);
0101     if (offset == NGX_ERROR || offset > max) {
0102         return NGX_ERROR;
0103     }
0104 
0105     offset *= scale;
0106 
0107     return offset;
0108 }
0109 
0110 
0111 ngx_int_t
0112 ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
0113 {
0114     u_char      *p, *last;
0115     ngx_int_t    value, total, scale;
0116     ngx_int_t    max, cutoff, cutlim;
0117     ngx_uint_t   valid;
0118     enum {
0119         st_start = 0,
0120         st_year,
0121         st_month,
0122         st_week,
0123         st_day,
0124         st_hour,
0125         st_min,
0126         st_sec,
0127         st_msec,
0128         st_last
0129     } step;
0130 
0131     valid = 0;
0132     value = 0;
0133     total = 0;
0134     cutoff = NGX_MAX_INT_T_VALUE / 10;
0135     cutlim = NGX_MAX_INT_T_VALUE % 10;
0136     step = is_sec ? st_start : st_month;
0137 
0138     p = line->data;
0139     last = p + line->len;
0140 
0141     while (p < last) {
0142 
0143         if (*p >= '0' && *p <= '9') {
0144             if (value >= cutoff && (value > cutoff || *p - '0' > cutlim)) {
0145                 return NGX_ERROR;
0146             }
0147 
0148             value = value * 10 + (*p++ - '0');
0149             valid = 1;
0150             continue;
0151         }
0152 
0153         switch (*p++) {
0154 
0155         case 'y':
0156             if (step > st_start) {
0157                 return NGX_ERROR;
0158             }
0159             step = st_year;
0160             max = NGX_MAX_INT_T_VALUE / (60 * 60 * 24 * 365);
0161             scale = 60 * 60 * 24 * 365;
0162             break;
0163 
0164         case 'M':
0165             if (step >= st_month) {
0166                 return NGX_ERROR;
0167             }
0168             step = st_month;
0169             max = NGX_MAX_INT_T_VALUE / (60 * 60 * 24 * 30);
0170             scale = 60 * 60 * 24 * 30;
0171             break;
0172 
0173         case 'w':
0174             if (step >= st_week) {
0175                 return NGX_ERROR;
0176             }
0177             step = st_week;
0178             max = NGX_MAX_INT_T_VALUE / (60 * 60 * 24 * 7);
0179             scale = 60 * 60 * 24 * 7;
0180             break;
0181 
0182         case 'd':
0183             if (step >= st_day) {
0184                 return NGX_ERROR;
0185             }
0186             step = st_day;
0187             max = NGX_MAX_INT_T_VALUE / (60 * 60 * 24);
0188             scale = 60 * 60 * 24;
0189             break;
0190 
0191         case 'h':
0192             if (step >= st_hour) {
0193                 return NGX_ERROR;
0194             }
0195             step = st_hour;
0196             max = NGX_MAX_INT_T_VALUE / (60 * 60);
0197             scale = 60 * 60;
0198             break;
0199 
0200         case 'm':
0201             if (p < last && *p == 's') {
0202                 if (is_sec || step >= st_msec) {
0203                     return NGX_ERROR;
0204                 }
0205                 p++;
0206                 step = st_msec;
0207                 max = NGX_MAX_INT_T_VALUE;
0208                 scale = 1;
0209                 break;
0210             }
0211 
0212             if (step >= st_min) {
0213                 return NGX_ERROR;
0214             }
0215             step = st_min;
0216             max = NGX_MAX_INT_T_VALUE / 60;
0217             scale = 60;
0218             break;
0219 
0220         case 's':
0221             if (step >= st_sec) {
0222                 return NGX_ERROR;
0223             }
0224             step = st_sec;
0225             max = NGX_MAX_INT_T_VALUE;
0226             scale = 1;
0227             break;
0228 
0229         case ' ':
0230             if (step >= st_sec) {
0231                 return NGX_ERROR;
0232             }
0233             step = st_last;
0234             max = NGX_MAX_INT_T_VALUE;
0235             scale = 1;
0236             break;
0237 
0238         default:
0239             return NGX_ERROR;
0240         }
0241 
0242         if (step != st_msec && !is_sec) {
0243             scale *= 1000;
0244             max /= 1000;
0245         }
0246 
0247         if (value > max) {
0248             return NGX_ERROR;
0249         }
0250 
0251         value *= scale;
0252 
0253         if (total > NGX_MAX_INT_T_VALUE - value) {
0254             return NGX_ERROR;
0255         }
0256 
0257         total += value;
0258 
0259         value = 0;
0260 
0261         while (p < last && *p == ' ') {
0262             p++;
0263         }
0264     }
0265 
0266     if (!valid) {
0267         return NGX_ERROR;
0268     }
0269 
0270     if (!is_sec) {
0271         if (value > NGX_MAX_INT_T_VALUE / 1000) {
0272             return NGX_ERROR;
0273         }
0274 
0275         value *= 1000;
0276     }
0277 
0278     if (total > NGX_MAX_INT_T_VALUE - value) {
0279         return NGX_ERROR;
0280     }
0281 
0282     return total + value;
0283 }