Skip to content

Commit

Permalink
StringImpl::copyCharacters incorrectly uses memcpy on destination
Browse files Browse the repository at this point in the history
pointers that may be null
https://bugs.webkit.org/show_bug.cgi?id=246260

We should assert StringImpl::copyCharacters does not discard information
https://bugs.webkit.org/show_bug.cgi?id=205355

rdar://problem/100962334

Reviewed by Yusuke Suzuki.

After studying the call sites of StringImpl::copyCharacters and its
implementation, it is clear that many callers can pass nullptr for either
the source or destination when the length passed in is 0. Since
std::memcpy behavior is undefined in such cases, need to change the
implementation of StringImpl::copyCharacters to not use it in those
cases. In the end, decided to check for zero length even though I advised
against that previously.

Visiting all the call sites of StringImpl::copyCharacters led to
discovering some other anomalies that are fixed with improved coding
idioms, no major changes.

* Source/JavaScriptCore/API/OpaqueJSString.cpp:
(OpaqueJSString::characters): Updated for name change of
StringView::getCharacters.

* Source/JavaScriptCore/jit/ExecutableAllocationFuzz.cpp: Added include
of NeverDestroyed.h.

* Source/JavaScriptCore/parser/Lexer.cpp:
(JSC::Lexer<T>::parseCommentDirectiveValue): Use String::make8Bit instead
of StringImpl::createUninitialized, for code that is more straightforward.
Also wondering why we don't need this optimization in more places.

* Source/JavaScriptCore/runtime/IntlLocale.cpp:
(JSC::LocaleIDBuilder::setKeywordValue): Use StringView::getCharacters.

* Source/JavaScriptCore/runtime/IntlObjectInlines.h:
(JSC::ListFormatInput::ListFormatInput): Use String::convertTo16Bit. This
eliminates the need for m_retainedUpconvertedStrings.

* Source/JavaScriptCore/runtime/JSString.cpp:
(JSC::JSRopeString::resolveRopeInternal const): Tweaked the comment
wording for clarity. Use StringView::getCharacters.
(JSC::JSRopeString::resolveRopeInternalNoSubstring const): Ditto.
(JSC::JSRopeString::resolveRopeSlowCase const): Ditto.

* Source/JavaScriptCore/runtime/JSStringJoiner.cpp:
(JSC::appendStringToData): Updated for name change of
StringView::getCharacters.

* Source/JavaScriptCore/runtime/StringPrototype.cpp:
(JSC::jsSpliceSubstrings): Removed unneeded checks for zero length;
adding a branch to optimize that case isn't valuable and it's not needed
for correctness.
* Source/JavaScriptCore/runtime/StringPrototypeInlines.h:
(JSC::jsSpliceSubstringsWithSeparators): Ditto. Also use
StringView::getCharacters.

* Source/JavaScriptCore/tools/JSDollarVM.cpp:
(JSC::functionMake16BitStringIfPossible): Use String::convertTo16Bit.

* Source/JavaScriptCore/jit/ExecutableAllocationFuzz.cpp: Added include
of NeverDestroyed.h.

* Source/WTF/wtf/DateMath.cpp:
(WTF::validateTimeZone): Use StringView::upconvertedCharacters.

* Source/WTF/wtf/LogInitialization.cpp: Added include of NeverDestroyed.h.
* Source/WTF/wtf/Logger.cpp: Ditto.

* Source/WTF/wtf/SortedArrayMap.h: Added support for a case-sensitive
version of PackedASCIILowerCodes, named PackedASCIILiteral, and for using
a span of characters as the key in the "packed" case without first
converting it to a StringView and then having to check is8Bit at runtime.

* Source/WTF/wtf/Threading.cpp: Added include of NeverDestroyed.h.
* Source/WTF/wtf/generic/RunLoopGeneric.cpp: Ditto.
* Source/WTF/wtf/linux/RealTimeThreads.cpp: Ditto.

* Source/WTF/wtf/text/ASCIIFastPath.h:
(WTF::copyLCharsFromUCharSource): Deleted. Moved into
StringImpl::copyCharacters.

* Source/WTF/wtf/text/AtomString.h: Removed unneeded includes and the
constructor that takes a Vector. Removed unneeded explicit
implementations of copy and move constructors and assignment operators
that are the same as the defaults. Added a lookUp function.

