Closed Bug 1832441 Opened 1 year ago Closed 1 year ago

Assertion failure: moved (Failed to put child back.), at /builds/worker/checkouts/gecko/accessible/generic/DocAccessible.cpp:2437

Categories

(Core :: Disability Access APIs, defect)

defect

Tracking

()

VERIFIED FIXED
115 Branch
Tracking Status
firefox-esr102 --- unaffected
firefox113 --- unaffected
firefox114 --- unaffected
firefox115 --- fixed

People

(Reporter: tsmith, Unassigned)

References

(Blocks 1 open bug, Regression)

Details

(Keywords: assertion, regression, testcase, Whiteboard: [bugmon:bisected,confirmed])

Attachments

(2 files)

Attached file testcase.html

Found while fuzzing m-c 20230509-169e7173a60f (--enable-debug --enable-fuzzing)

To reproduce via Grizzly Replay:

$ pip install fuzzfetch grizzly-framework
$ python -m fuzzfetch -d --fuzzing -n firefox
$ python -m grizzly.replay ./firefox/firefox testcase.html

Assertion failure: moved (Failed to put child back.), at /builds/worker/checkouts/gecko/accessible/generic/DocAccessible.cpp:2437

#0 0x7fa729f5f2ed in mozilla::a11y::DocAccessible::PutChildrenBack(nsTArray<RefPtr<mozilla::a11y::LocalAccessible>>*, unsigned int) /builds/worker/checkouts/gecko/accessible/generic/DocAccessible.cpp:2437:7
#1 0x7fa729f5e561 in mozilla::a11y::DocAccessible::UncacheChildrenInSubtree(mozilla::a11y::LocalAccessible*) /builds/worker/checkouts/gecko/accessible/generic/DocAccessible.cpp:2608:5
#2 0x7fa729f5e5e5 in mozilla::a11y::DocAccessible::UncacheChildrenInSubtree(mozilla::a11y::LocalAccessible*) /builds/worker/checkouts/gecko/accessible/generic/DocAccessible.cpp:2626:7
#3 0x7fa729f5e5e5 in mozilla::a11y::DocAccessible::UncacheChildrenInSubtree(mozilla::a11y::LocalAccessible*) /builds/worker/checkouts/gecko/accessible/generic/DocAccessible.cpp:2626:7
#4 0x7fa729f567dd in mozilla::a11y::DocAccessible::ContentRemoved(mozilla::a11y::LocalAccessible*) /builds/worker/checkouts/gecko/accessible/generic/DocAccessible.cpp:2190:3
#5 0x7fa729f528f2 in mozilla::a11y::DocAccessible::ContentRemoved(nsIContent*) /builds/worker/checkouts/gecko/accessible/generic/DocAccessible.cpp:2200:5
#6 0x7fa729f5539b in mozilla::a11y::DocAccessible::PruneOrInsertSubtree(nsIContent*) /builds/worker/checkouts/gecko/accessible/generic/DocAccessible.cpp
#7 0x7fa729f55665 in mozilla::a11y::DocAccessible::PruneOrInsertSubtree(nsIContent*) /builds/worker/checkouts/gecko/accessible/generic/DocAccessible.cpp:1436:11
#8 0x7fa729f55665 in mozilla::a11y::DocAccessible::PruneOrInsertSubtree(nsIContent*) /builds/worker/checkouts/gecko/accessible/generic/DocAccessible.cpp:1436:11
#9 0x7fa729f52b76 in mozilla::a11y::DocAccessible::ContentInserted(nsIContent*, nsIContent*) /builds/worker/checkouts/gecko/accessible/generic/DocAccessible.cpp:1251:9
#10 0x7fa728799764 in nsCSSFrameConstructor::ContentRangeInserted(nsIContent*, nsIContent*, nsCSSFrameConstructor::InsertionKind) /builds/worker/checkouts/gecko/layout/base/nsCSSFrameConstructor.cpp:6896:19
#11 0x7fa72875ad2d in mozilla::RestyleManager::ProcessRestyledFrames(nsStyleChangeList&) /builds/worker/checkouts/gecko/layout/base/RestyleManager.cpp:1607:25
#12 0x7fa728761a54 in mozilla::RestyleManager::DoProcessPendingRestyles(mozilla::ServoTraversalFlags) /builds/worker/checkouts/gecko/layout/base/RestyleManager.cpp:3179:9
#13 0x7fa728739960 in mozilla::RestyleManager::ProcessPendingRestyles() /builds/worker/checkouts/gecko/layout/base/RestyleManager.cpp:3264:3
#14 0x7fa728738eed in mozilla::PresShell::DoFlushPendingNotifications(mozilla::ChangesToFlush) /builds/worker/checkouts/gecko/layout/base/PresShell.cpp:4343:39
#15 0x7fa7268d9aa0 in FlushPendingNotifications /builds/worker/workspace/obj-build/dist/include/mozilla/PresShell.h:1461:5
#16 0x7fa7268d9aa0 in mozilla::EventStateManager::FlushLayout(nsPresContext*) /builds/worker/checkouts/gecko/dom/events/EventStateManager.cpp:5974:16
#17 0x7fa7268d6171 in mozilla::EventStateManager::PreHandleEvent(nsPresContext*, mozilla::WidgetEvent*, nsIFrame*, nsIContent*, nsEventStatus*, nsIContent*) /builds/worker/checkouts/gecko/dom/events/EventStateManager.cpp:795:7
#18 0x7fa72874dbad in mozilla::PresShell::EventHandler::DispatchEvent(mozilla::EventStateManager*, mozilla::WidgetEvent*, bool, nsEventStatus*, nsIContent*) /builds/worker/checkouts/gecko/layout/base/PresShell.cpp:8228:39
#19 0x7fa7287484c7 in mozilla::PresShell::EventHandler::HandleEventWithCurrentEventInfo(mozilla::WidgetEvent*, nsEventStatus*, bool, nsIContent*) /builds/worker/checkouts/gecko/layout/base/PresShell.cpp:8197:17
#20 0x7fa728747c82 in mozilla::PresShell::EventHandler::HandleEventUsingCoordinates(nsIFrame*, mozilla::WidgetGUIEvent*, nsEventStatus*, bool) /builds/worker/checkouts/gecko/layout/base/PresShell.cpp:7146:30
#21 0x7fa728746947 in mozilla::PresShell::EventHandler::HandleEvent(nsIFrame*, mozilla::WidgetGUIEvent*, bool, nsEventStatus*) /builds/worker/checkouts/gecko/layout/base/PresShell.cpp:6944:12
#22 0x7fa728745f24 in mozilla::PresShell::HandleEvent(nsIFrame*, mozilla::WidgetGUIEvent*, bool, nsEventStatus*) /builds/worker/checkouts/gecko/layout/base/PresShell.cpp:6887:23
#23 0x7fa72831aa7e in nsViewManager::DispatchEvent(mozilla::WidgetGUIEvent*, nsView*, nsEventStatus*) /builds/worker/checkouts/gecko/view/nsViewManager.cpp:678:18
#24 0x7fa72831a829 in nsView::HandleEvent(mozilla::WidgetGUIEvent*, bool) /builds/worker/checkouts/gecko/view/nsView.cpp:1149:9
#25 0x7fa728351017 in mozilla::widget::PuppetWidget::DispatchEvent(mozilla::WidgetGUIEvent*, nsEventStatus&) /builds/worker/checkouts/gecko/widget/PuppetWidget.cpp:351:37
#26 0x7fa72443a5ab in mozilla::layers::APZCCallbackHelper::DispatchWidgetEvent(mozilla::WidgetGUIEvent&) /builds/worker/checkouts/gecko/gfx/layers/apz/util/APZCCallbackHelper.cpp:506:21
#27 0x7fa727b25cc4 in DispatchWidgetEventViaAPZ /builds/worker/checkouts/gecko/dom/ipc/BrowserChild.cpp:1706:10
#28 0x7fa727b25cc4 in mozilla::dom::BrowserChild::HandleRealMouseButtonEvent(mozilla::WidgetMouseEvent const&, mozilla::layers::ScrollableLayerGuid const&, unsigned long const&) /builds/worker/checkouts/gecko/dom/ipc/BrowserChild.cpp:1669:3
#29 0x7fa727b2720b in mozilla::dom::BrowserChild::RecvRealMouseButtonEvent(mozilla::WidgetMouseEvent const&, mozilla::layers::ScrollableLayerGuid const&, unsigned long const&) /builds/worker/checkouts/gecko/dom/ipc/BrowserChild.cpp:1636:3
#30 0x7fa727b27378 in mozilla::dom::BrowserChild::RecvSynthMouseMoveEvent(mozilla::WidgetMouseEvent const&, mozilla::layers::ScrollableLayerGuid const&, unsigned long const&) /builds/worker/checkouts/gecko/dom/ipc/BrowserChild.cpp:1601:8
#31 0x7fa727c48035 in mozilla::dom::PBrowserChild::OnMessageReceived(IPC::Message const&) /builds/worker/workspace/obj-build/ipc/ipdl/PBrowserChild.cpp:5593:80
#32 0x7fa727cc8b20 in mozilla::dom::PContentChild::OnMessageReceived(IPC::Message const&) /builds/worker/workspace/obj-build/ipc/ipdl/PContentChild.cpp:8772:32
#33 0x7fa723d1826f in mozilla::ipc::MessageChannel::DispatchAsyncMessage(mozilla::ipc::ActorLifecycleProxy*, IPC::Message const&) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1800:25
#34 0x7fa723d14f22 in mozilla::ipc::MessageChannel::DispatchMessage(mozilla::ipc::ActorLifecycleProxy*, mozilla::UniquePtr<IPC::Message, mozilla::DefaultDelete<IPC::Message>>) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1725:9
#35 0x7fa723d15a54 in mozilla::ipc::MessageChannel::RunMessage(mozilla::ipc::ActorLifecycleProxy*, mozilla::ipc::MessageChannel::MessageTask&) /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1525:3
#36 0x7fa723d16d7f in mozilla::ipc::MessageChannel::MessageTask::Run() /builds/worker/checkouts/gecko/ipc/glue/MessageChannel.cpp:1623:14
#37 0x7fa7230bbda7 in mozilla::RunnableTask::Run() /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:555:16
#38 0x7fa7230b6faa in mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:879:26
#39 0x7fa7230b5a87 in mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:702:15
#40 0x7fa7230b5e05 in mozilla::TaskController::ProcessPendingMTTask(bool) /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:491:36
#41 0x7fa7230bf356 in operator() /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:218:37
#42 0x7fa7230bf356 in mozilla::detail::RunnableFunction<mozilla::TaskController::TaskController()::$_0>::Run() /builds/worker/checkouts/gecko/xpcom/threads/nsThreadUtils.h:548:5
#43 0x7fa7230d56fa in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/checkouts/gecko/xpcom/threads/nsThread.cpp:1239:16
#44 0x7fa7230dbd1d in NS_ProcessNextEvent(nsIThread*, bool) /builds/worker/checkouts/gecko/xpcom/threads/nsThreadUtils.cpp:479:10
#45 0x7fa723d1e215 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /builds/worker/checkouts/gecko/ipc/glue/MessagePump.cpp:85:21
#46 0x7fa723c3fdd1 in RunHandler /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:362:3
#47 0x7fa723c3fdd1 in MessageLoop::Run() /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:344:3
#48 0x7fa728382e08 in nsBaseAppShell::Run() /builds/worker/checkouts/gecko/widget/nsBaseAppShell.cpp:148:27
#49 0x7fa72a6133db in XRE_RunAppShell() /builds/worker/checkouts/gecko/toolkit/xre/nsEmbedFunctions.cpp:738:20
#50 0x7fa723d1f0c6 in mozilla::ipc::MessagePumpForChildProcess::Run(base::MessagePump::Delegate*) /builds/worker/checkouts/gecko/ipc/glue/MessagePump.cpp:235:9
#51 0x7fa723c3fdd1 in RunHandler /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:362:3
#52 0x7fa723c3fdd1 in MessageLoop::Run() /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:344:3
#53 0x7fa72a612ca2 in XRE_InitChildProcess(int, char**, XREChildData const*) /builds/worker/checkouts/gecko/toolkit/xre/nsEmbedFunctions.cpp:673:34
#54 0x557f038197a6 in content_process_main /builds/worker/checkouts/gecko/browser/app/../../ipc/contentproc/plugin-container.cpp:57:28
#55 0x557f038197a6 in main /builds/worker/checkouts/gecko/browser/app/nsBrowserApp.cpp:375:18
#56 0x7fa738429d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#57 0x7fa738429e3f in __libc_start_main csu/../csu/libc-start.c:392:3
#58 0x557f037f0a28 in _start (/home/user/workspace/browsers/m-c-20230510213701-fuzzing-debug/firefox-bin+0x58a28) (BuildId: 62943f22fb28e316d9baf2fbed5d93553833dc4a)
Flags: in-testsuite?
Attached file prefs.js

