Bug 33075

Summary: WebCore::RenderInline::mapLocalToContainer RecursionSOV (f6a51883f6be6a6c0fca30ae47a1b115)
Product: WebKit Reporter: Berend-Jan Wever <skylined>
Component: HTML EditingAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: eric, mitz, simon.fraser
Priority: P1    
Version: 528+ (Nightly build)   
Hardware: PC   
OS: Windows Vista   

Berend-Jan Wever
Reported 2009-12-31 00:42:23 PST
execCommand can be used to trigger infinite recursion. I'm having the repro reduced to workable size and will add it when it's done. The problem is obvious from the source code though; below is the vulnerable function, which calls itself on the last line. Once the repro is reduced, I should be able to show you how to trigger it. void RenderInline::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState) const { if (repaintContainer == this) return; if (RenderView *v = view()) { if (v->layoutStateEnabled() && !repaintContainer) { LayoutState* layoutState = v->layoutState(); IntSize offset = layoutState->m_offset; if (style()->position() == RelativePosition && layer()) offset += layer()->relativePositionOffset(); transformState.move(offset); return; } } bool containerSkipped; RenderObject* o = container(repaintContainer, &containerSkipped); if (!o) return; IntSize containerOffset = offsetFromContainer(o); bool preserve3D = useTransforms && (o->style()->preserves3D() || style()->preserves3D()); if (useTransforms && shouldUseTransformFromContainer(o)) { TransformationMatrix t; getTransformFromContainer(o, containerOffset, t); transformState.applyTransform(t, preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform); } else transformState.move(containerOffset.width(), containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform); if (containerSkipped) { // There can't be a transform between repaintContainer and o, because transforms create containers, so it should be safe // to just subtract the delta between the repaintContainer and o. IntSize containerOffset = repaintContainer->offsetFromAncestorContainer(o); transformState.move(-containerOffset.width(), -containerOffset.height(), preserve3D ? TransformState::AccumulateTransform : TransformState::FlattenTransform); return; } o->mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState); } Id: WebCore::RenderInline::mapLocalToContainer RecursionSOV (f6a51883f6be6a6c0fca30ae47a1b115) Description: Recursive function call in WebCore::RenderInline::mapLocalToContainer Stack: WebCore::RenderInline::mapLocalToContainer WebCore::RenderInline::mapLocalToContainer <snip> WebCore::RenderInline::mapLocalToContainer WebCore::RenderObject::mapLocalToContainer WebCore::RenderObject::localToAbsolute WebCore::VisiblePosition::xOffsetForVerticalNavigation WebCore::SelectionController::modify WebCore::TypingCommand::forwardDeleteKeyPressed WebCore::TypingCommand::doApply WebCore::EditCommand::apply WebCore::TypingCommand::forwardDeleteKeyPressed WebCore::executeForwardDelete WebCore::Editor::Command::execute WebCore::Document::execCommand WebCore::DocumentInternal::execCommandCallback v8::internal::Builtin_HandleApiCall v8::internal::Invoke v8::internal::Execution::Call v8::Script::Run WebCore::V8Proxy::runScript WebCore::V8Proxy::evaluate WebCore::ScriptController::evaluate WebCore::ScriptController::executeScript WebCore::ScriptController::executeScript WebCore::ScriptController::executeIfJavaScriptURL WebCore::FrameLoader::changeLocation WebCore::RedirectScheduler::timerFired WebCore::Timer<...>::fired WebCore::ThreadTimers::sharedTimerFiredInternal MessageLoop::RunTask MessageLoop::DoWork base::MessagePumpDefault::Run MessageLoop::RunInternal MessageLoop::Run RendererMain Event details Processes 0 id: f14 create name: chrome.exe . 1 id: 61c child name: chrome.exe Current process: 0n1564 C:\chromium-latest\chrome.exe Session: 0 User: VM3-XP32SP3-CJ\SkyLined Command Line: "C:\chromium-latest\chrome.exe" --type=renderer --no-sandbox --js-flags=--expose-gc --lang=en-US --force-fieldtest=DnsImpact/_max_2s_queue_prefetch/GlobalSdch/_global_enable_sdch/SocketLateBinding/_enable_late_binding/ --channel=3860.01052700.306296198 Threads . 12 Id: 61c.a84 Suspend: 1 Teb: 7ffdf000 Unfrozen "Main Thread" 13 Id: 61c.fa0 Suspend: 1 Teb: 7ffde000 Unfrozen 14 Id: 61c.c18 Suspend: 1 Teb: 7ffdd000 Unfrozen "Chrome_ChildIOThread" 15 Id: 61c.964 Suspend: 1 Teb: 7ffdc000 Unfrozen ExceptionAddress 02114d49 (chrome_1c30000!WebCore::RenderInline::mapLocalToContainer+0x00000009) ExceptionCode c00000fd (Stack overflow) ExceptionFlags 00000000 NumberParameters 2 Parameter[0] 00000001 Parameter[1] 00032fd8
Attachments
Berend-Jan Wever
Comment 1 2009-12-31 00:45:49 PST
Berend-Jan Wever
Comment 2 2010-01-05 02:16:01 PST
I can't seem to get a decent repro, sorry.
Berend-Jan Wever
Comment 3 2010-05-20 06:54:41 PDT
http://code.google.com/p/chromium/issues/detail?id=44638 Contains a working repro. However, it only crashes Chrome 4.1 and not 6.0, so I assume that this has been fixed.
Note You need to log in before you can comment on or make changes to this bug.