Annotation of embedaddon/nginx/src/http/ngx_http_parse_time.c, revision 1.1.1.1

1.1       misho       1: 
                      2: /*
                      3:  * Copyright (C) Igor Sysoev
                      4:  * Copyright (C) Nginx, Inc.
                      5:  */
                      6: 
                      7: 
                      8: #include <ngx_config.h>
                      9: #include <ngx_core.h>
                     10: #include <ngx_http.h>
                     11: 
                     12: 
                     13: static ngx_uint_t  mday[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
                     14: 
                     15: time_t
                     16: ngx_http_parse_time(u_char *value, size_t len)
                     17: {
                     18:     u_char      *p, *end;
                     19:     ngx_int_t    month;
                     20:     ngx_uint_t   day, year, hour, min, sec;
                     21:     uint64_t     time;
                     22:     enum {
                     23:         no = 0,
                     24:         rfc822,   /* Tue, 10 Nov 2002 23:50:13   */
                     25:         rfc850,   /* Tuesday, 10-Dec-02 23:50:13 */
                     26:         isoc      /* Tue Dec 10 23:50:13 2002    */
                     27:     } fmt;
                     28: 
                     29:     fmt = 0;
                     30:     end = value + len;
                     31: 
                     32: #if (NGX_SUPPRESS_WARN)
                     33:     day = 32;
                     34:     year = 2038;
                     35: #endif
                     36: 
                     37:     for (p = value; p < end; p++) {
                     38:         if (*p == ',') {
                     39:             break;
                     40:         }
                     41: 
                     42:         if (*p == ' ') {
                     43:             fmt = isoc;
                     44:             break;
                     45:         }
                     46:     }
                     47: 
                     48:     for (p++; p < end; p++)
                     49:         if (*p != ' ') {
                     50:             break;
                     51:         }
                     52: 
                     53:     if (end - p < 18) {
                     54:         return NGX_ERROR;
                     55:         }
                     56: 
                     57:     if (fmt != isoc) {
                     58:         if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
                     59:             return NGX_ERROR;
                     60:         }
                     61: 
                     62:         day = (*p - '0') * 10 + *(p + 1) - '0';
                     63:         p += 2;
                     64: 
                     65:         if (*p == ' ') {
                     66:             if (end - p < 18) {
                     67:                 return NGX_ERROR;
                     68:             }
                     69:             fmt = rfc822;
                     70: 
                     71:         } else if (*p == '-') {
                     72:             fmt = rfc850;
                     73: 
                     74:         } else {
                     75:             return NGX_ERROR;
                     76:         }
                     77: 
                     78:         p++;
                     79:     }
                     80: 
                     81:     switch (*p) {
                     82: 
                     83:     case 'J':
                     84:         month = *(p + 1) == 'a' ? 0 : *(p + 2) == 'n' ? 5 : 6;
                     85:         break;
                     86: 
                     87:     case 'F':
                     88:         month = 1;
                     89:         break;
                     90: 
                     91:     case 'M':
                     92:         month = *(p + 2) == 'r' ? 2 : 4;
                     93:         break;
                     94: 
                     95:     case 'A':
                     96:         month = *(p + 1) == 'p' ? 3 : 7;
                     97:         break;
                     98: 
                     99:     case 'S':
                    100:         month = 8;
                    101:         break;
                    102: 
                    103:     case 'O':
                    104:         month = 9;
                    105:         break;
                    106: 
                    107:     case 'N':
                    108:         month = 10;
                    109:         break;
                    110: 
                    111:     case 'D':
                    112:         month = 11;
                    113:         break;
                    114: 
                    115:     default:
                    116:         return NGX_ERROR;
                    117:     }
                    118: 
                    119:     p += 3;
                    120: 
                    121:     if ((fmt == rfc822 && *p != ' ') || (fmt == rfc850 && *p != '-')) {
                    122:         return NGX_ERROR;
                    123:     }
                    124: 
                    125:     p++;
                    126: 
                    127:     if (fmt == rfc822) {
                    128:         if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9'
                    129:             || *(p + 2) < '0' || *(p + 2) > '9'
                    130:             || *(p + 3) < '0' || *(p + 3) > '9')
                    131:         {
                    132:             return NGX_ERROR;
                    133:         }
                    134: 
                    135:         year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100
                    136:                + (*(p + 2) - '0') * 10 + *(p + 3) - '0';
                    137:         p += 4;
                    138: 
                    139:     } else if (fmt == rfc850) {
                    140:         if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
                    141:             return NGX_ERROR;
                    142:         }
                    143: 
                    144:         year = (*p - '0') * 10 + *(p + 1) - '0';
                    145:         year += (year < 70) ? 2000 : 1900;
                    146:         p += 2;
                    147:     }
                    148: 
                    149:     if (fmt == isoc) {
                    150:         if (*p == ' ') {
                    151:             p++;
                    152:         }
                    153: 
                    154:         if (*p < '0' || *p > '9') {
                    155:             return NGX_ERROR;
                    156:         }
                    157: 
                    158:         day = *p++ - '0';
                    159: 
                    160:         if (*p != ' ') {
                    161:             if (*p < '0' || *p > '9') {
                    162:                 return NGX_ERROR;
                    163:             }
                    164: 
                    165:             day = day * 10 + *p++ - '0';
                    166:         }
                    167: 
                    168:         if (end - p < 14) {
                    169:             return NGX_ERROR;
                    170:         }
                    171:     }
                    172: 
                    173:     if (*p++ != ' ') {
                    174:         return NGX_ERROR;
                    175:     }
                    176: 
                    177:     if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
                    178:         return NGX_ERROR;
                    179:     }
                    180: 
                    181:     hour = (*p - '0') * 10 + *(p + 1) - '0';
                    182:     p += 2;
                    183: 
                    184:     if (*p++ != ':') {
                    185:         return NGX_ERROR;
                    186:     }
                    187: 
                    188:     if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
                    189:         return NGX_ERROR;
                    190:     }
                    191: 
                    192:     min = (*p - '0') * 10 + *(p + 1) - '0';
                    193:     p += 2;
                    194: 
                    195:     if (*p++ != ':') {
                    196:         return NGX_ERROR;
                    197:     }
                    198: 
                    199:     if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
                    200:         return NGX_ERROR;
                    201:     }
                    202: 
                    203:     sec = (*p - '0') * 10 + *(p + 1) - '0';
                    204: 
                    205:     if (fmt == isoc) {
                    206:         p += 2;
                    207: 
                    208:         if (*p++ != ' ') {
                    209:             return NGX_ERROR;
                    210:         }
                    211: 
                    212:         if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9'
                    213:             || *(p + 2) < '0' || *(p + 2) > '9'
                    214:             || *(p + 3) < '0' || *(p + 3) > '9')
                    215:         {
                    216:             return NGX_ERROR;
                    217:         }
                    218: 
                    219:         year = (*p - '0') * 1000 + (*(p + 1) - '0') * 100
                    220:                + (*(p + 2) - '0') * 10 + *(p + 3) - '0';
                    221:     }
                    222: 
                    223:     if (hour > 23 || min > 59 || sec > 59) {
                    224:          return NGX_ERROR;
                    225:     }
                    226: 
                    227:     if (day == 29 && month == 1) {
                    228:         if ((year & 3) || ((year % 100 == 0) && (year % 400) != 0)) {
                    229:             return NGX_ERROR;
                    230:         }
                    231: 
                    232:     } else if (day > mday[month]) {
                    233:         return NGX_ERROR;
                    234:     }
                    235: 
                    236:     /*
                    237:      * shift new year to March 1 and start months from 1 (not 0),
                    238:      * it is needed for Gauss' formula
                    239:      */
                    240: 
                    241:     if (--month <= 0) {
                    242:         month += 12;
                    243:         year -= 1;
                    244:     }
                    245: 
                    246:     /* Gauss' formula for Gregorian days since March 1, 1 BC */
                    247: 
                    248:     time = (uint64_t) (
                    249:             /* days in years including leap years since March 1, 1 BC */
                    250: 
                    251:             365 * year + year / 4 - year / 100 + year / 400
                    252: 
                    253:             /* days before the month */
                    254: 
                    255:             + 367 * month / 12 - 30
                    256: 
                    257:             /* days before the day */
                    258: 
                    259:             + day - 1
                    260: 
                    261:             /*
                    262:              * 719527 days were between March 1, 1 BC and March 1, 1970,
                    263:              * 31 and 28 days were in January and February 1970
                    264:              */
                    265: 
                    266:             - 719527 + 31 + 28) * 86400 + hour * 3600 + min * 60 + sec;
                    267: 
                    268: #if (NGX_TIME_T_SIZE <= 4)
                    269: 
                    270:     if (time > 0x7fffffff) {
                    271:         return NGX_ERROR;
                    272:     }
                    273: 
                    274: #endif
                    275: 
                    276:     return (time_t) time;
                    277: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>