1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 13:37:45 +00:00

LibJS: Check dates are below the time_clip threshold

This commit is contained in:
Idan Horowitz 2021-06-06 17:42:49 +03:00 committed by Linus Groh
parent c4530e95f4
commit f65cb63aab
3 changed files with 60 additions and 12 deletions

View file

@ -15,6 +15,8 @@ class Date final : public Object {
JS_OBJECT(Date, Object);
public:
static constexpr double time_clip = 8.64e15;
static Date* create(GlobalObject&, Core::DateTime, i16 milliseconds, bool is_invalid = false);
static Date* now(GlobalObject&);

View file

@ -172,6 +172,8 @@ Value DateConstructor::construct(Function&)
// A timestamp since the epoch, in UTC.
double value_as_double = value.as_double();
if (value_as_double > Date::time_clip)
return create_invalid_date();
auto datetime = Core::DateTime::from_timestamp(static_cast<time_t>(value_as_double / 1000));
auto milliseconds = static_cast<i16>(fmod(value_as_double, 1000));
return Date::create(global_object(), datetime, milliseconds);
@ -247,7 +249,10 @@ Value DateConstructor::construct(Function&)
year += 1900;
int month = month_index + 1;
auto datetime = Core::DateTime::create(year, month, day, hours, minutes, seconds);
return Date::create(global_object(), datetime, milliseconds);
auto* date = Date::create(global_object(), datetime, milliseconds);
if (date->time() > Date::time_clip)
return create_invalid_date();
return date;
}
JS_DEFINE_NATIVE_FUNCTION(DateConstructor::now)

View file

@ -1,6 +1,7 @@
/*
* Copyright (c) 2020-2021, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2021, Petróczi Zoltán <petroczizoltan@tutanota.com>
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -127,9 +128,13 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_date)
}
auto new_date = new_date_value.as_i32();
this_object->set_is_invalid(false);
datetime.set_time(datetime.year(), datetime.month(), new_date, datetime.hour(), datetime.minute(), datetime.second());
if (this_object->time() > Date::time_clip) {
this_object->set_is_invalid(true);
return js_nan();
}
this_object->set_is_invalid(false);
return Value(this_object->time());
}
@ -195,6 +200,11 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_full_year)
auto new_day = new_day_value.as_i32();
datetime.set_time(new_year, new_month, new_day, datetime.hour(), datetime.minute(), datetime.second());
if (this_object->time() > Date::time_clip) {
this_object->set_is_invalid(true);
return js_nan();
}
this_object->set_is_invalid(false);
return Value(this_object->time());
@ -232,6 +242,11 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_year)
new_year += 1900;
datetime.set_time(new_year, datetime.month(), datetime.day(), datetime.hour(), datetime.minute(), datetime.second());
if (this_object->time() > Date::time_clip) {
this_object->set_is_invalid(true);
return js_nan();
}
this_object->set_is_invalid(false);
return Value(this_object->time());
@ -295,12 +310,16 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_hours)
}
auto new_milliseconds = new_milliseconds_value.as_i32();
this_object->set_is_invalid(false);
new_seconds += new_milliseconds / 1000;
this_object->set_milliseconds(new_milliseconds % 1000);
datetime.set_time(datetime.year(), datetime.month(), datetime.day(), new_hours, new_minutes, new_seconds);
if (this_object->time() > Date::time_clip) {
this_object->set_is_invalid(true);
return js_nan();
}
this_object->set_is_invalid(false);
return Value(this_object->time());
}
@ -341,6 +360,11 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_milliseconds)
datetime.set_time(datetime.year(), datetime.month(), datetime.day(), datetime.hour(), datetime.minute(), datetime.second() + added_seconds);
}
if (this_object->time() > Date::time_clip) {
this_object->set_is_invalid(true);
return js_nan();
}
this_object->set_is_invalid(false);
return Value(this_object->time());
@ -395,12 +419,16 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_minutes)
}
auto new_milliseconds = new_milliseconds_value.as_i32();
this_object->set_is_invalid(false);
new_seconds += new_milliseconds / 1000;
this_object->set_milliseconds(new_milliseconds % 1000);
datetime.set_time(datetime.year(), datetime.month(), datetime.day(), datetime.hour(), new_minutes, new_seconds);
if (this_object->time() > Date::time_clip) {
this_object->set_is_invalid(true);
return js_nan();
}
this_object->set_is_invalid(false);
return Value(this_object->time());
}
@ -444,9 +472,13 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_month)
}
auto new_date = new_date_value.as_i32();
this_object->set_is_invalid(false);
datetime.set_time(datetime.year(), new_month, new_date, datetime.hour(), datetime.minute(), datetime.second());
if (this_object->time() > Date::time_clip) {
this_object->set_is_invalid(true);
return js_nan();
}
this_object->set_is_invalid(false);
return Value(this_object->time());
}
@ -490,12 +522,16 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_seconds)
}
auto new_milliseconds = new_milliseconds_value.as_i32();
this_object->set_is_invalid(false);
new_seconds += new_milliseconds / 1000;
this_object->set_milliseconds(new_milliseconds % 1000);
datetime.set_time(datetime.year(), datetime.month(), datetime.day(), datetime.hour(), datetime.minute(), new_seconds);
if (this_object->time() > Date::time_clip) {
this_object->set_is_invalid(true);
return js_nan();
}
this_object->set_is_invalid(false);
return Value(this_object->time());
}
@ -526,11 +562,16 @@ JS_DEFINE_NATIVE_FUNCTION(DatePrototype::set_time)
}
auto new_time = new_time_value.as_double();
this_object->set_is_invalid(false);
if (new_time > Date::time_clip) {
this_object->set_is_invalid(true);
return js_nan();
}
auto new_date_time = Core::DateTime::from_timestamp(static_cast<time_t>(new_time / 1000));
this_object->datetime().set_time(new_date_time.year(), new_date_time.month(), new_date_time.day(), new_date_time.hour(), new_date_time.minute(), new_date_time.second());
this_object->set_milliseconds(static_cast<i16>(fmod(new_time, 1000)));
this_object->set_is_invalid(false);
return Value(this_object->time());
}