Bug 210246 - Use Node::length to replace Node::maxCharacterOffset and lastOffsetInNode; switch more offsets from int to unsigned
Summary: Use Node::length to replace Node::maxCharacterOffset and lastOffsetInNode; sw...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: DOM (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Darin Adler
URL:
Keywords: InRadar
Depends on:
Blocks: 212093
  Show dependency treegraph
 
Reported: 2020-04-08 21:20 PDT by Darin Adler
Modified: 2020-05-19 12:10 PDT (History)
20 users (show)

See Also:


Attachments
Patch (38.29 KB, patch)
2020-04-08 21:32 PDT, Darin Adler
no flags Details | Formatted Diff | Diff
Patch (39.15 KB, patch)
2020-04-08 21:45 PDT, Darin Adler
no flags Details | Formatted Diff | Diff
Patch (35.88 KB, patch)
2020-04-09 11:35 PDT, Darin Adler
no flags Details | Formatted Diff | Diff
Patch (24.69 KB, patch)
2020-04-09 14:08 PDT, Darin Adler
no flags Details | Formatted Diff | Diff
Patch (24.74 KB, patch)
2020-04-10 17:14 PDT, Darin Adler
koivisto: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Darin Adler 2020-04-08 21:20:01 PDT
Use Node::length to replace Node::maxCharacterOffset and lastOffsetInNode; switch more offsets from int to unsigned
Comment 1 Darin Adler 2020-04-08 21:32:52 PDT Comment hidden (obsolete)
Comment 2 Darin Adler 2020-04-08 21:34:10 PDT
While working on reducing the use of live ranges, discovered this improvement, so getting it reviewed and landed separately.
Comment 3 Darin Adler 2020-04-08 21:45:09 PDT Comment hidden (obsolete)
Comment 4 Antti Koivisto 2020-04-09 03:43:11 PDT
Looks like there is a behavior change here. Tests show failures but also new PASSes in WPT.
Comment 5 Darin Adler 2020-04-09 04:37:42 PDT
Looks like behavior change is in the text input selection part of this; I think it’s a change we will want, but I will separate that out into a much smaller patch.
Comment 6 Darin Adler 2020-04-09 11:35:30 PDT Comment hidden (obsolete)
Comment 7 Darin Adler 2020-04-09 11:35:50 PDT
This newer patch should leave out the behavior change, which we can consider and do later/separately.
Comment 8 Darin Adler 2020-04-09 12:21:04 PDT
Oops, looks like the behavior change is still there.
Comment 9 Darin Adler 2020-04-09 12:21:18 PDT Comment hidden (obsolete)
Comment 10 Darin Adler 2020-04-09 14:08:43 PDT Comment hidden (obsolete)
Comment 11 Darin Adler 2020-04-09 16:55:12 PDT
This last tiny layout change difference is a mystery.
Comment 12 Darin Adler 2020-04-10 17:14:46 PDT
Created attachment 396136 [details]
Patch
Comment 13 Darin Adler 2020-04-10 17:15:51 PDT
Mystery solved. Finally had a chance to debug and it was a refactoring error; fixed now.
Comment 14 Darin Adler 2020-04-10 19:38:44 PDT
This patch is now both a simple refactoring, and all tests are passing, so should be a quick review for someone.
Comment 15 Darin Adler 2020-04-11 08:35:11 PDT
Committed r259930: <https://trac.webkit.org/changeset/259930>
Comment 16 Radar WebKit Bug Importer 2020-04-11 08:36:14 PDT
<rdar://problem/61638646>
Comment 17 Daniel Bates 2020-05-19 11:15:54 PDT
Comment on attachment 396136 [details]
Patch

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

> Source/WebCore/dom/DocumentMarkerController.cpp:600
> +        if (static_cast<unsigned>(targetStartOffset) >= node.length() || targetEndOffset <= 0) {

This is a change in behavior that causes a regression: marker at the start of the text will **now be removed** if trailing whitespace was subsequently inserted and that whitespace is collapsed. When collapse happens, marker.startOffset() == 0, **delta** == -1. So, targetStartOffset == -1 and this blows up when casted to unsigned (i.e. it ALWAYS is >= node.length()).

Just for me: This iOS code was added to fix <rdar://problem/11478253>.

> Source/WebCore/dom/DocumentMarkerController.cpp:615
>                  list->remove(i);

Just for me: ^^^ line above (not part of this patch) is incorrect: performs **unsigned** comparison, but delta is signed so "+ delta" + implicit conversion to unsigned can blow up and make comparison meaningless. Also expression should reference targetEndOffset instead of re-computing <-- may have made the bug more obvious.
Comment 18 Darin Adler 2020-05-19 11:18:26 PDT
Comment on attachment 396136 [details]
Patch

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

>> Source/WebCore/dom/DocumentMarkerController.cpp:600
>> +        if (static_cast<unsigned>(targetStartOffset) >= node.length() || targetEndOffset <= 0) {
> 
> This is a change in behavior that causes a regression: marker at the start of the text will **now be removed** if trailing whitespace was subsequently inserted and that whitespace is collapsed. When collapse happens, marker.startOffset() == 0, **delta** == -1. So, targetStartOffset == -1 and this blows up when casted to unsigned (i.e. it ALWAYS is >= node.length()).
> 
> Just for me: This iOS code was added to fix <rdar://problem/11478253>.

Are you fixing it, or would you like me to?

Do you have an idea how to add a test?
Comment 19 Daniel Bates 2020-05-19 11:25:19 PDT
Comment on attachment 396136 [details]
Patch

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

>>> Source/WebCore/dom/DocumentMarkerController.cpp:600
>>> +        if (static_cast<unsigned>(targetStartOffset) >= node.length() || targetEndOffset <= 0) {
>> 
>> This is a change in behavior that causes a regression: marker at the start of the text will **now be removed** if trailing whitespace was subsequently inserted and that whitespace is collapsed. When collapse happens, marker.startOffset() == 0, **delta** == -1. So, targetStartOffset == -1 and this blows up when casted to unsigned (i.e. it ALWAYS is >= node.length()).
>> 
>> Just for me: This iOS code was added to fix <rdar://problem/11478253>.
> 
> Are you fixing it, or would you like me to?
> 
> Do you have an idea how to add a test?

You can fix it, but I will supply you with a bug + a test in a few minutes...
Comment 20 Daniel Bates 2020-05-19 12:00:20 PDT
Comment on attachment 396136 [details]
Patch

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

>>>> Source/WebCore/dom/DocumentMarkerController.cpp:600
>>>> +        if (static_cast<unsigned>(targetStartOffset) >= node.length() || targetEndOffset <= 0) {
>>> 
>>> This is a change in behavior that causes a regression: marker at the start of the text will **now be removed** if trailing whitespace was subsequently inserted and that whitespace is collapsed. When collapse happens, marker.startOffset() == 0, **delta** == -1. So, targetStartOffset == -1 and this blows up when casted to unsigned (i.e. it ALWAYS is >= node.length()).
>>> 
>>> Just for me: This iOS code was added to fix <rdar://problem/11478253>.
>> 
>> Are you fixing it, or would you like me to?
>> 
>> Do you have an idea how to add a test?
> 
> You can fix it, but I will supply you with a bug + a test in a few minutes...

Bug + test at posted at bug #212093.
Comment 21 Darin Adler 2020-05-19 12:10:52 PDT
Comment on attachment 396136 [details]
Patch

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

>> Source/WebCore/dom/DocumentMarkerController.cpp:615
>>                  list->remove(i);
> 
> Just for me: ^^^ line above (not part of this patch) is incorrect: performs **unsigned** comparison, but delta is signed so "+ delta" + implicit conversion to unsigned can blow up and make comparison meaningless. Also expression should reference targetEndOffset instead of re-computing <-- may have made the bug more obvious.

That’s incorrect.

If targetEndOffset is <= 0 we won’t get here; checked for above.