WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
162933
REGRESSION(
r203289
): Assertion in MathOperator::stretchTo() on Wikipedia Page
https://bugs.webkit.org/show_bug.cgi?id=162933
Summary
REGRESSION(r203289): Assertion in MathOperator::stretchTo() on Wikipedia Page
Brent Fulgham
Reported
2016-10-04 13:29:06 PDT
Visit the Wikipedia page for Levenshtein Distance in a debug build of WebKit:
https://en.wikipedia.org/wiki/Levenshtein_distance
This triggers the following assertion: void MathOperator::stretchTo(const RenderStyle& style, LayoutUnit targetSize) { ASSERT(m_operatorType == Type::VerticalOperator || m_operatorType == Type::HorizontalOperator); calculateStretchyData(style, false, targetSize); if (m_stretchType == StretchType::GlyphAssembly) { The assertion fires because we are attempting to apply the 'stretchTo' operation on a "NormalOperator" type.
Attachments
Test Case showing the null image
(1014 bytes, text/html)
2016-10-31 16:52 PDT
,
Brent Fulgham
no flags
Details
Patch
(885 bytes, patch)
2016-11-01 01:25 PDT
,
Frédéric Wang Nélar
no flags
Details
Formatted Diff
Diff
Patch
(8.59 KB, patch)
2016-11-01 13:01 PDT
,
Brent Fulgham
no flags
Details
Formatted Diff
Diff
Patch
(7.94 KB, patch)
2016-11-02 12:11 PDT
,
Brent Fulgham
dino
: review+
Details
Formatted Diff
Diff
Show Obsolete
(2)
View All
Add attachment
proposed patch, testcase, etc.
Brent Fulgham
Comment 1
2016-10-04 13:30:16 PDT
<
rdar://problem/28570590
>
Frédéric Wang Nélar
Comment 2
2016-10-04 23:43:06 PDT
Are you able to isolate the MathML fragment that triggers the assertion? As I see, RenderMathMLOperator::updateMathOperator() sets the type to NormalOperator if !shouldAllowStretching() i.e. we don't have !(textContent() && (hasOperatorFlag(MathMLOperatorDictionary::Stretchy) || isLargeOperatorInDisplayStyle())) On the other hand, MathOperator::stretchTo are called from the RenderMathMLOperator::stretchTo functions that explicitly checks hasOperatorFlag(MathMLOperatorDictionary::Stretchy). Is is possible that textContent() is empty? Or that RenderMathMLOperator::updateMathOperator() has not been called in time?
Brent Fulgham
Comment 3
2016-10-31 13:57:41 PDT
(In reply to
comment #2
)
> Are you able to isolate the MathML fragment that triggers the assertion?
I don't have a reduced test case.
> ... Is is possible that > textContent() is empty? Or that RenderMathMLOperator::updateMathOperator() > has not been called in time?
'textContent' is not empty. The 'operatorChar' member is set to "{".
Brent Fulgham
Comment 4
2016-10-31 14:00:49 PDT
(In reply to
comment #3
) Wait! I take it all back. I was not hitting the crash when I inspected those values. It appears that the RenderMathMLOperator object has an operatorChar of "", so yes -- it does seem to be empty.
Frédéric Wang Nélar
Comment 5
2016-10-31 14:08:47 PDT
(In reply to
comment #4
)
> (In reply to
comment #3
) > > Wait! I take it all back. I was not hitting the crash when I inspected those > values. > > It appears that the RenderMathMLOperator object has an operatorChar of "", > so yes -- it does seem to be empty.
OK, in that case we only need to avoid the (two IIRC?) calls to RenderMathMLOperator::stretchTo when the textContent == 0 (and maybe add assert in RenderMathMLOperator::stretchTo too).
Brent Fulgham
Comment 6
2016-10-31 16:52:20 PDT
Created
attachment 293495
[details]
Test Case showing the null image Reduced test case.
Brent Fulgham
Comment 7
2016-10-31 16:53:16 PDT
The assertion gets hit with the attached test case, specifically with this line: <mo fence="true" stretchy="true"></mo> Looks like we need to account for the possibility that content may be generated with an empty element of this kind.
Frédéric Wang Nélar
Comment 8
2016-11-01 01:05:01 PDT
(In reply to
comment #7
)
> The assertion gets hit with the attached test case, specifically with this > line: > > <mo fence="true" stretchy="true"></mo> > > Looks like we need to account for the possibility that content may be > generated with an empty element of this kind.
Yes, I think it will be considered vertical + stretchy. fence="true" should not be needed to trigger the assert.
Frédéric Wang Nélar
Comment 9
2016-11-01 01:25:41 PDT
Created
attachment 293537
[details]
Patch @Brent: This is a quick untested patch. Maybe a stronger solution is just to introduce bool RenderMathMLOperator::isStretchy() { return textContent() && element().hasProperty(MathMLOperatorDictionary::Stretchy); } and then replace each call to RenderMathMLOperator::hasProperty(MathMLOperatorDictionary::Stretchy) in the RenderMathML* classes with a call to RenderMathMLOperator::isStretchy().
Brent Fulgham
Comment 10
2016-11-01 10:51:31 PDT
(In reply to
comment #9
)
> Created
attachment 293537
[details]
> Patch > > @Brent: This is a quick untested patch. Maybe a stronger solution is just to > introduce > > bool RenderMathMLOperator::isStretchy() > { > return textContent() && > element().hasProperty(MathMLOperatorDictionary::Stretchy); > } > > and then replace each call to > RenderMathMLOperator::hasProperty(MathMLOperatorDictionary::Stretchy) in the > RenderMathML* classes with a call to RenderMathMLOperator::isStretchy().
Could we just use "shouldAllowStretching()"? It is very similar: bool RenderMathMLOperator::shouldAllowStretching() const { return textContent() && (hasOperatorFlag(MathMLOperatorDictionary::Stretchy) || isLargeOperatorInDisplayStyle()); }
Brent Fulgham
Comment 11
2016-11-01 12:30:07 PDT
I confirmed that Frédéric's patch works. We can generate a final patch once he confirms whether the existing shouldAllowStretching is suitable, or if we must use the new 'isStretchy()' method.
Frédéric Wang Nélar
Comment 12
2016-11-01 12:35:48 PDT
(In reply to
comment #10
)
> Could we just use "shouldAllowStretching()"? It is very similar: > > bool RenderMathMLOperator::shouldAllowStretching() const > { > return textContent() && > (hasOperatorFlag(MathMLOperatorDictionary::Stretchy) || > isLargeOperatorInDisplayStyle()); > }
I don't think so, stretchTo must only be called with stretchy operators. If we include large operators in displaystyle (e.g. <math display="block"><mo>&Sum</mo></math>) then I suspect you can also hit an ASSERT in RenderMathMLOperator because hasOperatorFlag(MathMLOperatorDictionary::Stretchy) is not satisfied.
Frédéric Wang Nélar
Comment 13
2016-11-01 12:51:14 PDT
(In reply to
comment #10
)
> Could we just use "shouldAllowStretching()"?
Incidentally, I suspect this method is just a legacy of old code that was kept after the refactoring. I believe that now we can just expand it inside RenderMathMLOperator::updateMathOperator() by doing something like: if (isStretchy()) type = isVertical() ? MathOperator::Type::VerticalOperator : MathOperator::Type::HorizontalOperator; else if (textContent() && isLargeOperatorInDisplayStyle()) type = MathOperator::Type::DisplayOperator; else type = MathOperator::Type::NormalOperator; and then the condition in RenderMathMLOperator::useMathOperator() will just become m_mathOperator.type() != MathOperator::Type::NormalOperator || textContent() == minusSign where we add the accessor MathOperator::type() { return m_operatorType; } We can even include the textContent() check inside isLargeOperatorInDisplayStyle and discard the case <math display="block"><mo largeop="true"></mo></math>.
Brent Fulgham
Comment 14
2016-11-01 13:01:54 PDT
Created
attachment 293573
[details]
Patch
Brent Fulgham
Comment 15
2016-11-01 13:06:08 PDT
(In reply to
comment #13
)
> (In reply to
comment #10
) > > Could we just use "shouldAllowStretching()"? > > Incidentally, I suspect this method is just a legacy of old code that was > kept after the refactoring. I believe that now we can just expand it inside > RenderMathMLOperator::updateMathOperator() by doing something like: > > if (isStretchy()) > type = isVertical() ? MathOperator::Type::VerticalOperator : > MathOperator::Type::HorizontalOperator; > else if (textContent() && isLargeOperatorInDisplayStyle()) > type = MathOperator::Type::DisplayOperator; > else > type = MathOperator::Type::NormalOperator; > > and then the condition in RenderMathMLOperator::useMathOperator() will just > become > > m_mathOperator.type() != MathOperator::Type::NormalOperator || textContent() > == minusSign > > where we add the accessor MathOperator::type() { return m_operatorType; } > > We can even include the textContent() check inside > isLargeOperatorInDisplayStyle and discard the case <math display="block"><mo > largeop="true"></mo></math>.
Seems like a nice idea for a future refactoring! :-)
Frédéric Wang Nélar
Comment 16
2016-11-02 02:19:53 PDT
Comment on
attachment 293573
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=293573&action=review
lgtm, but I'm not a reviewer.
> Source/WebCore/ChangeLog:11 > + We shouldn't be trying to apply stretch operations on an empty MathML element. Create a
I think it's actually any operator that is not made of a single character. For example the assert probably happens with <mo stretchy="true">++<mo> too.
> LayoutTests/mathml/empty-mo.html:8 > + <math xmlns="
http://www.w3.org/1998/Math/MathML
">
Maybe you can reduce this test case to <math><mo stretchy="true"></mo></math> ?
Frédéric Wang Nélar
Comment 17
2016-11-02 02:24:43 PDT
(In reply to
comment #15
)
> Seems like a nice idea for a future refactoring! :-)
I opened
bug 164313
Alejandro G. Castro
Comment 18
2016-11-02 05:16:32 PDT
(In reply to
comment #16
)
> Comment on
attachment 293573
[details]
> Patch > > View in context: >
https://bugs.webkit.org/attachment.cgi?id=293573&action=review
> > lgtm, but I'm not a reviewer.
> lgtm too.
> > Source/WebCore/ChangeLog:11 > > + We shouldn't be trying to apply stretch operations on an empty MathML element. Create a > > I think it's actually any operator that is not made of a single character. > For example the assert probably happens with <mo stretchy="true">++<mo> too. >
Can we add also this case (++) to the test, and check if the textContent() part of the condition is doing what we want for that case.
Brent Fulgham
Comment 19
2016-11-02 12:11:16 PDT
Comment on
attachment 293573
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=293573&action=review
>>> Source/WebCore/ChangeLog:11 >>> + We shouldn't be trying to apply stretch operations on an empty MathML element. Create a >> >> I think it's actually any operator that is not made of a single character. For example the assert probably happens with <mo stretchy="true">++<mo> too. > > Can we add also this case (++) to the test, and check if the textContent() part of the condition is doing what we want for that case.
Done.
Brent Fulgham
Comment 20
2016-11-02 12:11:23 PDT
Created
attachment 293684
[details]
Patch
Brent Fulgham
Comment 21
2016-11-02 12:12:26 PDT
(In reply to
comment #16
)
> Comment on
attachment 293573
[details]
> Maybe you can reduce this test case to <math><mo > stretchy="true"></mo></math> ?
Yes, this did work. I've revised the test cases as you suggested.
Brent Fulgham
Comment 22
2016-11-02 12:50:13 PDT
Committed
r208296
: <
http://trac.webkit.org/changeset/208296
>
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug