Closed Bug 1935714 Opened 2 months ago Closed 2 months ago

Assertion failure: aLength <= kMax (string is too large), at /builds/worker/checkouts/gecko/xpcom/string/nsTStringRepr.h:89

Categories

(Core :: XPCOM, defect)

defect

Tracking

()

VERIFIED FIXED
135 Branch
Tracking Status
firefox-esr115 --- wontfix
firefox-esr128 --- wontfix
firefox133 --- wontfix
firefox134 --- wontfix
firefox135 --- verified

People

(Reporter: tsmith, Assigned: nika)

References

Details

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

Crash Data

Attachments

(4 files)

Attached file testcase.html

Found while fuzzing 20241205-9dfed8478876 (--enable-address-sanitizer --enable-fuzzing)

To reproduce via Grizzly Replay:

$ pip install fuzzfetch grizzly-framework --upgrade
$ python -m fuzzfetch -a --fuzzing -n firefox
$ python -m grizzly.replay.bugzilla ./firefox/firefox <bugid>

Assertion failure: aLength <= kMax (string is too large), at /builds/worker/checkouts/gecko/xpcom/string/nsTStringRepr.h:89

#0 0x7c77e81b3967 in nsTStringLengthStorage /builds/worker/checkouts/gecko/xpcom/string/nsTStringRepr.h:89:5
#1 0x7c77e81b3967 in nsTSubstring<char>::Adopt(char*, unsigned long) /builds/worker/checkouts/gecko/xpcom/string/nsTSubstring.cpp:623:20
#2 0x7c77e8399809 in nsStringInputStream::AdoptData(char*, int) /builds/worker/checkouts/gecko/xpcom/io/nsStringStream.cpp:189:10
#3 0x7c77e839c37a in NS_NewByteInputStream(nsIInputStream**, mozilla::Span<char const, 18446744073709551615ul>, nsAssignmentType) /builds/worker/checkouts/gecko/xpcom/io/nsStringStream.cpp:509:20
#4 0x7c77eef9078d in mozilla::dom::GetBufferDataAsStream(mozilla::Vector<unsigned char, 0ul, mozilla::MallocAllocPolicy>&&, nsIInputStream**, unsigned long*, nsTSubstring<char>&, nsTSubstring<char>&) /builds/worker/checkouts/gecko/dom/fetch/BodyExtractor.cpp:36:17
#5 0x7c77eef901b4 in mozilla::dom::BodyExtractor<mozilla::dom::TypedArray<JS::ArrayBuffer> const>::GetAsStream(nsIInputStream**, unsigned long*, nsTSubstring<char>&, nsTSubstring<char>&) const /builds/worker/checkouts/gecko/dom/fetch/BodyExtractor.cpp:55:10
#6 0x7c77f25333d6 in mozilla::dom::XMLHttpRequestMainThread::SendInternal(mozilla::dom::BodyExtractorBase const*, bool, mozilla::ErrorResult&) /builds/worker/checkouts/gecko/dom/xhr/XMLHttpRequestMainThread.cpp:3162:18
#7 0x7c77f25327b6 in mozilla::dom::XMLHttpRequestMainThread::Send(mozilla::dom::Nullable<mozilla::dom::DocumentOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrURLSearchParamsOrUSVString> const&, mozilla::ErrorResult&) /builds/worker/checkouts/gecko/dom/xhr/XMLHttpRequestMainThread.cpp:3039:5
#8 0x7c77ed8c8ee9 in mozilla::dom::XMLHttpRequest_Binding::send(JSContext*, JS::Handle<JSObject*>, void*, JSJitMethodCallArgs const&) /builds/worker/workspace/obj-build/dom/bindings/./XMLHttpRequestBinding.cpp:1663:24
#9 0x7c77ee0786ef in bool mozilla::dom::binding_detail::GenericMethod<mozilla::dom::binding_detail::NormalThisPolicy, mozilla::dom::binding_detail::ThrowExceptions>(JSContext*, unsigned int, JS::Value*) /builds/worker/checkouts/gecko/dom/bindings/BindingUtils.cpp:3290:13
#10 0x7c77f4affc47 in CallJSNative /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:532:13
#11 0x7c77f4affc47 in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:628:12
#12 0x7c77f4b1ee88 in InternalCall /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:695:10
#13 0x7c77f4b1ee88 in CallFromStack /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:700:10
#14 0x7c77f4b1ee88 in js::Interpret(JSContext*, js::RunState&) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:3338:16
#15 0x7c77f4afe9b8 in MaybeEnterInterpreterTrampoline /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:433:10
#16 0x7c77f4afe9b8 in js::RunScript(JSContext*, js::RunState&) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:502:13
#17 0x7c77f4affdbd in js::InternalCallOrConstruct(JSContext*, JS::CallArgs const&, js::MaybeConstruct, js::CallReason) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:660:13
#18 0x7c77f4b01b01 in InternalCall /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:695:10
#19 0x7c77f4b01b01 in js::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, js::AnyInvokeArgs const&, JS::MutableHandle<JS::Value>, js::CallReason) /builds/worker/checkouts/gecko/js/src/vm/Interpreter.cpp:727:8
#20 0x7c77f4c2b88a in JS::Call(JSContext*, JS::Handle<JS::Value>, JS::Handle<JS::Value>, JS::HandleValueArray const&, JS::MutableHandle<JS::Value>) /builds/worker/checkouts/gecko/js/src/vm/CallAndConstruct.cpp:119:10
#21 0x7c77edba5405 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
#22 0x7c77eeee989b 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
#23 0x7c77eeee8f4d in mozilla::EventListenerManager::HandleEventSingleListener(mozilla::EventListenerManager::Listener*, nsAtom*, mozilla::WidgetEvent*, mozilla::dom::Event*, mozilla::dom::EventTarget*, bool) /builds/worker/checkouts/gecko/dom/events/EventListenerManager.cpp:1340:43
#24 0x7c77eeeeb10a in mozilla::EventListenerManager::HandleEventWithListenerArray(mozilla::EventListenerManager::ListenerArray*, nsAtom*, mozilla::EventMessage, nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, bool) /builds/worker/checkouts/gecko/dom/events/EventListenerManager.cpp:1663:12
#25 0x7c77eeeea027 in mozilla::EventListenerManager::HandleEventInternal(nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event**, mozilla::dom::EventTarget*, nsEventStatus*, bool) /builds/worker/checkouts/gecko/dom/events/EventListenerManager.cpp:1560:35
#26 0x7c77eeed2a69 in HandleEvent /builds/worker/workspace/obj-build/dist/include/mozilla/EventListenerManager.h:466:5
#27 0x7c77eeed2a69 in mozilla::EventTargetChainItem::HandleEvent(mozilla::EventChainPostVisitor&, mozilla::ELMCreationDetector&) /builds/worker/checkouts/gecko/dom/events/EventDispatcher.cpp:365:17
#28 0x7c77eeed0518 in mozilla::EventTargetChainItem::HandleEventTargetChain(nsTArray<mozilla::EventTargetChainItem>&, mozilla::EventChainPostVisitor&, mozilla::EventDispatchingCallback*, mozilla::ELMCreationDetector&) /builds/worker/checkouts/gecko/dom/events/EventDispatcher.cpp:606:16
#29 0x7c77eeed7088 in mozilla::EventDispatcher::Dispatch(mozilla::dom::EventTarget*, nsPresContext*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsEventStatus*, mozilla::EventDispatchingCallback*, nsTArray<mozilla::dom::EventTarget*>*) /builds/worker/checkouts/gecko/dom/events/EventDispatcher.cpp:1221:11
#30 0x7c77eeede450 in mozilla::EventDispatcher::DispatchDOMEvent(mozilla::dom::EventTarget*, mozilla::WidgetEvent*, mozilla::dom::Event*, nsPresContext*, nsEventStatus*) /builds/worker/checkouts/gecko/dom/events/EventDispatcher.cpp
#31 0x7c77ec61d427 in nsINode::DispatchEvent(mozilla::dom::Event&, mozilla::dom::CallerType, mozilla::ErrorResult&) /builds/worker/checkouts/gecko/dom/base/nsINode.cpp:1479:17
#32 0x7c77ebe33097 in nsContentUtils::DispatchEvent(mozilla::dom::Document*, mozilla::dom::EventTarget*, nsTSubstring<char16_t> const&, mozilla::CanBubble, mozilla::Cancelable, mozilla::Composed, mozilla::Trusted, bool*, mozilla::ChromeOnlyDispatch) /builds/worker/checkouts/gecko/dom/base/nsContentUtils.cpp:4759:29
#33 0x7c77ebe32de0 in nsContentUtils::DispatchTrustedEvent(mozilla::dom::Document*, mozilla::dom::EventTarget*, nsTSubstring<char16_t> const&, mozilla::CanBubble, mozilla::Cancelable, mozilla::Composed, bool*) /builds/worker/checkouts/gecko/dom/base/nsContentUtils.cpp:4725:10
#34 0x7c77ec201f91 in mozilla::dom::Document::DispatchContentLoadedEvents() /builds/worker/checkouts/gecko/dom/base/Document.cpp:8377:3
#35 0x7c77ec319ddf in operator()<> /builds/worker/workspace/obj-build/dist/include/nsThreadUtils.h:1085:18
#36 0x7c77ec319ddf in __invoke_impl<void, (lambda at /builds/worker/workspace/obj-build/dist/include/nsThreadUtils.h:1084:9)> /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/invoke.h:60:14
#37 0x7c77ec319ddf in __invoke<(lambda at /builds/worker/workspace/obj-build/dist/include/nsThreadUtils.h:1084:9)> /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/invoke.h:95:14
#38 0x7c77ec319ddf in __apply_impl<(lambda at /builds/worker/workspace/obj-build/dist/include/nsThreadUtils.h:1084:9), std::tuple<> &> /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/tuple:1678:14
#39 0x7c77ec319ddf in apply<(lambda at /builds/worker/workspace/obj-build/dist/include/nsThreadUtils.h:1084:9), std::tuple<> &> /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/tuple:1687:14
#40 0x7c77ec319ddf in apply<mozilla::dom::Document, void (mozilla::dom::Document::*)()> /builds/worker/workspace/obj-build/dist/include/nsThreadUtils.h:1083:12
#41 0x7c77ec319ddf 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:1134:13
#42 0x7c77e8412c7a in mozilla::RunnableTask::Run() /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:688:16
#43 0x7c77e83fa518 in mozilla::TaskController::RunTask(mozilla::Task*) /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:215:19
#44 0x7c77e840165d in mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:1015:20
#45 0x7c77e83ff198 in mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:838:15
#46 0x7c77e83ff7b6 in mozilla::TaskController::ProcessPendingMTTask(bool) /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:624:36
#47 0x7c77e8427611 in operator() /builds/worker/checkouts/gecko/xpcom/threads/TaskController.cpp:336:37
#48 0x7c77e8427611 in mozilla::detail::RunnableFunction<mozilla::TaskController::TaskController()::$_0>::Run() /builds/worker/checkouts/gecko/xpcom/threads/nsThreadUtils.h:548:5
#49 0x7c77e844799b in nsThread::ProcessNextEvent(bool, bool*) /builds/worker/checkouts/gecko/xpcom/threads/nsThread.cpp:1159:16
#50 0x7c77e8452498 in NS_ProcessNextEvent(nsIThread*, bool) /builds/worker/checkouts/gecko/xpcom/threads/nsThreadUtils.cpp:480:10
#51 0x7c77e9a2e18e in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /builds/worker/checkouts/gecko/ipc/glue/MessagePump.cpp:85:21
#52 0x7c77e9912d04 in RunInternal /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:369:10
#53 0x7c77e9912d04 in RunHandler /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:362:3
#54 0x7c77e9912d04 in MessageLoop::Run() /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:344:3
#55 0x7c77f29ec456 in nsBaseAppShell::Run() /builds/worker/checkouts/gecko/widget/nsBaseAppShell.cpp:148:27
#56 0x7c77f2b8e65a in nsAppShell::Run() /builds/worker/checkouts/gecko/widget/gtk/nsAppShell.cpp:469:33
#57 0x7c77f482ac8d in XRE_RunAppShell() /builds/worker/checkouts/gecko/toolkit/xre/nsEmbedFunctions.cpp:646:20
#58 0x7c77e9912d04 in RunInternal /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:369:10
#59 0x7c77e9912d04 in RunHandler /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:362:3
#60 0x7c77e9912d04 in MessageLoop::Run() /builds/worker/checkouts/gecko/ipc/chromium/src/base/message_loop.cc:344:3
#61 0x7c77f4829168 in XRE_InitChildProcess(int, char**, XREChildData const*) /builds/worker/checkouts/gecko/toolkit/xre/nsEmbedFunctions.cpp:584:34
#62 0x572b40efa0b1 in main /builds/worker/checkouts/gecko/browser/app/nsBrowserApp.cpp:397:22
Flags: in-testsuite?
Component: XPCOM → DOM: Networking

