Closed Bug 1755770 Opened 2 years ago Closed 2 years ago

Assertion failure: aMax >= aMin (clamped(): aMax must be greater than or equal to aMin), at /builds/worker/workspace/obj-build/dist/include/nsAlgorithm.h:37

Categories

(Core :: SVG, defect)

x86_64
Linux
defect

Tracking

()

VERIFIED FIXED
100 Branch
Tracking Status
firefox-esr91 --- unaffected
firefox97 --- unaffected
firefox98 --- wontfix
firefox99 --- wontfix
firefox100 --- verified

People

(Reporter: jkratzer, Assigned: dshin)

References

(Blocks 1 open bug, Regression)

Details

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

Attachments

(2 files)

Testcase found while fuzzing mozilla-central rev ae6487188557 (built with: --enable-debug --enable-fuzzing).

Testcase can be reproduced using the following commands:

$ pip install fuzzfetch grizzly-framework
$ python -m fuzzfetch --build ae6487188557 --debug --fuzzing -n firefox
$ python -m grizzly.replay ./firefox/firefox testcase.html
Assertion failure: aMax >= aMin (clamped(): aMax must be greater than or equal to aMin), at /builds/worker/workspace/obj-build/dist/include/nsAlgorithm.h:37

    ==3416627==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f5b1e519584 bp 0x7ffdb5064df0 sp 0x7ffdb5064be0 T3416627)
    ==3416627==The signal is caused by a WRITE memory access.
    ==3416627==Hint: address points to the zero page.
        #0 0x7f5b1e519584 in mozilla::SVGTextFrame::TransformFramePointToTextChild(mozilla::gfx::PointTyped<mozilla::gfx::UnknownUnits, float> const&, nsIFrame const*) /layout/svg/SVGTextFrame.cpp
        #1 0x7f5b1e26578e in TransformGfxPointFromAncestor(mozilla::RelativeTo, mozilla::gfx::PointTyped<mozilla::gfx::UnknownUnits, float> const&, mozilla::RelativeTo, mozilla::Maybe<mozilla::gfx::Matrix4x4TypedFlagged<mozilla::gfx::UnknownUnits, mozilla::gfx::UnknownUnits> >&, mozilla::gfx::PointTyped<mozilla::gfx::UnknownUnits, float>*) /layout/base/nsLayoutUtils.cpp:2278:19
        #2 0x7f5b1e265419 in nsLayoutUtils::TransformPoints(mozilla::RelativeTo, mozilla::RelativeTo, unsigned int, mozilla::gfx::PointTyped<mozilla::CSSPixel, float>*) /layout/base/nsLayoutUtils.cpp:2382:10
        #3 0x7f5b1e1b7d59 in mozilla::TransformPoints(nsINode*, mozilla::dom::TextOrElementOrDocument const&, unsigned int, mozilla::gfx::PointTyped<mozilla::CSSPixel, float>*, mozilla::dom::ConvertCoordinateOptions const&, mozilla::dom::CallerType, mozilla::ErrorResult&) /layout/base/GeometryUtils.cpp:425:39
        #4 0x7f5b1e1b7ec6 in mozilla::ConvertRectFromNode(nsINode*, mozilla::dom::DOMRectReadOnly&, mozilla::dom::TextOrElementOrDocument const&, mozilla::dom::ConvertCoordinateOptions const&, mozilla::dom::CallerType, mozilla::ErrorResult&) /layout/base/GeometryUtils.cpp:469:3
        #5 0x7f5b1b1df943 in nsINode::ConvertRectFromNode(mozilla::dom::DOMRectReadOnly&, mozilla::dom::TextOrElementOrDocument const&, mozilla::dom::ConvertCoordinateOptions const&, mozilla::dom::CallerType, mozilla::ErrorResult&) /dom/base/nsINode.cpp:1327:10
        #6 0x7f5b1bca96c5 in mozilla::dom::Text_Binding::convertRectFromNode(JSContext*, JS::Handle<JSObject*>, void*, JSJitMethodCallArgs const&) /builds/worker/workspace/obj-build/dom/bindings/TextBinding.cpp:490:74
        #7 0x7f5b1c533fb8 in bool mozilla::dom::binding_detail::GenericMethod<mozilla::dom::binding_detail::NormalThisPolicy, mozilla::dom::binding_detail::ThrowExceptions>(JSContext*, unsigned int, JS::Value*) /dom/bindings/BindingUtils.cpp:3306:13
        #8 0x7f5b200901cf in CallJSNative(JSContext*, bool (*)(JSContext*, unsigned int, JS::Value*), js::CallReason, JS::CallArgs const&) /js/src/vm/Interpreter.cpp:425:13
        #9 0x7f5b2008f8cd in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /js/src/vm/Interpreter.cpp:512:12
        #10 0x7f5b200913ae in InternalCall(JSContext*, js::AnyInvokeArgs const&, js::CallReason) /js/src/vm/Interpreter.cpp:572:10
        #11 0x7f5b20086c66 in CallFromStack /js/src/vm/Interpreter.cpp:576:10
        #12 0x7f5b20086c66 in Interpret(JSContext*, js::RunState&) /js/src/vm/Interpreter.cpp:3309:16
        #13 0x7f5b2007db63 in js::RunScript(JSContext*, js::RunState&) /js/src/vm/Interpreter.cpp:394:13
        #14 0x7f5b2008f7c8 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /js/src/vm/Interpreter.cpp:544:13
        #15 0x7f5b200913ae in InternalCall(JSContext*, js::AnyInvokeArgs const&, js::CallReason) /js/src/vm/Interpreter.cpp:572:10
        #16 0x7f5b200915b1 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason) /js/src/vm/Interpreter.cpp:589:8
        #17 0x7f5b201c13b1 in JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) /js/src/vm/CallAndConstruct.cpp:117:10
        #18 0x7f5b1c2531d7 in mozilla::dom::EventListener::HandleEvent(mozilla::dom::BindingCallContext&, JS::Handle<JS::Value>, mozilla::dom::Event&, mozilla::ErrorResult&) /builds/worker/workspace/obj-build/dom/bindings/EventListenerBinding.cpp:62:8
        #19 0x7f5b1ca3a4d6 in void mozilla::dom::EventListener::HandleEvent<mozilla::dom::EventTarget*>(mozilla::dom::EventTarget* const&, mozilla::dom::Event&, mozilla::ErrorResult&, char const*, mozilla::dom::CallbackObject::ExceptionHandling, JS::Realm*) /builds/worker/workspace/obj-build/dist/include/mozilla/dom/EventListenerBinding.h:65:12
        #20 0x7f5b1ca3a25a in mozilla::EventListenerManager::HandleEventSubType(mozilla::EventListenerManager::Listener*, mozilla::dom::Event*, mozilla::dom::EventTarget*) /dom/events/EventListenerManager.cpp:1308:43
        #21 0x7f5b1ca3af59 in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, nsEventStatus*, bool) /dom/events/EventListenerManager.cpp:1505:17
        #22 0x7f5b1ca2ff64 in HandleEvent /dom/events/EventListenerManager.h:395:5
        #23 0x7f5b1ca2ff64 in mozilla::EventTargetChainItem::HandleEvent(mozilla::EventChainPostVisitor&, mozilla::ELMCreationDetector&) /dom/events/EventDispatcher.cpp:348:17
        #24 0x7f5b1ca2f487 in mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) /dom/events/EventDispatcher.cpp:550:16
        #25 0x7f5b1ca31ce8 in mozilla::EventDispatcher::Dispatch(nsISupports*, nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*) /dom/events/EventDispatcher.cpp:1085:11
        #26 0x7f5b1e246923 in nsDocumentViewer::LoadComplete(nsresult) /layout/base/nsDocumentViewer.cpp:1084:7
        #27 0x7f5b1f87cd54 in nsDocShell::EndPageLoad(nsIWebProgress*, nsIChannel*, nsresult) /docshell/base/nsDocShell.cpp:6403:20
        #28 0x7f5b1f87c843 in nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, nsresult) /docshell/base/nsDocShell.cpp:5792:7
        #29 0x7f5b1f87d6df in non-virtual thunk to nsDocShell::OnStateChange(nsIWebProgress*, nsIRequest*, unsigned int, nsresult) /docshell/base/nsDocShell.cpp
        #30 0x7f5b1a5a5d8c in nsDocLoader::DoFireOnStateChange(nsIWebProgress*, nsIRequest*, int&, nsresult) /uriloader/base/nsDocLoader.cpp:1377:3
        #31 0x7f5b1a5a531a in nsDocLoader::doStopDocumentLoad(nsIRequest*, nsresult) /uriloader/base/nsDocLoader.cpp:975:14
        #32 0x7f5b1a5a36a0 in nsDocLoader::DocLoaderIsEmpty(bool, mozilla::Maybe<nsresult> const&) /uriloader/base/nsDocLoader.cpp:794:9
        #33 0x7f5b1a5a485d in nsDocLoader::OnStopRequest(nsIRequest*, nsresult) /uriloader/base/nsDocLoader.cpp:677:5
        #34 0x7f5b1f89e5bd in nsDocShell::OnStopRequest(nsIRequest*, nsresult) /docshell/base/nsDocShell.cpp:13715:23
        #35 0x7f5b192f6f9a in mozilla::net::nsLoadGroup::NotifyRemovalObservers(nsIRequest*, nsresult) /netwerk/base/nsLoadGroup.cpp:614:22
        #36 0x7f5b192f8583 in mozilla::net::nsLoadGroup::RemoveRequest(nsIRequest*, nsISupports*, nsresult) /netwerk/base/nsLoadGroup.cpp:518:10
        #37 0x7f5b1af790b5 in mozilla::dom::Document::DoUnblockOnload() /dom/base/Document.cpp:11549:18
        #38 0x7f5b1af43c13 in mozilla::dom::Document::UnblockOnload(bool) /dom/base/Document.cpp:11479:9
        #39 0x7f5b1af5fadb in mozilla::dom::Document::DispatchContentLoadedEvents() /dom/base/Document.cpp:7994:3
        #40 0x7f5b1b010e8b in applyImpl<mozilla::dom::Document, void (mozilla::dom::Document::*)()> /builds/worker/workspace/obj-build/dist/include/nsThreadUtils.h:1147:12
        #41 0x7f5b1b010e8b in apply<mozilla::dom::Document, void (mozilla::dom::Document::*)()> /builds/worker/workspace/obj-build/dist/include/nsThreadUtils.h:1153:12
        #42 0x7f5b1b010e8b in mozilla::detail::RunnableMethodImpl<mozilla::dom::Document*, void (mozilla::dom::Document::*)(), true, (mozilla::RunnableKind)0>::Run() /builds/worker/workspace/obj-build/dist/include/nsThreadUtils.h:1200:13
        #43 0x7f5b190fa042 in mozilla::SchedulerGroup::Runnable::Run() /xpcom/threads/SchedulerGroup.cpp:140:20
        #44 0x7f5b1912ae6e in mozilla::RunnableTask::Run() /xpcom/threads/TaskController.cpp:467:16
        #45 0x7f5b19104096 in mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /xpcom/threads/TaskController.cpp:770:26
        #46 0x7f5b19102d58 in mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /xpcom/threads/TaskController.cpp:606:15
        #47 0x7f5b19102fd3 in mozilla::TaskController::ProcessPendingMTTask(bool) /xpcom/threads/TaskController.cpp:390:36
        #48 0x7f5b1912e316 in operator() /xpcom/threads/TaskController.cpp:124:37
        #49 0x7f5b1912e316 in mozilla::detail::RunnableFunction<mozilla::TaskController::InitializeInternal()::$_0>::Run() /builds/worker/workspace/obj-build/dist/include/nsThreadUtils.h:531:5
        #50 0x7f5b19118fe3 in nsThread::ProcessNextEvent(bool, bool*) /xpcom/threads/nsThread.cpp:1171:16
        #51 0x7f5b191204fa in NS_ProcessNextEvent(nsIThread*, bool) /xpcom/threads/nsThreadUtils.cpp:467:10
        #52 0x7f5b19bcca96 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /ipc/glue/MessagePump.cpp:85:21
        #53 0x7f5b19ae9bc7 in MessageLoop::RunInternal() /ipc/chromium/src/base/message_loop.cc:331:10
        #54 0x7f5b19ae9ad2 in RunHandler /ipc/chromium/src/base/message_loop.cc:324:3
        #55 0x7f5b19ae9ad2 in MessageLoop::Run() /ipc/chromium/src/base/message_loop.cc:306:3
        #56 0x7f5b1dea1d98 in nsBaseAppShell::Run() /widget/nsBaseAppShell.cpp:137:27
        #57 0x7f5b1ff13923 in XRE_RunAppShell() /toolkit/xre/nsEmbedFunctions.cpp:878:20
        #58 0x7f5b19bcd98a in mozilla::ipc::MessagePumpForChildProcess::Run(base::MessagePump::Delegate*) /ipc/glue/MessagePump.cpp:235:9
        #59 0x7f5b19ae9bc7 in MessageLoop::RunInternal() /ipc/chromium/src/base/message_loop.cc:331:10
        #60 0x7f5b19ae9ad2 in RunHandler /ipc/chromium/src/base/message_loop.cc:324:3
        #61 0x7f5b19ae9ad2 in MessageLoop::Run() /ipc/chromium/src/base/message_loop.cc:306:3
        #62 0x7f5b1ff12f5c in XRE_InitChildProcess(int, char**, XREChildData const*) /toolkit/xre/nsEmbedFunctions.cpp:715:34
        #63 0x558ab9594d37 in content_process_main /browser/app/../../ipc/contentproc/plugin-container.cpp:57:28
        #64 0x558ab9594d37 in main /browser/app/nsBrowserApp.cpp:327:18
        #65 0x7f5b2e02e0b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
        #66 0x558ab95704bc in _start (/home/jkratzer/builds/mc-debug/firefox-bin+0x154bc)
    
    UndefinedBehaviorSanitizer can not provide additional info.
    SUMMARY: UndefinedBehaviorSanitizer: SEGV /layout/svg/SVGTextFrame.cpp in mozilla::SVGTextFrame::TransformFramePointToTextChild(mozilla::gfx::PointTyped<mozilla::gfx::UnknownUnits, float> const&, nsIFrame const*)
    ==3416627==ABORTING
