Bug 210736

Summary: REGRESSION (r253987): StringImpl::adopt(Vector&&) copies only half of the characters in the Vector when copying across malloc zones
Product: WebKit Reporter: Fujii Hironori <Hironori.Fujii>
Component: Web Template FrameworkAssignee: Darin Adler <darin>
Status: RESOLVED FIXED    
Severity: Normal CC: benjamin, cdumez, cmarcelo, darin, ews-watchlist, webkit-bug-importer, ysuzuki
Priority: P1 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
Patch
none
Patch
none
Patch none

Description Fujii Hironori 2020-04-20 00:06:48 PDT
StringImpl::adopt truncates the string by copying only half of the argument Vector

r253987 (Bug 186422) added the following line:

> memcpy(stringImplBuffer.get(), vectorBuffer.get(), size);

But it should be the following for UChar string.

> memcpy(stringImplBuffer.get(), vectorBuffer.get(), size * sizeof(CharacterType));
Comment 1 Fujii Hironori 2020-04-20 00:09:27 PDT
Or,

> return StringImpl::create(vector.data(), size);
Comment 2 Darin Adler 2020-04-20 09:33:54 PDT
(In reply to Fujii Hironori from comment #0)
> StringImpl::adopt truncates the string by copying only half of the argument
> Vector
> 
> r253987 (Bug 186422) added the following line:
> 
> > memcpy(stringImplBuffer.get(), vectorBuffer.get(), size);
> 
> But it should be the following for UChar string.
> 
> > memcpy(stringImplBuffer.get(), vectorBuffer.get(), size * sizeof(CharacterType));

StringImpl::copyCharacters(stringImplBuffer.get(), vectorBuffer.get(), size);
Comment 3 Darin Adler 2020-04-20 09:34:23 PDT
(In reply to Darin Adler from comment #2)
> StringImpl::copyCharacters(stringImplBuffer.get(), vectorBuffer.get(), size);

Since the code is inside StringImpl:

    copyCharacters(stringImplBuffer.get(), vectorBuffer.get(), size);
Comment 4 Darin Adler 2020-04-20 09:35:40 PDT
Should use copyCharacters instead of memcpy both in StringImpl::adopt and in StringImpl::replace.
Comment 5 Darin Adler 2020-04-20 09:37:18 PDT
And in StringImpl::StringImpl.

    copyCharacters(const_cast<LChar*>(m_data8), characters.get(), length);

Let's just not use memcpy, which ignores the types of the pointers, except in copyCharacters, which respects the types of the pointers.
Comment 6 Darin Adler 2020-04-20 09:37:37 PDT
Hard part about this is adding an appropriate test case.
Comment 7 Yusuke Suzuki 2020-04-20 09:41:02 PDT
Oops, nice catch!
I think this is hard to test without manual one, because this code is used when malloc_zone breakdown debugging feature is enabled.
Comment 8 Darin Adler 2020-04-20 09:48:35 PDT Comment hidden (obsolete)
Comment 9 Darin Adler 2020-04-20 09:48:59 PDT
I did not add a test. Maybe someone else wants to pick up my patch and add a test?
Comment 10 Darin Adler 2020-04-20 09:53:44 PDT Comment hidden (obsolete)
Comment 11 Darin Adler 2020-04-20 10:04:15 PDT
Created attachment 396983 [details]
Patch
Comment 12 Darin Adler 2020-04-20 10:05:26 PDT
Comment on attachment 396983 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=396983&action=review

> Source/WTF/wtf/text/StringImpl.h:1044
> +        return create(vector.data(), vector.size());

Could have this do vector.clear() after creating the StringImpl, but I don’t think that’s necessary.
Comment 13 Darin Adler 2020-04-20 10:27:03 PDT
Yusuke, as further cleanup maybe we could change the StringImpl(MallocPtr) constructor to not be a template, and only work with StringImplMalloc. Make it a caller responsibility to check. Is there any other caller?
Comment 14 Darin Adler 2020-04-20 10:29:54 PDT
(In reply to Darin Adler from comment #13)
> Yusuke, as further cleanup maybe we could change the StringImpl(MallocPtr)
> constructor to not be a template, and only work with StringImplMalloc. Make
> it a caller responsibility to check. Is there any other caller?

Hmm, no it seems that it can be called with StringBufferMalloc, so I guess we'll leave it alone for now.
Comment 15 Yusuke Suzuki 2020-04-20 11:48:51 PDT
Comment on attachment 396983 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=396983&action=review

r=me

>> Source/WTF/wtf/text/StringImpl.h:1044
>> +        return create(vector.data(), vector.size());
> 
> Could have this do vector.clear() after creating the StringImpl, but I don’t think that’s necessary.

Yeah, I think either is OK.
Comment 16 EWS 2020-04-20 12:10:03 PDT
Committed r260383: <https://trac.webkit.org/changeset/260383>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 396983 [details].
Comment 17 Radar WebKit Bug Importer 2020-04-20 12:11:13 PDT
<rdar://problem/62069530>