Title: [104251] trunk
Revision
104251
Author
[email protected]
Date
2012-01-05 17:08:34 -0800 (Thu, 05 Jan 2012)

Log Message

Date parsing is too restrictive.
https://bugs.webkit.org/show_bug.cgi?id=75671

Reviewed by Oliver Hunt.

Source/_javascript_Core: 

ES5 date parsing currently requires all fields to be present, which does not match the spec (ES5.1 15.9.1.15).
The spec allow a date to be date only, or date + time.

The date portion on the should match: (pseudocode!:)
    [(+|-)YY]YYYY[-MM[-DD]]
though we are slightly more liberal (permitted by the spec), allowing:
    [+|-]Y+[-MM[-DD]]
The time portion should match:
    THH:mm[:ss[.sss]][Z|(+|-)HH:mm]
again we're slightly more liberal, allowing:
    THH:mm[:ss[.s+]][Z|(+|-)HH:mm]

* wtf/DateMath.cpp:
(WTF::parseES5DatePortion):
    - Month/day fields are optional, default to 01.
(WTF::parseES5TimePortion):
    - Hours/Minutes are requires, seconds/timezone are optional.
(WTF::parseES5DateFromNullTerminatedCharacters):
    - Dates may be date only, or date + time.

LayoutTests: 

* fast/js/date-parse-test-expected.txt:
* fast/js/script-tests/date-parse-test.js:
    - Add more test cases for Date.parse.

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (104250 => 104251)


--- trunk/LayoutTests/ChangeLog	2012-01-06 01:05:10 UTC (rev 104250)
+++ trunk/LayoutTests/ChangeLog	2012-01-06 01:08:34 UTC (rev 104251)
@@ -1,3 +1,14 @@
+2012-01-05  Gavin Barraclough  <[email protected]>
+
+        Date parsing is too restrictive.
+        https://bugs.webkit.org/show_bug.cgi?id=75671
+
+        Reviewed by Oliver Hunt.
+
+        * fast/js/date-parse-test-expected.txt:
+        * fast/js/script-tests/date-parse-test.js:
+            - Add more test cases for Date.parse.
+
 2012-01-05  Adam Barth  <[email protected]>
 
         Mark flaky test as flaky.  Filed

Modified: trunk/LayoutTests/fast/js/date-parse-test-expected.txt (104250 => 104251)


--- trunk/LayoutTests/fast/js/date-parse-test-expected.txt	2012-01-06 01:05:10 UTC (rev 104250)
+++ trunk/LayoutTests/fast/js/date-parse-test-expected.txt	2012-01-06 01:08:34 UTC (rev 104251)
@@ -29,6 +29,59 @@
 PASS Date.parse("1995-02-29T00:00:00Z") is NaN
 PASS Date.parse("1995-12-25 01:30:00Z") is NaN
 PASS Date.parse("1995-12-25T01:30:00z") is NaN
