Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package webkit2gtk3 for openSUSE:Factory 
checked in at 2024-08-05 17:20:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/webkit2gtk3 (Old)
 and      /work/SRC/openSUSE:Factory/.webkit2gtk3.new.7232 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "webkit2gtk3"

Mon Aug  5 17:20:19 2024 rev:197 rq:1191197 version:2.44.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/webkit2gtk3/webkit2gtk3.changes  2024-07-05 
19:44:13.463050337 +0200
+++ /work/SRC/openSUSE:Factory/.webkit2gtk3.new.7232/webkit2gtk3.changes        
2024-08-05 17:20:21.968889100 +0200
@@ -1,0 +2,9 @@
+Thu Aug  1 20:25:14 UTC 2024 - Michael Gorse <mgo...@suse.com>
+
+- Add CVE fixes:
+  + webkit2gtk3-CVE-2024-40776.patch (boo#1228613 CVE-2024-40776)
+  + webkit2gtk3-CVE-2024-40779.patch (boo#1228693 CVE-2024-40779)
+  + webkit2gtk3-CVE-2024-40780.patch (boo#1228694 CVE-2024-40780)
+  + webkit2gtk3-CVE-2024-40782.patch (boo#1228695 CVE-2024-40782)
+
+-------------------------------------------------------------------

New:
----
  webkit2gtk3-CVE-2024-40776.patch
  webkit2gtk3-CVE-2024-40779.patch
  webkit2gtk3-CVE-2024-40780.patch
  webkit2gtk3-CVE-2024-40782.patch

BETA DEBUG BEGIN:
  New:- Add CVE fixes:
  + webkit2gtk3-CVE-2024-40776.patch (boo#1228613 CVE-2024-40776)
  + webkit2gtk3-CVE-2024-40779.patch (boo#1228693 CVE-2024-40779)
  New:  + webkit2gtk3-CVE-2024-40776.patch (boo#1228613 CVE-2024-40776)
  + webkit2gtk3-CVE-2024-40779.patch (boo#1228693 CVE-2024-40779)
  + webkit2gtk3-CVE-2024-40780.patch (boo#1228694 CVE-2024-40780)
  New:  + webkit2gtk3-CVE-2024-40779.patch (boo#1228693 CVE-2024-40779)
  + webkit2gtk3-CVE-2024-40780.patch (boo#1228694 CVE-2024-40780)
  + webkit2gtk3-CVE-2024-40782.patch (boo#1228695 CVE-2024-40782)
  New:  + webkit2gtk3-CVE-2024-40780.patch (boo#1228694 CVE-2024-40780)
  + webkit2gtk3-CVE-2024-40782.patch (boo#1228695 CVE-2024-40782)
BETA DEBUG END:

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ webkit2gtk3.spec ++++++
--- /var/tmp/diff_new_pack.B9nhLf/_old  2024-08-05 17:20:22.880926504 +0200
+++ /var/tmp/diff_new_pack.B9nhLf/_new  2024-08-05 17:20:22.880926504 +0200
@@ -93,6 +93,14 @@
 Patch2:         webkit2gtk3-disable-dmabuf-nvidia.patch
 # PATCH-FIX-UPSTREAM 9d5844679af8f84036f1b800307e799bd7ab73ba -- VA+DMABuf 
videos flicker
 Patch3:         
https://github.com/WebKit/WebKit/commit/9d5844679af8f84036f1b800307e799bd7ab73ba.patch
+# PATCH-FIX-UPSTREAM webkit2gtk3-CVE-2024-40776.patch boo#1228613 
mgo...@suse.com -- fix a use after free.
+Patch4:         webkit2gtk3-CVE-2024-40776.patch
+# PATCH-FIX-UPSTREAM webkit2gtk3-CVE-2024-40779.patch boo#1228693 
mgo...@suse.com -- fix a buffer overflow.
+Patch5:         webkit2gtk3-CVE-2024-40779.patch
+# PATCH-FIX-UPSTREAM webkit2gtk3-CVE-2024-40780.patch boo#1228694 
mgo...@suse.com -- fix an out-of-bounds read.
+Patch6:         webkit2gtk3-CVE-2024-40780.patch
+# PATCH-FIX-UPSTREAM webkit2gtk3-CVE-2024-40782.patch boo#1228695 
mgo...@suse.com -- fix a NULL pointer dereference.
+Patch7:         webkit2gtk3-CVE-2024-40782.patch
 
 BuildRequires:  Mesa-libEGL-devel
 BuildRequires:  Mesa-libGL-devel

++++++ webkit2gtk3-CVE-2024-40776.patch ++++++
>From b951404ea74ae432312a83138f5c8945a0d09e1b Mon Sep 17 00:00:00 2001
From: Jean-Yves Avenard <j...@apple.com>
Date: Wed, 24 Apr 2024 19:01:06 -0700
Subject: [PATCH] Cherry-pick 272448.960@safari-7618-branch (b7ccdb65258e).
 https://bugs.webkit.org/show_bug.cgi?id=273176

Always copy all audio channels to the AudioBus to guarantee data lifetime.
https://bugs.webkit.org/show_bug.cgi?id=273176
rdar://125166710

Reviewed by Chris Dumez.

Following 275262@main, a task is dispatched on the audio render thread.
This task dispatch takes a reference to the source and destination AudioBus
however when a MultiChannelResampler is in use, the source AudioBus may
contain a raw pointer to the resampled's AudioArray and the lifetime of
this object may be shorter than the AudioBus.

In 232182@main, a speed and memory optimisation was added by passed-in buffer
as memory for the first channel in the AudioBus.
We revert this change for now and copy all channels' data to the AudioBus.

Added test.

* 
LayoutTests/webaudio/crashtest/audioworklet-concurrent-resampler-crash-expected.txt:
 Added.
* LayoutTests/webaudio/crashtest/audioworklet-concurrent-resampler-crash.html: 
Added.
* Source/WebCore/platform/audio/MultiChannelResampler.cpp:
(WebCore::MultiChannelResampler::MultiChannelResampler):
(WebCore::MultiChannelResampler::provideInputForChannel):
* Source/WebCore/platform/audio/MultiChannelResampler.h:

Canonical link: https://commits.webkit.org/274313.332@webkitglib/2.44
---
 ...et-concurrent-resampler-crash-expected.txt |  1 +
 ...dioworklet-concurrent-resampler-crash.html | 44 +++++++++++++++++++
 .../platform/audio/MultiChannelResampler.cpp  | 23 ++--------
 .../platform/audio/MultiChannelResampler.h    |  2 -
 4 files changed, 48 insertions(+), 22 deletions(-)
 create mode 100644 
LayoutTests/webaudio/crashtest/audioworklet-concurrent-resampler-crash-expected.txt
 create mode 100644 
LayoutTests/webaudio/crashtest/audioworklet-concurrent-resampler-crash.html

diff --git 
a/LayoutTests/webaudio/crashtest/audioworklet-concurrent-resampler-crash-expected.txt
 
b/LayoutTests/webaudio/crashtest/audioworklet-concurrent-resampler-crash-expected.txt
new file mode 100644
index 000000000000..654ddf7f17ef
--- /dev/null
+++ 
b/LayoutTests/webaudio/crashtest/audioworklet-concurrent-resampler-crash-expected.txt
@@ -0,0 +1 @@
+This test passes if it does not crash.
diff --git 
a/LayoutTests/webaudio/crashtest/audioworklet-concurrent-resampler-crash.html 
b/LayoutTests/webaudio/crashtest/audioworklet-concurrent-resampler-crash.html
new file mode 100644
index 000000000000..b3ab181d4787
--- /dev/null
+++ 
b/LayoutTests/webaudio/crashtest/audioworklet-concurrent-resampler-crash.html
@@ -0,0 +1,44 @@
+<html>
+<head>
+    <script>
+        let worklet_source = `
+            class Processor extends AudioWorkletProcessor {
+                process(inputs, outputs, parameters) {
+                    return true;
+                }
+            }
+            registerProcessor('P2', Processor);
+        `;
+
+        let blob = new Blob([worklet_source], { type: 'application/javascript' 
});
+        let worklet = URL.createObjectURL(blob);
+
+        var ctx = new AudioContext({ sampleRate: 44100});
+        const dest = ctx.destination;
+        dest.channelCountMode = "max";
+
+        async function main() {
+            await ctx.audioWorklet.addModule(worklet);
+            var script_processor = ctx.createScriptProcessor();
+            script_processor.onaudioprocess = function() {
+                dest.channelCount = 1;
+                audio_worklet.disconnect();
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }
+            var audio_worklet = new AudioWorkletNode(ctx, "P2");
+            script_processor.connect(audio_worklet);
+            audio_worklet.connect(dest);
+        }
+    </script>
+</head>
+<body onload="main()">
+    <p>This test passes if it does not crash.</p>
+    <script>
+    if (window.testRunner) {
+        testRunner.waitUntilDone();
+        testRunner.dumpAsText();
+    }
+    </script>
+</body>
+</html>
diff --git a/Source/WebCore/platform/audio/MultiChannelResampler.cpp 
b/Source/WebCore/platform/audio/MultiChannelResampler.cpp
index e5a0cfc10caa..c44df274cbbc 100644
--- a/Source/WebCore/platform/audio/MultiChannelResampler.cpp
+++ b/Source/WebCore/platform/audio/MultiChannelResampler.cpp
@@ -42,19 +42,8 @@ namespace WebCore {
 MultiChannelResampler::MultiChannelResampler(double scaleFactor, unsigned 
numberOfChannels, unsigned requestFrames, Function<void(AudioBus*, size_t 
framesToProcess)>&& provideInput)
     : m_numberOfChannels(numberOfChannels)
     , m_provideInput(WTFMove(provideInput))
-    , m_multiChannelBus(AudioBus::create(numberOfChannels, requestFrames, 
false))
+    , m_multiChannelBus(AudioBus::create(numberOfChannels, requestFrames))
 {
-    // As an optimization, we will use the buffer passed to 
provideInputForChannel() as channel memory for the first channel so we
-    // only need to allocate memory if there is more than one channel.
-    if (numberOfChannels > 1) {
-        m_channelsMemory = 
Vector<std::unique_ptr<AudioFloatArray>>(numberOfChannels - 1, [&](size_t i) {
-            size_t channelIndex = i + 1;
-            auto floatArray = makeUnique<AudioFloatArray>(requestFrames);
-            m_multiChannelBus->setChannelMemory(channelIndex, 
floatArray->data(), requestFrames);
-            return floatArray;
-        });
-    }
-
     // Create each channel's resampler.
     m_kernels = Vector<std::unique_ptr<SincResampler>>(numberOfChannels, 
[&](size_t channelIndex) {
         return makeUnique<SincResampler>(scaleFactor, requestFrames, 
std::bind(&MultiChannelResampler::provideInputForChannel, this, 
std::placeholders::_1, std::placeholders::_2, channelIndex));
@@ -93,16 +82,10 @@ void MultiChannelResampler::process(AudioBus* destination, 
size_t framesToProces
 void MultiChannelResampler::provideInputForChannel(std::span<float> buffer, 
size_t framesToProcess, unsigned channelIndex)
 {
     ASSERT(channelIndex < m_multiChannelBus->numberOfChannels());
-    ASSERT(framesToProcess == m_multiChannelBus->length());
+    ASSERT(framesToProcess <= m_multiChannelBus->length());
 
-    if (!channelIndex) {
-        // As an optimization, we use the provided buffer as memory for the 
first channel in the AudioBus. This avoids
-        // having to memcpy() for the first channel.
-        RELEASE_ASSERT(framesToProcess <= buffer.size());
-        m_multiChannelBus->setChannelMemory(0, buffer.data(), framesToProcess);
+    if (!channelIndex)
         m_provideInput(m_multiChannelBus.get(), framesToProcess);
-        return;
-    }
 
     // Copy the channel data from what we received from m_multiChannelProvider.
     memcpySpan(buffer.subspan(0, framesToProcess), 
m_multiChannelBus->channel(channelIndex)->span().subspan(0, framesToProcess));
diff --git a/Source/WebCore/platform/audio/MultiChannelResampler.h 
b/Source/WebCore/platform/audio/MultiChannelResampler.h
index 25d43100b71f..214ee06567ac 100644
--- a/Source/WebCore/platform/audio/MultiChannelResampler.h
+++ b/Source/WebCore/platform/audio/MultiChannelResampler.h
@@ -29,7 +29,6 @@
 #ifndef MultiChannelResampler_h
 #define MultiChannelResampler_h
 
-#include "AudioArray.h"
 #include <memory>
 #include <wtf/Function.h>
 #include <wtf/Vector.h>
@@ -62,7 +61,6 @@ private:
     size_t m_outputFramesReady { 0 };
     Function<void(AudioBus*, size_t framesToProcess)> m_provideInput;
     RefPtr<AudioBus> m_multiChannelBus;
-    Vector<std::unique_ptr<AudioFloatArray>> m_channelsMemory;
 };
 
 } // namespace WebCore
-- 
2.45.2


++++++ webkit2gtk3-CVE-2024-40779.patch ++++++
>From 2fe5ae29a5f6434ef456afe9673a4f400ec63848 Mon Sep 17 00:00:00 2001
From: Jean-Yves Avenard <j...@apple.com>
Date: Fri, 14 Jun 2024 16:08:19 -0700
Subject: [PATCH] Cherry-pick 272448.1085@safari-7618.3.10-branch
 (ff52ff7cb64e). https://bugs.webkit.org/show_bug.cgi?id=275431

HeapBufferOverflow in computeSampleUsingLinearInterpolation
https://bugs.webkit.org/show_bug.cgi?id=275431
rdar://125617812

Reviewed by Youenn Fablet.

Add boundary check.
This is a copy of blink code for that same function.
https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/modules/webaudio/audio_buffer_source_handler.cc;l=336-341

* 
LayoutTests/webaudio/crashtest/audiobuffer-sourcenode-resampler-crash-expected.txt:
 Added.
* LayoutTests/webaudio/crashtest/audiobuffer-sourcenode-resampler-crash.html: 
Added.
* Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp:
(WebCore::AudioBufferSourceNode::renderFromBuffer):

Canonical link: https://commits.webkit.org/274313.347@webkitglib/2.44
---
 ...er-sourcenode-resampler-crash-expected.txt |  1 +
 ...udiobuffer-sourcenode-resampler-crash.html | 25 +++++++++++++++++++
 .../webaudio/AudioBufferSourceNode.cpp        |  6 +++++
 3 files changed, 32 insertions(+)
 create mode 100644 
LayoutTests/webaudio/crashtest/audiobuffer-sourcenode-resampler-crash-expected.txt
 create mode 100644 
LayoutTests/webaudio/crashtest/audiobuffer-sourcenode-resampler-crash.html

diff --git 
a/LayoutTests/webaudio/crashtest/audiobuffer-sourcenode-resampler-crash-expected.txt
 
b/LayoutTests/webaudio/crashtest/audiobuffer-sourcenode-resampler-crash-expected.txt
new file mode 100644
index 000000000000..654ddf7f17ef
--- /dev/null
+++ 
b/LayoutTests/webaudio/crashtest/audiobuffer-sourcenode-resampler-crash-expected.txt
@@ -0,0 +1 @@
+This test passes if it does not crash.
diff --git 
a/LayoutTests/webaudio/crashtest/audiobuffer-sourcenode-resampler-crash.html 
b/LayoutTests/webaudio/crashtest/audiobuffer-sourcenode-resampler-crash.html
new file mode 100644
index 000000000000..5fb2dd8c8a5f
--- /dev/null
+++ b/LayoutTests/webaudio/crashtest/audiobuffer-sourcenode-resampler-crash.html
@@ -0,0 +1,25 @@
+<html>
+<head>
+    <script>
+        async function main() {
+            var ctx = new AudioContext();
+            var src = new AudioBufferSourceNode(ctx);
+            src.buffer = ctx.createBuffer(1, 8192, 44100);
+            src.start(undefined, 0.5);
+            src.playbackRate.value = -1;
+            src.connect(ctx.destination, 0, 0);
+            if (window.testRunner)
+                testRunner.notifyDone();
+        }
+    </script>
+</head>
+<body onload="main()">
+    <p>This test passes if it does not crash.</p>
+    <script>
+    if (window.testRunner) {
+        testRunner.waitUntilDone();
+        testRunner.dumpAsText();
+    }
+    </script>
+</body>
+</html>
diff --git a/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp 
b/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
index 298bd48cdff5..740b793e0ec5 100644
--- a/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
+++ b/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
@@ -350,6 +350,12 @@ bool AudioBufferSourceNode::renderFromBuffer(AudioBus* 
bus, unsigned destination
             if (readIndex2 >= maxFrame)
                 readIndex2 = m_isLooping ? minFrame : readIndex;
 
+            // Final sanity check on buffer access.
+            // FIXME: as an optimization, try to get rid of this inner-loop 
check and
+            // put assertions and guards before the loop.
+            if (readIndex >= bufferLength || readIndex2 >= bufferLength)
+                break;
+
             // Linear interpolation.
             for (unsigned i = 0; i < numberOfChannels; ++i) {
                 float* destination = destinationChannels[i];
-- 
2.45.2


++++++ webkit2gtk3-CVE-2024-40780.patch ++++++
>From e83e4c7460972898dc06a5f5ab36eed7c6b101b5 Mon Sep 17 00:00:00 2001
From: Jer Noble <jer.no...@apple.com>
Date: Tue, 11 Jun 2024 11:54:06 -0700
Subject: [PATCH] Cherry-pick 272448.1080@safari-7618.3.10-branch
 (64c9479d6f29). https://bugs.webkit.org/show_bug.cgi?id=275273

Add check in AudioBufferSourceNode::renderFromBuffer() when detune is set to 
large negative value
https://bugs.webkit.org/show_bug.cgi?id=275273
rdar://125617842

Reviewed by Eric Carlson.

* LayoutTests/webaudio/audiobuffersourcenode-detune-crash-expected.txt: Added.
* LayoutTests/webaudio/audiobuffersourcenode-detune-crash.html: Added.
* Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp:
(WebCore::AudioBufferSourceNode::renderFromBuffer):

Canonical link: https://commits.webkit.org/274313.345@webkitglib/2.44
---
 ...buffersourcenode-detune-crash-expected.txt | 10 +++++++
 .../audiobuffersourcenode-detune-crash.html   | 30 +++++++++++++++++++
 .../webaudio/AudioBufferSourceNode.cpp        |  7 +++++
 3 files changed, 47 insertions(+)
 create mode 100644 
LayoutTests/webaudio/audiobuffersourcenode-detune-crash-expected.txt
 create mode 100644 LayoutTests/webaudio/audiobuffersourcenode-detune-crash.html

diff --git 
a/LayoutTests/webaudio/audiobuffersourcenode-detune-crash-expected.txt 
b/LayoutTests/webaudio/audiobuffersourcenode-detune-crash-expected.txt
new file mode 100644
index 000000000000..914ba0b133c4
--- /dev/null
+++ b/LayoutTests/webaudio/audiobuffersourcenode-detune-crash-expected.txt
@@ -0,0 +1,10 @@
+Attempting to create a AudioBufferSourceNode with a large negative detune 
value should not crash.
+
+On success, you will see a series of "PASS" messages, followed by "TEST 
COMPLETE".
+
+
+PASS Test passed because it did not crash.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/webaudio/audiobuffersourcenode-detune-crash.html 
b/LayoutTests/webaudio/audiobuffersourcenode-detune-crash.html
new file mode 100644
index 000000000000..e8af579db9d2
--- /dev/null
+++ b/LayoutTests/webaudio/audiobuffersourcenode-detune-crash.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+    <head>
+    <script src="../resources/js-test-pre.js"></script>
+    <script src="resources/audio-testing.js"></script>
+    </head>
+    <body>
+        <script>
+            description("Attempting to create a AudioBufferSourceNode with a 
large negative detune value should not crash.");
+
+            jsTestIsAsync = true;
+
+            var context = new AudioContext();
+            var src = context.createBufferSource();
+            var buffer = context.createBuffer(1, 256, 44100);
+            src.buffer = buffer;
+            src.start(undefined, 1);
+            src.connect(context.listener.positionX, 0);
+            var panner = context.createPanner();
+            src.detune.value = -0xffffff;
+            panner.connect(context.destination);
+            setTimeout(() => {
+                testPassed("Test passed because it did not crash.");
+                finishJSTest();
+            }, 100);
+        </script>
+
+        <script src="../resources/js-test-post.js"></script>
+    </body>
+</html>
diff --git a/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp 
b/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
index f86bffb9b507..298bd48cdff5 100644
--- a/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
+++ b/Source/WebCore/Modules/webaudio/AudioBufferSourceNode.cpp
@@ -328,9 +328,16 @@ bool AudioBufferSourceNode::renderFromBuffer(AudioBus* 
bus, unsigned destination
         virtualReadIndex = readIndex;
     } else if (!pitchRate) {
         unsigned readIndex = static_cast<unsigned>(virtualReadIndex);
+        int deltaFrames = static_cast<int>(virtualDeltaFrames);
+        maxFrame = static_cast<unsigned>(virtualMaxFrame);
+
+        if (readIndex >= maxFrame)
+            readIndex -= deltaFrames;
 
         for (unsigned i = 0; i < numberOfChannels; ++i)
             std::fill_n(destinationChannels[i] + writeIndex, framesToProcess, 
sourceChannels[i][readIndex]);
+
+        virtualReadIndex = readIndex;
     } else if (reverse) {
         unsigned maxFrame = static_cast<unsigned>(virtualMaxFrame);
         unsigned minFrame = static_cast<unsigned>(floorf(virtualMinFrame));
-- 
2.45.2


++++++ webkit2gtk3-CVE-2024-40782.patch ++++++
>From 617f1c4c9c7f1525abc47967d4c7734fed3ff525 Mon Sep 17 00:00:00 2001
From: Antti Koivisto <an...@apple.com>
Date: Mon, 20 May 2024 11:36:34 -0700
Subject: [PATCH] Cherry-pick 279005@main (c2f9092d3a8e).
 https://bugs.webkit.org/show_bug.cgi?id=268770

    Nullptr crash due to `display:block ruby` and continuations
    https://bugs.webkit.org/show_bug.cgi?id=268770
    rdar://121960530

    Reviewed by Alan Baradlay.

    Continuations may end up splitting anonymous 'display:ruby' box inside 
block ruby.

    * LayoutTests/fast/ruby/ruby-block-continuation-crash-expected.txt: Added.
    * LayoutTests/fast/ruby/ruby-block-continuation-crash.html: Added.
    * Source/WebCore/rendering/updating/RenderTreeBuilderRuby.cpp:
    
(WebCore::RenderTreeBuilder::Ruby::findOrCreateParentForStyleBasedRubyChild):

    Find the correct anonymous box from nested continuation structure.

    Canonical link: https://commits.webkit.org/279005@main

Canonical link: https://commits.webkit.org/274313.286@webkitglib/2.44
---
 .../ruby/ruby-block-continuation-crash-expected.txt |  3 +++
 .../fast/ruby/ruby-block-continuation-crash.html    |  9 +++++++++
 .../rendering/updating/RenderTreeBuilderRuby.cpp    | 13 ++++++++++---
 3 files changed, 22 insertions(+), 3 deletions(-)
 create mode 100644 
LayoutTests/fast/ruby/ruby-block-continuation-crash-expected.txt
 create mode 100644 LayoutTests/fast/ruby/ruby-block-continuation-crash.html

diff --git a/LayoutTests/fast/ruby/ruby-block-continuation-crash-expected.txt 
b/LayoutTests/fast/ruby/ruby-block-continuation-crash-expected.txt
new file mode 100644
index 000000000000..f85a15505104
--- /dev/null
+++ b/LayoutTests/fast/ruby/ruby-block-continuation-crash-expected.txt
@@ -0,0 +1,3 @@
+base with
+forced
+line break annotation This test passes if it doesn't crash.
diff --git a/LayoutTests/fast/ruby/ruby-block-continuation-crash.html 
b/LayoutTests/fast/ruby/ruby-block-continuation-crash.html
new file mode 100644
index 000000000000..3f762d4236ea
--- /dev/null
+++ b/LayoutTests/fast/ruby/ruby-block-continuation-crash.html
@@ -0,0 +1,9 @@
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+</script>
+<ruby style="position: absolute">
+  <rb><span>base with <div>forced</div> line break</span></rb>
+  <rt>annotation</rt>
+</ruby>
+This test passes if it doesn't crash.
diff --git a/Source/WebCore/rendering/updating/RenderTreeBuilderRuby.cpp 
b/Source/WebCore/rendering/updating/RenderTreeBuilderRuby.cpp
index 62d8b6803323..9f7634612822 100644
--- a/Source/WebCore/rendering/updating/RenderTreeBuilderRuby.cpp
+++ b/Source/WebCore/rendering/updating/RenderTreeBuilderRuby.cpp
@@ -271,10 +271,17 @@ RenderElement& 
RenderTreeBuilder::Ruby::findOrCreateParentForStyleBasedRubyChild
     if (!child.isRenderText() && child.style().display() == DisplayType::Ruby 
&& parent.style().display() == DisplayType::RubyBlock)
         return parent;
 
-    if (parent.style().display() == DisplayType::RubyBlock && 
parent.firstChild()) {
+    if (parent.style().display() == DisplayType::RubyBlock) {
         // See if we have an anonymous ruby box already.
-        ASSERT(parent.firstChild()->style().display() == DisplayType::Ruby);
-        return downcast<RenderElement>(*parent.firstChild());
+        // FIXME: It should be the immediate child but continuations can break 
this assumption.
+        for (CheckedPtr first = parent.firstChild(); first; first = 
first->firstChildSlow()) {
+            if (!first->isAnonymous()) {
+                ASSERT_NOT_REACHED();
+                break;
+            }
+            if (first->style().display() == DisplayType::Ruby)
+                return downcast<RenderElement>(*first);
+        }
     }
 
     if (parent.style().display() != DisplayType::Ruby) {
-- 
2.45.2

Reply via email to