From 6ea555e8ac6aa83aa98b4bfe8f1c73038ce507b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Thu, 24 Nov 2022 11:41:02 +0100 Subject: [PATCH] deps: V8: cherry-pick 2ada52cffbff Original commit message: [intl] Enhance Date parser to take Unicode SPACE This is needed to prepare for the landing of ICU72. Allow U+202F in the Date String, which the toLocaleString("en-US") will generate w/ ICU72. Bug: v8:13494 Change-Id: I41b83c4094ce3d0737a72dcd6310b52c68fdcdca Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4027341 Reviewed-by: Yang Guo Reviewed-by: Jungshik Shin Commit-Queue: Frank Tang Cr-Commit-Position: refs/heads/main@{#84308} Refs: https://github.com/v8/v8/commit/2ada52cffbff11074abfaac18938bf02d85454f5 Fixes: https://github.com/nodejs/node/issues/45171 PR-URL: https://github.com/nodejs/node/pull/45573 Reviewed-By: Jiawen Geng Reviewed-By: Richard Lau Reviewed-By: Colin Ihrig Reviewed-By: Yagiz Nizipli --- common.gypi | 2 +- deps/v8/src/date/dateparser-inl.h | 2 +- deps/v8/src/date/dateparser.h | 4 ++- deps/v8/test/intl/regress-13494.js | 47 ++++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 3 deletions(-) create mode 100644 deps/v8/test/intl/regress-13494.js diff --git a/common.gypi b/common.gypi index 3f708d89b1ef38..0e5ce682494601 100644 --- a/common.gypi +++ b/common.gypi @@ -36,7 +36,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.12', + 'v8_embedder_string': '-node.13', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/src/date/dateparser-inl.h b/deps/v8/src/date/dateparser-inl.h index 623986d2b10acc..b45479dc516e70 100644 --- a/deps/v8/src/date/dateparser-inl.h +++ b/deps/v8/src/date/dateparser-inl.h @@ -192,7 +192,7 @@ DateParser::DateToken DateParser::DateStringTokenizer::Scan() { if (in_->Skip('+')) return DateToken::Symbol('+'); if (in_->Skip('.')) return DateToken::Symbol('.'); if (in_->Skip(')')) return DateToken::Symbol(')'); - if (in_->IsAsciiAlphaOrAbove()) { + if (in_->IsAsciiAlphaOrAbove() && !in_->IsWhiteSpaceChar()) { DCHECK_EQ(KeywordTable::kPrefixLength, 3); uint32_t buffer[3] = {0, 0, 0}; int length = in_->ReadWord(buffer, 3); diff --git a/deps/v8/src/date/dateparser.h b/deps/v8/src/date/dateparser.h index 1a0a0b15ab7585..59b2f3c9fd235f 100644 --- a/deps/v8/src/date/dateparser.h +++ b/deps/v8/src/date/dateparser.h @@ -91,7 +91,8 @@ class DateParser : public AllStatic { // Return word length. int ReadWord(uint32_t* prefix, int prefix_size) { int len; - for (len = 0; IsAsciiAlphaOrAbove(); Next(), len++) { + for (len = 0; IsAsciiAlphaOrAbove() && !IsWhiteSpaceChar(); + Next(), len++) { if (len < prefix_size) prefix[len] = AsciiAlphaToLower(ch_); } for (int i = len; i < prefix_size; i++) prefix[i] = 0; @@ -115,6 +116,7 @@ class DateParser : public AllStatic { bool IsEnd() const { return ch_ == 0; } bool IsAsciiDigit() const { return IsDecimalDigit(ch_); } bool IsAsciiAlphaOrAbove() const { return ch_ >= 'A'; } + bool IsWhiteSpaceChar() const { return IsWhiteSpace(ch_); } bool IsAsciiSign() const { return ch_ == '+' || ch_ == '-'; } // Return 1 for '+' and -1 for '-'. diff --git a/deps/v8/test/intl/regress-13494.js b/deps/v8/test/intl/regress-13494.js new file mode 100644 index 00000000000000..d1446aff073a15 --- /dev/null +++ b/deps/v8/test/intl/regress-13494.js @@ -0,0 +1,47 @@ +// Copyright 2022 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Test the new Date( date.toLocaleString("en-US")) is not invalid. +// This is not guaranteed by the standard but many code use that to set the +// timezone as suggested in +// https://stackoverflow.com/questions/15141762/how-to-initialize-a-javascript-date-to-a-particular-time-zone + +let d = new Date(); + +// https://tc39.es/ecma262/#sec-todatestring +// 21.4.4.41.4 ToDateString ( tv ) +// 1. If tv is NaN, return "Invalid Date". +let invalid = "Invalid Date"; +let largestDiff = 25*60*60*1000; + +let garbage = new Date("garbage"); +assertTrue(invalid == garbage); +assertEquals(NaN, garbage.getTime()); + +let d1 = new Date(d.toLocaleString("en-US")); +assertTrue(d1 != invalid); +assertTrue(d1.getTime() != NaN); +// The milliseconds are different between d1 and d. +assertTrue(Math.abs(d1-d) < 1000); + +// Force a version of date string which have U+202f before AM +let nnbsp_am = new Date("11/16/2022, 9:04:55\u202fAM"); +assertTrue(nnbsp_am != invalid); +assertTrue(nnbsp_am.getTime() != NaN); +// Force a version of date string which have U+202f before PM +let nnbsp_pm = new Date("11/16/2022, 9:04:55\u202fPM"); +assertTrue(nnbsp_pm != invalid); +assertTrue(nnbsp_pm.getTime() != NaN); + +let d2 = new Date(d.toLocaleString("en-US", {timeZone: "Asia/Taipei"})); +assertTrue(d2 != invalid); +assertTrue(d2.getTime() != NaN); +// The differences should be within 25 hours. +assertTrue(Math.abs(d2-d) < largestDiff); + +let d3 = new Date(d.toLocaleString("en-US", {timeZone: "Africa/Lusaka"})); +assertTrue(d3 != invalid); +assertTrue(d3.getTime() != NaN); +// The differences should be within 25 hours. +assertTrue(Math.abs(d3-d) < largestDiff);