+PASS Number(Date.parse('1970')) is 0
+PASS Number(Date.parse('1970-01')) is 0
+PASS Number(Date.parse('1970-01-01')) is 0
+PASS Number(Date.parse('1970T00:00')) is 0
+PASS Number(Date.parse('1970-01T00:00')) is 0
+PASS Number(Date.parse('1970-01-01T00:00')) is 0
+PASS Number(Date.parse('1970T00:00:00')) is 0
+PASS Number(Date.parse('1970-01T00:00:00')) is 0
+PASS Number(Date.parse('1970-01-01T00:00:00')) is 0
+PASS Number(Date.parse('1970T00:00:00.000')) is 0
+PASS Number(Date.parse('1970-01T00:00:00.000')) is 0
+PASS Number(Date.parse('1970-01-01T00:00:00.000')) is 0
+PASS Number(Date.parse('1970T00:00Z')) is 0
+PASS Number(Date.parse('1970-01T00:00Z')) is 0
+PASS Number(Date.parse('1970-01-01T00:00Z')) is 0
+PASS Number(Date.parse('1970T00:00:00Z')) is 0
+PASS Number(Date.parse('1970-01T00:00:00Z')) is 0
+PASS Number(Date.parse('1970-01-01T00:00:00Z')) is 0
+PASS Number(Date.parse('1970T00:00:00.000Z')) is 0
+PASS Number(Date.parse('1970-01T00:00:00.000Z')) is 0
+PASS Number(Date.parse('1970-01-01T00:00:00.000Z')) is 0
+PASS Number(Date.parse('1970T00:00+00:00')) is 0
+PASS Number(Date.parse('1970-01T00:00+00:00')) is 0
+PASS Number(Date.parse('1970-01-01T00:00+00:00')) is 0
+PASS Number(Date.parse('1970T00:00:00+00:00')) is 0
+PASS Number(Date.parse('1970-01T00:00:00+00:00')) is 0
+PASS Number(Date.parse('1970-01-01T00:00:00+00:00')) is 0
+PASS Number(Date.parse('1970T00:00:00.000+00:00')) is 0
+PASS Number(Date.parse('1970-01T00:00:00.000+00:00')) is 0
+PASS Number(Date.parse('1970-01-01T00:00:00.000+00:00')) is 0
+PASS String(Date.parse('')) is "NaN"
+PASS String(Date.parse('T00:00:00.000')) is "NaN"
+PASS String(Date.parse('T00:00:00.000Z')) is "NaN"
+PASS String(Date.parse('Z')) is "NaN"
+PASS String(Date.parse('1970-01-01Z')) is "NaN"
+PASS String(Date.parse('1970-01-01+00:00')) is "NaN"
+PASS String(Date.parse('1970-')) is "NaN"
+PASS String(Date.parse('1970-01-')) is "NaN"
+PASS String(Date.parse('1970-01-01T')) is "NaN"
+PASS String(Date.parse('1970-01-01T0')) is "NaN"
+PASS String(Date.parse('1970-01-01T00')) is "NaN"
+PASS String(Date.parse('1970-01-01T00:')) is "NaN"
+PASS String(Date.parse('1970-01-01T00:0')) is "NaN"
+PASS String(Date.parse('1970-01-01T0:0')) is "NaN"
+PASS String(Date.parse('1970-01-01T00:00:')) is "NaN"
+PASS String(Date.parse('1970-01-01T00:00:00.')) is "NaN"
+PASS String(Date.parse('1970-01-01T00:00:00.000-')) is "NaN"
+PASS String(Date.parse('1970-01-01T00:00:00.000+')) is "NaN"
+PASS String(Date.parse('1970-01-01T00:00:00.000+0')) is "NaN"
+PASS String(Date.parse('1970-01-01T00:00:00.000+00')) is "NaN"
+PASS String(Date.parse('1970-01-01T00:00:00.000+00:')) is "NaN"
+PASS String(Date.parse('1970-01-01T00:00:00.000+00:0')) is "NaN"
+PASS String(Date.parse('1970-01-01T00:00:00.000+0:0')) is "NaN"
 PASS Date.parse("Dec 25 1995 GMT") == 819849600000 is true
 PASS Date.parse("DEC 25 1995 GMT") == 819849600000 is true
 PASS Date.parse("dec 25 1995 gmt") == 819849600000 is true

Modified: trunk/LayoutTests/fast/js/script-tests/date-parse-test.js (104250 => 104251)


--- trunk/LayoutTests/fast/js/script-tests/date-parse-test.js	2012-01-06 01:05:10 UTC (rev 104250)
+++ trunk/LayoutTests/fast/js/script-tests/date-parse-test.js	2012-01-06 01:08:34 UTC (rev 104251)
@@ -68,7 +68,72 @@
 testDateParseExact("1995-12-25 01:30:00Z", "NaN");
 testDateParseExact("1995-12-25T01:30:00z", "NaN");
 