prefs.js file for bugmon

Keywords: regression
Regressed by: 1455416
Flags: needinfo?(nlapre)

Set release status flags based on info from the regressing bug 1455416

Verified bug as reproducible on mozilla-central 20230511040639-da13ef752e22.
The bug appears to have been introduced in the following build range:

Start: a7a328c86d5bab5e73de7abf526304c96addccc3 (20230508201033)
End: cc7b419c4bbea93ee3364cf6749a0d6dcbb0a991 (20230508213519)
Pushlog: https://hg.mozilla.org/integration/autoland/pushloghtml?fromchange=a7a328c86d5bab5e73de7abf526304c96addccc3&tochange=cc7b419c4bbea93ee3364cf6749a0d6dcbb0a991

Whiteboard: [bugmon:bisected,confirmed]

I've investigated this and I think I know what's going on. Consider this case:

<script>
window.requestIdleCallback(() => {
  document.documentElement.style.display = 'none'
})
document.addEventListener('DOMContentLoaded', () => {
  let button = document.createElement('button')
  button.setAttribute('id', 'b')
  document.getElementById('c').appendChild(button)
  document.getElementById('a').setAttribute('aria-owns', 'b')
})
</script>
<a id="a">
<hr id="c">

We aren't able to add a child to a LeafAccessible like <hr> without doing it through javascript, as we do in appendChild here. But appendChild seems specified to allow it, so I think that's valid. Once we do that, we add the aria-owns to hoist b up to be a sibling of c. When we set display to none, we find ourselves removing the accessibles and calling UncacheChildrenInSubtree on a, which aria-owns the button. We end up trying to move the button to where it would be without aria-owns: a child of the hr. However, a LeafAccessible is not allowed children, so we don't move it. Hence the failed assertion (we didn't move the acc).

This is an unfortunate situation to be in. I think it makes sense to make the button a sibling of the hr. That is, we could make moving accs siblings of the target element if that element is not a suitable parent for the moving acc. I think maybe we can fix this by messing with the loop in PutChildrenBack to ensure that we have a valid container to move the previously-owned child to, before we try to move it.

Flags: needinfo?(nlapre)

I think it makes sense to make the button a sibling of the hr.

Or we could just remove it from the tree, since it wouldn't be allowed in normal tree creation anyway. For example:
data:text/html,<hr id="hr"><script>hr.append(document.createElement("button"));</script>
The button isn't in the a11y tree at all because the hr refuses it as a child. So, when we "put children back", we can reasonably put this child back in the void. :)

Setting 115 to Fixed as the regressor Bug 1455416 was backed out of central

Fixed by backout.

Status: NEW → RESOLVED
Closed: 1 year ago
Resolution: --- → FIXED

Verified bug as fixed on rev mozilla-central 20230519041011-d97636946466.

Status: RESOLVED → VERIFIED
Target Milestone: --- → 115 Branch
Keywords: bugmon
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: