Bug 225279 - [GTK] segmentation fault in WebKit::IconDatabase::loadIconForPageURL
Summary: [GTK] segmentation fault in WebKit::IconDatabase::loadIconForPageURL
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebKitGTK (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords:
: 225313 225348 (view as bug list)
Depends on:
Blocks:
 
Reported: 2021-05-02 08:17 PDT by Jim Mason
Modified: 2021-05-05 06:17 PDT (History)
8 users (show)

See Also:


Attachments
Patch (2.31 KB, patch)
2021-05-02 08:19 PDT, Jim Mason
no flags Details | Formatted Diff | Diff
Patch (2.28 KB, patch)
2021-05-02 08:23 PDT, Jim Mason
no flags Details | Formatted Diff | Diff
Patch (2.35 KB, patch)
2021-05-02 09:43 PDT, Jim Mason
no flags Details | Formatted Diff | Diff
Patch (2.54 KB, patch)
2021-05-04 03:36 PDT, Jim Mason
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jim Mason 2021-05-02 08:17:38 PDT
gtk3: 3.24.11
gdk-pixbuf: 2.40.0
cairo: 1.16.0
glib2: 2.66.8

I am encountering a segmentation fault in IconDatabase::loadIconForPageURL due to dereference of a null pointer returned by NativeImage::nativeImageForCurrentFrame.  This happens for certain (broken? unsupported?) icons, but not all.  One such icon is the favicon for this URL:

    https://thomas-guettler.de/htmx-swap-err-webkit/page.html

For me, entering the above URL in epiphany 40.0 elicits the seg fault.

I've attached a patch which clears the issue.  The patch also applies a similar null pointer check in the method setIconForPageURL.

The fix assumes `nativeImageForCurrentFrame` can return null.  If that method is supposed to return non-null in all cases, then there is another problem.
Comment 1 Jim Mason 2021-05-02 08:19:01 PDT
Created attachment 427525 [details]
Patch
Comment 2 EWS Watchlist 2021-05-02 08:20:05 PDT
Thanks for the patch. If this patch contains new public API please make sure it follows the guidelines for new WebKit2 GTK+ API. See https://trac.webkit.org/wiki/WebKitGTK/AddingNewWebKit2API
Comment 3 Jim Mason 2021-05-02 08:23:29 PDT
Created attachment 427526 [details]
Patch
Comment 4 Jim Mason 2021-05-02 09:43:28 PDT
Created attachment 427529 [details]
Patch
Comment 5 Carlos Garcia Campos 2021-05-04 00:20:44 PDT
Comment on attachment 427529 [details]
Patch

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

> Source/WebKit/UIProcess/API/glib/IconDatabase.cpp:586
> +                if (nativeImage != nullptr)

Do not compare to nullptr. We normally prefer the early return first and avoid the else, so this would be:

if (!nativeImage) {
    completionHandler(nullptr);
    return;
}

addResult.iterator->value.first = nativeImage->platformImage();

> Source/WebKit/UIProcess/API/glib/IconDatabase.cpp:626
> +                    auto nativeImage = image->nativeImageForCurrentFrame();
> +                    if (nativeImage != nullptr)

And here this could be

if (auto nativeImage = image->nativeImageForCurrentFrame())
Comment 6 Carlos Garcia Campos 2021-05-04 02:26:07 PDT
*** Bug 225313 has been marked as a duplicate of this bug. ***
Comment 7 Jim Mason 2021-05-04 03:11:32 PDT
Thanks for the feedback.

In setIconForPageURL, I am tempted to simplify this:

    auto image = BitmapImage::create();
    if (image->setData(SharedBuffer::create(iconData, iconDataSize), true) < EncodedDataStatus::SizeAvailable)
        result = false;
    else if (auto nativeImage = image->nativeImageForCurrentFrame())
        addResult.iterator->value.first = nativeImage->platformImage();
    else
        result = false;

to something like this:

    RefPtr<NativeImage> nativeImage;
    auto image = BitmapImage::create();
    if (image->setData(SharedBuffer::create(iconData, iconDataSize), true) >= EncodedDataStatus::SizeAvailable &&
            (nativeImage = image->nativeImageForCurrentFrame()))
        addResult.iterator->value.first = nativeImage->platformImage();
    else
        result = false;

However, this means using RefPtr<NativeImage> instead of auto; I have doubts whether this frowned upon.  Advice?
Comment 8 Adrian Perez 2021-05-04 03:14:04 PDT
(In reply to Jim Mason from comment #7)
> Thanks for the feedback.
> 
> In setIconForPageURL, I am tempted to simplify this:
> 
>     auto image = BitmapImage::create();
>     if (image->setData(SharedBuffer::create(iconData, iconDataSize), true) <
> EncodedDataStatus::SizeAvailable)
>         result = false;
>     else if (auto nativeImage = image->nativeImageForCurrentFrame())
>         addResult.iterator->value.first = nativeImage->platformImage();
>     else
>         result = false;
> 
> to something like this:
> 
>     RefPtr<NativeImage> nativeImage;
>     auto image = BitmapImage::create();
>     if (image->setData(SharedBuffer::create(iconData, iconDataSize), true)
> >= EncodedDataStatus::SizeAvailable &&
>             (nativeImage = image->nativeImageForCurrentFrame()))
>         addResult.iterator->value.first = nativeImage->platformImage();
>     else
>         result = false;
> 
> However, this means using RefPtr<NativeImage> instead of auto; I have doubts
> whether this frowned upon.  Advice?

There are similar bits of code all around WebKit, this is fine 👌️
Comment 9 Jim Mason 2021-05-04 03:36:10 PDT
Created attachment 427648 [details]
Patch
Comment 10 EWS 2021-05-04 05:38:28 PDT
Committed r276954 (237287@main): <https://commits.webkit.org/237287@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 427648 [details].
Comment 11 Jim Mason 2021-05-04 09:32:31 PDT
Fix verified in r276954.
Comment 12 Adrian Perez 2021-05-05 06:17:42 PDT
*** Bug 225348 has been marked as a duplicate of this bug. ***