* Source/WTF/wtf/text/Base64.h: Removed the overloads that take a String
so we don't implicitly create a String when a StringView will do.

* Source/WTF/wtf/text/StringConcatenate.h: Updated for name change of
StringView::getCharacters.

* Source/WTF/wtf/text/StringImpl.h:
(WTF::StringImpl::copyCharacters): Used overloading instead of
unnecessarily complex template programming. Made the version that uses
memcpy do a zero-length check so we aren't relying on undefined behavior
of memcpy. Moved the code from copyLCharsFromUCharSource here.
(WTF::StringImpl::removeCharactersImpl): Removed unneeded zero-length
check before calling StringImpl::copyCharacters.

* Source/WTF/wtf/text/StringView.h: Renamed getCharactersWithUpconvert to
just getCharacters since it can be used in many cases that don't involve
upconversion. Also implemented it as a template since there seems no
disadvantage to doing so. Added getCharacters8, getCharacters16, span8,
and span16.

* Source/WTF/wtf/text/IntegerToStringConversion.h: Added a missing
include.

* Source/WTF/wtf/text/WTFString.cpp:
(WTF::String::charactersWithoutNullTermination const): Removed unnecessary
use of size_t.
(WTF::String::make8Bit): Renamed from make8BitFrom16BitSource, changed the
argument type from size_t to unsigned. Changed to return an empty string
rather than a null string by removing a special case for zero length.
(WTF::String::convertTo16Bit): Added. Replaces make16BitFrom8BitSource,
since all callers can do better by converting a String in place, and we
can significantly simplify them since this efficiently does nothing if
characters are already 16-bit.
(WTF::fromUTF8Impl): Rewrote the "crash if size is too big" to use
RELEASE_ASSERT for clarity.
(WTF::String::fromUTF8WithLatin1Fallback): Added a missing RELEASE_ASSERT
for the fallback case, just like the one above.

* Source/WTF/wtf/text/WTFString.h: Updated for the above changes. Removed
some stray semicolons. Removed the constructor that takes a Vector.

* Source/WTF/wtf/text/icu/UTextProviderLatin1.cpp:
(WTF::uTextLatin1Access): Removed unneeded static_cast.
(WTF::uTextLatin1Extract): Ditto.
(WTF::textLatin1ContextAwareMoveInPrimaryContext): Ditto.

* Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp:
(WebCore::ThreadableWebSocketChannelClientWrapper::setSubprotocol):
Updated for name change of StringView::getCharacters.
(WebCore::ThreadableWebSocketChannelClientWrapper::setExtensions): Ditto.
* Source/WebCore/html/canvas/CanvasRenderingContext2DBase.cpp:
(WebCore::CanvasRenderingContext2DBase::normalizeSpaces): Ditto.

* Source/WebCore/html/HTMLImageElement.cpp:
(WebCore::HTMLImageElement::hasLazyLoadableAttributeValue): Take a
StringView.
* Source/WebCore/html/HTMLImageElement.h: Updated for the above.

* Source/WebCore/html/LinkRelAttribute.cpp:
(WebCore::LinkRelAttribute::LinkRelAttribute): Moved most initialization
into the class definition. Take a StringView, and don't allocate any
String as part of parsing.
* Source/WebCore/html/LinkRelAttribute.h: Updated for the above.

* Source/WebCore/html/parser/AtomHTMLToken.h: Updated to use
String::make8Bit. Removed the overload of make8BitFrom16BitSource that
took a Vector directly since this was the only place it was used, and such
functions bloat the String interface with little benefit.

* Source/WebCore/html/parser/HTMLMetaCharsetParser.cpp:
(WebCore::extractCharset): Take StringView.
(WebCore::HTMLMetaCharsetParser::processMeta): Pass StringView to
encodingFromMetaAttributes.
(WebCore::HTMLMetaCharsetParser::encodingFromMetaAttributes): Take
StringView.
(WebCore::HTMLMetaCharsetParser::checkForMetaCharset): Use
AtomString::lookUp since we only need to handle existing known tags, not
any that aren't already in the atom string table.
* Source/WebCore/html/parser/HTMLMetaCharsetParser.h: Update
encodingFromMetaAttributes to take StringView.