Attached file Testcase

Bugmon Analysis
Verified bug as reproducible on mozilla-central 20220216214005-d0676cb0864b.
The bug appears to have been introduced in the following build range:

Start: cef9ae46c12502db5397009a26ee7c303dd5d8a3 (20220128165222)
End: 68f4953185a3165f6114c3e2c9af9fcf7c009c33 (20220128171420)
Pushlog: https://hg.mozilla.org/integration/autoland/pushloghtml?fromchange=cef9ae46c12502db5397009a26ee7c303dd5d8a3&tochange=68f4953185a3165f6114c3e2c9af9fcf7c009c33

Whiteboard: [bugmon:confirm] → [bugmon:bisected,confirmed]
Attachment #9264244 - Attachment mime type: text/plain → text/html

So the line of code here is:

      pointInRun.x =
          clamped(pointInRunUserSpace.x, runRect.X(), runRect.XMost());

...where, for our rect types, XMost() is just shorthand for X() + Width().

The problem here is that runRect has a negative width, so XMost() is lower than X(), which means this clamped() invocation violates its "max value must be larger than min value" assertion.

Just before the fatal assertion-failure, I see this non-fatal assertion logging as well:

###!!! ASSERTION: bad inline size: 'reflowOutput.ISize(lineWM) >= 0', file mozilla/layout/generic/nsLineLayout.cpp:950

