Bug 1310077 - Implement the value sanitizing algorithm for <input type=datetime-local>. r=smaug
This commit is contained in:
@@ -5314,6 +5314,15 @@ HTMLInputElement::SanitizeValue(nsAString& aValue)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NS_FORM_INPUT_DATETIME_LOCAL:
|
||||
{
|
||||
if (!aValue.IsEmpty() && !IsValidDateTimeLocal(aValue)) {
|
||||
aValue.Truncate();
|
||||
} else {
|
||||
NormalizeDateTimeLocal(aValue);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NS_FORM_INPUT_COLOR:
|
||||
{
|
||||
if (IsValidSimpleColor(aValue)) {
|
||||
@@ -5401,7 +5410,15 @@ HTMLInputElement::IsValidDate(const nsAString& aValue) const
|
||||
return ParseDate(aValue, &year, &month, &day);
|
||||
}
|
||||
|
||||
bool HTMLInputElement::ParseYear(const nsAString& aValue, uint32_t* aYear) const
|
||||
bool
|
||||
HTMLInputElement::IsValidDateTimeLocal(const nsAString& aValue) const
|
||||
{
|
||||
uint32_t year, month, day, time;
|
||||
return ParseDateTimeLocal(aValue, &year, &month, &day, &time);
|
||||
}
|
||||
|
||||
bool
|
||||
HTMLInputElement::ParseYear(const nsAString& aValue, uint32_t* aYear) const
|
||||
{
|
||||
if (aValue.Length() < 4) {
|
||||
return false;
|
||||
@@ -5411,9 +5428,9 @@ bool HTMLInputElement::ParseYear(const nsAString& aValue, uint32_t* aYear) const
|
||||
*aYear > 0;
|
||||
}
|
||||
|
||||
bool HTMLInputElement::ParseMonth(const nsAString& aValue,
|
||||
uint32_t* aYear,
|
||||
uint32_t* aMonth) const
|
||||
bool
|
||||
HTMLInputElement::ParseMonth(const nsAString& aValue, uint32_t* aYear,
|
||||
uint32_t* aMonth) const
|
||||
{
|
||||
// Parse the year, month values out a string formatted as 'yyyy-mm'.
|
||||
if (aValue.Length() < 7) {
|
||||
@@ -5434,9 +5451,9 @@ bool HTMLInputElement::ParseMonth(const nsAString& aValue,
|
||||
*aMonth > 0 && *aMonth <= 12;
|
||||
}
|
||||
|
||||
bool HTMLInputElement::ParseWeek(const nsAString& aValue,
|
||||
uint32_t* aYear,
|
||||
uint32_t* aWeek) const
|
||||
bool
|
||||
HTMLInputElement::ParseWeek(const nsAString& aValue, uint32_t* aYear,
|
||||
uint32_t* aWeek) const
|
||||
{
|
||||
// Parse the year, month values out a string formatted as 'yyyy-Www'.
|
||||
if (aValue.Length() < 8) {
|
||||
@@ -5462,10 +5479,9 @@ bool HTMLInputElement::ParseWeek(const nsAString& aValue,
|
||||
|
||||
}
|
||||
|
||||
bool HTMLInputElement::ParseDate(const nsAString& aValue,
|
||||
uint32_t* aYear,
|
||||
uint32_t* aMonth,
|
||||
uint32_t* aDay) const
|
||||
bool
|
||||
HTMLInputElement::ParseDate(const nsAString& aValue, uint32_t* aYear,
|
||||
uint32_t* aMonth, uint32_t* aDay) const
|
||||
{
|
||||
/*
|
||||
* Parse the year, month, day values out a date string formatted as 'yyyy-mm-dd'.
|
||||
@@ -5492,6 +5508,85 @@ bool HTMLInputElement::ParseDate(const nsAString& aValue,
|
||||
*aDay > 0 && *aDay <= NumberOfDaysInMonth(*aMonth, *aYear);
|
||||
}
|
||||
|
||||
bool
|
||||
HTMLInputElement::ParseDateTimeLocal(const nsAString& aValue, uint32_t* aYear,
|
||||
uint32_t* aMonth, uint32_t* aDay,
|
||||
uint32_t* aTime) const
|
||||
{
|
||||
// Parse the year, month, day and time values out a string formatted as
|
||||
// 'yyyy-mm-ddThh:mm[:ss.s] or 'yyyy-mm-dd hh:mm[:ss.s]', where fractions of
|
||||
// seconds can be 1 to 3 digits.
|
||||
// The minimum length allowed is 16, which is of the form 'yyyy-mm-ddThh:mm'
|
||||
// or 'yyyy-mm-dd hh:mm'.
|
||||
if (aValue.Length() < 16) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint32_t sepIndex = 10;
|
||||
if (aValue[sepIndex] != 'T' && aValue[sepIndex] != ' ') {
|
||||
return false;
|
||||
}
|
||||
|
||||
const nsAString& dateStr = Substring(aValue, 0, sepIndex);
|
||||
if (!ParseDate(dateStr, aYear, aMonth, aDay)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const nsAString& timeStr = Substring(aValue, sepIndex + 1,
|
||||
aValue.Length() - sepIndex + 1);
|
||||
if (!ParseTime(timeStr, aTime)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
HTMLInputElement::NormalizeDateTimeLocal(nsAString& aValue) const
|
||||
{
|
||||
if (aValue.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use 'T' as the separator between date string and time string.
|
||||
const uint32_t sepIndex = 10;
|
||||
if (aValue[sepIndex] == ' ') {
|
||||
aValue.Replace(sepIndex, 1, NS_LITERAL_STRING("T"));
|
||||
}
|
||||
|
||||
// Time expressed as the shortest possible string.
|
||||
if (aValue.Length() == 16) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Fractions of seconds part is optional, ommit it if it's 0.
|
||||
if (aValue.Length() > 19) {
|
||||
uint32_t milliseconds;
|
||||
if (!DigitSubStringToNumber(aValue, 20, aValue.Length() - 20,
|
||||
&milliseconds)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (milliseconds != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
aValue.Cut(19, aValue.Length() - 19);
|
||||
}
|
||||
|
||||
// Seconds part is optional, ommit it if it's 0.
|
||||
uint32_t seconds;
|
||||
if (!DigitSubStringToNumber(aValue, 17, aValue.Length() - 17, &seconds)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (seconds != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
aValue.Cut(16, aValue.Length() - 16);
|
||||
}
|
||||
|
||||
double
|
||||
HTMLInputElement::DaysSinceEpochFromWeek(uint32_t aYear, uint32_t aWeek) const
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user