Commit 16b0eaf9 authored by msaboff@apple.com's avatar msaboff@apple.com
Browse files

HTMLConstructionSite::insertTextNode isn't optimized for 8 bit strings

https://bugs.webkit.org/show_bug.cgi?id=97740

Reviewed by Darin Adler.

Source/WebCore: 

Changed parserAppendData to take a string instead of a UChar*.  Also added an optional offset
argument to handle string+offset.  The actual string append now uses the appropriate string
size.

* dom/CharacterData.cpp:
(WebCore::CharacterData::parserAppendData):
* dom/CharacterData.h:
(CharacterData):
* dom/Text.cpp:
(WebCore::Text::createWithLengthLimit):
* html/parser/HTMLConstructionSite.cpp:
(WebCore::HTMLConstructionSite::insertTextNode):

Source/WTF: 

Added an append method that takes an LChar source.  Made both the UChar and LChar versions optimally handle
the appendee and appendend string bitness.

* wtf/text/WTFString.cpp:
(WTF::String::append):
* wtf/text/WTFString.h:
(String):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@130190 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent af0689b9
2012-10-02 Michael Saboff <msaboff@apple.com>
HTMLConstructionSite::insertTextNode isn't optimized for 8 bit strings
https://bugs.webkit.org/show_bug.cgi?id=97740
Reviewed by Darin Adler.
Added an append method that takes an LChar source. Made both the UChar and LChar versions optimally handle
the appendee and appendend string bitness.
* wtf/text/WTFString.cpp:
(WTF::String::append):
* wtf/text/WTFString.h:
(String):
2012-10-02 Ilya Tikhonovsky <loislo@chromium.org>
Web Inspector: NMI: switch to non intrusive instrumentation of ParsedURL.
......
......@@ -167,7 +167,7 @@ void String::insert(const String& str, unsigned pos)
insert(str.characters(), str.length(), pos);
}
void String::append(const UChar* charactersToAppend, unsigned lengthToAppend)
void String::append(const LChar* charactersToAppend, unsigned lengthToAppend)
{
if (!m_impl) {
if (!charactersToAppend)
......@@ -180,15 +180,57 @@ void String::append(const UChar* charactersToAppend, unsigned lengthToAppend)
return;
ASSERT(charactersToAppend);
UChar* data;
if (lengthToAppend > numeric_limits<unsigned>::max() - length())
unsigned strLength = m_impl->length();
if (m_impl->is8Bit()) {
if (lengthToAppend > numeric_limits<unsigned>::max() - strLength)
CRASH();
LChar* data;
RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength + lengthToAppend, data);
StringImpl::copyChars(data, m_impl->characters8(), strLength);
StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend);
m_impl = newImpl.release();
return;
}
if (lengthToAppend > numeric_limits<unsigned>::max() - strLength)
CRASH();
UChar* data;
RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() + lengthToAppend, data);
memcpy(data, characters(), length() * sizeof(UChar));
memcpy(data + length(), charactersToAppend, lengthToAppend * sizeof(UChar));
StringImpl::copyChars(data, m_impl->characters16(), strLength);
StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend);
m_impl = newImpl.release();
}
void String::append(const UChar* charactersToAppend, unsigned lengthToAppend)
{
if (!m_impl) {
if (!charactersToAppend)
return;
m_impl = StringImpl::create(charactersToAppend, lengthToAppend);
return;
}
if (!lengthToAppend)
return;
unsigned strLength = m_impl->length();
ASSERT(charactersToAppend);
if (lengthToAppend > numeric_limits<unsigned>::max() - strLength)
CRASH();
UChar* data;
RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength + lengthToAppend, data);
if (m_impl->is8Bit())
StringImpl::copyChars(data, characters8(), strLength);
else
StringImpl::copyChars(data, characters16(), strLength);
StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend);
m_impl = newImpl.release();
}
void String::insert(const UChar* charactersToInsert, unsigned lengthToInsert, unsigned position)
{
if (position >= length()) {
......
......@@ -302,6 +302,7 @@ public:
WTF_EXPORT_STRING_API void append(LChar);
void append(char c) { append(static_cast<LChar>(c)); };
WTF_EXPORT_STRING_API void append(UChar);
WTF_EXPORT_STRING_API void append(const LChar*, unsigned length);
WTF_EXPORT_STRING_API void append(const UChar*, unsigned length);
WTF_EXPORT_STRING_API void insert(const String&, unsigned pos);
void insert(const UChar*, unsigned length, unsigned pos);
......
2012-10-02 Michael Saboff <msaboff@apple.com>
HTMLConstructionSite::insertTextNode isn't optimized for 8 bit strings
https://bugs.webkit.org/show_bug.cgi?id=97740
Reviewed by Darin Adler.
Changed parserAppendData to take a string instead of a UChar*. Also added an optional offset
argument to handle string+offset. The actual string append now uses the appropriate string
size.
* dom/CharacterData.cpp:
(WebCore::CharacterData::parserAppendData):
* dom/CharacterData.h:
(CharacterData):
* dom/Text.cpp:
(WebCore::Text::createWithLengthLimit):
* html/parser/HTMLConstructionSite.cpp:
(WebCore::HTMLConstructionSite::insertTextNode):
2012-10-02 Ojan Vafai <ojan@chromium.org>
 
Unreviewed, rolling out r130103 and r130125.
......@@ -63,26 +63,32 @@ String CharacterData::substringData(unsigned offset, unsigned count, ExceptionCo
return m_data.substring(offset, count);
}
unsigned CharacterData::parserAppendData(const UChar* data, unsigned dataLength, unsigned lengthLimit)
unsigned CharacterData::parserAppendData(const String& string, unsigned offset, unsigned lengthLimit)
{
unsigned oldLength = m_data.length();
unsigned end = min(dataLength, lengthLimit - oldLength);
ASSERT(lengthLimit >= oldLength);
unsigned characterLength = string.length() - offset;
unsigned characterLengthLimit = min(characterLength, lengthLimit - oldLength);
// Check that we are not on an unbreakable boundary.
// Some text break iterator implementations work best if the passed buffer is as small as possible,
// see <https://bugs.webkit.org/show_bug.cgi?id=29092>.
// Some text break iterator implementations work best if the passed buffer is as small as possible,
// see <https://bugs.webkit.org/show_bug.cgi?id=29092>.
// We need at least two characters look-ahead to account for UTF-16 surrogates.
if (end < dataLength) {
NonSharedCharacterBreakIterator it(data, (end + 2 > dataLength) ? dataLength : end + 2);
if (!isTextBreak(it, end))
end = textBreakPreceding(it, end);
if (characterLengthLimit < characterLength) {
NonSharedCharacterBreakIterator it(string.characters() + offset, (characterLengthLimit + 2 > characterLength) ? characterLength : characterLengthLimit + 2);
if (!isTextBreak(it, characterLengthLimit))
characterLengthLimit = textBreakPreceding(it, characterLengthLimit);
}
if (!end)
if (!characterLengthLimit)
return 0;
m_data.append(data, end);
if (string.is8Bit())
m_data.append(string.characters8() + offset, characterLengthLimit);
else
m_data.append(string.characters16() + offset, characterLengthLimit);
updateRenderer(oldLength, 0);
document()->incDOMTreeVersion();
......@@ -90,8 +96,8 @@ unsigned CharacterData::parserAppendData(const UChar* data, unsigned dataLength,
// parser to dispatch DOM mutation events.
if (parentNode())
parentNode()->childrenChanged();
return end;
return characterLengthLimit;
}
void CharacterData::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
......
......@@ -45,7 +45,7 @@ public:
// Like appendData, but optimized for the parser (e.g., no mutation events).
// Returns how much could be added before length limit was met.
unsigned parserAppendData(const UChar*, unsigned dataLength, unsigned lengthLimit);
unsigned parserAppendData(const String& string, unsigned offset, unsigned lengthLimit);
virtual void reportMemoryUsage(MemoryObjectInfo*) const;
......
......@@ -288,7 +288,7 @@ PassRefPtr<Text> Text::createWithLengthLimit(Document* document, const String& d
return create(document, data);
RefPtr<Text> result = Text::create(document, String());
result->parserAppendData(data.characters() + start, dataLength - start, maxChars);
result->parserAppendData(data, start, maxChars);
return result;
}
......
......@@ -368,7 +368,7 @@ void HTMLConstructionSite::insertTextNode(const String& characters, WhitespaceMo
// FIXME: We're only supposed to append to this text node if it
// was the last text node inserted by the parser.
CharacterData* textNode = static_cast<CharacterData*>(previousChild);
currentPosition = textNode->parserAppendData(characters.characters(), characters.length(), Text::defaultLengthLimit);
currentPosition = textNode->parserAppendData(characters, 0, Text::defaultLengthLimit);
}
while (currentPosition < characters.length()) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment