mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 04:41:11 +00:00
Bug 1872116 - Fix year detection in checkTimeDateString r=whimboo,webdriver-reviewers,arai
Differential Revision: https://phabricator.services.mozilla.com/D197325
This commit is contained in:
parent
04392edd34
commit
7db77c05c4
@ -10,6 +10,7 @@
|
||||
#include "js/CallAndConstruct.h" // JS::Call
|
||||
#include "js/ColumnNumber.h" // JS::TaggedColumnNumberOneOrigin, JS::ColumnNumberOneOrigin
|
||||
#include "js/CharacterEncoding.h"
|
||||
#include "js/Date.h" // JS::IsISOStyleDate
|
||||
#include "js/Object.h" // JS::GetClass
|
||||
#include "js/PropertyAndElement.h" // JS_DefineProperty, JS_DefinePropertyById, JS_Enumerate, JS_GetProperty, JS_GetPropertyById, JS_SetProperty, JS_SetPropertyById, JS::IdVector
|
||||
#include "js/PropertyDescriptor.h" // JS::PropertyDescriptor, JS_GetOwnPropertyDescriptorById
|
||||
@ -366,6 +367,15 @@ bool ChromeUtils::IsDOMObject(GlobalObject& aGlobal, JS::Handle<JSObject*> aObj,
|
||||
return mozilla::dom::IsDOMObject(obj);
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool ChromeUtils::IsISOStyleDate(GlobalObject& aGlobal,
|
||||
const nsACString& aStr) {
|
||||
// aStr is a UTF-8 string, however we can cast to JS::Latin1Chars
|
||||
// because JS::IsISOStyleDate handles ASCII only
|
||||
return JS::IsISOStyleDate(aGlobal.Context(),
|
||||
JS::Latin1Chars(aStr.Data(), aStr.Length()));
|
||||
}
|
||||
|
||||
/* static */
|
||||
void ChromeUtils::ShallowClone(GlobalObject& aGlobal,
|
||||
JS::Handle<JSObject*> aObj,
|
||||
|
@ -166,6 +166,8 @@ class ChromeUtils {
|
||||
static bool IsDOMObject(GlobalObject& aGlobal, JS::Handle<JSObject*> aObj,
|
||||
bool aUnwrap);
|
||||
|
||||
static bool IsISOStyleDate(GlobalObject& aGlobal, const nsACString& aStr);
|
||||
|
||||
static void ShallowClone(GlobalObject& aGlobal, JS::Handle<JSObject*> aObj,
|
||||
JS::Handle<JSObject*> aTarget,
|
||||
JS::MutableHandle<JSObject*> aRetval,
|
||||
|
@ -462,6 +462,11 @@ partial namespace ChromeUtils {
|
||||
*/
|
||||
boolean isDOMObject(object obj, optional boolean unwrap = true);
|
||||
|
||||
/**
|
||||
* Returns whether |str| follows the Date Time String Format.
|
||||
*/
|
||||
boolean isISOStyleDate(UTF8String str);
|
||||
|
||||
/**
|
||||
* Clones the properties of the given object into a new object in the given
|
||||
* target compartment (or the caller compartment if no target is provided).
|
||||
|
@ -32,8 +32,9 @@
|
||||
#include "mozilla/FloatingPoint.h" // mozilla::{IsFinite,}, mozilla::UnspecifiedNaN
|
||||
#include "mozilla/MathAlgorithms.h" // mozilla::Abs
|
||||
|
||||
#include "js/Conversions.h" // JS::ToInteger
|
||||
#include "js/RealmOptions.h" // JS::RTPCallerTypeToken
|
||||
#include "js/CharacterEncoding.h" // JS::Latin1Chars
|
||||
#include "js/Conversions.h" // JS::ToInteger
|
||||
#include "js/RealmOptions.h" // JS::RTPCallerTypeToken
|
||||
#include "js/TypeDecls.h"
|
||||
#include "js/Value.h" // JS::CanonicalizeNaN, JS::DoubleValue, JS::Value
|
||||
|
||||
@ -213,6 +214,9 @@ GetReduceMicrosecondTimePrecisionCallback();
|
||||
// occur. This is used if the callback above is not specified.
|
||||
JS_PUBLIC_API void SetTimeResolutionUsec(uint32_t resolution, bool jitter);
|
||||
|
||||
// Returns whether a given string follows the Date Time String Format.
|
||||
JS_PUBLIC_API bool IsISOStyleDate(JSContext* cx, const JS::Latin1Chars& str);
|
||||
|
||||
} // namespace JS
|
||||
|
||||
#endif /* js_Date_h */
|
||||
|
@ -78,6 +78,7 @@ UNIFIED_SOURCES += [
|
||||
"testIntlAvailableLocales.cpp",
|
||||
"testIntString.cpp",
|
||||
"testIsInsideNursery.cpp",
|
||||
"testIsISOStyleDate.cpp",
|
||||
"testIteratorObject.cpp",
|
||||
"testJSEvaluateScript.cpp",
|
||||
"testJSON.cpp",
|
||||
|
79
js/src/jsapi-tests/testIsISOStyleDate.cpp
Normal file
79
js/src/jsapi-tests/testIsISOStyleDate.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: set ts=8 sts=2 et sw=2 tw=80:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "js/Date.h"
|
||||
#include "jsapi-tests/tests.h"
|
||||
|
||||
const char* VALID_DATES[] = {
|
||||
"2009",
|
||||
"2009-05",
|
||||
"2009-05-19",
|
||||
"2022-02-29",
|
||||
"2009T15:00",
|
||||
"2009-05T15:00",
|
||||
"2022-06-31T15:00",
|
||||
"2009-05-19T15:00",
|
||||
"2009-05-19T15:00:15",
|
||||
"2009-05-19T15:00-00:00",
|
||||
"2009-05-19T15:00:15.452",
|
||||
"2009-05-19T15:00:15.452Z",
|
||||
"2009-05-19T15:00:15.452+02:00",
|
||||
"2009-05-19T15:00:15.452-02:00",
|
||||
"-271821-04-20T00:00:00Z",
|
||||
"+000000-01-01T00:00:00Z",
|
||||
};
|
||||
|
||||
const char* INVALID_DATES[] = {
|
||||
"10",
|
||||
"20009",
|
||||
"+20009",
|
||||
"2009-",
|
||||
"2009-0",
|
||||
"2009-15",
|
||||
"2009-02-1",
|
||||
"2009-02-50",
|
||||
"15:00",
|
||||
"T15:00",
|
||||
"9-05-19T15:00",
|
||||
"2009-5-19T15:00",
|
||||
"2009-05-1T15:00",
|
||||
"2009-02-10T15",
|
||||
"2009-05-19T15:",
|
||||
"2009-05-19T1:00",
|
||||
"2009-05-19T10:1",
|
||||
"2009-05-19T60:00",
|
||||
"2009-05-19T15:70",
|
||||
"2009-05-19T15:00.25",
|
||||
"2009-05-19+10:00",
|
||||
"2009-05-19Z",
|
||||
"2009-05-19 15:00",
|
||||
"2009-05-19t15:00Z",
|
||||
"2009-05-19T15:00z",
|
||||
"2009-05-19T15:00+01",
|
||||
"2009-05-19T10:10+1:00",
|
||||
"2009-05-19T10:10+01:1",
|
||||
"2009-05-19T15:00+75:00",
|
||||
"2009-05-19T15:00+02:80",
|
||||
"02009-05-19T15:00",
|
||||
};
|
||||
|
||||
BEGIN_TEST(testIsISOStyleDate_success) {
|
||||
for (const char* date : VALID_DATES) {
|
||||
CHECK(ValidDate(date));
|
||||
}
|
||||
for (const char* date : INVALID_DATES) {
|
||||
CHECK(!ValidDate(date));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ValidDate(const char* str) {
|
||||
return JS::IsISOStyleDate(cx, JS::Latin1Chars(str, strlen(str)));
|
||||
}
|
||||
|
||||
END_TEST(testIsISOStyleDate_success)
|
@ -3971,3 +3971,10 @@ JS_PUBLIC_API bool js::DateGetMsecSinceEpoch(JSContext* cx, HandleObject obj,
|
||||
*msecsSinceEpoch = unboxed.toNumber();
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API bool JS::IsISOStyleDate(JSContext* cx,
|
||||
const JS::Latin1Chars& str) {
|
||||
ClippedTime result;
|
||||
return ParseISOStyleDate(ForceUTC(cx->realm()), str.begin().get(),
|
||||
str.length(), &result);
|
||||
}
|
||||
|
@ -116,41 +116,6 @@ function buildSerialized(type, handle = null) {
|
||||
return serialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to validate if a date string follows Date Time String format.
|
||||
*
|
||||
* @see https://tc39.es/ecma262/#sec-date-time-string-format
|
||||
*
|
||||
* @param {string} dateString
|
||||
* String which needs to be validated.
|
||||
*
|
||||
* @throws {InvalidArgumentError}
|
||||
* If <var>dateString</var> doesn't follow the format.
|
||||
*/
|
||||
function checkDateTimeString(dateString) {
|
||||
// Check if a date string follows a simplification of
|
||||
// the ISO 8601 calendar date extended format.
|
||||
const expandedYear = "[+-]\\d{6}";
|
||||
const year = "\\d{4}";
|
||||
const YYYY = `${expandedYear}|${year}`;
|
||||
const MM = "\\d{2}";
|
||||
const DD = "\\d{2}";
|
||||
const date = `${YYYY}(?:-${MM})?(?:-${DD})?`;
|
||||
const HH_mm = "\\d{2}:\\d{2}";
|
||||
const SS = "\\d{2}";
|
||||
const sss = "\\d{3}";
|
||||
const TZ = `Z|[+-]${HH_mm}`;
|
||||
const time = `T${HH_mm}(?::${SS}(?:\\.${sss})?(?:${TZ})?)?`;
|
||||
const iso8601Format = new RegExp(`^${date}(?:${time})?$`);
|
||||
|
||||
// Check also if a date string is a valid date.
|
||||
if (Number.isNaN(Date.parse(dateString)) || !iso8601Format.test(dateString)) {
|
||||
throw new lazy.error.InvalidArgumentError(
|
||||
`Expected "value" for Date to be a Date Time string, got ${dateString}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to deserialize value list.
|
||||
*
|
||||
@ -389,7 +354,11 @@ export function deserialize(realm, serializedValue, extraOptions) {
|
||||
case "date":
|
||||
// We want to support only Date Time String format,
|
||||
// check if the value follows it.
|
||||
checkDateTimeString(value);
|
||||
if (!ChromeUtils.isISOStyleDate(value)) {
|
||||
throw new lazy.error.InvalidArgumentError(
|
||||
`Expected "value" for Date to be a Date Time string, got ${value}`
|
||||
);
|
||||
}
|
||||
|
||||
return realm.cloneIntoRealm(new Date(value));
|
||||
case "map":
|
||||
|
@ -421,8 +421,10 @@ add_task(function test_deserializeDateLocalValue() {
|
||||
"2022-02-29",
|
||||
"2009T15:00",
|
||||
"2009-05T15:00",
|
||||
"2022-06-31T15:00",
|
||||
"2009-05-19T15:00",
|
||||
"2009-05-19T15:00:15",
|
||||
"2009-05-19T15:00-00:00",
|
||||
"2009-05-19T15:00:15.452",
|
||||
"2009-05-19T15:00:15.452Z",
|
||||
"2009-05-19T15:00:15.452+02:00",
|
||||
@ -601,7 +603,6 @@ add_task(function test_deserializeDateLocalValueInvalidValues() {
|
||||
"2009-05-19T15:",
|
||||
"2009-05-19T1:00",
|
||||
"2009-05-19T10:1",
|
||||
"2022-06-31T15:00",
|
||||
"2009-05-19T60:00",
|
||||
"2009-05-19T15:70",
|
||||
"2009-05-19T15:00.25",
|
||||
@ -615,7 +616,6 @@ add_task(function test_deserializeDateLocalValueInvalidValues() {
|
||||
"2009-05-19T10:10+01:1",
|
||||
"2009-05-19T15:00+75:00",
|
||||
"2009-05-19T15:00+02:80",
|
||||
"2009-05-19T15:00-00:00",
|
||||
"02009-05-19T15:00",
|
||||
];
|
||||
for (const dateString of invalidaDateStrings) {
|
||||
|
Loading…
Reference in New Issue
Block a user