From 8d6f36f8d6c0aea0253df8c84746f8c99bf79b4d Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Sun, 8 Sep 2024 11:15:07 -0400 Subject: [PATCH] LibJS+LibWeb: Add a custom host hook to log unparsed date strings This lets us log when our Date.parse implementation was unable to handle a string found on the web. --- Userland/Libraries/LibJS/Runtime/DateConstructor.cpp | 7 ++++--- Userland/Libraries/LibJS/Runtime/VM.cpp | 4 ++++ Userland/Libraries/LibJS/Runtime/VM.h | 1 + Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp | 4 ++++ 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibJS/Runtime/DateConstructor.cpp b/Userland/Libraries/LibJS/Runtime/DateConstructor.cpp index f965f7375fa..1c9a8ba3ba5 100644 --- a/Userland/Libraries/LibJS/Runtime/DateConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/DateConstructor.cpp @@ -150,7 +150,7 @@ static double parse_simplified_iso8601(ByteString const& iso_8601) return time_clip(time_ms); } -static double parse_date_string(ByteString const& date_string) +static double parse_date_string(VM& vm, ByteString const& date_string) { auto value = parse_simplified_iso8601(date_string); if (isfinite(value)) @@ -188,6 +188,7 @@ static double parse_date_string(ByteString const& date_string) return 1000.0 * maybe_datetime->timestamp(); } + vm.host_unrecognized_date_string(date_string); return NAN; } @@ -257,7 +258,7 @@ ThrowCompletionOr> DateConstructor::construct(FunctionObjec if (primitive.is_string()) { // 1. Assert: The next step never returns an abrupt completion because Type(v) is String. // 2. Let tv be the result of parsing v as a date, in exactly the same manner as for the parse method (21.4.3.2). - time_value = parse_date_string(primitive.as_string().byte_string()); + time_value = parse_date_string(vm, primitive.as_string().byte_string()); } // iii. Else, else { @@ -334,7 +335,7 @@ JS_DEFINE_NATIVE_FUNCTION(DateConstructor::parse) auto date_string = TRY(vm.argument(0).to_byte_string(vm)); - return Value(parse_date_string(date_string)); + return Value(parse_date_string(vm, date_string)); } // 21.4.3.4 Date.UTC ( year [ , month [ , date [ , hours [ , minutes [ , seconds [ , ms ] ] ] ] ] ] ), https://tc39.es/ecma262/#sec-date.utc diff --git a/Userland/Libraries/LibJS/Runtime/VM.cpp b/Userland/Libraries/LibJS/Runtime/VM.cpp index 5ed5d02cb79..ce57100ab39 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.cpp +++ b/Userland/Libraries/LibJS/Runtime/VM.cpp @@ -164,6 +164,10 @@ VM::VM(OwnPtr custom_data, ErrorMessages error_messages) return HandledByHost::Handled; }; + + // AD-HOC: Inform the host that we received a date string we were unable to parse. + host_unrecognized_date_string = [](StringView) { + }; } VM::~VM() = default; diff --git a/Userland/Libraries/LibJS/Runtime/VM.h b/Userland/Libraries/LibJS/Runtime/VM.h index d636cccca4e..d5960888e92 100644 --- a/Userland/Libraries/LibJS/Runtime/VM.h +++ b/Userland/Libraries/LibJS/Runtime/VM.h @@ -274,6 +274,7 @@ public: Function(Realm&)> host_ensure_can_compile_strings; Function(Object&)> host_ensure_can_add_private_element; Function(ArrayBuffer&, size_t)> host_resize_array_buffer; + Function host_unrecognized_date_string; Vector stack_trace() const; diff --git a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp index e4055f4d685..a43d672baa5 100644 --- a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp +++ b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp @@ -545,6 +545,10 @@ ErrorOr initialize_main_thread_vm(HTML::EventLoop::Type type) HTML::fetch_single_imported_module_script(realm, url.release_value(), *fetch_client, destination, fetch_options, *settings_object, fetch_referrer, module_request, perform_fetch, on_single_fetch_complete); }; + s_main_thread_vm->host_unrecognized_date_string = [](StringView date) { + dbgln("Unable to parse date string: \"{}\"", date); + }; + return {}; }