src/core/ngx_parse.c - nginx source code

Data types defined

Functions defined

Source code


  1. /*
  2. * Copyright (C) Igor Sysoev
  3. * Copyright (C) Nginx, Inc.
  4. */


  5. #include <ngx_config.h>
  6. #include <ngx_core.h>


  7. ssize_t
  8. ngx_parse_size(ngx_str_t *line)
  9. {
  10.     u_char   unit;
  11.     size_t   len;
  12.     ssize_t  size, scale, max;

  13.     len = line->len;

  14.     if (len == 0) {
  15.         return NGX_ERROR;
  16.     }

  17.     unit = line->data[len - 1];

  18.     switch (unit) {
  19.     case 'K':
  20.     case 'k':
  21.         len--;
  22.         max = NGX_MAX_SIZE_T_VALUE / 1024;
  23.         scale = 1024;
  24.         break;

  25.     case 'M':
  26.     case 'm':
  27.         len--;
  28.         max = NGX_MAX_SIZE_T_VALUE / (1024 * 1024);
  29.         scale = 1024 * 1024;
  30.         break;

  31.     default:
  32.         max = NGX_MAX_SIZE_T_VALUE;
  33.         scale = 1;
  34.     }

  35.     size = ngx_atosz(line->data, len);
  36.     if (size == NGX_ERROR || size > max) {
  37.         return NGX_ERROR;
  38.     }

  39.     size *= scale;

  40.     return size;
  41. }


  42. off_t
  43. ngx_parse_offset(ngx_str_t *line)
  44. {
  45.     u_char  unit;
  46.     off_t   offset, scale, max;
  47.     size_t  len;

  48.     len = line->len;

  49.     if (len == 0) {
  50.         return NGX_ERROR;
  51.     }

  52.     unit = line->data[len - 1];

  53.     switch (unit) {
  54.     case 'K':
  55.     case 'k':
  56.         len--;
  57.         max = NGX_MAX_OFF_T_VALUE / 1024;
  58.         scale = 1024;
  59.         break;

  60.     case 'M':
  61.     case 'm':
  62.         len--;
  63.         max = NGX_MAX_OFF_T_VALUE / (1024 * 1024);
  64.         scale = 1024 * 1024;
  65.         break;

  66.     case 'G':
  67.     case 'g':
  68.         len--;
  69.         max = NGX_MAX_OFF_T_VALUE / (1024 * 1024 * 1024);
  70.         scale = 1024 * 1024 * 1024;
  71.         break;

  72.     default:
  73.         max = NGX_MAX_OFF_T_VALUE;
  74.         scale = 1;
  75.     }

  76.     offset = ngx_atoof(line->data, len);
  77.     if (offset == NGX_ERROR || offset > max) {
  78.         return NGX_ERROR;
  79.     }

  80.     offset *= scale;

  81.     return offset;
  82. }


  83. ngx_int_t
  84. ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
  85. {
  86.     u_char      *p, *last;
  87.     ngx_int_t    value, total, scale;
  88.     ngx_int_t    max, cutoff, cutlim;
  89.     ngx_uint_t   valid;
  90.     enum {
  91.         st_start = 0,
  92.         st_year,
  93.         st_month,
  94.         st_week,
  95.         st_day,
  96.         st_hour,
  97.         st_min,
  98.         st_sec,
  99.         st_msec,
  100.         st_last
  101.     } step;

  102.     valid = 0;
  103.     value = 0;
  104.     total = 0;
  105.     cutoff = NGX_MAX_INT_T_VALUE / 10;
  106.     cutlim = NGX_MAX_INT_T_VALUE % 10;
  107.     step = is_sec ? st_start : st_month;

  108.     p = line->data;
  109.     last = p + line->len;

  110.     while (p < last) {

  111.         if (*p >= '0' && *p <= '9') {
  112.             if (value >= cutoff && (value > cutoff || *p - '0' > cutlim)) {
  113.                 return NGX_ERROR;
  114.             }

  115.             value = value * 10 + (*p++ - '0');
  116.             valid = 1;
  117.             continue;
  118.         }

  119.         switch (*p++) {

  120.         case 'y':
  121.             if (step > st_start) {
  122.                 return NGX_ERROR;
  123.             }
  124.             step = st_year;
  125.             max = NGX_MAX_INT_T_VALUE / (60 * 60 * 24 * 365);
  126.             scale = 60 * 60 * 24 * 365;
  127.             break;

  128.         case 'M':
  129.             if (step >= st_month) {
  130.                 return NGX_ERROR;
  131.             }
  132.             step = st_month;
  133.             max = NGX_MAX_INT_T_VALUE / (60 * 60 * 24 * 30);
  134.             scale = 60 * 60 * 24 * 30;
  135.             break;

  136.         case 'w':
  137.             if (step >= st_week) {
  138.                 return NGX_ERROR;
  139.             }
  140.             step = st_week;
  141.             max = NGX_MAX_INT_T_VALUE / (60 * 60 * 24 * 7);
  142.             scale = 60 * 60 * 24 * 7;
  143.             break;

  144.         case 'd':
  145.             if (step >= st_day) {
  146.                 return NGX_ERROR;
  147.             }
  148.             step = st_day;
  149.             max = NGX_MAX_INT_T_VALUE / (60 * 60 * 24);
  150.             scale = 60 * 60 * 24;
  151.             break;

  152.         case 'h':
  153.             if (step >= st_hour) {
  154.                 return NGX_ERROR;
  155.             }
  156.             step = st_hour;
  157.             max = NGX_MAX_INT_T_VALUE / (60 * 60);
  158.             scale = 60 * 60;
  159.             break;

  160.         case 'm':
  161.             if (p < last && *p == 's') {
  162.                 if (is_sec || step >= st_msec) {
  163.                     return NGX_ERROR;
  164.                 }
  165.                 p++;
  166.                 step = st_msec;
  167.                 max = NGX_MAX_INT_T_VALUE;
  168.                 scale = 1;
  169.                 break;
  170.             }

  171.             if (step >= st_min) {
  172.                 return NGX_ERROR;
  173.             }
  174.             step = st_min;
  175.             max = NGX_MAX_INT_T_VALUE / 60;
  176.             scale = 60;
  177.             break;

  178.         case 's':
  179.             if (step >= st_sec) {
  180.                 return NGX_ERROR;
  181.             }
  182.             step = st_sec;
  183.             max = NGX_MAX_INT_T_VALUE;
  184.             scale = 1;
  185.             break;

  186.         case ' ':
  187.             if (step >= st_sec) {
  188.                 return NGX_ERROR;
  189.             }
  190.             step = st_last;
  191.             max = NGX_MAX_INT_T_VALUE;
  192.             scale = 1;
  193.             break;

  194.         default:
  195.             return NGX_ERROR;
  196.         }

  197.         if (step != st_msec && !is_sec) {
  198.             scale *= 1000;
  199.             max /= 1000;
  200.         }

  201.         if (value > max) {
  202.             return NGX_ERROR;
  203.         }

  204.         value *= scale;

  205.         if (total > NGX_MAX_INT_T_VALUE - value) {
  206.             return NGX_ERROR;
  207.         }

  208.         total += value;

  209.         value = 0;

  210.         while (p < last && *p == ' ') {
  211.             p++;
  212.         }
  213.     }

  214.     if (!valid) {
  215.         return NGX_ERROR;
  216.     }

  217.     if (!is_sec) {
  218.         if (value > NGX_MAX_INT_T_VALUE / 1000) {
  219.             return NGX_ERROR;
  220.         }

  221.         value *= 1000;
  222.     }

  223.     if (total > NGX_MAX_INT_T_VALUE - value) {
  224.         return NGX_ERROR;
  225.     }

  226.     return total + value;
  227. }