+// Date-only dates.
+shouldBe("Number(Date.parse('1970'))", '0');
+shouldBe("Number(Date.parse('1970-01'))", '0');
+shouldBe("Number(Date.parse('1970-01-01'))", '0');
+// Date-time dates
+shouldBe("Number(Date.parse('1970T00:00'))", '0');
+shouldBe("Number(Date.parse('1970-01T00:00'))", '0');
+shouldBe("Number(Date.parse('1970-01-01T00:00'))", '0');
+shouldBe("Number(Date.parse('1970T00:00:00'))", '0');
+shouldBe("Number(Date.parse('1970-01T00:00:00'))", '0');
+shouldBe("Number(Date.parse('1970-01-01T00:00:00'))", '0');
+shouldBe("Number(Date.parse('1970T00:00:00.000'))", '0');
+shouldBe("Number(Date.parse('1970-01T00:00:00.000'))", '0');
+shouldBe("Number(Date.parse('1970-01-01T00:00:00.000'))", '0');
+// Date-time dates with UTC timezone
+shouldBe("Number(Date.parse('1970T00:00Z'))", '0');
+shouldBe("Number(Date.parse('1970-01T00:00Z'))", '0');
+shouldBe("Number(Date.parse('1970-01-01T00:00Z'))", '0');
+shouldBe("Number(Date.parse('1970T00:00:00Z'))", '0');
+shouldBe("Number(Date.parse('1970-01T00:00:00Z'))", '0');
+shouldBe("Number(Date.parse('1970-01-01T00:00:00Z'))", '0');
+shouldBe("Number(Date.parse('1970T00:00:00.000Z'))", '0');
+shouldBe("Number(Date.parse('1970-01T00:00:00.000Z'))", '0');
+shouldBe("Number(Date.parse('1970-01-01T00:00:00.000Z'))", '0');
+// Date-time dates with timezone
+shouldBe("Number(Date.parse('1970T00:00+00:00'))", '0');
+shouldBe("Number(Date.parse('1970-01T00:00+00:00'))", '0');
+shouldBe("Number(Date.parse('1970-01-01T00:00+00:00'))", '0');
+shouldBe("Number(Date.parse('1970T00:00:00+00:00'))", '0');
+shouldBe("Number(Date.parse('1970-01T00:00:00+00:00'))", '0');
+shouldBe("Number(Date.parse('1970-01-01T00:00:00+00:00'))", '0');
+shouldBe("Number(Date.parse('1970T00:00:00.000+00:00'))", '0');
+shouldBe("Number(Date.parse('1970-01T00:00:00.000+00:00'))", '0');
+shouldBe("Number(Date.parse('1970-01-01T00:00:00.000+00:00'))", '0');
 
+// Year may not be omitted
+shouldBe("String(Date.parse(''))", '"NaN"');
+shouldBe("String(Date.parse('T00:00:00.000'))", '"NaN"');
+shouldBe("String(Date.parse('T00:00:00.000Z'))", '"NaN"');
+shouldBe("String(Date.parse('Z'))", '"NaN"');
+// Timezone only valid with a time.
+shouldBe("String(Date.parse('1970-01-01Z'))", '"NaN"');
+shouldBe("String(Date.parse('1970-01-01+00:00'))", '"NaN"');
+// Month/day expected after '-'.
+shouldBe("String(Date.parse('1970-'))", '"NaN"');
+shouldBe("String(Date.parse('1970-01-'))", '"NaN"');
+// Hours & minutes expected after 'T'.
+shouldBe("String(Date.parse('1970-01-01T'))", '"NaN"');
+shouldBe("String(Date.parse('1970-01-01T0'))", '"NaN"');
+shouldBe("String(Date.parse('1970-01-01T00'))", '"NaN"');
+shouldBe("String(Date.parse('1970-01-01T00:'))", '"NaN"');
+shouldBe("String(Date.parse('1970-01-01T00:0'))", '"NaN"');
+shouldBe("String(Date.parse('1970-01-01T0:0'))", '"NaN"');
+// Seconds expected after ':'
+shouldBe("String(Date.parse('1970-01-01T00:00:'))", '"NaN"');
+// Fraction expected after '.'
+shouldBe("String(Date.parse('1970-01-01T00:00:00.'))", '"NaN"');
+// Timezone expected after '+'.
+shouldBe("String(Date.parse('1970-01-01T00:00:00.000-'))", '"NaN"');
+shouldBe("String(Date.parse('1970-01-01T00:00:00.000+'))", '"NaN"');
+shouldBe("String(Date.parse('1970-01-01T00:00:00.000+0'))", '"NaN"');
+shouldBe("String(Date.parse('1970-01-01T00:00:00.000+00'))", '"NaN"');
+shouldBe("String(Date.parse('1970-01-01T00:00:00.000+00:'))", '"NaN"');
+shouldBe("String(Date.parse('1970-01-01T00:00:00.000+00:0'))", '"NaN"');
+shouldBe("String(Date.parse('1970-01-01T00:00:00.000+0:0'))", '"NaN"');
+
 // test old implementation fallback
 
 var timeZoneOffset = Date.parse(" Dec 25 1995 1:30 ") - Date.parse(" Dec 25 1995 1:30 GMT ");
