Skip to content

Commit

Permalink
Merge r166420 - Clear SVGInlineTextBox fragments when the text changes.
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=130879

Reviewed by Darin Adler.

Ported from Blink: https://src.chromium.org/viewvc/blink?revision=150456&view=revision

Source/WebCore:

This patch modifies SVGInlineTextBox::dirtyLineBoxes to clear all
following text boxes when invoked. Typically this method is called
when the underlying text string changes, and that change needs to
be propagated to all the boxes that use the text beyond the point
where the text is first modified.

Also cleans up final function keywords for SVGRootInlineBox.

Test: svg/custom/unicode-in-tspan-multi-svg-crash.html

* rendering/InlineTextBox.h: Added (non-recursive) dirtyOwnLineBoxes() function
(WebCore::InlineTextBox::dirtyOwnLineBoxes): Calls dirtyLineBoxes()
* rendering/svg/SVGInlineTextBox.h: Added (non-recursive) dirtyOwnLineBoxes() function
(WebCore::SVGInlineTextBox::dirtyOwnLineBoxes):
* rendering/svg/SVGInlineTextBox.cpp:
(WebCore::SVGInlineTextBox::dirtyOwnLineBoxes): Non-recursive part of dirtyLineBoxes()
(WebCore::SVGInlineTextBox::dirtyLineBoxes): Calls dirtyOwnLineBoxes() in a loop
* rendering/svg/SVGRootInlineBox.h:

LayoutTests:

When failing, this test will render garbage characters or crash.

* svg/custom/unicode-in-tspan-multi-svg-crash-expected.txt: Added.
* svg/custom/unicode-in-tspan-multi-svg-crash.html: Added.
  • Loading branch information
litherum authored and carlosgcampos committed May 5, 2014
1 parent 9d2f04c commit 1dbfdb3
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 5 deletions.
14 changes: 14 additions & 0 deletions LayoutTests/ChangeLog
@@ -1,3 +1,17 @@
2014-03-28 Myles C. Maxfield <mmaxfield@apple.com>

Clear SVGInlineTextBox fragments when the text changes.
https://bugs.webkit.org/show_bug.cgi?id=130879

Reviewed by Darin Adler.

Ported from Blink: https://src.chromium.org/viewvc/blink?revision=150456&view=revision

When failing, this test will render garbage characters or crash.

* svg/custom/unicode-in-tspan-multi-svg-crash-expected.txt: Added.
* svg/custom/unicode-in-tspan-multi-svg-crash.html: Added.

2014-03-01 David Kilzer <ddkilzer@apple.com>

Fix lifetime handling of SVGPropertyTearOffs
Expand Down
@@ -0,0 +1 @@
Test Passes if there is no crash in Debug or Asan builds. There should be no characters preceding "Test".
38 changes: 38 additions & 0 deletions LayoutTests/svg/custom/unicode-in-tspan-multi-svg-crash.html
@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<script>
if (window.testRunner)
testRunner.dumpAsText(false);

onload = function() {
tSpanElement = document.getElementById('tSpanInFirstRoot');
tSpanElement.appendChild(document.createTextNode(unescape('%ufe9e%ue28f%ue47e')));

document.body.offsetTop;
document.body.style.zoom=0.9;

document.designMode='on';
filterInFirstRoot = document.getElementById('filterInFirstRoot');
useElement = document.getElementById('useElement');
window.getSelection().setBaseAndExtent(filterInFirstRoot, useElement, 5);
document.execCommand('ForwardDelete');
document.designMode='off';
}
</script>
<body>
<svg xmlns="http://www.w3.org/2000/svg">
<text>
<filter id="filterInFirstRoot"/>
<tspan id="tSpanInFirstRoot"/>
</text>
<path filter="url(#filterInSecondRoot)"/>
</svg>

<svg xmlns="http://www.w3.org/2000/svg">
<use id="useElement"/>
<filter id="filterInSecondRoot"/>
</svg>

<p>Test Passes if there is no crash in Debug or Asan builds. There should be no characters preceding "Test".</p>
</body>
</html>
28 changes: 28 additions & 0 deletions Source/WebCore/ChangeLog
@@ -1,3 +1,31 @@
2014-03-28 Myles C. Maxfield <mmaxfield@apple.com>

Clear SVGInlineTextBox fragments when the text changes.
https://bugs.webkit.org/show_bug.cgi?id=130879

Reviewed by Darin Adler.

Ported from Blink: https://src.chromium.org/viewvc/blink?revision=150456&view=revision

