diff --git a/mozilla/extensions/schema-validation/src/nsSchemaValidator.cpp b/mozilla/extensions/schema-validation/src/nsSchemaValidator.cpp index e73acda4a09..f9c6c656a44 100644 --- a/mozilla/extensions/schema-validation/src/nsSchemaValidator.cpp +++ b/mozilla/extensions/schema-validation/src/nsSchemaValidator.cpp @@ -2656,15 +2656,13 @@ nsSchemaValidator::IsValidSchemaDate(const nsAString & aNodeValue, /* http://www.w3.org/TR/xmlschema-2/#date - (-)CCYY-MM-DDT - then either: Z - or [+/-]hh:mm + (-)CCYY-MM-DD + then optionally either: + Z + or [+/-]hh:mm */ - // append 'T' to end to make ParseSchemaDate happy. - dateString.Append('T'); - - isValid = nsSchemaValidatorUtils::ParseSchemaDate(dateString, aResult); + isValid = nsSchemaValidatorUtils::ParseSchemaDate(dateString, PR_TRUE, aResult); return isValid; } diff --git a/mozilla/extensions/schema-validation/src/nsSchemaValidatorUtils.cpp b/mozilla/extensions/schema-validation/src/nsSchemaValidatorUtils.cpp index 3f61db1a61e..040582d63a0 100644 --- a/mozilla/extensions/schema-validation/src/nsSchemaValidatorUtils.cpp +++ b/mozilla/extensions/schema-validation/src/nsSchemaValidatorUtils.cpp @@ -170,9 +170,11 @@ nsSchemaValidatorUtils::ParseDateTime(const nsAString & aNodeValue, // if no T, invalid if (findString >= 0) { - isValid = ParseSchemaDate(Substring(aNodeValue, 0, findString+1), &aResult->date); + // we get the date part (from 0 to before 'T') + isValid = ParseSchemaDate(Substring(aNodeValue, 0, findString), PR_FALSE, &aResult->date); if (isValid) { + // we get the time part (from after the 'T' till the end) isValid = ParseSchemaTime( Substring(aNodeValue, findString + 1, aNodeValue.Length()), &aResult->time); @@ -184,13 +186,16 @@ nsSchemaValidatorUtils::ParseDateTime(const nsAString & aNodeValue, PRBool nsSchemaValidatorUtils::ParseSchemaDate(const nsAString & aStrValue, + PRBool aAllowTimeZone, nsSchemaDate *aDate) { PRBool isValid = PR_FALSE; /* http://www.w3.org/TR/xmlschema-2/#date - (-)CCYY-MM-DDT + (-)CCYY-MM-DD + then optionally: Z + or [+/-]hh:mm */ const PRUnichar *start, *end, *buffStart; @@ -204,6 +209,8 @@ nsSchemaValidatorUtils::ParseSchemaDate(const nsAString & aStrValue, nsAutoString year; char month[3] = ""; char day[3] = ""; + char timezoneHour[3] = ""; + char timezoneMinute[3] = ""; // if year is negative, skip it if (aStrValue.First() == '-') { @@ -261,10 +268,24 @@ nsSchemaValidatorUtils::ParseSchemaDate(const nsAString & aStrValue, // day if (buffLength > 2) { done = PR_TRUE; - } else if (currentChar == 'T') { - if ((start == end) && (buffLength == 2) && (strcmp(day, "31") < 1)) + } else if (currentChar == 'Z') { + if (aAllowTimeZone) { + if ((start == end) && (buffLength == 2) && (strcmp(day, "31") < 1)) { isValid = PR_TRUE; + } + } + done = PR_TRUE; + } else if ((currentChar == '+') || (currentChar == '-')) { + // timezone + if (aAllowTimeZone) { + state = 3; + buffLength = 0; + buffStart = start; + } else { + // no timezones allowed + done = PR_TRUE; + } } else { // has to be a numerical character or else abort if ((currentChar > '9') || (currentChar < '0')) @@ -273,10 +294,26 @@ nsSchemaValidatorUtils::ParseSchemaDate(const nsAString & aStrValue, day[buffLength] = currentChar; } buffLength++; + + // are we at the end? + if (start == end && buffLength == 2) { + isValid = PR_TRUE; + done = PR_TRUE; + } } break; } + case 3: { + // timezone hh:mm + if (end-buffStart == 5) { + isValid = ParseSchemaTimeZone(Substring(buffStart, end), timezoneHour, + timezoneMinute); + } + + done = PR_TRUE; + break; + } } } diff --git a/mozilla/extensions/schema-validation/src/nsSchemaValidatorUtils.h b/mozilla/extensions/schema-validation/src/nsSchemaValidatorUtils.h index 0df0ecc78cc..0cafeb72273 100644 --- a/mozilla/extensions/schema-validation/src/nsSchemaValidatorUtils.h +++ b/mozilla/extensions/schema-validation/src/nsSchemaValidatorUtils.h @@ -182,7 +182,9 @@ public: static PRBool ParseDateTime(const nsAString & aNodeValue, nsSchemaDateTime *aResult); - static PRBool ParseSchemaDate(const nsAString & aStrValue, nsSchemaDate *aDate); + static PRBool ParseSchemaDate(const nsAString & aStrValue, + PRBool aAllowTimeZone, + nsSchemaDate *aDate); static PRBool ParseSchemaTime(const nsAString & aStrValue, nsSchemaTime *aTime); static PRBool ParseSchemaTimeZone(const nsAString & aStrValue, diff --git a/mozilla/extensions/schema-validation/tests/schema.html b/mozilla/extensions/schema-validation/tests/schema.html index 4346edb8ef9..c1b27710625 100644 --- a/mozilla/extensions/schema-validation/tests/schema.html +++ b/mozilla/extensions/schema-validation/tests/schema.html @@ -468,6 +468,8 @@ validate("-2004-02-28T12:21:03.434Z", "datetime-test-1", true); validate("-2004-02-28T12:21:03-04:00", "datetime-test-1", true); validate("-2004-02-30T12:21:03Z", "datetime-test-1", false); + validate("2004-02-28ZT24:21:03Z", "datetime-test-1", false); + validate("2004-02-28+06:00T24:21:03Z", "datetime-test-1", false); validate("2004-02-11T12:21:03Z", "datetime-test-2", true); validate("2004-02-18T00:00:00Z", "datetime-test-2", true); @@ -501,6 +503,15 @@ // leap year test validate("2000-02-29", "date-test-1", true); validate("2001-02-29", "date-test-1", false); + // timezone test + validate("2001-01-18Z", "date-test-1", true); + validate("2001-01-18A", "date-test-1", false); + validate("2001-01-18Z2", "date-test-1", false); + validate("2007-01-01-06:00", "date-test-1", true); + validate("2007-01-01+06:00", "date-test-1", true); + validate("2007-01-01A06:00", "date-test-1", false); + validate("2007-01-01-06:00Z", "date-test-1", false); + validate("2007-01-01Z-06:00", "date-test-1", false); validate("2004-02-17", "date-test-2", true); validate("2004-02-18", "date-test-2", false);