* Source/WebCore/html/parser/HTMLPreloadScanner.cpp:
(WebCore::TokenPreloadScanner::tagIdFor): Use a sorted array map instead
of contructing an atom string.
(WebCore::TokenPreloadScanner::StartTagScanner::processAttributes): Use
AtomString::lookUp and StringView.
(WebCore::TokenPreloadScanner::StartTagScanner::processImageAndScriptAttribute):
Use StringView for attribute values, making strings only when the
attribute name indicates we should store the value.
(WebCore::TokenPreloadScanner::StartTagScanner::processAttribute): Ditto.
(WebCore::TokenPreloadScanner::StartTagScanner::setURLToLoad): Take a
StringView, also use a separate named function instead of a mysterious
boolean argument.
(WebCore::TokenPreloadScanner::StartTagScanner::setURLToLoadAllowingReplacement):
More of the same.
(WebCore::HTMLPreloadScanner::scan): Use AtomString::lookUp since we only
need to handle existing known tags, not any that aren't already in the
atom string table.

* Source/WebCore/html/parser/HTMLSrcsetParser.cpp:
(WebCore::bestFitSourceForImageAttributes): Take StringView.
* Source/WebCore/html/parser/HTMLSrcsetParser.h: Update for the above.

* Source/WebCore/html/parser/HTMLTreeBuilder.cpp:
(WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::makeString const):
Updated for name change of String::make8Bit.

* Source/WebCore/layout/formattingContexts/inline/InlineLineBuilder.cpp:
(WebCore::Layout::endsWithSoftWrapOpportunity): Use
String::convertTo16Bit.

* Source/WebCore/platform/glib/ApplicationGLib.cpp: Added include of
NeverDestroyed.h.

* Source/WebCore/platform/graphics/ComplexTextController.cpp:
(WebCore::ComplexTextController::collectComplexTextRuns): Use
String::convertTo16Bit.

* Source/WebCore/page/PageSerializer.cpp:
(WebCore::isCharsetSpecifyingNode): Handle the type of the argument in a
simpler way, and use HTMLMetaElement instead of metaTag. Use StringView
instead of atom strings for encodingFromMetaAttributes.

* Source/WebCore/platform/graphics/StringTruncator.cpp:
(WebCore::centerTruncateToBuffer): Updated for name change of
StringView::getCharacters.
(WebCore::rightTruncateToBuffer): Ditto.
(WebCore::rightClipToCharacterBuffer): Ditto.
(WebCore::rightClipToWordBuffer): Ditto.
(WebCore::leftTruncateToBuffer): Ditto.
(WebCore::truncateString): Ditto.

* Source/WebCore/platform/graphics/TextRun.h: Added textAsString.
There's one new call site that takes advantage of taking the string out.
We could also just consider changing the text funtion to return a
const String&, but to do that safely we'd have to make sure no callers
are using substring or similar functions.

* Source/WebCore/platform/graphics/gstreamer/eme/GStreamerEMEUtilities.h:
(WebCore::GStreamerEMEUtilities::uuidToKeySystem): Removed the peculiar
use of NeverDestroyed here. Since ASCIILiteral is just a pointer, used
it as a return type instead of const ASCIILiteral&.

* Source/WebCore/platform/graphics/win/FontCacheWin.cpp:
(WebCore::FontCache::systemFallbackForCharacters): Updated for name change
of StringView::getCharacters. Would be more elegant to add a
platform-specific StringView::getWideCharactersWithNullTermination
function since this pattern repeats.
(WebCore::createGDIFont): Ditto.
(WebCore::FontCache::getFontSelectionCapabilitiesInFamily): Ditto.

* Source/WebCore/platform/mediastream/CaptureDevice.h: Added include of
NeverDestroyed.h.

* Source/WebCore/platform/win/ClipboardUtilitiesWin.cpp:
(WebCore::createGlobalData): Updated for name change of
StringView::getCharacters.
* Source/WebCore/platform/win/PasteboardWin.cpp:
(WebCore::fileSystemPathFromURLOrTitle): Ditto.
(WebCore::Pasteboard::writeURLToDataObject): Ditto.
(WebCore::createGlobalImageFileDescriptor): Ditto.

* Source/WebKitLegacy/win/DOMCoreClasses.cpp:
(DOMElement::font): Updated for name change of StringView::getCharacters.
Would be more elegant to add a platform-specific StringView::getWideCharacters
functionsince this pattern repeats.

* Source/WebCore/platform/xr/openxr/OpenXRInstance.cpp: Added include of
NeverDestroyed.h.
* Source/WebKit/Platform/LogInitialization.cpp: Ditto.

