RESOLVED FIXED 286477
REGRESSION(288455@main): Crash in WebCore::ImageBackingStore::clearRect when opening emoji chooser on Slack
https://bugs.webkit.org/show_bug.cgi?id=286477
Summary REGRESSION(288455@main): Crash in WebCore::ImageBackingStore::clearRect when ...
Michael Catanzaro
Reported 2025-01-24 08:12:35 PST
Created attachment 474001 [details] Full backtrace When opening the emoji chooser on Red Hat's internal Slack website, the web process immediately crashes when decoding GIF images: #0 __pthread_kill_implementation (threadid=<optimized out>, signo=signo@entry=6, no_tid=no_tid@entry=0) at pthread_kill.c:44 #1 0x00007f060fc9ae23 in __pthread_kill_internal (threadid=<optimized out>, signo=6) at pthread_kill.c:78 #2 0x00007f060fc4208e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 #3 0x00007f060fc29882 in __GI_abort () at abort.c:79 #4 0x00007f060b0e8c1d in std::__glibcxx_assert_fail (file=<optimized out>, line=line@entry=433, function=<optimized out>, condition=<optimized out>) at ../../../../../libstdc++-v3/src/c++11/assert_fail.cc:41 #5 0x00007f0610feec8a in WebCore::ImageBackingStore::clearRect (this=0x7f0283381f00, rect=...) at /buildstream/gnome/sdk/webkitgtk-6.0.bst/Source/WebCore/platform/graphics/ImageBackingStore.h:105 #6 0x00007f0610fee680 in WebCore::GIFImageDecoder::initFrameBuffer (this=0x7f02832ed900, frameIndex=<optimized out>) at /buildstream/gnome/sdk/webkitgtk-6.0.bst/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp:411 #7 0x00007f0610fee15e in WebCore::GIFImageDecoder::haveDecodedRow (this=0x7f02832ed900, frameIndex=2, rowBuffer=WTF::Vector of length 106, capacity 106 = {...}, width=<optimized out>, rowNumber=<optimized out>, repeatCount=1, writeTransparentPixels=<optimized out>) at /buildstream/gnome/sdk/webkitgtk-6.0.bst/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp:237 #8 0x00007f0610feef3e in GIFLZWContext::outputRow (this=0x7f0283387a60) at /buildstream/gnome/sdk/webkitgtk-6.0.bst/Source/WebCore/platform/image-decoders/gif/GIFImageReader.cpp:156 #9 0x00007f0610fef3ac in GIFLZWContext::doLZW (this=0x7f0283387a60, block=Python Exception <class 'gdb.error'>: value has been optimized out ) at /buildstream/gnome/sdk/webkitgtk-6.0.bst/Source/WebCore/platform/image-decoders/gif/GIFImageReader.cpp:307 #10 0x00007f0610fef48b in GIFFrameContext::decode (this=0x7f02832ff9c0, data=std::span of length 19802 = {...}, client=<optimized out>, frameDecoded=@0x7ffc4f9f0ccf: false) at /buildstream/gnome/sdk/webkitgtk-6.0.bst/Source/WebCore/platform/image-decoders/gif/GIFImageReader.cpp:341 #11 0x00007f0610fef868 in GIFImageReader::decode (this=0x7f02832e3180, query=<optimized out>, haltAtFrame=3) at /buildstream/gnome/sdk/webkitgtk-6.0.bst/Source/WebCore/platform/image-decoders/gif/GIFImageReader.cpp:378 #12 0x00007f0610fedca4 in WebCore::GIFImageDecoder::decode (this=0x7f02832ed900, haltAtFrame=3, query=WebCore::GIFImageDecoder::GIFFullQuery, allDataReceived=true) at /buildstream/gnome/sdk/webkitgtk-6.0.bst/Source/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp:35 I will attach the full backtrace. Unfortunately it is not detailed enough for me to understand where exactly the assertion is coming from, though I guess we're probably reading out of the bounds of the IntRect, but the assertion is . This problem never occurs on webkit.slack.com, only on Red Hat's internal Slack. I think Red Hat's emoji chooser is different (bigger). Unfortunately the problem is not occurring in my development environment, but I'm hoping that's because we don't enable standard library assertions by default. I'll find out. If I can reproduce it in my development environment, then I can bisect it.
Attachments
Full backtrace (270.19 KB, text/plain)
2025-01-24 08:12 PST, Michael Catanzaro
no flags
Michael Catanzaro
Comment 1 2025-01-24 09:00:33 PST
I was able to reproduce after adding -DCMAKE_CXX_FLAGS="-Wp,-D_GLIBCXX_ASSERTIONS". We really need to do that on the bots. Anyway, got an error message: /usr/bin/../lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/span:433: span<element_type, dynamic_extent> std::span<unsigned int>::subspan(size_type, size_type) const [_Type = unsigned int, _Extent = 18446744073709551615]: Assertion '__offset <= size()' failed. It's caused by 288455@main "Adopt more spans in ImageBackingStore.h"
Michael Catanzaro
Comment 2 2025-01-24 09:26:59 PST
I changed all the ASSERTS to RELEASE_ASSERTs, but none of them are hit. Next I added some debug: @@ -100,6 +100,7 @@ public: auto pixels = pixelsStartingAt(rect.x(), rect.y()); for (int i = 0; i < rect.height(); ++i) { zeroSpan(pixels.first(rect.width())); + WTFLogAlways("About to skip %d pixels in span of size %zu", m_size.width(), pixels.size()); skip(pixels, m_size.width()); } } Output is: About to skip 128 pixels in span of size 15475 About to skip 128 pixels in span of size 15347 About to skip 128 pixels in span of size 15219 About to skip 128 pixels in span of size 15091 About to skip 128 pixels in span of size 14963 About to skip 128 pixels in span of size 14835 About to skip 128 pixels in span of size 14707 About to skip 128 pixels in span of size 14579 About to skip 128 pixels in span of size 14451 About to skip 128 pixels in span of size 14323 About to skip 128 pixels in span of size 14195 About to skip 128 pixels in span of size 14067 About to skip 128 pixels in span of size 13939 About to skip 128 pixels in span of size 13811 About to skip 128 pixels in span of size 13683 About to skip 128 pixels in span of size 13555 About to skip 128 pixels in span of size 13427 About to skip 128 pixels in span of size 13299 About to skip 128 pixels in span of size 13171 About to skip 128 pixels in span of size 13043 About to skip 128 pixels in span of size 12915 About to skip 128 pixels in span of size 12787 About to skip 128 pixels in span of size 12659 About to skip 128 pixels in span of size 12531 About to skip 128 pixels in span of size 12403 About to skip 128 pixels in span of size 12275 About to skip 128 pixels in span of size 12147 About to skip 128 pixels in span of size 12019 About to skip 128 pixels in span of size 11891 About to skip 128 pixels in span of size 11763 About to skip 128 pixels in span of size 11635 About to skip 128 pixels in span of size 11507 About to skip 128 pixels in span of size 11379 About to skip 128 pixels in span of size 11251 About to skip 128 pixels in span of size 11123 About to skip 128 pixels in span of size 10995 About to skip 128 pixels in span of size 10867 About to skip 128 pixels in span of size 10739 About to skip 128 pixels in span of size 10611 About to skip 128 pixels in span of size 10483 About to skip 128 pixels in span of size 10355 About to skip 128 pixels in span of size 10227 About to skip 128 pixels in span of size 10099 About to skip 128 pixels in span of size 9971 About to skip 128 pixels in span of size 9843 About to skip 128 pixels in span of size 9715 About to skip 128 pixels in span of size 9587 About to skip 128 pixels in span of size 9459 About to skip 128 pixels in span of size 9331 About to skip 128 pixels in span of size 9203 About to skip 128 pixels in span of size 9075 About to skip 128 pixels in span of size 8947 About to skip 128 pixels in span of size 8819 About to skip 128 pixels in span of size 8691 About to skip 128 pixels in span of size 8563 About to skip 128 pixels in span of size 8435 About to skip 128 pixels in span of size 8307 About to skip 128 pixels in span of size 8179 About to skip 128 pixels in span of size 8051 About to skip 128 pixels in span of size 7923 About to skip 128 pixels in span of size 7795 About to skip 128 pixels in span of size 7667 About to skip 128 pixels in span of size 7539 About to skip 128 pixels in span of size 7411 About to skip 128 pixels in span of size 7283 About to skip 128 pixels in span of size 7155 About to skip 128 pixels in span of size 7027 About to skip 128 pixels in span of size 6899 About to skip 128 pixels in span of size 6771 About to skip 128 pixels in span of size 6643 About to skip 128 pixels in span of size 6515 About to skip 128 pixels in span of size 6387 About to skip 128 pixels in span of size 6259 About to skip 128 pixels in span of size 6131 About to skip 128 pixels in span of size 6003 About to skip 128 pixels in span of size 5875 About to skip 128 pixels in span of size 5747 About to skip 128 pixels in span of size 5619 About to skip 128 pixels in span of size 5491 About to skip 128 pixels in span of size 5363 About to skip 128 pixels in span of size 5235 About to skip 128 pixels in span of size 5107 About to skip 128 pixels in span of size 4979 About to skip 128 pixels in span of size 4851 About to skip 128 pixels in span of size 4723 About to skip 128 pixels in span of size 4595 About to skip 128 pixels in span of size 4467 About to skip 128 pixels in span of size 4339 About to skip 128 pixels in span of size 4211 About to skip 128 pixels in span of size 4083 About to skip 128 pixels in span of size 3955 About to skip 128 pixels in span of size 3827 About to skip 128 pixels in span of size 3699 About to skip 128 pixels in span of size 3571 About to skip 128 pixels in span of size 3443 About to skip 128 pixels in span of size 3315 About to skip 128 pixels in span of size 3187 About to skip 128 pixels in span of size 3059 About to skip 128 pixels in span of size 2931 About to skip 128 pixels in span of size 2803 About to skip 128 pixels in span of size 2675 About to skip 128 pixels in span of size 2547 About to skip 128 pixels in span of size 2419 About to skip 128 pixels in span of size 2291 About to skip 128 pixels in span of size 2163 About to skip 128 pixels in span of size 2035 About to skip 128 pixels in span of size 1907 About to skip 128 pixels in span of size 1779 About to skip 128 pixels in span of size 1651 About to skip 128 pixels in span of size 1523 About to skip 128 pixels in span of size 1395 About to skip 128 pixels in span of size 1267 About to skip 128 pixels in span of size 1139 About to skip 128 pixels in span of size 1011 About to skip 128 pixels in span of size 883 About to skip 128 pixels in span of size 755 About to skip 128 pixels in span of size 627 About to skip 128 pixels in span of size 499 About to skip 128 pixels in span of size 371 About to skip 128 pixels in span of size 243 About to skip 128 pixels in span of size 115 /usr/bin/../lib/gcc/x86_64-redhat-linux/14/../../../../include/c++/14/span:433: span<element_type, dynamic_extent> std::span<unsigned int>::subspan(size_type, size_type) const [_Type = unsigned int, _Extent = 18446744073709551615]: Assertion '__offset <= size()' failed. Can't skip 128 bytes in a span of size 115. The clearRect function assumes that rect.height() % rect.width() == 0, but it's not. I'm not sure, but this might be a preexisting bug that was only exposed by the switch to std::span?
Michael Catanzaro
Comment 3 2025-01-24 09:30:59 PST
> The clearRect function assumes that rect.height() % rect.width() == 0, but it's not. I'm not sure, but this might be a preexisting bug that was only exposed by the switch to std::span? Oops, that precondition should be: pixelsStartingAt(rect.x(), rect.y()).size() % rect.width() == 0
Radar WebKit Bug Importer
Comment 4 2025-01-31 08:13:12 PST
Michael Catanzaro
Comment 5 2025-01-31 12:03:38 PST
This is also causing crashes when scrolling on youtube.com player views.
Michael Catanzaro
Comment 6 2025-02-17 15:20:57 PST
Test image: https://emoji.slack-edge.com/T030G10V24F/clapping-7001/65bfed96fee186b2.gif If somebody wants to figure out how to construct an image that similarly triggers the crash, then we could add a layout test for this. I'm not sure about including this image directly into WebKit due to unclear licensing.
Michael Catanzaro
Comment 7 2025-02-17 15:21:44 PST
EWS
Comment 8 2025-02-19 08:06:26 PST
Committed 290611@main (32dd4c71d022): <https://commits.webkit.org/290611@main> Reviewed commits have been landed. Closing PR #40730 and removing active labels.
Note You need to log in before you can comment on or make changes to this bug.