This patch modifies SVGInlineTextBox::dirtyLineBoxes to clear all
following text boxes when invoked. Typically this method is called
when the underlying text string changes, and that change needs to
be propagated to all the boxes that use the text beyond the point
where the text is first modified.

Also cleans up final function keywords for SVGRootInlineBox.

Test: svg/custom/unicode-in-tspan-multi-svg-crash.html

* rendering/InlineTextBox.h: Added (non-recursive) dirtyOwnLineBoxes() function
(WebCore::InlineTextBox::dirtyOwnLineBoxes): Calls dirtyLineBoxes()
* rendering/svg/SVGInlineTextBox.h: Added (non-recursive) dirtyOwnLineBoxes() function
(WebCore::SVGInlineTextBox::dirtyOwnLineBoxes):
* rendering/svg/SVGInlineTextBox.cpp:
(WebCore::SVGInlineTextBox::dirtyOwnLineBoxes): Non-recursive part of dirtyLineBoxes()
(WebCore::SVGInlineTextBox::dirtyLineBoxes): Calls dirtyOwnLineBoxes() in a loop
* rendering/svg/SVGRootInlineBox.h:

2014-02-02 Andreas Kling <akling@apple.com>

Minor SVGRootInlineBox cleanup.
Expand Down
2 changes: 2 additions & 0 deletions Source/WebCore/rendering/InlineTextBox.h
Expand Up @@ -98,6 +98,8 @@ class InlineTextBox : public InlineBox {
LayoutUnit logicalLeftVisualOverflow() const { return logicalOverflowRect().x(); }
LayoutUnit logicalRightVisualOverflow() const { return logicalOverflowRect().maxX(); }

virtual void dirtyOwnLineBoxes() { dirtyLineBoxes(); }

#ifndef NDEBUG
virtual void showBox(int = 0) const;
virtual const char* boxName() const;
Expand Down
12 changes: 11 additions & 1 deletion Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
Expand Up @@ -58,14 +58,24 @@ SVGInlineTextBox::SVGInlineTextBox(RenderSVGInlineText& renderer)
{
}

void SVGInlineTextBox::dirtyLineBoxes()
void SVGInlineTextBox::dirtyOwnLineBoxes()
{
InlineTextBox::dirtyLineBoxes();

// Clear the now stale text fragments
clearTextFragments();
}

void SVGInlineTextBox::dirtyLineBoxes()
{
dirtyOwnLineBoxes();

// And clear any following text fragments as the text on which they
// depend may now no longer exist, or glyph positions may be wrong
for (InlineTextBox* nextBox = nextTextBox(); nextBox; nextBox = nextBox->nextTextBox())
nextBox->dirtyOwnLineBoxes();
}

int SVGInlineTextBox::offsetForPosition(float, bool) const
{
// SVG doesn't use the standard offset <-> position selection system, as it's not suitable for SVGs complex needs.
Expand Down
3 changes: 2 additions & 1 deletion Source/WebCore/rendering/svg/SVGInlineTextBox.h
Expand Up @@ -58,7 +58,8 @@ class SVGInlineTextBox final : public InlineTextBox {
Vector<SVGTextFragment>& textFragments() { return m_textFragments; }
const Vector<SVGTextFragment>& textFragments() const { return m_textFragments; }

virtual void dirtyLineBoxes() override;
virtual void dirtyOwnLineBoxes() override final;
virtual void dirtyLineBoxes() override final;

bool startsNewTextChunk() const { return m_startsNewTextChunk; }
void setStartsNewTextChunk(bool newTextChunk) { m_startsNewTextChunk = newTextChunk; }
Expand Down
6 changes: 3 additions & 3 deletions Source/WebCore/rendering/svg/SVGRootInlineBox.h
Expand Up @@ -39,17 +39,17 @@ class SVGRootInlineBox final : public RootInlineBox {

RenderSVGText& renderSVGText();

virtual float virtualLogicalHeight() const override { return m_logicalHeight; }
virtual float virtualLogicalHeight() const override final { return m_logicalHeight; }
void setLogicalHeight(float height) { m_logicalHeight = height; }

virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) override;
virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) override final;

void computePerCharacterLayoutInformation();

InlineBox* closestLeafChildForPosition(const LayoutPoint&);

private:
virtual bool isSVGRootInlineBox() const override { return true; }
virtual bool isSVGRootInlineBox() const override final { return true; }
void reorderValueLists(Vector<SVGTextLayoutAttributes*>&);
void layoutCharactersInTextBoxes(InlineFlowBox*, SVGTextLayoutEngine&);
void layoutChildBoxes(InlineFlowBox*, FloatRect* = 0);
Expand Down

0 comments on commit 1dbfdb3

Please sign in to comment.