* Source/WebKit/Shared/API/c/WKString.cpp:
(WKStringGetCharacters): Updated for name change of
StringView::getCharacters.

* Source/WebKit/UIProcess/Inspector/mac/WebInspectorUIProxyMac.mm:
(WebKit::WebInspectorUIProxy::showSavePanel): Make the String to pass to
base64Decode explicitly from the NSString.

* Source/WebKit/webpushd/PushService.mm:
(WebPushD::base64URLDecode): Added. Makes the String to pass explicitly
from the NSString passed in.
(WebPushD::base64Decode): Ditto.

* Source/WebKitLegacy/win/WebKitGraphics.cpp:
(CenterTruncateStringToWidth): Ditto.
(RightTruncateStringToWidth): Ditto.

* Source/WebKitLegacy/win/WebView.cpp:
(WebView::onIMERequestReconvertString): Ditto.

* Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp: Added
include of NeverDestroyed.h.

Canonical link: https://commits.webkit.org/255600@main
  • Loading branch information
darinadler committed Oct 16, 2022
1 parent 33f7c1b commit 7126575
Show file tree
Hide file tree
Showing 60 changed files with 481 additions and 570 deletions.
5 changes: 2 additions & 3 deletions Source/JavaScriptCore/API/OpaqueJSString.cpp
Expand Up @@ -91,9 +91,8 @@ const UChar* OpaqueJSString::characters()
if (m_string.isNull())
return nullptr;

unsigned length = m_string.length();
UChar* newCharacters = static_cast<UChar*>(fastMalloc(length * sizeof(UChar)));
StringView(m_string).getCharactersWithUpconvert(newCharacters);
UChar* newCharacters = static_cast<UChar*>(fastMalloc(m_string.length() * sizeof(UChar)));
StringView { m_string }.getCharacters(newCharacters);

if (!m_characters.compare_exchange_strong(characters, newCharacters)) {
fastFree(newCharacters);
Expand Down
1 change: 1 addition & 0 deletions Source/JavaScriptCore/jit/ExecutableAllocationFuzz.cpp
Expand Up @@ -29,6 +29,7 @@
#include "TestRunnerUtils.h"
#include <wtf/Atomics.h>
#include <wtf/DataLog.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/WeakRandom.h>

namespace JSC {
Expand Down
30 changes: 11 additions & 19 deletions Source/JavaScriptCore/parser/Lexer.cpp
Expand Up @@ -1839,35 +1839,27 @@ ALWAYS_INLINE void Lexer<T>::parseCommentDirective()
}
}

