Skip to content
Permalink
Browse files
[JSC] Date parse should accept narrow-no-break-space
https://bugs.webkit.org/show_bug.cgi?id=247986
rdar://102427399

Reviewed by Alexey Shvayka.

After ICU 72, CLDR generates narrow-no-break-space for date time output. So, `new Date().toLocaleString('en-US')` starts generating
a string including narrow-no-break-space instead of simple spaces. However since code in the wild assumes `new Date(new Date().toLocaleString('en-US'))`
works, we need to maintain the ability to parse string including narrowNoBreakSpaces. Rough consensus among implementaters (V8, SpiderMonkey, and us)
is replacing narrowNoBreakSpaces with simple spaces before parsing.

* JSTests/complex.yaml:
* JSTests/complex/date-parse-with-narrow-no-break-space.js: Added.
(shouldBe):
* Source/JavaScriptCore/runtime/JSDateMath.cpp:
(JSC::DateCache::parseDate):
* Source/WTF/wtf/unicode/CharacterNames.h:

Canonical link: https://commits.webkit.org/256754@main
  • Loading branch information
Constellation committed Nov 16, 2022
1 parent c388572 commit a8f967cd42c5add143939660b7cd928375182377
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 3 deletions.
@@ -64,3 +64,6 @@

- path: complex/intl-date-time-format-date-parse.js
cmd: runComplexTest [], [], "TZ=America/New_York"

- path: complex/date-parse-with-narrow-no-break-space.js
cmd: runComplexTest [], [], "TZ=America/Los_Angeles"
@@ -0,0 +1,11 @@
function shouldBe(actual, expected) {
if (actual !== expected)
throw new Error('bad value: ' + actual);
}
var space = ' ';
var narrowNoBreakSpace = '\u202f';

shouldBe(new Date(`11/16/2022, 10:33:58${space}AM`).getTime(), 1668623638000);
shouldBe(new Date(`11/16/2022, 10:33:58${narrowNoBreakSpace}AM`).getTime(), 1668623638000);
shouldBe(Date.parse(`11/16/2022, 10:33:58${space}AM`), 1668623638000);
shouldBe(Date.parse(`11/16/2022, 10:33:58${narrowNoBreakSpace}AM`), 1668623638000);
@@ -76,6 +76,7 @@
#include "VM.h"
#include <limits>
#include <wtf/Language.h>
#include <wtf/unicode/CharacterNames.h>
#include <wtf/unicode/icu/ICUHelpers.h>

#if U_ICU_VERSION_MAJOR_NUM >= 69 || (U_ICU_VERSION_MAJOR_NUM == 68 && USE(APPLE_INTERNAL_SDK))
@@ -317,7 +318,14 @@ double DateCache::parseDate(JSGlobalObject* globalObject, VM& vm, const String&

if (date == m_cachedDateString)
return m_cachedDateStringValue;
auto expectedString = date.tryGetUTF8();

// After ICU 72, CLDR generates narrowNoBreakSpace for date time format. Thus, `new Date().toLocaleString('en-US')` starts generating
// a string including narrowNoBreakSpaces instead of simple spaces. However since code in the wild assumes `new Date(new Date().toLocaleString('en-US'))`
// works, we need to maintain the ability to parse string including narrowNoBreakSpaces. Rough consensus among implementaters is replacing narrowNoBreakSpaces
// with simple spaces before parsing.
String updatedString = makeStringByReplacingAll(date, narrowNoBreakSpace, space);

auto expectedString = updatedString.tryGetUTF8();
if (!expectedString) {
if (expectedString.error() == UTF8ConversionError::OutOfMemory)
throwOutOfMemoryError(globalObject, scope);
@@ -89,7 +89,6 @@ constexpr UChar lowDoublePrimeQuotationMark = 0x301F;
constexpr UChar lowLine = 0x005F;
constexpr UChar minusSign = 0x2212;
constexpr UChar narrowNoBreakSpace = 0x202F;
constexpr UChar narrowNonBreakingSpace = 0x202F;
constexpr UChar newlineCharacter = 0x000A;
constexpr UChar noBreakSpace = 0x00A0;
constexpr UChar nullCharacter = 0x0;
@@ -206,7 +205,6 @@ using WTF::Unicode::leftToRightOverride;
using WTF::Unicode::lowLine;
using WTF::Unicode::minusSign;
using WTF::Unicode::narrowNoBreakSpace;
using WTF::Unicode::narrowNonBreakingSpace;
using WTF::Unicode::newlineCharacter;
using WTF::Unicode::noBreakSpace;
using WTF::Unicode::nullCharacter;

0 comments on commit a8f967c

Please sign in to comment.