Skip to content

Commit

Permalink
Merge r222221 - Do not mutate RenderText content during layout.
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=176219
<rdar://problem/34205724>

Reviewed by David Hyatt.

Source/WebCore:

Update combined text when the style/content change as opposed to lazily, during layout.
-content mutation during layout might make the inline tree go out of sync.

Test: fast/text/international/dynamic-text-combine-crash.html

* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::computeInlinePreferredLogicalWidths const):
* rendering/RenderCombineText.cpp:
(WebCore::RenderCombineText::styleDidChange):
(WebCore::RenderCombineText::setRenderedText):
(WebCore::RenderCombineText::combineTextIfNeeded):
(WebCore::RenderCombineText::combineText): Deleted.
* rendering/RenderCombineText.h:
* rendering/RenderText.h:
* rendering/line/BreakingContext.h:
(WebCore::BreakingContext::handleText):
* rendering/line/LineBreaker.cpp:
(WebCore::LineBreaker::skipLeadingWhitespace):

LayoutTests:

* fast/text/international/dynamic-text-combine-crash.html: Added.
* fast/text/text-combine-crash-expected.txt:
  • Loading branch information
alanbaradlay authored and carlosgcampos committed Oct 16, 2017
1 parent 5f520ae commit e8488c1
Show file tree
Hide file tree
Showing 12 changed files with 79 additions and 11 deletions.
11 changes: 11 additions & 0 deletions LayoutTests/ChangeLog
@@ -1,3 +1,14 @@
2017-09-19 Zalan Bujtas <zalan@apple.com>

Do not mutate RenderText content during layout.
https://bugs.webkit.org/show_bug.cgi?id=176219
<rdar://problem/34205724>

Reviewed by David Hyatt.

* fast/text/international/dynamic-text-combine-crash.html: Added.
* fast/text/text-combine-crash-expected.txt:

2017-09-15 Wenson Hsieh <wenson_hsieh@apple.com>

createMarkupInternal should protect its pointer to the Range's common ancestor
Expand Down
@@ -0,0 +1,6 @@
Pass if no crash.




@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<style>
h3 {
max-height: 0;
-webkit-text-combine: horizontal;
-webkit-writing-mode: vertical-rl;
}
</style>
</head>
<body><listing>Pass if no crash.<dd contenteditable="true"><h3 id="h">foobar</h3></body>
<script>
if (window.testRunner)
testRunner.dumpAsText();
window.getSelection().setPosition(h, 1);
document.execCommand("delete", false);
document.execCommand("delete", false);
</script>
</html>
6 changes: 3 additions & 3 deletions LayoutTests/fast/text/text-combine-crash-expected.txt
Expand Up @@ -4,14 +4,14 @@ Test passes if there's no crash.




Errlog webtest_fn_1: TypeError: undefined is not an object (evaluating 'document.applets[0].addEventListener')
Errlog webtest_fn_2: TypeError: Argument 1 ('node') to Range.setStartBefore must be an instance of Node
Errlog webtest_fn_3: TypeError: undefined is not an object (evaluating 'document.images[2].contentEditable="true"')
Errlog webtest_fn_8: TypeError: null is not an object (evaluating 'lis.length')
Errlog webtest_fn_9: TypeError: undefined is not an object (evaluating 'document.anchors[4].setAttribute')
Errlog webtest_fn_9: TypeError: undefined is not an object (evaluating 'document.anchors[4].setAttribute')
Errlog webtest_fn_10: TypeError: Argument 1 ('node') to Range.setStartAfter must be an instance of Node
Errlog webtest_fn_15: TypeError: Argument 1 ('node') to Range.setStart must be an instance of Node
Errlog webtest_fn_15: TypeError: Argument 1 ('node') to Range.setStart must be an instance of Node
Errlog webtest_fn_16: TypeError: undefined is not an object (evaluating 'elem.parentNode')
Errlog webtest_fn_18: TypeError: undefined is not an object (evaluating 'document.applets[0].contentEditable="true"')
Errlog webtest_fn_21: TypeError: undefined is not an object (evaluating 'document.anchors[4].appendChild')
Expand Down
27 changes: 27 additions & 0 deletions Source/WebCore/ChangeLog
@@ -1,3 +1,30 @@
2017-09-19 Zalan Bujtas <zalan@apple.com>

Do not mutate RenderText content during layout.
https://bugs.webkit.org/show_bug.cgi?id=176219
<rdar://problem/34205724>

Reviewed by David Hyatt.

Update combined text when the style/content change as opposed to lazily, during layout.
-content mutation during layout might make the inline tree go out of sync.

Test: fast/text/international/dynamic-text-combine-crash.html

* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::computeInlinePreferredLogicalWidths const):
* rendering/RenderCombineText.cpp:
(WebCore::RenderCombineText::styleDidChange):
(WebCore::RenderCombineText::setRenderedText):
(WebCore::RenderCombineText::combineTextIfNeeded):
(WebCore::RenderCombineText::combineText): Deleted.
* rendering/RenderCombineText.h:
* rendering/RenderText.h:
* rendering/line/BreakingContext.h:
(WebCore::BreakingContext::handleText):
* rendering/line/LineBreaker.cpp:
(WebCore::LineBreaker::skipLeadingWhitespace):