template <typename T>
ALWAYS_INLINE String Lexer<T>::parseCommentDirectiveValue()
template<typename CharacterType> ALWAYS_INLINE String Lexer<CharacterType>::parseCommentDirectiveValue()
{
skipWhitespace();
bool hasNonLatin1 = false;
const T* stringStart = currentSourcePtr();
UChar mergedCharacterBits = 0;
auto stringStart = currentSourcePtr();
while (!isWhiteSpace(m_current) && !isLineTerminator(m_current) && m_current != '"' && m_current != '\'' && !atEnd()) {
if (!isLatin1(m_current))
hasNonLatin1 = true;
if constexpr (std::is_same_v<CharacterType, UChar>)
mergedCharacterBits |= m_current;
shift();
}
const T* stringEnd = currentSourcePtr();
skipWhitespace();
unsigned length = currentSourcePtr() - stringStart;

skipWhitespace();
if (!isLineTerminator(m_current) && !atEnd())
return String();

unsigned length = stringEnd - stringStart;
if (hasNonLatin1) {
UChar* buffer = nullptr;
String result = StringImpl::createUninitialized(length, buffer);
StringImpl::copyCharacters(buffer, stringStart, length);
return result;
if constexpr (std::is_same_v<CharacterType, UChar>) {
if (isLatin1(mergedCharacterBits))
return String::make8Bit(stringStart, length);
}

LChar* buffer = nullptr;
String result = StringImpl::createUninitialized(length, buffer);
StringImpl::copyCharacters(buffer, stringStart, length);
return result;
return { stringStart, length };
}

template <typename T>
Expand Down
5 changes: 1 addition & 4 deletions Source/JavaScriptCore/runtime/IntlLocale.cpp
Expand Up @@ -185,10 +185,7 @@ void LocaleIDBuilder::setKeywordValue(ASCIILiteral key, StringView value)

ASSERT(value.isAllASCII());
Vector<char, 32> rawValue(value.length() + 1);
if (value.is8Bit())
StringImpl::copyCharacters(reinterpret_cast<LChar*>(rawValue.data()), value.characters8(), value.length());
else
StringImpl::copyCharacters(reinterpret_cast<LChar*>(rawValue.data()), value.characters16(), value.length());
value.getCharacters(reinterpret_cast<LChar*>(rawValue.data()));
rawValue[value.length()] = '\0';

UErrorCode status = U_ZERO_ERROR;
Expand Down
11 changes: 2 additions & 9 deletions Source/JavaScriptCore/runtime/IntlObjectInlines.h
Expand Up @@ -314,14 +314,8 @@ class ListFormatInput {
m_stringPointers.reserveInitialCapacity(m_strings.size());
m_stringLengths.reserveInitialCapacity(m_strings.size());
for (auto& string : m_strings) {
if (string.is8Bit()) {
auto vector = makeUnique<Vector<UChar>>();
vector->resize(string.length());
StringImpl::copyCharacters(vector->data(), string.characters8(), string.length());
m_retainedUpconvertedStrings.append(WTFMove(vector));
m_stringPointers.append(m_retainedUpconvertedStrings.last()->data());
} else
m_stringPointers.append(string.characters16());
string.convertTo16Bit();
m_stringPointers.append(string.characters16());
m_stringLengths.append(string.length());
}
}
Expand All @@ -332,7 +326,6 @@ class ListFormatInput {

private:
Vector<String, 4> m_strings;
Vector<std::unique_ptr<Vector<UChar>>, 4> m_retainedUpconvertedStrings;
Vector<const UChar*, 4> m_stringPointers;
Vector<int32_t, 4> m_stringLengths;
};
Expand Down
40 changes: 12 additions & 28 deletions Source/JavaScriptCore/runtime/JSString.cpp
Expand Up @@ -145,16 +145,12 @@ template<typename CharacterType>
void JSRopeString::resolveRopeInternal(CharacterType* buffer) const
{
if (isSubstring()) {
// It is possible that underlying string becomes 8bit/16bit while wrapper substring is saying it is 16bit/8bit.
// But It is definitely true that substring part can be represented as its parent's status 8bit/16bit, which is described as CharacterType.
auto& string = substringBase()->valueInternal();
if (string.is8Bit())
StringImpl::copyCharacters(buffer, string.characters8() + substringOffset(), length());
else
StringImpl::copyCharacters(buffer, string.characters16() + substringOffset(), length());
// It is possible underlying string is now 8-bit/16-bit even if wrapper substring says it is 16-bit/8-bit.
// But it's guaranteed substring characters can be represented in parent rope's character width, passed as CharacterType.
StringView { substringBase()->valueInternal() }.substring(substringOffset(), length()).getCharacters(buffer);
return;
}

resolveRopeInternalNoSubstring(buffer);
}

Expand All @@ -170,13 +166,9 @@ void JSRopeString::resolveRopeInternalNoSubstring(CharacterType* buffer) const

CharacterType* position = buffer;
for (size_t i = 0; i < s_maxInternalRopeLength && fiber(i); ++i) {
const StringImpl& fiberString = *fiber(i)->valueInternal().impl();
unsigned length = fiberString.length();
if (fiberString.is8Bit())
StringImpl::copyCharacters(position, fiberString.characters8(), length);
else
StringImpl::copyCharacters(position, fiberString.characters16(), length);
position += length;
StringView view = *fiber(i)->valueInternal().impl();
view.getCharacters(position);
position += view.length();
}
ASSERT((buffer + length()) == position);
}
Expand Down Expand Up @@ -336,29 +328,21 @@ void JSRopeString::resolveRopeSlowCase(CharacterType* buffer) const
JSRopeString* currentFiberAsRope = static_cast<JSRopeString*>(currentFiber);
if (currentFiberAsRope->isSubstring()) {
ASSERT(!currentFiberAsRope->substringBase()->isRope());
StringImpl* string = static_cast<StringImpl*>(
currentFiberAsRope->substringBase()->valueInternal().impl());
StringView view = *currentFiberAsRope->substringBase()->valueInternal().impl();
unsigned offset = currentFiberAsRope->substringOffset();
unsigned length = currentFiberAsRope->length();
position -= length;
if (string->is8Bit())
StringImpl::copyCharacters(position, string->characters8() + offset, length);
else
StringImpl::copyCharacters(position, string->characters16() + offset, length);
view.substring(offset, length).getCharacters(position);
continue;
}
for (size_t i = 0; i < s_maxInternalRopeLength && currentFiberAsRope->fiber(i); ++i)
workQueue.append(currentFiberAsRope->fiber(i));
continue;
}

