Bug 92376 - Avoid Assertion Failure in HarfBuzzRun::characterIndexForXPosition
Summary: Avoid Assertion Failure in HarfBuzzRun::characterIndexForXPosition
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Platform (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Dominik Röttsches (drott)
URL:
Keywords:
: 40673 (view as bug list)
Depends on:
Blocks:
 
Reported: 2012-07-26 06:11 PDT by Dominik Röttsches (drott)
Modified: 2013-01-28 02:20 PST (History)
11 users (show)

See Also:


Attachments
Avoiding assertion failure. (3.06 KB, patch)
2012-07-26 06:52 PDT, Dominik Röttsches (drott)
no flags Details | Formatted Diff | Diff
Mouse selection fuzzing test. (1.38 KB, text/html)
2012-07-27 07:24 PDT, Dominik Röttsches (drott)
no flags Details
Fix for assertion being hit, test case. (8.60 KB, patch)
2012-07-30 02:18 PDT, Dominik Röttsches (drott)
no flags Details | Formatted Diff | Diff
Fix for assertion being hit, test case, v2. (8.74 KB, patch)
2012-07-30 04:30 PDT, Dominik Röttsches (drott)
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Dominik Röttsches (drott) 2012-07-26 06:11:09 PDT
Some floating point intricacies here...patch follows.
Comment 1 Dominik Röttsches (drott) 2012-07-26 06:52:39 PDT
Created attachment 154644 [details]
Avoiding assertion failure.
Comment 2 Simon Hausmann 2012-07-26 08:45:40 PDT
Comment on attachment 154644 [details]
Avoiding assertion failure.

I think at the very least this deserves a comment in the code. But it is not clear from the ChangeLog why the sum of glyph advances would not be cleanly representable in float?

Are you suggesting that the advances are all zero? Could the reason for that be a differen one, i.e. lack of glyphs present in the given font for a given string?
Comment 3 Tony Chang 2012-07-26 11:21:25 PDT
Can you add a LayoutTest that triggers the ASSERT?  That may make it more clear what this change is doing.
Comment 4 Kenichi Ishibashi 2012-07-26 15:51:38 PDT
Comment on attachment 154644 [details]
Avoiding assertion failure.

View in context: https://bugs.webkit.org/attachment.cgi?id=154644&action=review

> Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp:351
> +            int nextX = currentX + static_cast<int>(m_harfbuzzRuns[i]->width());

Couldn't we use float instead casting int?
Comment 5 Simon Hausmann 2012-07-27 01:20:57 PDT
Comment on attachment 154644 [details]
Avoiding assertion failure.

I think that there is consensus that this needs either a test or more information how exactly this bug is triggered.
Comment 6 Dominik Röttsches (drott) 2012-07-27 01:28:08 PDT
(In reply to comment #5)
> (From update of attachment 154644 [details])
> I think that there is consensus that this needs either a test or more information how exactly this bug is triggered.

Well, I can trigger this if I select text like crazy back and forth with the mouse on a page that has complex text. Isn't that a great reproduction? ;-) What i see in this case is a mismatch of for example 85.999975 vs. 86 when entering the function. I will try to come up with a test case - not sure if I will succeed.

(In reply to comment #4)
> (From update of attachment 154644 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=154644&action=review
> 
> > Source/WebCore/platform/graphics/harfbuzz/ng/HarfBuzzShaper.cpp:351
> > +            int nextX = currentX + static_cast<int>(m_harfbuzzRuns[i]->width());
> 
> Couldn't we use float instead casting int?

For nextX and currentX you mean? Sure can, but I thought you had a perfomance reason or something for using int's all over the place here. Maybe that assumption was wrong?
Comment 7 Simon Hausmann 2012-07-27 01:56:38 PDT
(In reply to comment #6)
> (In reply to comment #5)
> > (From update of attachment 154644 [details] [details])
> > I think that there is consensus that this needs either a test or more information how exactly this bug is triggered.
> 
> Well, I can trigger this if I select text like crazy back and forth with the mouse on a page that has complex text. Isn't that a great reproduction? ;-) What i see in this case is a mismatch of for example 85.999975 vs. 86 when entering the function. I will try to come up with a test case - not sure if I will succeed.

Perhaps you can figure out which sequence of fonts and characters causes this with excessive debug output right before the ASSERT?
Comment 8 Kenichi Ishibashi 2012-07-27 02:59:25 PDT
(In reply to comment #6)
> (In reply to comment #5)
> For nextX and currentX you mean? Sure can, but I thought you had a perfomance reason or something for using int's all over the place here. Maybe that assumption was wrong?

Yes. Sorry for confusion, but when I started writing the code, I used ComplexControllerHarfBuzz::offsetForPosition() as a reference. I prefer accuracy than performance here.

As Tony and Simon suggest, please consider adding a test to the patch.
Comment 9 Dominik Röttsches (drott) 2012-07-27 07:24:33 PDT
Created attachment 154941 [details]
Mouse selection fuzzing test.

So, this is the best I could come up with. It fuzzes the mouse selection in a brute force way. This test crashes 100% reliably on my machine before the DRT timeout. Requires the Telugu Lohi font to be installed into the EFL DRT fonts directory like:
cp /usr/share/fonts/truetype/ttf-telugu-fonts/lohit_te.ttf WebKitBuild/Dependencies/Source/webkitgtk-test-fonts-0.0.3
Unfortunately, this doesn't really work as a regression test eventually. I also tried replaying exactly the same sequence of random numbers to reproduce the crash, but that doesn't work. Suggestions on how to exercise this code path in a different way are welcome.

Can we agree that there is a problem and change the types to float here - which makes sense not only for the assertion failure issue, but in general, for reasons of precision?
Comment 10 Kenichi Ishibashi 2012-07-27 07:49:00 PDT
(In reply to comment #9)

> Can we agree that there is a problem and change the types to float here - which makes sense not only for the assertion failure issue, but in general, for reasons of precision?

I have no objection if you describe why adding a test is difficult in ChangeLog.
Comment 11 Tony Chang 2012-07-27 11:11:05 PDT
(In reply to comment #10)
> (In reply to comment #9)
> 
> > Can we agree that there is a problem and change the types to float here - which makes sense not only for the assertion failure issue, but in general, for reasons of precision?
> 
> I have no objection if you describe why adding a test is difficult in ChangeLog.

It would also be OK to add this to WebKit/ManualTests (maybe with harfbuzz in the test name?).
Comment 12 Dominik Röttsches (drott) 2012-07-30 02:18:24 PDT
Created attachment 155236 [details]
Fix for assertion being hit, test case.
Comment 13 Kenichi Ishibashi 2012-07-30 02:53:54 PDT
Comment on attachment 155236 [details]
Fix for assertion being hit, test case.

View in context: https://bugs.webkit.org/attachment.cgi?id=155236&action=review

> ManualTests/harfbuzz-mouse-selection-crash.html:14
> +layoutTestController.waitUntilDone();

if (testRunner)
    testRunner.waitUntilDone();

?

How does this test finish successfully?

> ManualTests/harfbuzz-mouse-selection-crash.html:18
> +          var body = document.body;

We prefer 4-spaces indentation.

> ManualTests/harfbuzz-mouse-selection-crash.html:24
> +          eventSender.mouseMoveTo(xStart, yStart);

Please ensure evenSender exists.

> ManualTests/harfbuzz-mouse-selection-crash.html:29
> +/*            console.log("{x:"+randomX+",y:"+randomY+"} "); */

Please remove this.

> ManualTests/harfbuzz-mouse-selection-crash.html:40
> +<body onload="mouseSelection()"><!--

It would be better to include the following description as a part of the test (not as comment).
Comment 14 Shinya Kawanaka 2012-07-30 03:29:46 PDT
Comment on attachment 155236 [details]
Fix for assertion being hit, test case.

View in context: https://bugs.webkit.org/attachment.cgi?id=155236&action=review

>> ManualTests/harfbuzz-mouse-selection-crash.html:14
>> +layoutTestController.waitUntilDone();
> 
> if (testRunner)
>     testRunner.waitUntilDone();
> 
> ?
> 
> How does this test finish successfully?

if (testRunner)
-->
if (window.testRunner)
Comment 15 Dominik Röttsches (drott) 2012-07-30 04:30:46 PDT
Created attachment 155253 [details]
Fix for assertion being hit, test case, v2.
Comment 16 Dominik Röttsches (drott) 2012-07-30 04:33:55 PDT
(In reply to comment #13)
> (From update of attachment 155236 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=155236&action=review
> 
> > ManualTests/harfbuzz-mouse-selection-crash.html:14
> > +layoutTestController.waitUntilDone();
> 
> if (testRunner)
>     testRunner.waitUntilDone();

Changed to 
if (window.testRunner)
    testRunner.waitUntilDone();
  
> How does this test finish successfully?

Changed, now using a large enough number of iterations to reliably crash. Completes successfully if it doesn't crash. Note added in the description.

> > ManualTests/harfbuzz-mouse-selection-crash.html:18
> > +          var body = document.body;
> 
> We prefer 4-spaces indentation.

Done.


> > ManualTests/harfbuzz-mouse-selection-crash.html:24
> > +          eventSender.mouseMoveTo(xStart, yStart);
> 
> Please ensure evenSender exists.

Done, checking for window.eventSender

> > ManualTests/harfbuzz-mouse-selection-crash.html:29
> > +/*            console.log("{x:"+randomX+",y:"+randomY+"} "); */
> 
> Please remove this.

Done.

> > ManualTests/harfbuzz-mouse-selection-crash.html:40
> > +<body onload="mouseSelection()"><!--
> 
> It would be better to include the following description as a part of the test (not as comment).

Changed.
Comment 17 Tony Chang 2012-07-30 11:34:51 PDT
Comment on attachment 155253 [details]
Fix for assertion being hit, test case, v2.

This code change seems fine.

In the test, would it be possible to run the test until it crashes while recording the mouseMoveTo positions, then use the mouse positions to make a reliable ASSERT?  You could take the minimum number of mouse positions to hit the ASSERT and create an automated layout test for it.

It would also be OK to run such a layout test on all ports because it should still pass on all ports.

Hmm, I guess you need a certain font installed.  Does it repro with either lohit_hi.ttf, lohit_ta.ttf, or MuktiNarrow.ttf from ttf-indic-fonts-core?  We already use those fonts on Chromium Linux.

This manual test also seems OK.
Comment 18 Dominik Röttsches (drott) 2012-07-30 13:49:28 PDT
Tony, thanks for the r+ - comments below.

CC'ing Raphael, cq+? Kiitos paljon! :-)

(In reply to comment #17)
> (From update of attachment 155253 [details])
> This code change seems fine.
> 
> In the test, would it be possible to run the test until it crashes while recording the mouseMoveTo positions, then use the mouse positions to make a reliable ASSERT?  You could take the minimum number of mouse positions to hit the ASSERT and create an automated layout test for it.

As mentioned in comment 9, I tried recording and replaying, but that didn't do it for some unknown reason. :-(

> It would also be OK to run such a layout test on all ports because it should still pass on all ports.
> 
> Hmm, I guess you need a certain font installed.  Does it repro with either lohit_hi.ttf, lohit_ta.ttf, or MuktiNarrow.ttf from ttf-indic-fonts-core?  We already use those fonts on Chromium Linux.

I can give this a try, with a different text and these fonts and see what happens.
Comment 19 WebKit Review Bot 2012-07-30 16:13:42 PDT
Comment on attachment 155253 [details]
Fix for assertion being hit, test case, v2.

Clearing flags on attachment: 155253

Committed r124111: <http://trac.webkit.org/changeset/124111>
Comment 20 WebKit Review Bot 2012-07-30 16:13:48 PDT
All reviewed patches have been landed.  Closing bug.
Comment 21 Dominik Röttsches (drott) 2013-01-28 02:20:25 PST
*** Bug 40673 has been marked as a duplicate of this bug. ***