2017-09-15 Wenson Hsieh <wenson_hsieh@apple.com>

createMarkupInternal should protect its pointer to the Range's common ancestor
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/rendering/RenderBlockFlow.cpp
Expand Up @@ -4398,7 +4398,7 @@ void RenderBlockFlow::computeInlinePreferredLogicalWidths(LayoutUnit& minLogical
RenderText& renderText = downcast<RenderText>(*child);

if (renderText.style().hasTextCombine() && renderText.isCombineText())
downcast<RenderCombineText>(renderText).combineText();
downcast<RenderCombineText>(renderText).combineTextIfNeeded();

// Determine if we have a breakable character. Pass in
// whether or not we should ignore any spaces at the front
Expand Down
6 changes: 5 additions & 1 deletion Source/WebCore/rendering/RenderCombineText.cpp
Expand Up @@ -54,13 +54,15 @@ void RenderCombineText::styleDidChange(StyleDifference diff, const RenderStyle*
}

m_needsFontUpdate = true;
combineTextIfNeeded();
}

void RenderCombineText::setRenderedText(const String& text)
{
RenderText::setRenderedText(text);

m_needsFontUpdate = true;
combineTextIfNeeded();
}

float RenderCombineText::width(unsigned from, unsigned length, const FontCascade& font, float xPosition, HashSet<const Font*>* fallbackFonts, GlyphOverflow* glyphOverflow) const
Expand Down Expand Up @@ -95,7 +97,7 @@ String RenderCombineText::combinedStringForRendering() const
return { };
}

void RenderCombineText::combineText()
void RenderCombineText::combineTextIfNeeded()
{
if (!m_needsFontUpdate)
return;
Expand Down Expand Up @@ -192,6 +194,8 @@ void RenderCombineText::combineText()
m_combinedTextWidth = combinedTextWidth;
m_combinedTextAscent = glyphOverflow.top;
m_combinedTextDescent = glyphOverflow.bottom;
m_lineBoxes.dirtyRange(*this, 0, originalText().length(), originalText().length());
setNeedsLayout();
}
}

Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/rendering/RenderCombineText.h
Expand Up @@ -32,7 +32,7 @@ class RenderCombineText final : public RenderText {

Text& textNode() const { return downcast<Text>(nodeForNonAnonymous()); }

void combineText();
void combineTextIfNeeded();
std::optional<FloatPoint> computeTextOrigin(const FloatRect& boxRect) const;
String combinedStringForRendering() const;
bool isCombined() const { return m_isCombined; }
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/rendering/RenderText.cpp
Expand Up @@ -69,13 +69,13 @@ using namespace Unicode;
namespace WebCore {

struct SameSizeAsRenderText : public RenderObject {
void* pointers[2];
uint32_t bitfields : 16;
#if ENABLE(TEXT_AUTOSIZING)
float candidateTextSize;
#endif
float widths[4];
String text;
void* pointers[2];
};

COMPILE_ASSERT(sizeof(RenderText) == sizeof(SameSizeAsRenderText), RenderText_should_stay_small);
Expand Down
4 changes: 2 additions & 2 deletions Source/WebCore/rendering/RenderText.h
Expand Up @@ -186,6 +186,8 @@ class RenderText : public RenderObject {
virtual void setRenderedText(const String&);
virtual UChar previousCharacter() const;

RenderTextLineBoxes m_lineBoxes;

private:
RenderText(Node&, const String&);

Expand Down Expand Up @@ -243,8 +245,6 @@ class RenderText : public RenderObject {
float m_endMinWidth;

String m_text;

RenderTextLineBoxes m_lineBoxes;
};

inline UChar RenderText::uncheckedCharacterAt(unsigned i) const
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/rendering/line/BreakingContext.h
Expand Up @@ -773,7 +773,7 @@ inline bool BreakingContext::handleText(WordMeasurements& wordMeasurements, bool

if (renderText.style().hasTextCombine() && is<RenderCombineText>(*m_current.renderer())) {
auto& combineRenderer = downcast<RenderCombineText>(*m_current.renderer());
combineRenderer.combineText();
combineRenderer.combineTextIfNeeded();
// The length of the renderer's text may have changed. Increment stale iterator positions
if (iteratorIsBeyondEndOfRenderCombineText(m_lineBreakHistory.current(), combineRenderer)) {
ASSERT(iteratorIsBeyondEndOfRenderCombineText(m_resolver.position(), combineRenderer));
Expand Down
2 changes: 1 addition & 1 deletion Source/WebCore/rendering/line/LineBreaker.cpp
Expand Up @@ -68,7 +68,7 @@ void LineBreaker::skipLeadingWhitespace(InlineBidiResolver& resolver, LineInfo&
} else if (object.isFloating())
m_block.positionNewFloatOnLine(*m_block.insertFloatingObject(downcast<RenderBox>(object)), lastFloatFromPreviousLine, lineInfo, width);
else if (object.style().hasTextCombine() && is<RenderCombineText>(object)) {
downcast<RenderCombineText>(object).combineText();
downcast<RenderCombineText>(object).combineTextIfNeeded();
if (downcast<RenderCombineText>(object).isCombined())
continue;
}
Expand Down

0 comments on commit e8488c1

Please sign in to comment.