src/core/ngx_parse.c - nginx-1.7.10

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;
  13.     ngx_int_t  scale;

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

  16.     switch (unit) {
  17.     case 'K':
  18.     case 'k':
  19.         len--;
  20.         scale = 1024;
  21.         break;

  22.     case 'M':
  23.     case 'm':
  24.         len--;
  25.         scale = 1024 * 1024;
  26.         break;

  27.     default:
  28.         scale = 1;
  29.     }

  30.     size = ngx_atosz(line->data, len);
  31.     if (size == NGX_ERROR) {
  32.         return NGX_ERROR;
  33.     }

  34.     size *= scale;

  35.     return size;
  36. }


  37. off_t
  38. ngx_parse_offset(ngx_str_t *line)
  39. {
  40.     u_char     unit;
  41.     off_t      offset;
  42.     size_t     len;
  43.     ngx_int_t  scale;

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

  46.     switch (unit) {
  47.     case 'K':
  48.     case 'k':
  49.         len--;
  50.         scale = 1024;
  51.         break;

  52.     case 'M':
  53.     case 'm':
  54.         len--;
  55.         scale = 1024 * 1024;
  56.         break;

  57.     case 'G':
  58.     case 'g':
  59.         len--;
  60.         scale = 1024 * 1024 * 1024;
  61.         break;

  62.     default:
  63.         scale = 1;
  64.     }

  65.     offset = ngx_atoof(line->data, len);
  66.     if (offset == NGX_ERROR) {
  67.         return NGX_ERROR;
  68.     }

  69.     offset *= scale;

  70.     return offset;
  71. }


  72. ngx_int_t
  73. ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
  74. {
  75.     u_char      *p, *last;
  76.     ngx_int_t    value, total, scale;
  77.     ngx_uint_t   max, valid;
  78.     enum {
  79.         st_start = 0,
  80.         st_year,
  81.         st_month,
  82.         st_week,
  83.         st_day,
  84.         st_hour,
  85.         st_min,
  86.         st_sec,
  87.         st_msec,
  88.         st_last
  89.     } step;

  90.     valid = 0;
  91.     value = 0;
  92.     total = 0;
  93.     step = is_sec ? st_start : st_month;
  94.     scale = is_sec ? 1 : 1000;

  95.     p = line->data;
  96.     last = p + line->len;

  97.     while (p < last) {

  98.         if (*p >= '0' && *p <= '9') {
  99.             value = value * 10 + (*p++ - '0');
  100.             valid = 1;
  101.             continue;
  102.         }

  103.         switch (*p++) {

  104.         case 'y':
  105.             if (step > st_start) {
  106.                 return NGX_ERROR;
  107.             }
  108.             step = st_year;
  109.             max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 365);
  110.             scale = 60 * 60 * 24 * 365;
  111.             break;

  112.         case 'M':
  113.             if (step >= st_month) {
  114.                 return NGX_ERROR;
  115.             }
  116.             step = st_month;
  117.             max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 30);
  118.             scale = 60 * 60 * 24 * 30;
  119.             break;

  120.         case 'w':
  121.             if (step >= st_week) {
  122.                 return NGX_ERROR;
  123.             }
  124.             step = st_week;
  125.             max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 7);
  126.             scale = 60 * 60 * 24 * 7;
  127.             break;

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

  136.         case 'h':
  137.             if (step >= st_hour) {
  138.                 return NGX_ERROR;
  139.             }
  140.             step = st_hour;
  141.             max = NGX_MAX_INT32_VALUE / (60 * 60);
  142.             scale = 60 * 60;
  143.             break;

  144.         case 'm':
  145.             if (*p == 's') {
  146.                 if (is_sec || step >= st_msec) {
  147.                     return NGX_ERROR;
  148.                 }
  149.                 p++;
  150.                 step = st_msec;
  151.                 max = NGX_MAX_INT32_VALUE;
  152.                 scale = 1;
  153.                 break;
  154.             }

  155.             if (step >= st_min) {
  156.                 return NGX_ERROR;
  157.             }
  158.             step = st_min;
  159.             max = NGX_MAX_INT32_VALUE / 60;
  160.             scale = 60;
  161.             break;

  162.         case 's':
  163.             if (step >= st_sec) {
  164.                 return NGX_ERROR;
  165.             }
  166.             step = st_sec;
  167.             max = NGX_MAX_INT32_VALUE;
  168.             scale = 1;
  169.             break;

  170.         case ' ':
  171.             if (step >= st_sec) {
  172.                 return NGX_ERROR;
  173.             }
  174.             step = st_last;
  175.             max = NGX_MAX_INT32_VALUE;
  176.             scale = 1;
  177.             break;

  178.         default:
  179.             return NGX_ERROR;
  180.         }

  181.         if (step != st_msec && !is_sec) {
  182.             scale *= 1000;
  183.             max /= 1000;
  184.         }

  185.         if ((ngx_uint_t) value > max) {
  186.             return NGX_ERROR;
  187.         }

  188.         total += value * scale;

  189.         if ((ngx_uint_t) total > NGX_MAX_INT32_VALUE) {
  190.             return NGX_ERROR;
  191.         }

  192.         value = 0;
  193.         scale = is_sec ? 1 : 1000;

  194.         while (p < last && *p == ' ') {
  195.             p++;
  196.         }
  197.     }

  198.     if (valid) {
  199.         return total + value * scale;
  200.     }

  201.     return NGX_ERROR;
  202. }