AztecEditor-Android: Crash when applying special comments on API 26/27

Applying a special comment (more, page) results in a crash on Oreo 8.1 (API 27)

Reproduced

  1. Start the demo app (in Calypso mode)
  2. Tap on the More button
  3. Observe the crash
    FATAL EXCEPTION: main
    Process: org.wordpress.aztec, PID: 6582
    java.lang.ArrayIndexOutOfBoundsException: length=39; index=-1
    at android.text.DynamicLayout.getBlockIndex(DynamicLayout.java:648)
    at android.widget.Editor.drawHardwareAccelerated(Editor.java:1703)
    at android.widget.Editor.onDraw(Editor.java:1672)
    at android.widget.TextView.onDraw(TextView.java:6882)
    at android.view.View.draw(View.java:19192)
    at android.view.View.updateDisplayListIfDirty(View.java:18142)
    at android.view.View.draw(View.java:18920)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
    at android.view.View.updateDisplayListIfDirty(View.java:18133)
    at android.view.View.draw(View.java:18920)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
    at android.view.View.draw(View.java:19195)
    at android.widget.ScrollView.draw(ScrollView.java:1739)
    at android.view.View.updateDisplayListIfDirty(View.java:18142)
    at android.view.View.draw(View.java:18920)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
    at android.view.View.updateDisplayListIfDirty(View.java:18133)
    at android.view.View.draw(View.java:18920)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
    at android.view.View.updateDisplayListIfDirty(View.java:18133)
    at android.view.View.draw(View.java:18920)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
    at android.view.View.updateDisplayListIfDirty(View.java:18133)
    at android.view.View.draw(View.java:18920)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
    at android.view.View.updateDisplayListIfDirty(View.java:18133)
    at android.view.View.draw(View.java:18920)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
    at android.view.View.updateDisplayListIfDirty(View.java:18133)
    at android.view.View.draw(View.java:18920)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4236)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4022)
    at android.view.View.draw(View.java:19195)
    at com.android.internal.policy.DecorView.draw(DecorView.java:788)
    at android.view.View.updateDisplayListIfDirty(View.java:18142)
    at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:669)
    at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:675)
    at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:783)
    at android.view.ViewRootImpl.draw(ViewRootImpl.java:2992)
    at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2806)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2359)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1392)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6752)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:911)
    at android.view.Choreographer.doCallbacks(Choreographer.java:723)
    at android.view.Choreographer.doFrame(Choreographer.java:658)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:897)
    at android.os.Handler.handleCallback(Handler.java:790)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6494)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

Tested

Emulator running API 27.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 17 (17 by maintainers)

Most upvoted comments

Fixed for now I Android 8.x via #801, closing

I’ve played around with the app and I can confirm what you mentioned above. Setting the HTML to the following will always crash:

[caption align="alignright"]<img src="https://examplebloge.files.wordpress.com/2017/02/3def4804-d9b5-11e6-88e6-d7d8864392e0.png">Caption[/caption]

Apparently, checking the code I can avoid this crash from happening when commenting out the following piece of code, which was introduced in commit 668dcfb

The code above is just one of many manifestations of the same error and it’s not limited to CaptionWatcher. It appears that in specific situations setSpan() throws that exception but it doesn’t in others. For the example above, adding a character before an image calls setSpan(<caption_span>, 1, span.end, span.flags). If I changed the start position to 0 it would not crash, however. Also changing the span to an inline span also works even with the original bounds.

I tried a couple of things, like removing some other spans, removing and then setting the caption span but nothing worked. The only thing that did work was setting a span on a separate Editable, like this:

val t = aztecText.text
t.setSpan(...)
aztecText.text = t

It could probably work for the other case with the special comment, we’d just need to find the specific call to setSpan().