@@ -163,3 +228,4 @@
 testDateParseExact("4/13/2008 12:00 AM GMT-0024", "1208046240000");
 testDateParseExact("4/13/2008 12:00 AM GMT-123", "1208049780000");
 testDateParseExact("4/13/2008 12:00 AM GMT-1230", "1208089800000");
+

Modified: trunk/Source/_javascript_Core/ChangeLog (104250 => 104251)


--- trunk/Source/_javascript_Core/ChangeLog	2012-01-06 01:05:10 UTC (rev 104250)
+++ trunk/Source/_javascript_Core/ChangeLog	2012-01-06 01:08:34 UTC (rev 104251)
@@ -1,3 +1,30 @@
+2012-01-05  Gavin Barraclough  <[email protected]>
+
+        Date parsing is too restrictive.
+        https://bugs.webkit.org/show_bug.cgi?id=75671
+
+        Reviewed by Oliver Hunt.
+
+        ES5 date parsing currently requires all fields to be present, which does not match the spec (ES5.1 15.9.1.15).
+        The spec allow a date to be date only, or date + time.
+
+        The date portion on the should match: (pseudocode!:)
+            [(+|-)YY]YYYY[-MM[-DD]]
+        though we are slightly more liberal (permitted by the spec), allowing:
+            [+|-]Y+[-MM[-DD]]
+        The time portion should match:
+            THH:mm[:ss[.sss]][Z|(+|-)HH:mm]
+        again we're slightly more liberal, allowing:
+            THH:mm[:ss[.s+]][Z|(+|-)HH:mm]
+
+        * wtf/DateMath.cpp:
+        (WTF::parseES5DatePortion):
+            - Month/day fields are optional, default to 01.
+        (WTF::parseES5TimePortion):
+            - Hours/Minutes are requires, seconds/timezone are optional.
+        (WTF::parseES5DateFromNullTerminatedCharacters):
+            - Dates may be date only, or date + time.
+
 2012-01-05  Bruno Dilly  <[email protected]>
 
         [EFL] Undefined references to ICU_I18N symbols on WTF

Modified: trunk/Source/_javascript_Core/wtf/DateMath.cpp (104250 => 104251)


--- trunk/Source/_javascript_Core/wtf/DateMath.cpp	2012-01-06 01:05:10 UTC (rev 104250)
+++ trunk/Source/_javascript_Core/wtf/DateMath.cpp	2012-01-06 01:08:34 UTC (rev 104251)
@@ -535,91 +535,176 @@
     return true;
 }
 