From the stack, it looks like this is due to XHR.

This is because we can't have a nsCString which is over 2Gb in size due to various legacy restrictions in our string types (such as ensuring that string sizes always fit within a signed int32_t for backwards compatibility reasons). Unlike the normal assignment operators, this was an Adopt call, meaning that we assert if the length is too long, rather than failing with an OOM or similar.

This is actually an example of one of the old places which expects int32_t to be valid for a string, as the string length is actually being truncated to an int32_t before being passed to AdoptData here, (https://searchfox.org/mozilla-central/rev/e3d80c5d94cbfa5dc579d5536cccea2b69b60635/xpcom/io/nsStringStream.cpp#183), meaning that we're actually probably seeing a length large enough to be represented as a negative number here.

In general it seems like our handling around large sizes and nsStringInputStream leaves a bit to be wanted, so there is some general cleanup we should do here so we don't fall over.

Crash Signature: [@ mozilla::detail::nsTStringLengthStorage<T>::nsTStringLengthStorage ]
See Also: → 1869203

Verified bug as reproducible on mozilla-central 20241207091049-78d8afbe5767.
Unable to bisect testcase (Testcase reproduces on start build!):

Start: 8839a3ba62436bd0ea7e5bd07e2b63a8d45b8609 (20231209093328)
End: 9dfed84788763ffc06a9d2893c839221ce8f49c7 (20241205213207)
BuildFlags: BuildFlags(asan=True, tsan=False, debug=False, fuzzing=True, coverage=False, valgrind=False, no_opt=False, fuzzilli=False, nyx=False, searchfox=False, afl=False)

Whiteboard: [bugmon:bisected,confirmed]
Component: DOM: Networking → XPCOM

This changes how the nsIStringInputStream interface is initialized in
C++ code to make it support larger stream sizes better. This involved
moving away from using nsCString in some cases, as it has a maximum
string length of approximately 2GiB.

This also required changing the signature of one of the methods making
it no longer JS-compatible. As the setData method was awkward to use
from JS anyway, the method was split into two (one for C++ callers, and
one for JS callers), and renamed. This required changes to the various
JS callers.

Assignee: nobody → nika
Status: NEW → ASSIGNED
Attachment #9443279 - Attachment description: Bug 1935714 - Improve handling of large nsStringStream streams at the API level, r=mccr8! → Bug 1935714 - Part 1: Improve handling of large nsStringStream streams at the API level, r=mccr8!

No C++ callers use the -1 length argument for these methods, so support for passing a default value can be removed now that the JS callers which pass -1 have been removed.

The method is equivalent to the setByteStringData method on nsIStringInputStream, which has been used to replace the .data setter in these places. There may still be callers of the .data getter/setter, however they aren't easy to find.

Pushed by nlayzell@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/adc7412eeab1 Part 1: Improve handling of large nsStringStream streams at the API level, r=mccr8,webdriver-reviewers,necko-reviewers,valentin,extension-reviewers,devtools-reviewers,robwu,ochameau https://hg.mozilla.org/integration/autoland/rev/79a34b17ab7b Part 2: Remove unused default length support from nsIStringInputStream, r=xpcom-reviewers,mccr8
Status: ASSIGNED → RESOLVED
Closed: 2 months ago
Resolution: --- → FIXED
Target Milestone: --- → 135 Branch
See Also: → 1937716

Verified bug as fixed on rev mozilla-central 20241217050910-d6aa02d4fc03.
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
Pushed by nlayzell@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/2f7058ea3047 Part 3: Avoid using nsISupportsCString to initialize nsStringInputStream instances, r=xpcom-reviewers,necko-reviewers,extension-reviewers,search-reviewers,devtools-reviewers,urlbar-reviewers,firefox-ai-ml-reviewers,mccr8,jteow,mcheang,ochameau,robwu,tarek
Flags: in-testsuite? → in-testsuite+

Backed out for causing mochitest failures on test_progress_events_for_gzip_data.html

Backout link

Push with failures

Failure log

Flags: needinfo?(nika)
Pushed by nlayzell@mozilla.com: https://hg.mozilla.org/integration/autoland/rev/8681c548ecc8 Part 3: Avoid using nsISupportsCString to initialize nsStringInputStream instances, r=xpcom-reviewers,necko-reviewers,extension-reviewers,search-reviewers,devtools-reviewers,urlbar-reviewers,firefox-ai-ml-reviewers,mccr8,jteow,mcheang,ochameau,robwu,tarek
Flags: needinfo?(nika)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: