From: Iskren Chernev Date: Mon, 7 Aug 2017 21:38:17 +0000 (+0300) Subject: Fix rfc2822 multiple issues X-Git-Tag: 2.19.0~15^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ba763de31380a62ee9dbd98436d83d0399c92d53;p=thirdparty%2Fmoment.git Fix rfc2822 multiple issues --- diff --git a/src/lib/create/from-string.js b/src/lib/create/from-string.js index d7081e085..7c1052a3e 100644 --- a/src/lib/create/from-string.js +++ b/src/lib/create/from-string.js @@ -1,4 +1,5 @@ import { configFromStringAndFormat } from './from-string-and-format'; +import { createUTCDate } from './date-from-array'; import { configFromArray } from './from-array'; import { hooks } from '../utils/hooks'; import { deprecate } from '../utils/deprecate'; @@ -97,7 +98,7 @@ export function configFromISO(config) { } // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 -var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|(?:([+-]\d\d)(\d\d)))$/; +var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/; function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { var result = [ @@ -130,13 +131,6 @@ function preprocessRFC2822(s) { return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').trim(); } -function signedOffset(offHourStr, offMinuteStr) { - var offHour = parseInt(offHourStr, 10) || 0, - offMin = parseInt(offMinuteStr, 10) || 0, - offMinSigned = offHour < 0 ? -offMin : offMin; - return offHour * 60 + offMinSigned; -} - function checkWeekday(weekdayStr, parsedInput, config) { if (weekdayStr) { // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check. @@ -152,22 +146,28 @@ function checkWeekday(weekdayStr, parsedInput, config) { } var obsOffsets = { + UT: 0, GMT: 0, EDT: -4 * 60, EST: -5 * 60, - CDT: 5 * 60, - CST: 6 * 60, - MDT: 6 * 60, - MST: 7 * 60, - PDT: 7 * 60, - PST: 8 * 60 + CDT: -5 * 60, + CST: -6 * 60, + MDT: -6 * 60, + MST: -7 * 60, + PDT: -7 * 60, + PST: -8 * 60 }; -function calculateOffset(obsOffset, milOffset, offHourStr, offMinuteStr) { +function calculateOffset(obsOffset, militaryOffset, numOffset) { if (obsOffset) { return obsOffsets[obsOffset]; + } else if (militaryOffset) { + // the only allowed military tz is Z + return 0; } else { - return (milOffset) ? 0 : signedOffset(offHourStr, offMinuteStr); + var hm = parseInt(numOffset, 10); + var m = hm % 100, h = (hm - m) / 100; + return h * 60 + m; } } @@ -181,9 +181,11 @@ export function configFromRFC2822(config) { } config._a = parsedArray; - config._tzm = calculateOffset(match[8], match[9], match[10], match[11]); + config._tzm = calculateOffset(match[8], match[9], match[10]); + + config._d = createUTCDate.apply(null, config._a); + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); - configFromArray(config); getParsingFlags(config).rfc2822 = true; } else { config._isValid = false; diff --git a/src/test/moment/create.js b/src/test/moment/create.js index cc29957d2..652e0cf90 100644 --- a/src/test/moment/create.js +++ b/src/test/moment/create.js @@ -456,34 +456,50 @@ test('cloning carrying over utc mode', function (assert) { test('parsing RFC 2822', function (assert) { var testCases = { - 'clean RFC2822 datetime with all options': 'Tue, 01 Nov 2016 01:23:45 UT', - 'clean RFC2822 datetime without comma': 'Tue 01 Nov 2016 02:23:45 GMT', - 'clean RFC2822 datetime without seconds': 'Tue, 01 Nov 2016 03:23 +0000', - 'clean RFC2822 datetime without century': 'Tue, 01 Nov 16 04:23:45 Z', - 'clean RFC2822 datetime without day': '01 Nov 2016 05:23:45 z', - 'clean RFC2822 datetime with single-digit day-of-month': 'Tue, 1 Nov 2016 06:23:45 GMT', - 'RFC2822 datetime with CFWSs': '(Init Comment) Tue,\n 1 Nov 2016 (Split\n Comment) 07:23:45 +0000 (GMT)' + 'Tue, 01 Nov 2016 01:23:45 UT': [2016, 10, 1, 1, 23, 45, 0], + 'Sun, 12 Apr 2015 05:06:07 GMT': [2015, 3, 12, 5, 6, 7, 0], + 'Tue, 01 Nov 2016 01:23:45 +0000': [2016, 10, 1, 1, 23, 45, 0], + 'Tue, 01 Nov 16 04:23:45 Z': [2016, 10, 1, 4, 23, 45, 0], + '01 Nov 2016 05:23:45 z': [2016, 10, 1, 5, 23, 45, 0], + '(Init Comment) Tue,\n 1 Nov 2016 (Split\n Comment) 07:23:45 +0000 (GMT)': [2016, 10, 1, 7, 23, 45, 0], + 'Mon, 02 Jan 2017 06:00:00 -0800': [2017, 0, 2, 6, 0, 0, -8 * 60], + 'Mon, 02 Jan 2017 06:00:00 +0800': [2017, 0, 2, 6, 0, 0, +8 * 60], + 'Mon, 02 Jan 2017 06:00:00 +0330': [2017, 0, 2, 6, 0, 0, + (3 * 60 + 30)], + 'Mon, 02 Jan 2017 06:00:00 -0330': [2017, 0, 2, 6, 0, 0, - (3 * 60 + 30)], + 'Mon, 02 Jan 2017 06:00:00 PST': [2017, 0, 2, 6, 0, 0, -8 * 60], + 'Mon, 02 Jan 2017 06:00:00 PDT': [2017, 0, 2, 6, 0, 0, -7 * 60], + 'Mon, 02 Jan 2017 06:00:00 MST': [2017, 0, 2, 6, 0, 0, -7 * 60], + 'Mon, 02 Jan 2017 06:00:00 MDT': [2017, 0, 2, 6, 0, 0, -6 * 60], + 'Mon, 02 Jan 2017 06:00:00 CST': [2017, 0, 2, 6, 0, 0, -6 * 60], + 'Mon, 02 Jan 2017 06:00:00 CDT': [2017, 0, 2, 6, 0, 0, -5 * 60], + 'Mon, 02 Jan 2017 06:00:00 EST': [2017, 0, 2, 6, 0, 0, -5 * 60], + 'Mon, 02 Jan 2017 06:00:00 EDT': [2017, 0, 2, 6, 0, 0, -4 * 60], }; - var testCase; - for (testCase in testCases) { - var testResult = moment(testCases[testCase], moment.RFC_2822, true); - assert.ok(testResult.isValid(), testResult); - assert.ok(testResult.parsingFlags().rfc2822, testResult + ' - rfc2822 parsingFlag'); + var inp, tokens; + + for (inp in testCases) { + var tokens = testCases[inp]; + var parseResult = moment(inp, moment.RFC_2822, true).parseZone(); + var expResult = moment.utc(tokens.slice(0, 6)).utcOffset(tokens[6], true); + assert.ok(parseResult.isValid(), inp); + assert.ok(parseResult.parsingFlags().rfc2822, inp + ' - rfc2822 parsingFlag'); + assert.equal(parseResult.utcOffset(), expResult.utcOffset(), inp + ' - zone'); + assert.equal(parseResult.valueOf(), expResult.valueOf(), inp + ' - correctness'); } }); test('non RFC 2822 strings', function (assert) { var testCases = { 'RFC2822 datetime with all options but invalid day delimiter': 'Tue. 01 Nov 2016 01:23:45 GMT', - 'RFC2822 datetime with mismatching Day (week v date)': 'Mon, 01 Nov 2016 01:23:45 GMT' + 'RFC2822 datetime with mismatching Day (weekday v date)': 'Mon, 01 Nov 2016 01:23:45 GMT' }; var testCase; for (testCase in testCases) { var testResult = moment(testCases[testCase], moment.RFC_2822, true); - assert.ok(!testResult.isValid(), testResult); - assert.ok(!testResult.parsingFlags().rfc2822, testResult + ' - rfc2822 parsingFlag'); + assert.ok(!testResult.isValid(), testCase + ': ' + testResult + ' - is invalid rfc2822'); + assert.ok(!testResult.parsingFlags().rfc2822, testCase + ': ' + testResult + ' - rfc2822 parsingFlag'); } });