StringImpl* string = static_cast<StringImpl*>(currentFiber->valueInternal().impl());
unsigned length = string->length();
position -= length;
if (string->is8Bit())
StringImpl::copyCharacters(position, string->characters8(), length);
else
StringImpl::copyCharacters(position, string->characters16(), length);
StringView view = *currentFiber->valueInternal().impl();
position -= view.length();
view.getCharacters(position);
}

ASSERT(buffer == position);
Expand Down
2 changes: 1 addition & 1 deletion Source/JavaScriptCore/runtime/JSStringJoiner.cpp
Expand Up @@ -37,7 +37,7 @@ JSStringJoiner::~JSStringJoiner()
template<typename CharacterType>
static inline void appendStringToData(CharacterType*& data, StringView string)
{
string.getCharactersWithUpconvert(data);
string.getCharacters(data);
data += string.length();
}

Expand Down
14 changes: 6 additions & 8 deletions Source/JavaScriptCore/runtime/StringPrototype.cpp
Expand Up @@ -313,10 +313,9 @@ static ALWAYS_INLINE JSString* jsSpliceSubstrings(JSGlobalObject* globalObject,

Checked<int, AssertNoOverflow> bufferPos = 0;
for (int i = 0; i < rangeCount; i++) {
if (int srcLen = substringRanges[i].distance()) {
StringImpl::copyCharacters(buffer + bufferPos.value(), sourceData + substringRanges[i].begin(), srcLen);
bufferPos += srcLen;
}
int srcLen = substringRanges[i].distance();
StringImpl::copyCharacters(buffer + bufferPos.value(), sourceData + substringRanges[i].begin(), srcLen);
bufferPos += srcLen;
}

RELEASE_AND_RETURN(scope, jsString(vm, impl.releaseNonNull()));
Expand All @@ -333,10 +332,9 @@ static ALWAYS_INLINE JSString* jsSpliceSubstrings(JSGlobalObject* globalObject,

Checked<int, AssertNoOverflow> bufferPos = 0;
for (int i = 0; i < rangeCount; i++) {
if (int srcLen = substringRanges[i].distance()) {
StringImpl::copyCharacters(buffer + bufferPos.value(), sourceData + substringRanges[i].begin(), srcLen);
bufferPos += srcLen;
}
int srcLen = substringRanges[i].distance();
StringImpl::copyCharacters(buffer + bufferPos.value(), sourceData + substringRanges[i].begin(), srcLen);
bufferPos += srcLen;
}

RELEASE_AND_RETURN(scope, jsString(vm, impl.releaseNonNull()));
Expand Down
36 changes: 12 additions & 24 deletions Source/JavaScriptCore/runtime/StringPrototypeInlines.h
Expand Up @@ -138,8 +138,6 @@ ALWAYS_INLINE JSString* jsSpliceSubstringsWithSeparators(JSGlobalObject* globalO

if (source.is8Bit() && allSeparators8Bit) {
LChar* buffer;
const LChar* sourceData = source.characters8();

auto impl = StringImpl::tryCreateUninitialized(totalLength, buffer);
if (!impl) {
throwOutOfMemoryError(globalObject, scope);
Expand All @@ -150,16 +148,14 @@ ALWAYS_INLINE JSString* jsSpliceSubstringsWithSeparators(JSGlobalObject* globalO
Checked<int, AssertNoOverflow> bufferPos = 0;
for (int i = 0; i < maxCount; i++) {
if (i < rangeCount) {
if (int srcLen = substringRanges[i].distance()) {
StringImpl::copyCharacters(buffer + bufferPos.value(), sourceData + substringRanges[i].begin(), srcLen);
bufferPos += srcLen;
}
auto substring = StringView { source }.substring(substringRanges[i].begin(), substringRanges[i].distance());
substring.getCharacters8(buffer + bufferPos.value());
bufferPos += substring.length();
}
if (i < separatorCount) {
if (int sepLen = separators[i].length()) {
StringImpl::copyCharacters(buffer + bufferPos.value(), separators[i].characters8(), sepLen);
bufferPos += sepLen;
}
StringView separator = separators[i];
separator.getCharacters8(buffer + bufferPos.value());
bufferPos += separator.length();
}
}

Expand All @@ -177,22 +173,14 @@ ALWAYS_INLINE JSString* jsSpliceSubstringsWithSeparators(JSGlobalObject* globalO
Checked<int, AssertNoOverflow> bufferPos = 0;
for (int i = 0; i < maxCount; i++) {
if (i < rangeCount) {
if (int srcLen = substringRanges[i].distance()) {
if (source.is8Bit())
StringImpl::copyCharacters(buffer + bufferPos.value(), source.characters8() + substringRanges[i].begin(), srcLen);
else
StringImpl::copyCharacters(buffer + bufferPos.value(), source.characters16() + substringRanges[i].begin(), srcLen);
bufferPos += srcLen;
}
auto substring = StringView { source }.substring(substringRanges[i].begin(), substringRanges[i].distance());
substring.getCharacters(buffer + bufferPos.value());
bufferPos += substring.length();
}
if (i < separatorCount) {
if (int sepLen = separators[i].length()) {
if (separators[i].is8Bit())
StringImpl::copyCharacters(buffer + bufferPos.value(), separators[i].characters8(), sepLen);
else
StringImpl::copyCharacters(buffer + bufferPos.value(), separators[i].characters16(), sepLen);
bufferPos += sepLen;
}
StringView separator = separators[i];
separator.getCharacters(buffer + bufferPos.value());
bufferPos += separator.length();
}
}

Expand Down
8 changes: 2 additions & 6 deletions Source/JavaScriptCore/tools/JSDollarVM.cpp
Expand Up @@ -3640,12 +3640,8 @@ JSC_DEFINE_HOST_FUNCTION(functionMake16BitStringIfPossible, (JSGlobalObject* glo
auto scope = DECLARE_THROW_SCOPE(vm);
String string = callFrame->argument(0).toWTFString(globalObject);
RETURN_IF_EXCEPTION(scope, { });
if (!string.is8Bit())
return JSValue::encode(jsString(vm, WTFMove(string)));
Vector<UChar> buffer;
buffer.resize(string.length());
StringImpl::copyCharacters(buffer.data(), string.characters8(), string.length());
return JSValue::encode(jsString(vm, String::adopt(WTFMove(buffer))));
string.convertTo16Bit();
return JSValue::encode(jsString(vm, WTFMove(string)));
}

JSC_DEFINE_HOST_FUNCTION(functionGetStructureTransitionList, (JSGlobalObject* globalObject, CallFrame* callFrame))
Expand Down
7 changes: 3 additions & 4 deletions Source/WTF/wtf/DateMath.cpp
Expand Up @@ -1039,11 +1039,10 @@ String makeRFC2822DateString(unsigned dayOfWeek, unsigned day, unsigned month, u

static std::optional<Vector<UChar, 32>> validateTimeZone(StringView timeZone)
{
Vector<UChar, 32> buffer(timeZone.length());
timeZone.getCharactersWithUpconvert(buffer.data());

auto buffer = timeZone.upconvertedCharacters();
const UChar* characters = buffer;
Vector<UChar, 32> canonicalBuffer;
auto status = callBufferProducingFunction(ucal_getCanonicalTimeZoneID, buffer.data(), buffer.size(), canonicalBuffer, nullptr);
auto status = callBufferProducingFunction(ucal_getCanonicalTimeZoneID, characters, timeZone.length(), canonicalBuffer, nullptr);
if (!U_SUCCESS(status))
return std::nullopt;
return canonicalBuffer;
Expand Down
1 change: 1 addition & 0 deletions Source/WTF/wtf/LogInitialization.cpp
Expand Up @@ -28,6 +28,7 @@

#include <wtf/LogChannels.h>
#include <wtf/Logging.h>
#include <wtf/NeverDestroyed.h>

namespace WTF {

Expand Down
1 change: 1 addition & 0 deletions Source/WTF/wtf/Logger.cpp
Expand Up @@ -28,6 +28,7 @@

#include <mutex>
#include <wtf/HexNumber.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/text/WTFString.h>

namespace WTF {
Expand Down

0 comments on commit 7126575

Please sign in to comment.