Bug 144666 - WebBackForwardList::backForwardListState(filter) can set the currentIndex to a really large number
Summary: WebBackForwardList::backForwardListState(filter) can set the currentIndex to ...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKit2 (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Ada Chan
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-05-05 22:50 PDT by Ada Chan
Modified: 2015-05-07 10:54 PDT (History)
6 users (show)

See Also:


Attachments
Patch (2.74 KB, patch)
2015-05-06 13:46 PDT, Ada Chan
darin: review+
Details | Formatted Diff | Diff
Updated patch (13.88 KB, patch)
2015-05-06 21:27 PDT, Ada Chan
darin: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ada Chan 2015-05-05 22:50:13 PDT
If the currentIndex is 0 and the first item gets filtered out, we'll end up decrementing currentIndex (which is bad as it's unsigned).

See the code here:

    for (size_t i = 0; i < m_entries.size(); ++i) {
        auto& entry = *m_entries[i];

        if (filter && !filter(entry)) {
            if (backForwardListState.currentIndex && i <= backForwardListState.currentIndex.value())
                --backForwardListState.currentIndex.value();

            continue;
        }

        backForwardListState.items.append(entry.itemState());
    }

Seems like we should check whether the currentIndex > 0 before decrementing it. And if the list items end up being all filtered out, then the currentIndex should be set to the "uninitialized" value.
Comment 1 Ada Chan 2015-05-06 13:46:57 PDT
Created attachment 252516 [details]
Patch
Comment 2 Darin Adler 2015-05-06 16:50:41 PDT
Comment on attachment 252516 [details]
Patch

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

> Source/WebKit2/UIProcess/WebBackForwardList.cpp:401
> +            if (backForwardListState.currentIndex && i <= backForwardListState.currentIndex.value() && backForwardListState.currentIndex.value())
>                  --backForwardListState.currentIndex.value();

Common subexpression is getting out of hand here. Here’s one way to deal with that

    auto& index = backForwardListState.currentIndex;
    if (index && i <= index.value() && index.value())
        --index.value();

> Source/WebKit2/UIProcess/WebBackForwardList.cpp:410
> +        backForwardListState.currentIndex = Optional<uint32_t>();

There are two other ways to write this that are both more terse:

    backForwardListState.currentIndex = Nullopt;
    backForwardListState.currentIndex = { };

I suggest using one of those.
Comment 3 Ada Chan 2015-05-06 21:15:47 PDT
Thanks Darin.  I'll incorporate your feedback and post an updated patch (this time with a test).
Comment 4 Ada Chan 2015-05-06 21:27:31 PDT
Created attachment 252566 [details]
Updated patch
Comment 5 Ada Chan 2015-05-07 10:44:21 PDT
I ended up removing the Util::run(&didFinishLoad) after restoring the page with sessionStateWithAllItemsRemoved because nothing really gets loaded in that case.  I'll add a comment about that.
Comment 6 Ada Chan 2015-05-07 10:54:10 PDT
Committed:
http://trac.webkit.org/changeset/183933