Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (260881 => 260882)
--- trunk/Source/_javascript_Core/ChangeLog 2020-04-29 07:09:44 UTC (rev 260881)
+++ trunk/Source/_javascript_Core/ChangeLog 2020-04-29 07:15:18 UTC (rev 260882)
@@ -1,3 +1,30 @@
+2020-04-29 Saam Barati <[email protected]>
+
+ U_STRING_NOT_TERMINATED_WARNING ICU must be handled when using the output buffer as a C string
+ https://bugs.webkit.org/show_bug.cgi?id=211142
+ <rdar://problem/62530860>
+
+ Reviewed by Darin Adler.
+
+ * runtime/IntlDateTimeFormat.cpp:
+ (JSC::defaultTimeZone):
+ (JSC::canonicalizeTimeZoneName):
+ (JSC::IntlDateTimeFormat::initializeDateTimeFormat):
+ (JSC::IntlDateTimeFormat::format):
+ (JSC::IntlDateTimeFormat::formatToParts):
+ * runtime/IntlNumberFormat.cpp:
+ (JSC::IntlNumberFormat::format):
+ (JSC::IntlNumberFormat::formatToParts):
+ * runtime/IntlObject.cpp:
+ (JSC::convertICULocaleToBCP47LanguageTag):
+ (JSC::canonicalizeLanguageTag):
+ * runtime/IntlRelativeTimeFormat.cpp:
+ (JSC::IntlRelativeTimeFormat::formatInternal):
+ (JSC::IntlRelativeTimeFormat::formatToParts):
+ * runtime/StringPrototype.cpp:
+ (JSC::toLocaleCase):
+ (JSC::normalize):
+
2020-04-28 Saam Barati <[email protected]>
Unreviewed. Fix 32-bit build.
Modified: trunk/Source/_javascript_Core/runtime/IntlDateTimeFormat.cpp (260881 => 260882)
--- trunk/Source/_javascript_Core/runtime/IntlDateTimeFormat.cpp 2020-04-29 07:09:44 UTC (rev 260881)
+++ trunk/Source/_javascript_Core/runtime/IntlDateTimeFormat.cpp 2020-04-29 07:15:18 UTC (rev 260882)
@@ -39,6 +39,7 @@
#include <unicode/uenum.h>
#include <unicode/ufieldpositer.h>
#include <wtf/text/StringBuilder.h>
+#include <wtf/unicode/icu/ICUHelpers.h>
namespace JSC {
@@ -119,7 +120,7 @@
Vector<UChar, 32> buffer(32);
auto bufferLength = ucal_getDefaultTimeZone(buffer.data(), buffer.size(), &status);
- if (status == U_BUFFER_OVERFLOW_ERROR) {
+ if (needsToGrowToProduceBuffer(status)) {
status = U_ZERO_ERROR;
buffer.grow(bufferLength);
ucal_getDefaultTimeZone(buffer.data(), bufferLength, &status);
@@ -128,7 +129,7 @@
status = U_ZERO_ERROR;
Vector<UChar, 32> canonicalBuffer(32);
auto canonicalLength = ucal_getCanonicalTimeZoneID(buffer.data(), bufferLength, canonicalBuffer.data(), canonicalBuffer.size(), nullptr, &status);
- if (status == U_BUFFER_OVERFLOW_ERROR) {
+ if (needsToGrowToProduceBuffer(status)) {
status = U_ZERO_ERROR;
canonicalBuffer.grow(canonicalLength);
ucal_getCanonicalTimeZoneID(buffer.data(), bufferLength, canonicalBuffer.data(), canonicalLength, nullptr, &status);
@@ -175,7 +176,7 @@
Vector<UChar, 32> buffer(ianaTimeZoneLength);
status = U_ZERO_ERROR;
auto canonicalLength = ucal_getCanonicalTimeZoneID(ianaTimeZone, ianaTimeZoneLength, buffer.data(), ianaTimeZoneLength, nullptr, &status);
- if (status == U_BUFFER_OVERFLOW_ERROR) {
+ if (needsToGrowToProduceBuffer(status)) {
buffer.grow(canonicalLength);
status = U_ZERO_ERROR;
ucal_getCanonicalTimeZoneID(ianaTimeZone, ianaTimeZoneLength, buffer.data(), canonicalLength, nullptr, &status);
@@ -650,7 +651,7 @@
Vector<UChar, 32> patternBuffer(32);
status = U_ZERO_ERROR;
auto patternLength = udatpg_getBestPatternWithOptions(generator, skeletonView.upconvertedCharacters(), skeletonView.length(), UDATPG_MATCH_HOUR_FIELD_LENGTH, patternBuffer.data(), patternBuffer.size(), &status);
- if (status == U_BUFFER_OVERFLOW_ERROR) {
+ if (needsToGrowToProduceBuffer(status)) {
status = U_ZERO_ERROR;
patternBuffer.grow(patternLength);
udatpg_getBestPattern(generator, skeletonView.upconvertedCharacters(), skeletonView.length(), patternBuffer.data(), patternLength, &status);
@@ -908,7 +909,7 @@
UErrorCode status = U_ZERO_ERROR;
Vector<UChar, 32> result(32);
auto resultLength = udat_format(m_dateFormat.get(), value, result.data(), result.size(), nullptr, &status);
- if (status == U_BUFFER_OVERFLOW_ERROR) {
+ if (needsToGrowToProduceBuffer(status)) {
status = U_ZERO_ERROR;
result.grow(resultLength);
udat_format(m_dateFormat.get(), value, result.data(), resultLength, nullptr, &status);
@@ -1000,7 +1001,7 @@
status = U_ZERO_ERROR;
Vector<UChar, 32> result(32);
auto resultLength = udat_formatForFields(m_dateFormat.get(), value, result.data(), result.size(), fields.get(), &status);
- if (status == U_BUFFER_OVERFLOW_ERROR) {
+ if (needsToGrowToProduceBuffer(status)) {
status = U_ZERO_ERROR;
result.grow(resultLength);
udat_formatForFields(m_dateFormat.get(), value, result.data(), resultLength, fields.get(), &status);
Modified: trunk/Source/_javascript_Core/runtime/IntlNumberFormat.cpp (260881 => 260882)
--- trunk/Source/_javascript_Core/runtime/IntlNumberFormat.cpp 2020-04-29 07:09:44 UTC (rev 260881)
+++ trunk/Source/_javascript_Core/runtime/IntlNumberFormat.cpp 2020-04-29 07:15:18 UTC (rev 260882)
@@ -37,6 +37,7 @@
#include "JSCInlines.h"
#include "ObjectConstructor.h"
#include <unicode/ufieldpositer.h>
+#include <wtf/unicode/icu/ICUHelpers.h>
namespace JSC {
@@ -361,7 +362,7 @@
UErrorCode status = U_ZERO_ERROR;
Vector<UChar, 32> buffer(32);
auto length = unum_formatDouble(m_numberFormat.get(), value, buffer.data(), buffer.size(), nullptr, &status);
- if (status == U_BUFFER_OVERFLOW_ERROR) {
+ if (needsToGrowToProduceBuffer(status)) {
buffer.grow(length);
status = U_ZERO_ERROR;
unum_formatDouble(m_numberFormat.get(), value, buffer.data(), length, nullptr, &status);
@@ -389,7 +390,7 @@
UErrorCode status = U_ZERO_ERROR;
Vector<UChar, 32> buffer(32);
auto length = unum_formatDecimal(m_numberFormat.get(), rawString, string.length(), buffer.data(), buffer.size(), nullptr, &status);
- if (status == U_BUFFER_OVERFLOW_ERROR) {
+ if (needsToGrowToProduceBuffer(status)) {
buffer.grow(length);
status = U_ZERO_ERROR;
unum_formatDecimal(m_numberFormat.get(), rawString, string.length(), buffer.data(), length, nullptr, &status);
@@ -552,7 +553,7 @@
Vector<UChar, 32> result(32);
auto resultLength = unum_formatDoubleForFields(m_numberFormat.get(), value, result.data(), result.size(), fieldItr.get(), &status);
- if (status == U_BUFFER_OVERFLOW_ERROR) {
+ if (needsToGrowToProduceBuffer(status)) {
status = U_ZERO_ERROR;
result.grow(resultLength);
unum_formatDoubleForFields(m_numberFormat.get(), value, result.data(), resultLength, fieldItr.get(), &status);
Modified: trunk/Source/_javascript_Core/runtime/IntlObject.cpp (260881 => 260882)
--- trunk/Source/_javascript_Core/runtime/IntlObject.cpp 2020-04-29 07:09:44 UTC (rev 260881)
+++ trunk/Source/_javascript_Core/runtime/IntlObject.cpp 2020-04-29 07:15:18 UTC (rev 260882)
@@ -54,6 +54,7 @@
#include <wtf/NeverDestroyed.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/text/StringImpl.h>
+#include <wtf/unicode/icu/ICUHelpers.h>
namespace JSC {
@@ -144,13 +145,17 @@
UErrorCode status = U_ZERO_ERROR;
Vector<char, 32> buffer(32);
auto length = uloc_toLanguageTag(localeID, buffer.data(), buffer.size(), false, &status);
- if (status == U_BUFFER_OVERFLOW_ERROR) {
+ if (needsToGrowToProduceBuffer(status)) {
buffer.grow(length);
status = U_ZERO_ERROR;
uloc_toLanguageTag(localeID, buffer.data(), buffer.size(), false, &status);
}
- if (!U_FAILURE(status))
+ if (!U_FAILURE(status)) {
+ // This is used to store into static variables that may be shared across
+ // JSC execution threads. This must be immortal to make concurrent ref/deref
+ // safe.
return String(StringImpl::createStaticStringImpl(buffer.data(), length));
+ }
return String();
}
@@ -322,10 +327,10 @@
// - uloc_toLanguageTag doesn't take an input size param so we must ensure the string is null-terminated ourselves
// - before ICU 64, there's a chance that it will "buffer overflow" while requesting a *smaller* size
UErrorCode status = U_ZERO_ERROR;
- Vector<char, 32> intermediate(31);
+ Vector<char, 32> intermediate(32);
int32_t parsedLength;
auto intermediateLength = uloc_forLanguageTag(input.data(), intermediate.data(), intermediate.size(), &parsedLength, &status);
- if (status == U_BUFFER_OVERFLOW_ERROR) {
+ if (needsToGrowToProduceCString(status)) {
intermediate.resize(intermediateLength + 1);
status = U_ZERO_ERROR;
uloc_forLanguageTag(input.data(), intermediate.data(), intermediateLength + 1, &parsedLength, &status);
@@ -333,9 +338,12 @@
if (U_FAILURE(status) || parsedLength != static_cast<int32_t>(input.length()))
return String();
+ ASSERT(intermediate.contains('\0'));
+
+ status = U_ZERO_ERROR;
Vector<char, 32> result(32);
auto resultLength = uloc_toLanguageTag(intermediate.data(), result.data(), result.size(), false, &status);
- if (status == U_BUFFER_OVERFLOW_ERROR) {
+ if (needsToGrowToProduceBuffer(status)) {
result.grow(resultLength);
status = U_ZERO_ERROR;
uloc_toLanguageTag(intermediate.data(), result.data(), resultLength, false, &status);
Modified: trunk/Source/_javascript_Core/runtime/IntlRelativeTimeFormat.cpp (260881 => 260882)
--- trunk/Source/_javascript_Core/runtime/IntlRelativeTimeFormat.cpp 2020-04-29 07:09:44 UTC (rev 260881)
+++ trunk/Source/_javascript_Core/runtime/IntlRelativeTimeFormat.cpp 2020-04-29 07:15:18 UTC (rev 260882)
@@ -31,6 +31,7 @@
#include "IntlObject.h"
#include "JSCInlines.h"
#include "ObjectConstructor.h"
+#include <wtf/unicode/icu/ICUHelpers.h>
namespace JSC {
@@ -253,7 +254,7 @@
UErrorCode status = U_ZERO_ERROR;
Vector<UChar, 32> result(32);
auto resultLength = formatRelativeTime(m_relativeDateTimeFormatter.get(), value, unitType.value(), result.data(), result.size(), &status);
- if (status == U_BUFFER_OVERFLOW_ERROR) {
+ if (needsToGrowToProduceBuffer(status)) {
status = U_ZERO_ERROR;
result.grow(resultLength);
formatRelativeTime(m_relativeDateTimeFormatter.get(), value, unitType.value(), result.data(), resultLength, &status);
@@ -295,7 +296,7 @@
Vector<UChar, 32> buffer(32);
auto numberLength = unum_formatDoubleForFields(m_numberFormat.get(), absValue, buffer.data(), buffer.size(), iterator.get(), &status);
- if (status == U_BUFFER_OVERFLOW_ERROR) {
+ if (needsToGrowToProduceBuffer(status)) {
status = U_ZERO_ERROR;
buffer.grow(numberLength);
unum_formatDoubleForFields(m_numberFormat.get(), absValue, buffer.data(), numberLength, iterator.get(), &status);
Modified: trunk/Source/_javascript_Core/runtime/StringPrototype.cpp (260881 => 260882)
--- trunk/Source/_javascript_Core/runtime/StringPrototype.cpp 2020-04-29 07:09:44 UTC (rev 260881)
+++ trunk/Source/_javascript_Core/runtime/StringPrototype.cpp 2020-04-29 07:15:18 UTC (rev 260882)
@@ -58,6 +58,7 @@
#include <wtf/MathExtras.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/text/StringView.h>
+#include <wtf/unicode/icu/ICUHelpers.h>
namespace JSC {
@@ -1620,15 +1621,15 @@
// 17. Let L be a String whose elements are, in order, the elements of cuList.
// Most strings lower/upper case will be the same size as original, so try that first.
- UErrorCode error(U_ZERO_ERROR);
+ UErrorCode error = U_ZERO_ERROR;
Vector<UChar> buffer(viewLength);
String lower;
const int32_t resultLength = convertCase(buffer.data(), viewLength, view.upconvertedCharacters(), viewLength, utf8LocaleBuffer.data(), &error);
if (U_SUCCESS(error))
lower = String(buffer.data(), resultLength);
- else if (error == U_BUFFER_OVERFLOW_ERROR) {
+ else if (needsToGrowToProduceBuffer(error)) {
// Converted case needs more space than original. Try again.
- UErrorCode error(U_ZERO_ERROR);
+ UErrorCode error = U_ZERO_ERROR;
Vector<UChar> buffer(resultLength);
convertCase(buffer.data(), resultLength, view.upconvertedCharacters(), viewLength, utf8LocaleBuffer.data(), &error);
if (U_FAILURE(error))
@@ -1926,7 +1927,7 @@
RELEASE_AND_RETURN(scope, string);
int32_t normalizedStringLength = unorm2_normalize(normalizer, characters, view.length(), nullptr, 0, &status);
- ASSERT(status == U_BUFFER_OVERFLOW_ERROR);
+ ASSERT(needsToGrowToProduceBuffer(status));
UChar* buffer;
auto result = StringImpl::tryCreateUninitialized(normalizedStringLength, buffer);
Modified: trunk/Source/WTF/ChangeLog (260881 => 260882)
--- trunk/Source/WTF/ChangeLog 2020-04-29 07:09:44 UTC (rev 260881)
+++ trunk/Source/WTF/ChangeLog 2020-04-29 07:15:18 UTC (rev 260882)
@@ -1,3 +1,43 @@
+2020-04-29 Saam Barati <[email protected]>
+
+ U_STRING_NOT_TERMINATED_WARNING ICU must be handled when using the output buffer as a C string
+ https://bugs.webkit.org/show_bug.cgi?id=211142
+ <rdar://problem/62530860>
+
+ Reviewed by Darin Adler.
+
+ Most of our uses of ICU require us to produce a buffer of the correct
+ length. We often test if the first call to ICU API succeeds, and if it
+ doesn't, we grow to the required buffer size, and try again. However,
+ there are a few APIs that we use like this, except that they write their
+ output to a C string instead of a buffer.
+
+ In a couple scenarios when we were producing C strings, we were only testing
+ for the U_BUFFER_OVERFLOW_ERROR, instead of both U_BUFFER_OVERFLOW_ERROR and
+ U_STRING_NOT_TERMINATED_WARNING. This patch fixes those bugs. It also
+ introduces two new helper methods for testing error codes returned by ICU.
+
+ - The first is needsToGrowToProduceBuffer, which returns true if we need to
+ grow the buffer and re-call into ICU to get the result.
+ - The second is needsToGrowToProduceCString, which returns true if we need to
+ grow the buffer and re-call into ICU to produce a valid C string.
+
+ I've audited all uses of U_BUFFER_OVERFLOW_ERROR and converted them to use one
+ of the above helper methods instead.
+
+ The issues in our handling of U_STRING_NOT_TERMINATED_WARNING were caught on iOS JSC
+ tests in JSTests/stress/intl-datetimeformat.js
+
+ * WTF.xcodeproj/project.pbxproj:
+ * wtf/CMakeLists.txt:
+ * wtf/text/LineBreakIteratorPoolICU.h:
+ (WTF::LineBreakIteratorPool::makeLocaleWithBreakKeyword):
+ * wtf/text/StringView.cpp:
+ (WTF::normalizedNFC):
+ * wtf/unicode/icu/ICUHelpers.h: Added.
+ (WTF::needsToGrowToProduceCString):
+ (WTF::needsToGrowToProduceBuffer):
+
2020-04-29 Noam Rosenthal <[email protected]>
Add StringView::isAllSpecialCharacters()
Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (260881 => 260882)
--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2020-04-29 07:09:44 UTC (rev 260881)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2020-04-29 07:15:18 UTC (rev 260882)
@@ -392,6 +392,7 @@
51F175291F3D486000C74950 /* PersistentEncoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PersistentEncoder.cpp; sourceTree = "<group>"; };
51F1752A1F3D486000C74950 /* PersistentEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PersistentEncoder.h; sourceTree = "<group>"; };
526AEC911F6B4E5C00695F5D /* NoTailCalls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NoTailCalls.h; sourceTree = "<group>"; };
+ 52B228C12458DC8200753D91 /* ICUHelpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ICUHelpers.h; sourceTree = "<group>"; };
530A63481FA3E3A00026A545 /* Scripts */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Scripts; sourceTree = "<group>"; };
5311BD511EA71CAD00525281 /* Signals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Signals.cpp; sourceTree = "<group>"; };
5311BD551EA7E15A00525281 /* LocklessBag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LocklessBag.h; sourceTree = "<group>"; };
@@ -1438,6 +1439,7 @@
A8A4734F151A825B004123FF /* icu */ = {
isa = PBXGroup;
children = (
+ 52B228C12458DC8200753D91 /* ICUHelpers.h */,
A8A47350151A825B004123FF /* CollatorICU.cpp */,
);
path = icu;
Modified: trunk/Source/WTF/wtf/CMakeLists.txt (260881 => 260882)
--- trunk/Source/WTF/wtf/CMakeLists.txt 2020-04-29 07:09:44 UTC (rev 260881)
+++ trunk/Source/WTF/wtf/CMakeLists.txt 2020-04-29 07:15:18 UTC (rev 260882)
@@ -358,6 +358,8 @@
unicode/CharacterNames.h
unicode/Collator.h
unicode/UTF8Conversion.h
+
+ unicode/icu/ICUHelpers.h
)
set(WTF_SOURCES
Modified: trunk/Source/WTF/wtf/text/LineBreakIteratorPoolICU.h (260881 => 260882)
--- trunk/Source/WTF/wtf/text/LineBreakIteratorPoolICU.h 2020-04-29 07:09:44 UTC (rev 260881)
+++ trunk/Source/WTF/wtf/text/LineBreakIteratorPoolICU.h 2020-04-29 07:15:18 UTC (rev 260882)
@@ -30,6 +30,7 @@
#include <wtf/NeverDestroyed.h>
#include <wtf/ThreadSpecific.h>
#include <wtf/text/AtomString.h>
+#include <wtf/unicode/icu/ICUHelpers.h>
namespace WTF {
@@ -74,7 +75,7 @@
int32_t lengthNeeded = uloc_setKeywordValue("lb", keywordValue, scratchBuffer.data(), scratchBuffer.size(), &status);
if (U_SUCCESS(status))
return AtomString::fromUTF8(scratchBuffer.data(), lengthNeeded);
- if (status == U_BUFFER_OVERFLOW_ERROR) {
+ if (needsToGrowToProduceBuffer(status)) {
scratchBuffer.grow(lengthNeeded + 1);
memset(scratchBuffer.data() + utf8Locale.length(), 0, scratchBuffer.size() - utf8Locale.length());
status = U_ZERO_ERROR;
Modified: trunk/Source/WTF/wtf/text/StringView.cpp (260881 => 260882)
--- trunk/Source/WTF/wtf/text/StringView.cpp 2020-04-29 07:09:44 UTC (rev 260881)
+++ trunk/Source/WTF/wtf/text/StringView.cpp 2020-04-29 07:15:18 UTC (rev 260882)
@@ -37,6 +37,7 @@
#include <wtf/Optional.h>
#include <wtf/text/StringToIntegerConversion.h>
#include <wtf/text/TextBreakIterator.h>
+#include <wtf/unicode/icu/ICUHelpers.h>
namespace WTF {
@@ -291,7 +292,7 @@
return { string, { } };
unsigned normalizedLength = unorm2_normalize(normalizer, string.characters16(), string.length(), nullptr, 0, &status);
- ASSERT(status == U_BUFFER_OVERFLOW_ERROR);
+ ASSERT(needsToGrowToProduceBuffer(status));
UChar* characters;
String result = String::createUninitialized(normalizedLength, characters);
Added: trunk/Source/WTF/wtf/unicode/icu/ICUHelpers.h (0 => 260882)
--- trunk/Source/WTF/wtf/unicode/icu/ICUHelpers.h (rev 0)
+++ trunk/Source/WTF/wtf/unicode/icu/ICUHelpers.h 2020-04-29 07:15:18 UTC (rev 260882)
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <unicode/utypes.h>
+
+namespace WTF {
+
+inline bool needsToGrowToProduceCString(UErrorCode errorCode)
+{
+ return errorCode == U_BUFFER_OVERFLOW_ERROR || errorCode == U_STRING_NOT_TERMINATED_WARNING;
+}
+
+inline bool needsToGrowToProduceBuffer(UErrorCode errorCode)
+{
+ return errorCode == U_BUFFER_OVERFLOW_ERROR;
+}
+
+}
+
+using WTF::needsToGrowToProduceCString;
+using WTF::needsToGrowToProduceBuffer;
Modified: trunk/Source/WebCore/ChangeLog (260881 => 260882)
--- trunk/Source/WebCore/ChangeLog 2020-04-29 07:09:44 UTC (rev 260881)
+++ trunk/Source/WebCore/ChangeLog 2020-04-29 07:15:18 UTC (rev 260882)
@@ -1,3 +1,25 @@
+2020-04-29 Saam Barati <[email protected]>
+
+ U_STRING_NOT_TERMINATED_WARNING ICU must be handled when using the output buffer as a C string
+ https://bugs.webkit.org/show_bug.cgi?id=211142
+ <rdar://problem/62530860>
+
+ Reviewed by Darin Adler.
+
+ * editing/TextIterator.cpp:
+ (WebCore::normalizeCharacters):
+ * platform/text/LocaleICU.cpp:
+ (WebCore::LocaleICU::decimalSymbol):
+ (WebCore::LocaleICU::decimalTextAttribute):
+ (WebCore::getDateFormatPattern):
+ (WebCore::LocaleICU::createLabelVector):
+ (WebCore::getFormatForSkeleton):
+ * platform/text/LocaleToScriptMappingICU.cpp:
+ (WebCore::localeToScriptCodeForFontSelection):
+ * platform/text/TextCodecICU.cpp:
+ (WebCore::TextCodecICU::decode):
+ (WebCore::TextCodecICU::encode):
+
2020-04-29 Noam Rosenthal <[email protected]>
Add StringView::isAllSpecialCharacters()
Modified: trunk/Source/WebCore/editing/TextIterator.cpp (260881 => 260882)
--- trunk/Source/WebCore/editing/TextIterator.cpp 2020-04-29 07:09:44 UTC (rev 260881)
+++ trunk/Source/WebCore/editing/TextIterator.cpp 2020-04-29 07:15:18 UTC (rev 260882)
@@ -66,6 +66,7 @@
#include <wtf/text/StringBuilder.h>
#include <wtf/text/TextBreakIterator.h>
#include <wtf/unicode/CharacterNames.h>
+#include <wtf/unicode/icu/ICUHelpers.h>
#if !UCONFIG_NO_COLLATION
#include <unicode/usearch.h>
@@ -1836,7 +1837,7 @@
buffer.resize(length);
auto normalizedLength = unorm2_normalize(normalizer, characters, length, buffer.data(), length, &status);
- ASSERT(U_SUCCESS(status) || status == U_BUFFER_OVERFLOW_ERROR);
+ ASSERT(U_SUCCESS(status) || needsToGrowToProduceBuffer(status));
buffer.resize(normalizedLength);
Modified: trunk/Source/WebCore/platform/text/LocaleICU.cpp (260881 => 260882)
--- trunk/Source/WebCore/platform/text/LocaleICU.cpp 2020-04-29 07:09:44 UTC (rev 260881)
+++ trunk/Source/WebCore/platform/text/LocaleICU.cpp 2020-04-29 07:15:18 UTC (rev 260882)
@@ -37,6 +37,7 @@
#include <unicode/uloc.h>
#include <wtf/DateMath.h>
#include <wtf/text/StringBuilder.h>
+#include <wtf/unicode/icu/ICUHelpers.h>
namespace WebCore {
@@ -69,8 +70,8 @@
{
UErrorCode status = U_ZERO_ERROR;
int32_t bufferLength = unum_getSymbol(m_numberFormat, symbol, 0, 0, &status);
- ASSERT(U_SUCCESS(status) || status == U_BUFFER_OVERFLOW_ERROR);
- if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR)
+ ASSERT(U_SUCCESS(status) || needsToGrowToProduceBuffer(status));
+ if (U_FAILURE(status) && !needsToGrowToProduceBuffer(status))
return String();
Vector<UChar> buffer(bufferLength);
status = U_ZERO_ERROR;
@@ -84,8 +85,8 @@
{
UErrorCode status = U_ZERO_ERROR;
int32_t bufferLength = unum_getTextAttribute(m_numberFormat, tag, 0, 0, &status);
- ASSERT(U_SUCCESS(status) || status == U_BUFFER_OVERFLOW_ERROR);
- if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR)
+ ASSERT(U_SUCCESS(status) || needsToGrowToProduceBuffer(status));
+ if (U_FAILURE(status) && !needsToGrowToProduceBuffer(status))
return String();
Vector<UChar> buffer(bufferLength);
status = U_ZERO_ERROR;
@@ -150,7 +151,7 @@
UErrorCode status = U_ZERO_ERROR;
int32_t length = udat_toPattern(dateFormat, TRUE, 0, 0, &status);
- if (status != U_BUFFER_OVERFLOW_ERROR || !length)
+ if (!needsToGrowToProduceBuffer(status) || !length)
return emptyString();
Vector<UChar> buffer(length);
status = U_ZERO_ERROR;
@@ -172,7 +173,7 @@
for (int32_t i = 0; i < size; ++i) {
UErrorCode status = U_ZERO_ERROR;
int32_t length = udat_getSymbols(dateFormat, type, startIndex + i, 0, 0, &status);
- if (status != U_BUFFER_OVERFLOW_ERROR)
+ if (!needsToGrowToProduceBuffer(status))
return makeUnique<Vector<String>>();
Vector<UChar> buffer(length);
status = U_ZERO_ERROR;
@@ -264,7 +265,7 @@
return format;
status = U_ZERO_ERROR;
int32_t length = udatpg_getBestPattern(patternGenerator, skeleton, skeletonLength, 0, 0, &status);
- if (status == U_BUFFER_OVERFLOW_ERROR && length) {
+ if (needsToGrowToProduceBuffer(status) && length) {
Vector<UChar> buffer(length);
status = U_ZERO_ERROR;
udatpg_getBestPattern(patternGenerator, skeleton, skeletonLength, buffer.data(), length, &status);
Modified: trunk/Source/WebCore/platform/text/LocaleToScriptMappingICU.cpp (260881 => 260882)
--- trunk/Source/WebCore/platform/text/LocaleToScriptMappingICU.cpp 2020-04-29 07:09:44 UTC (rev 260881)
+++ trunk/Source/WebCore/platform/text/LocaleToScriptMappingICU.cpp 2020-04-29 07:15:18 UTC (rev 260882)
@@ -34,6 +34,7 @@
#include <unicode/uloc.h>
#include <wtf/text/CString.h>
#include <wtf/text/WTFString.h>
+#include <wtf/unicode/icu/ICUHelpers.h>
namespace WebCore {
@@ -71,7 +72,7 @@
UScriptCode scriptCode = USCRIPT_COMMON;
uscript_getCode(script, &scriptCode, 1, &status);
// Ignore error that multiple scripts could be returned, since we only want one script.
- if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR)
+ if (U_FAILURE(status) && !needsToGrowToProduceBuffer(status))
return USCRIPT_COMMON;
return scriptCodeForFontSelection(scriptCode);
Modified: trunk/Source/WebCore/platform/text/TextCodecICU.cpp (260881 => 260882)
--- trunk/Source/WebCore/platform/text/TextCodecICU.cpp 2020-04-29 07:09:44 UTC (rev 260881)
+++ trunk/Source/WebCore/platform/text/TextCodecICU.cpp 2020-04-29 07:15:18 UTC (rev 260882)
@@ -36,6 +36,7 @@
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/unicode/CharacterNames.h>
+#include <wtf/unicode/icu/ICUHelpers.h>
namespace WebCore {
@@ -308,7 +309,7 @@
do {
int ucharsDecoded = decodeToBuffer(buffer, bufferLimit, source, sourceLimit, offsets, flush, err);
result.appendCharacters(buffer, ucharsDecoded);
- } while (err == U_BUFFER_OVERFLOW_ERROR);
+ } while (needsToGrowToProduceBuffer(err));
if (U_FAILURE(err)) {
// flush the converter so it can be reused, and not be bothered by this error.
@@ -461,7 +462,7 @@
error = U_ZERO_ERROR;
ucnv_fromUnicode(m_converter.get(), &target, targetLimit, &source, sourceLimit, 0, true, &error);
result.append(reinterpret_cast<uint8_t*>(buffer), target - buffer);
- } while (error == U_BUFFER_OVERFLOW_ERROR);
+ } while (needsToGrowToProduceBuffer(error));
return result;
}