-double parseES5DateFromNullTerminatedCharacters(const char* dateString)
+// Parses a date with the format YYYY[-MM[-DD]].
+// Year parsing is lenient, allows any number of digits, and +/-.
+// Returns 0 if a parse error occurs, else returns the end of the parsed portion of the string.
+static char* parseES5DatePortion(const char* currentPosition, long& year, long& month, long& day)
 {
-    // This parses a date of the form defined in ECMA-262-5, section 15.9.1.15
-    // (similar to RFC 3339 / ISO 8601: YYYY-MM-DDTHH:mm:ss[.sss]Z).
-    // In most cases it is intentionally strict (e.g. correct field widths, no stray whitespace).
-    
-    static const long daysPerMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-    
-    const char* currentPosition = dateString;
     char* postParsePosition;
-    
+
     // This is a bit more lenient on the year string than ES5 specifies:
     // instead of restricting to 4 digits (or 6 digits with mandatory +/-),
     // it accepts any integer value. Consider this an implementation fallback.
-    long year;
     if (!parseLong(currentPosition, &postParsePosition, 10, &year))
-        return std::numeric_limits<double>::quiet_NaN();
+        return 0;
+
+    // Check for presence of -MM portion.
     if (*postParsePosition != '-')
-        return std::numeric_limits<double>::quiet_NaN();
+        return postParsePosition;
     currentPosition = postParsePosition + 1;
     
-    long month;
     if (!isASCIIDigit(*currentPosition))
-        return std::numeric_limits<double>::quiet_NaN();
+        return 0;
     if (!parseLong(currentPosition, &postParsePosition, 10, &month))
-        return std::numeric_limits<double>::quiet_NaN();
-    if (*postParsePosition != '-' || (postParsePosition - currentPosition) != 2)
-        return std::numeric_limits<double>::quiet_NaN();
+        return 0;
+    if ((postParsePosition - currentPosition) != 2)
+        return 0;
+
+    // Check for presence of -DD portion.
+    if (*postParsePosition != '-')
+        return postParsePosition;
     currentPosition = postParsePosition + 1;
     
-    long day;
     if (!isASCIIDigit(*currentPosition))
-        return std::numeric_limits<double>::quiet_NaN();
+        return 0;
     if (!parseLong(currentPosition, &postParsePosition, 10, &day))
-        return std::numeric_limits<double>::quiet_NaN();
-    if (*postParsePosition != 'T' || (postParsePosition - currentPosition) != 2)
-        return std::numeric_limits<double>::quiet_NaN();
-    currentPosition = postParsePosition + 1;
-    
-    long hours;
+        return 0;
+    if ((postParsePosition - currentPosition) != 2)
+        return 0;
+    return postParsePosition;
+}
+
+// Parses a time with the format HH:mm[:ss[.sss]][Z|(+|-)00:00].
+// Fractional seconds parsing is lenient, allows any number of digits.
+// Returns 0 if a parse error occurs, else returns the end of the parsed portion of the string.
+static char* parseES5TimePortion(char* currentPosition, long& hours, long& minutes, double& seconds, long& timeZoneSeconds)
+{
+    char* postParsePosition;
     if (!isASCIIDigit(*currentPosition))
-        return std::numeric_limits<double>::quiet_NaN();
+        return 0;
     if (!parseLong(currentPosition, &postParsePosition, 10, &hours))
-        return std::numeric_limits<double>::quiet_NaN();
+        return 0;
     if (*postParsePosition != ':' || (postParsePosition - currentPosition) != 2)
-        return std::numeric_limits<double>::quiet_NaN();
+        return 0;
     currentPosition = postParsePosition + 1;
     
-    long minutes;
     if (!isASCIIDigit(*currentPosition))
-        return std::numeric_limits<double>::quiet_NaN();
+        return 0;
     if (!parseLong(currentPosition, &postParsePosition, 10, &minutes))
-        return std::numeric_limits<double>::quiet_NaN();
+        return 0;
+    if ((postParsePosition - currentPosition) != 2)
+        return 0;
+    currentPosition = postParsePosition;
+
+    // Seconds are optional.
+    if (*currentPosition == ':') {
+        ++currentPosition;
+    
+        long intSeconds;
+        if (!isASCIIDigit(*currentPosition))
+            return 0;
+        if (!parseLong(currentPosition, &postParsePosition, 10, &intSeconds))
+            return 0;
+        if ((postParsePosition - currentPosition) != 2)
+            return 0;
+        seconds = intSeconds;
+        if (*postParsePosition == '.') {
+            currentPosition = postParsePosition + 1;
+            
+            // In ECMA-262-5 it's a bit unclear if '.' can be present without milliseconds, but
+            // a reasonable interpretation guided by the given examples and RFC 3339 says "no".
+            // We check the next character to avoid reading +/- timezone hours after an invalid decimal.
+            if (!isASCIIDigit(*currentPosition))
+                return 0;
+            
+            // We are more lenient than ES5 by accepting more or less than 3 fraction digits.
+            long fracSeconds;
+            if (!parseLong(currentPosition, &postParsePosition, 10, &fracSeconds))
+                return 0;
+            
+            long numFracDigits = postParsePosition - currentPosition;
+            seconds += fracSeconds * pow(10.0, static_cast<double>(-numFracDigits));
+        }
+        currentPosition = postParsePosition;
+    }
+
+    if (*currentPosition == 'Z')
+        return currentPosition + 1;
+
+    bool tzNegative;
+    if (*currentPosition == '-')
+        tzNegative = true;
+    else if (*currentPosition == '+')
+        tzNegative = false;
+    else
+        return currentPosition; // no timezone
+    ++currentPosition;
+    
+    long tzHours;
+    long tzHoursAbs;
+    long tzMinutes;
+    
+    if (!isASCIIDigit(*currentPosition))
+        return 0;
+    if (!parseLong(currentPosition, &postParsePosition, 10, &tzHours))
+        return 0;
     if (*postParsePosition != ':' || (postParsePosition - currentPosition) != 2)
-        return std::numeric_limits<double>::quiet_NaN();
+        return 0;
+    tzHoursAbs = labs(tzHours);
     currentPosition = postParsePosition + 1;
     
-    long intSeconds;
     if (!isASCIIDigit(*currentPosition))
-        return std::numeric_limits<double>::quiet_NaN();
-    if (!parseLong(currentPosition, &postParsePosition, 10, &intSeconds))
-        return std::numeric_limits<double>::quiet_NaN();
+        return 0;
+    if (!parseLong(currentPosition, &postParsePosition, 10, &tzMinutes))
+        return 0;
     if ((postParsePosition - currentPosition) != 2)
+        return 0;
+    currentPosition = postParsePosition;
+    
+    if (tzHoursAbs > 24)
+        return 0;
+    if (tzMinutes < 0 || tzMinutes > 59)
+        return 0;
+    
+    timeZoneSeconds = 60 * (tzMinutes + (60 * tzHoursAbs));
+    if (tzNegative)
+        timeZoneSeconds = -timeZoneSeconds;
+
+    return currentPosition;
+}
+
+double parseES5DateFromNullTerminatedCharacters(const char* dateString)
+{
+    // This parses a date of the form defined in ECMA-262-5, section 15.9.1.15
+    // (similar to RFC 3339 / ISO 8601: YYYY-MM-DDTHH:mm:ss[.sss]Z).
+    // In most cases it is intentionally strict (e.g. correct field widths, no stray whitespace).
+    
+    static const long daysPerMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+    
+    // The year must be present, but the other fields may be omitted - see ES5.1 15.9.1.15.
+    long year = 0;
+    long month = 1;
+    long day = 1;
+    long hours = 0;
+    long minutes = 0;
+    double seconds = 0;
+    long timeZoneSeconds = 0;
+
+    // Parse the date YYYY[-MM[-DD]]
+    char* currentPosition = parseES5DatePortion(dateString, year, month, day);
+    if (!currentPosition)
         return std::numeric_limits<double>::quiet_NaN();
-    
-    double seconds = intSeconds;
-    if (*postParsePosition == '.') {
-        currentPosition = postParsePosition + 1;
-        
-        // In ECMA-262-5 it's a bit unclear if '.' can be present without milliseconds, but
-        // a reasonable interpretation guided by the given examples and RFC 3339 says "no".
-        // We check the next character to avoid reading +/- timezone hours after an invalid decimal.
-        if (!isASCIIDigit(*currentPosition))
+    // Look for a time portion.
+    if (*currentPosition == 'T') {
+        // Parse the time HH:mm[:ss[.sss]][Z|(+|-)00:00]
+        currentPosition = parseES5TimePortion(currentPosition + 1, hours, minutes, seconds, timeZoneSeconds);
+        if (!currentPosition)
             return std::numeric_limits<double>::quiet_NaN();
-        
-        // We are more lenient than ES5 by accepting more or less than 3 fraction digits.
-        long fracSeconds;
-        if (!parseLong(currentPosition, &postParsePosition, 10, &fracSeconds))
-            return std::numeric_limits<double>::quiet_NaN();
-        
-        long numFracDigits = postParsePosition - currentPosition;
-        seconds += fracSeconds * pow(10.0, static_cast<double>(-numFracDigits));
     }
-    currentPosition = postParsePosition;
-    
+    // Check that we have parsed all characters in the string.
+    if (*currentPosition)
+        return std::numeric_limits<double>::quiet_NaN();
+
     // A few of these checks could be done inline above, but since many of them are interrelated
     // we would be sacrificing readability to "optimize" the (presumably less common) failure path.
     if (month < 1 || month > 12)
@@ -640,53 +725,7 @@
         // Discard leap seconds by clamping to the end of a minute.
         seconds = 60;
     }
-    
-    long timeZoneSeconds = 0;
-    if (*currentPosition != 'Z') {
-        bool tzNegative;
-        if (*currentPosition == '-')
-            tzNegative = true;
-        else if (*currentPosition == '+')
-            tzNegative = false;
-        else
-            return std::numeric_limits<double>::quiet_NaN();
-        currentPosition += 1;
         
-        long tzHours;
-        long tzHoursAbs;
-        long tzMinutes;
-        
-        if (!isASCIIDigit(*currentPosition))
-            return std::numeric_limits<double>::quiet_NaN();
-        if (!parseLong(currentPosition, &postParsePosition, 10, &tzHours))
-            return std::numeric_limits<double>::quiet_NaN();
-        if (*postParsePosition != ':' || (postParsePosition - currentPosition) != 2)
-            return std::numeric_limits<double>::quiet_NaN();
-        tzHoursAbs = labs(tzHours);
-        currentPosition = postParsePosition + 1;
-        
-        if (!isASCIIDigit(*currentPosition))
-            return std::numeric_limits<double>::quiet_NaN();
-        if (!parseLong(currentPosition, &postParsePosition, 10, &tzMinutes))
-            return std::numeric_limits<double>::quiet_NaN();
-        if ((postParsePosition - currentPosition) != 2)
-            return std::numeric_limits<double>::quiet_NaN();
-        currentPosition = postParsePosition;
-        
-        if (tzHoursAbs > 24)
-            return std::numeric_limits<double>::quiet_NaN();
-        if (tzMinutes < 0 || tzMinutes > 59)
-            return std::numeric_limits<double>::quiet_NaN();
-        
-        timeZoneSeconds = 60 * (tzMinutes + (60 * tzHoursAbs));
-        if (tzNegative)
-            timeZoneSeconds = -timeZoneSeconds;
-    } else {
-        currentPosition += 1;
-    }
-    if (*currentPosition)
-        return std::numeric_limits<double>::quiet_NaN();
-    
     double dateSeconds = ymdhmsToSeconds(year, month, day, hours, minutes, seconds) - timeZoneSeconds;
     return dateSeconds * msPerSecond;
 }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to