Changeset 166245 in webkit
- Timestamp:
- Mar 25, 2014 1:15:14 PM (10 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r166243 r166245 1 2014-03-25 Myles C. Maxfield <mmaxfield@apple.com> 2 3 InlineIterator position (unsigned int) variable can wrap around 4 https://bugs.webkit.org/show_bug.cgi?id=130540 5 6 Reviewed by Simon Fraser. 7 8 This test triggers an ASSERT that occurs when we are ignoring spaces (to collapse them 9 into a single whitespace mark) but then encounter a line break. Because we don't ignore 10 the first space (but do ignore subsequent spaces), when we hit a newline in an RTL context 11 we want to ignore that first space as well (so as not to push the text away from the right 12 edge). We do this by decrementing the InlineIterator pointing to this first space, so all 13 the spaces get ignored. However, if that space is the first character in a Text node, the 14 decrement will try to go past the beginning of the node, and trigger an ASSERT. 15 16 This design is not great. At some point we should rework it to more elegantly handle 17 collapsing whitespace in both RTL and LTR writing modes. 18 19 * fast/text/whitespace-only-text-in-rtl-expected.txt: Added. 20 * fast/text/whitespace-only-text-in-rtl.html: Added. 21 1 22 2014-03-25 Oliver Hunt <oliver@apple.com> 2 23 -
trunk/Source/WebCore/ChangeLog
r166239 r166245 1 2014-03-25 Myles C. Maxfield <mmaxfield@apple.com> 2 3 InlineIterator position (unsigned int) variable can wrap around 4 https://bugs.webkit.org/show_bug.cgi?id=130540 5 6 Reviewed by Simon Fraser. 7 8 We trigger an ASSERT that occurs when we are ignoring spaces (to collapse them 9 into a single whitespace mark) but then encounter a line break. Because we don't ignore 10 the first space (but do ignore subsequent spaces), when we hit a newline in an RTL context 11 we want to ignore that first space as well (so as not to push the text away from the right 12 edge). We do this by decrementing the InlineIterator pointing to this first space, so all 13 the spaces get ignored. However, if that space is the first character in a Text node, the 14 decrement will try to go past the beginning of the node, and trigger an ASSERT. 15 16 This design is not great. At some point we should rework it to more elegantly handle 17 collapsing whitespace in both RTL and LTR writing modes. 18 19 This patch adds an ASSERT earlier in this codepath to catch potential problems earlier. 20 It also pulls our sentinel value out into a separate boolean to make it more clear what is 21 going on. 22 23 Test: fast/text/whitespace-only-text-in-rtl.html 24 25 * rendering/InlineIterator.h: 26 (WebCore::InlineIterator::moveTo): Use the set***() calls 27 (WebCore::InlineIterator::setOffset): ASSERT early that our math hasn't wrapped 28 * rendering/RenderBlockLineLayout.cpp: 29 (WebCore::RenderBlockFlow::appendRunsForObject): Use new boolean value 30 * rendering/line/BreakingContextInlineHeaders.h: 31 (WebCore::BreakingContext::handleText): Guard against wraps 32 (WebCore::checkMidpoints): Use new boolean value 33 * rendering/line/TrailingObjects.cpp: 34 (WebCore::TrailingObjects::updateMidpointsForTrailingBoxes): Use new boolean value 35 1 36 2014-03-25 Martin Robinson <mrobinson@igalia.com> 2 37 -
trunk/Source/WebCore/rendering/InlineIterator.h
r163465 r166245 42 42 , m_nextBreakablePosition(-1) 43 43 , m_pos(0) 44 , m_refersToEndOfPreviousNode(false) 44 45 { 45 46 } … … 50 51 , m_nextBreakablePosition(-1) 51 52 , m_pos(p) 53 , m_refersToEndOfPreviousNode(false) 52 54 { 53 55 } … … 62 64 void moveTo(RenderObject* object, unsigned offset, int nextBreak = -1) 63 65 { 64 m_renderer = object;65 m_pos = offset;66 m_nextBreakablePosition = nextBreak;66 setRenderer(object); 67 setOffset(offset); 68 setNextBreakablePosition(nextBreak); 67 69 } 68 70 … … 70 72 void setRenderer(RenderObject* renderer) { m_renderer = renderer; } 71 73 unsigned offset() const { return m_pos; } 72 void setOffset(unsigned position) { m_pos = position; }74 void setOffset(unsigned position); 73 75 RenderElement* root() const { return m_root; } 74 76 int nextBreakablePosition() const { return m_nextBreakablePosition; } 75 77 void setNextBreakablePosition(int position) { m_nextBreakablePosition = position; } 78 bool refersToEndOfPreviousNode() const { return m_refersToEndOfPreviousNode; } 79 void setRefersToEndOfPreviousNode(); 76 80 77 81 void fastIncrementInTextNode(); 78 82 void increment(InlineBidiResolver* = 0); 83 void fastDecrement(); 79 84 bool atEnd() const; 80 85 … … 101 106 int m_nextBreakablePosition; 102 107 unsigned m_pos; 108 109 // There are a couple places where we want to decrement an InlineIterator. 110 // Usually this take the form of decrementing m_pos; however, m_pos might be 0. 111 // However, we shouldn't ever need to decrement an InlineIterator more than 112 // once, so rather than implementing a decrement() function which traverses 113 // nodes, we can simply keep track of this state and handle it. 114 bool m_refersToEndOfPreviousNode; 103 115 }; 104 116 … … 322 334 } 323 335 336 inline void InlineIterator::setOffset(unsigned position) 337 { 338 ASSERT(position <= UINT_MAX - 10); // Sanity check 339 m_pos = position; 340 } 341 342 inline void InlineIterator::setRefersToEndOfPreviousNode() 343 { 344 ASSERT(!m_pos); 345 ASSERT(!m_refersToEndOfPreviousNode); 346 m_refersToEndOfPreviousNode = true; 347 } 348 324 349 // FIXME: This is used by RenderBlock for simplified layout, and has nothing to do with bidi 325 350 // it shouldn't use functions called bidiFirst and bidiNext. … … 364 389 // bidiNext can return 0, so use moveTo instead of moveToStartOf 365 390 moveTo(bidiNextSkippingEmptyInlines(*m_root, m_renderer, resolver), 0); 391 } 392 393 inline void InlineIterator::fastDecrement() 394 { 395 ASSERT(!refersToEndOfPreviousNode()); 396 if (m_pos) 397 setOffset(m_pos - 1); 398 else 399 setRefersToEndOfPreviousNode(); 366 400 } 367 401 -
trunk/Source/WebCore/rendering/RenderBlockLineLayout.cpp
r165607 r166245 106 106 lineMidpointState.setBetweenMidpoints(true); 107 107 lineMidpointState.incrementCurrentMidpoint(); 108 if (nextMidpoint.offset() != UINT_MAX) { // UINT_MAX means stop at the object and don't include any of it. 109 if (static_cast<int>(nextMidpoint.offset() + 1) > start) 110 runs.addRun(createRun(start, nextMidpoint.offset() + 1, obj, resolver)); 111 return appendRunsForObject(runs, nextMidpoint.offset() + 1, end, obj, resolver); 112 } 108 // The end of the line is before the object we're inspecting. Skip everything and return 109 if (nextMidpoint.refersToEndOfPreviousNode()) 110 return; 111 if (static_cast<int>(nextMidpoint.offset() + 1) > start) 112 runs.addRun(createRun(start, nextMidpoint.offset() + 1, obj, resolver)); 113 appendRunsForObject(runs, nextMidpoint.offset() + 1, end, obj, resolver); 113 114 } else 114 115 runs.addRun(createRun(start, end, obj, resolver)); -
trunk/Source/WebCore/rendering/line/BreakingContextInlineHeaders.h
r166120 r166245 905 905 // space doesn't seem to push the text out from the right-hand edge. 906 906 // FIXME: Do this regardless of the container's alignment - will require rebaselining a lot of test results. 907 if (m_nextObject && m_ nextObject->isBR() && (m_blockStyle.textAlign() == RIGHT || m_blockStyle.textAlign() == WEBKIT_RIGHT)) {907 if (m_nextObject && m_startOfIgnoredSpaces.offset() && m_nextObject->isBR() && (m_blockStyle.textAlign() == RIGHT || m_blockStyle.textAlign() == WEBKIT_RIGHT)) { 908 908 m_startOfIgnoredSpaces.setOffset(m_startOfIgnoredSpaces.offset() - 1); 909 909 // If there's just a single trailing space start ignoring it now so it collapses away. … … 1066 1066 lineMidpointState.decreaseNumMidpoints(); 1067 1067 if (endpoint.renderer()->style().collapseWhiteSpace() && endpoint.renderer()->isText()) 1068 endpoint. setOffset(endpoint.offset() - 1);1068 endpoint.fastDecrement(); 1069 1069 } 1070 1070 } -
trunk/Source/WebCore/rendering/line/TrailingObjects.cpp
r162472 r166245 43 43 ASSERT(trailingSpaceMidpoint >= 0); 44 44 if (collapseFirstSpace == CollapseFirstSpace) 45 lineMidpointState.midpoints()[trailingSpaceMidpoint]. setOffset(lineMidpointState.midpoints()[trailingSpaceMidpoint].offset() -1);45 lineMidpointState.midpoints()[trailingSpaceMidpoint].fastDecrement(); 46 46 47 47 // Now make sure every single trailingPositionedBox following the trailingSpaceMidpoint properly stops and starts
Note: See TracChangeset
for help on using the changeset viewer.