So it looks like we've triggered nscoord integer overflow and have some frames that end up with negative sizes (which is where this negative-width rect ends up coming from).

This is not super surprising; the testcase does indeed use bogus-large sizes, via letter-spacing: 65535pc (which is 1,048,560px; and that amount of space gets inserted between each letter in the testcase's generated text node, I think).

So, bottom line: this fatal assertion-failure is just a downstream effect of the fact that bogus-huge-content can cause negative-sized frames via integer overflow, and I guess we should adjust these clamped() calls to avoid passing in a possibly-lower XMost() value, by e.g. checking if the rect's width is negative and bypassing the clamped() call (and just using runRect.x) if it is. This will allow us to gracefully proceed without aborting.

[Rather than fixing this, I'm going to reserve this bug as a good-first-bug for a new team member who's starting soon -- I'll self-assign for now, and will reassign in a few weeks.]

Assignee: nobody → dholbert
Severity: -- → S3

When fixing this, we should be sure to include the testcase as a crashtest in layout/svg/crashtests (with the test file using this bug number as the filename, as with neighboring testts; and with the filename referenced in crashtests.list in that folder so that it gets run).

There's one other interesting wrinkle here: this bug doesn't reproduce (I don't get a fatal assertion) if I load the test locally (as a file:/// URI) -- it only reproduces if I load the attachment from Bugzilla, or from a local HTTP server (e.g. python2 -m SimpleHTTPServer 8000 in the same directory where I've placed the file).

I'm not sure precisely why that is, but it means we should double-check that the issue actually reproduces with the crashtest. If the crashtest needs to be served over HTTP in order to reproduce the issue, then we can make that happen with the HTTP magic word at the beginning of the crashtests.list line, like in https://searchfox.org/mozilla-central/rev/48c71577cbb4ce5a218cf4385aff1ff244dc4432/image/test/crashtests/crashtests.list#68

:dholbert, since this bug contains a bisection range, could you fill (if possible) the regressed_by field?
For more information, please visit auto_nag documentation.

Flags: needinfo?(dholbert)

Sure; given that this involves SVG Text, this was presumably a regression from bug 1746794 (that's the only thing SVG-text-related in the regression-range).

Though it's likely not a regression in the sense of being a bug in that patch, but rather it seems like it was a preexisting issue that was uncovered (or became more-easily-exercized-by-our-fuzzers) via that patch.

Flags: needinfo?(dholbert)
Regressed by: 1746794

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

Has Regression Range: --- → yes

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

(In reply to Daniel Holbert [:dholbert] from comment #3)

[Rather than fixing this, I'm going to reserve this bug as a good-first-bug for a new team member who's starting soon -- I'll self-assign for now, and will reassign in a few weeks.]

Handing this off to David Shin - David, see comment 3 and comment 4 for some analysis here.

Assignee: dholbert → dshin
Attachment #9269687 - Attachment description: Bug 1755770 - Ensure `TextRenderedRun::GetRunUserSpaceRect` casts flaot to int without invoking Undefined Behavior r=dholbert → Bug 1755770 - Ensure `TextRenderedRun::GetRunUserSpaceRect` casts float to int without invoking Undefined Behavior r=dholbert
Pushed by dholbert@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/6f139fed188c
Ensure `TextRenderedRun::GetRunUserSpaceRect` casts float to int without invoking Undefined Behavior r=dholbert
Status: NEW → RESOLVED
Closed: 2 years ago
Resolution: --- → FIXED
Target Milestone: --- → 100 Branch

Bugmon Analysis
Verified bug as fixed on rev mozilla-central 20220329095604-f5e1d3d4bb8e.
Removing bugmon keyword as no further action possible. Please review the bug and re-add the keyword for further analysis.

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

Attachment

General

Created:
Updated:
Size: