From 73595a315989581e2f59b28af5d150d39ea6b8ff Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 29 Jul 2010 22:09:00 +0200 Subject: Updated WebKit to e6e692bb056670e2781dd0bc473a60757ae53992 Backported various crash fixes --- src/3rdparty/webkit/.tag | 2 +- src/3rdparty/webkit/JavaScriptCore/ChangeLog | 73 +++++++++ .../JavaScriptCore/interpreter/Interpreter.cpp | 16 +- .../webkit/JavaScriptCore/jit/JITStubs.cpp | 43 +++--- .../webkit/JavaScriptCore/runtime/Arguments.h | 4 + .../webkit/JavaScriptCore/runtime/JSArray.cpp | 6 +- .../JavaScriptCore/yarr/RegexInterpreter.cpp | 2 +- src/3rdparty/webkit/VERSION | 2 +- src/3rdparty/webkit/WebCore/ChangeLog | 166 +++++++++++++++++++++ src/3rdparty/webkit/WebCore/dom/CharacterData.cpp | 8 +- src/3rdparty/webkit/WebCore/dom/Element.cpp | 17 ++- src/3rdparty/webkit/WebCore/dom/Element.h | 4 + src/3rdparty/webkit/WebCore/dom/Text.cpp | 2 +- .../webkit/WebCore/platform/text/BidiResolver.h | 67 +++++---- .../webkit/WebCore/rendering/RenderBlock.cpp | 6 + .../webkit/WebCore/rendering/RenderSVGText.cpp | 13 ++ .../webkit/WebCore/rendering/RenderSVGText.h | 3 + .../webkit/WebCore/rendering/RenderWidget.cpp | 4 + src/3rdparty/webkit/WebCore/svg/SVGElement.cpp | 9 ++ .../webkit/WebCore/svg/SVGFontFaceElement.cpp | 1 - .../webkit/WebCore/svg/SVGForeignObjectElement.cpp | 4 + src/3rdparty/webkit/WebCore/svg/SVGSVGElement.cpp | 4 + src/3rdparty/webkit/WebCore/svg/SVGUseElement.cpp | 2 +- 23 files changed, 393 insertions(+), 65 deletions(-) diff --git a/src/3rdparty/webkit/.tag b/src/3rdparty/webkit/.tag index 3cb818d..0b414ab 100644 --- a/src/3rdparty/webkit/.tag +++ b/src/3rdparty/webkit/.tag @@ -1 +1 @@ -0be9ff9f2b1ec2b748885ac15299bc1c65aca590 +e6e692bb056670e2781dd0bc473a60757ae53992 diff --git a/src/3rdparty/webkit/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/JavaScriptCore/ChangeLog index ea680ac..c09ad79 100644 --- a/src/3rdparty/webkit/JavaScriptCore/ChangeLog +++ b/src/3rdparty/webkit/JavaScriptCore/ChangeLog @@ -1,3 +1,76 @@ +2010-07-02 Peter Varga + + Reviewed by Oliver Hunt. + + The alternativeFrameLocation value is wrong in the emitDisjunction function in + case of PatternTerm::TypeParentheticalAssertion. This value needs to be + computed from term.frameLocation instead of term.inputPosition. This mistake caused glibc + memory corruption in some cases. + Layout test added for checking of TypeParentheticalAssertion case. + https://bugs.webkit.org/show_bug.cgi?id=41458 + + * yarr/RegexInterpreter.cpp: + (JSC::Yarr::ByteCompiler::emitDisjunction): + +2010-07-03 Yong Li + + Reviewed by Darin Adler. + + Make Arguments::MaxArguments clamping work for numbers >= 0x80000000 in + the interpreter as well as the JIT. + + https://bugs.webkit.org/show_bug.cgi?id=41351 + rdar://problem/8142141 + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): Fix signed integer overflow problem + in op_load_varargs handling. 0xFFFFFFFF was read as -1. + +2010-07-04 Mark Rowe + + Build fix after r62456. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): Be slightly more consistent in using uint32_t to prevent + warnings about comparisons between signed and unsigned types, and attempts to call an overload + of std::min that doesn't exist. + +2010-07-02 Oliver Hunt + + Reviewed by Gavin Barraclough. + + Clamp the number of arguments supported by function.apply + https://bugs.webkit.org/show_bug.cgi?id=41351 + + + Add clamping logic to function.apply similar to that + enforced by firefox. We have a smaller clamp than + firefox as our calling convention means that stack + usage is proportional to argument count -- the firefox + limit is larger than you could actually call. + + * interpreter/Interpreter.cpp: + (JSC::Interpreter::privateExecute): + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + * runtime/Arguments.h: + (JSC::Arguments::): + +2010-07-01 Oliver Hunt + + Reviewed by Geoff Garen. + + Improve reentrancy logic in polymorphic cache stubs + + + + Make the polymorphic cache stubs handle reentrancy + better. + + * jit/JITStubs.cpp: + (JSC::DEFINE_STUB_FUNCTION): + (JSC::getPolymorphicAccessStructureListSlot): + 2009-10-30 Tor Arne Vestbø Reviewed by Kenneth Rohde Christiansen. diff --git a/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.cpp b/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.cpp index 2713fd4..73efc0d 100644 --- a/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/interpreter/Interpreter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. + * Copyright (C) 2008, 2009, 2010 Apple Inc. All rights reserved. * Copyright (C) 2008 Cameron Zwarich * * Redistribution and use in source and binary forms, with or without @@ -3454,9 +3454,10 @@ skip_id_custom_self: int argsOffset = vPC[2].u.operand; JSValue arguments = callFrame->r(argsOffset).jsValue(); - int32_t argCount = 0; + uint32_t argCount = 0; if (!arguments) { argCount = (uint32_t)(callFrame->argumentCount()) - 1; + argCount = min(argCount, Arguments::MaxArguments); int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; Register* newEnd = callFrame->registers() + sizeDelta; if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { @@ -3464,9 +3465,9 @@ skip_id_custom_self: goto vm_throw; } ASSERT(!callFrame->callee()->isHostFunction()); - int32_t expectedParams = callFrame->callee()->jsExecutable()->parameterCount(); - int32_t inplaceArgs = min(argCount, expectedParams); - int32_t i = 0; + uint32_t expectedParams = callFrame->callee()->jsExecutable()->parameterCount(); + uint32_t inplaceArgs = min(argCount, expectedParams); + uint32_t i = 0; Register* argStore = callFrame->registers() + argsOffset; // First step is to copy the "expected" parameters from their normal location relative to the callframe @@ -3483,6 +3484,7 @@ skip_id_custom_self: if (asObject(arguments)->classInfo() == &Arguments::info) { Arguments* args = asArguments(arguments); argCount = args->numProvidedArguments(callFrame); + argCount = min(argCount, Arguments::MaxArguments); int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; Register* newEnd = callFrame->registers() + sizeDelta; if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { @@ -3493,6 +3495,7 @@ skip_id_custom_self: } else if (isJSArray(&callFrame->globalData(), arguments)) { JSArray* array = asArray(arguments); argCount = array->length(); + argCount = min(argCount, Arguments::MaxArguments); int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; Register* newEnd = callFrame->registers() + sizeDelta; if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { @@ -3503,6 +3506,7 @@ skip_id_custom_self: } else if (asObject(arguments)->inherits(&JSArray::info)) { JSObject* argObject = asObject(arguments); argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame); + argCount = min(argCount, Arguments::MaxArguments); int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; Register* newEnd = callFrame->registers() + sizeDelta; if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { @@ -3510,7 +3514,7 @@ skip_id_custom_self: goto vm_throw; } Register* argsBuffer = callFrame->registers() + argsOffset; - for (int32_t i = 0; i < argCount; ++i) { + for (uint32_t i = 0; i < argCount; ++i) { argsBuffer[i] = asObject(arguments)->get(callFrame, i); CHECK_FOR_EXCEPTION(); } diff --git a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp index daa945c..e5fcdc4 100644 --- a/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/jit/JITStubs.cpp @@ -1330,17 +1330,18 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_self_fail) if (stubInfo->accessType == access_get_by_id_self) { ASSERT(!stubInfo->stubRoutine); polymorphicStructureList = new PolymorphicAccessStructureList(CodeLocationLabel(), stubInfo->u.getByIdSelf.baseObjectStructure); - stubInfo->initGetByIdSelfList(polymorphicStructureList, 2); + stubInfo->initGetByIdSelfList(polymorphicStructureList, 1); } else { polymorphicStructureList = stubInfo->u.getByIdSelfList.structureList; listIndex = stubInfo->u.getByIdSelfList.listSize; - stubInfo->u.getByIdSelfList.listSize++; } + if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) { + stubInfo->u.getByIdSelfList.listSize++; + JIT::compileGetByIdSelfList(callFrame->scopeChain()->globalData, codeBlock, stubInfo, polymorphicStructureList, listIndex, asCell(baseValue)->structure(), ident, slot, slot.cachedOffset()); - JIT::compileGetByIdSelfList(callFrame->scopeChain()->globalData, codeBlock, stubInfo, polymorphicStructureList, listIndex, asCell(baseValue)->structure(), ident, slot, slot.cachedOffset()); - - if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) - ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_generic)); + if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) + ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_generic)); + } } else ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_generic)); return JSValue::encode(result); @@ -1365,13 +1366,14 @@ static PolymorphicAccessStructureList* getPolymorphicAccessStructureListSlot(Str case access_get_by_id_proto_list: prototypeStructureList = stubInfo->u.getByIdProtoList.structureList; listIndex = stubInfo->u.getByIdProtoList.listSize; - stubInfo->u.getByIdProtoList.listSize++; + if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) + stubInfo->u.getByIdProtoList.listSize++; break; default: ASSERT_NOT_REACHED(); } - ASSERT(listIndex < POLYMORPHIC_LIST_CACHE_SIZE); + ASSERT(listIndex <= POLYMORPHIC_LIST_CACHE_SIZE); return prototypeStructureList; } @@ -1446,21 +1448,24 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_id_proto_list) int listIndex; PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex); + if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) { + JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), propertyName, slot, offset); - JIT::compileGetByIdProtoList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, slotBaseObject->structure(), propertyName, slot, offset); - - if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) - ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full)); + if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) + ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full)); + } } else if (size_t count = normalizePrototypeChain(callFrame, baseValue, slot.slotBase(), propertyName, offset)) { ASSERT(!asCell(baseValue)->structure()->isDictionary()); int listIndex; PolymorphicAccessStructureList* prototypeStructureList = getPolymorphicAccessStructureListSlot(stubInfo, listIndex); + + if (listIndex < POLYMORPHIC_LIST_CACHE_SIZE) { + StructureChain* protoChain = structure->prototypeChain(callFrame); + JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, propertyName, slot, offset); - StructureChain* protoChain = structure->prototypeChain(callFrame); - JIT::compileGetByIdChainList(callFrame->scopeChain()->globalData, callFrame, codeBlock, stubInfo, prototypeStructureList, listIndex, structure, protoChain, count, propertyName, slot, offset); - - if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) - ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full)); + if (listIndex == (POLYMORPHIC_LIST_CACHE_SIZE - 1)) + ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_list_full)); + } } else ctiPatchCallByReturnAddress(codeBlock, STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_id_proto_fail)); @@ -2129,6 +2134,7 @@ DEFINE_STUB_FUNCTION(int, op_load_varargs) if (!arguments) { int providedParams = callFrame->registers()[RegisterFile::ArgumentCount].i() - 1; argCount = providedParams; + argCount = min(argCount, static_cast(Arguments::MaxArguments)); int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; Register* newEnd = callFrame->registers() + sizeDelta; if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { @@ -2164,6 +2170,7 @@ DEFINE_STUB_FUNCTION(int, op_load_varargs) if (asObject(arguments)->classInfo() == &Arguments::info) { Arguments* argsObject = asArguments(arguments); argCount = argsObject->numProvidedArguments(callFrame); + argCount = min(argCount, static_cast(Arguments::MaxArguments)); int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; Register* newEnd = callFrame->registers() + sizeDelta; if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { @@ -2174,6 +2181,7 @@ DEFINE_STUB_FUNCTION(int, op_load_varargs) } else if (isJSArray(&callFrame->globalData(), arguments)) { JSArray* array = asArray(arguments); argCount = array->length(); + argCount = min(argCount, static_cast(Arguments::MaxArguments)); int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; Register* newEnd = callFrame->registers() + sizeDelta; if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { @@ -2184,6 +2192,7 @@ DEFINE_STUB_FUNCTION(int, op_load_varargs) } else if (asObject(arguments)->inherits(&JSArray::info)) { JSObject* argObject = asObject(arguments); argCount = argObject->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame); + argCount = min(argCount, static_cast(Arguments::MaxArguments)); int32_t sizeDelta = argsOffset + argCount + RegisterFile::CallFrameHeaderSize; Register* newEnd = callFrame->registers() + sizeDelta; if (!registerFile->grow(newEnd) || ((newEnd - callFrame->registers()) != sizeDelta)) { diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h b/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h index 9797e08..cca3cf2 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/Arguments.h @@ -55,6 +55,10 @@ namespace JSC { class Arguments : public JSObject { public: + // Use an enum because otherwise gcc insists on doing a memory + // read. + enum { MaxArguments = 0x10000 }; + enum NoParametersType { NoParameters }; Arguments(CallFrame*); diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp index d3ef44c..ae9e038 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSArray.cpp @@ -948,10 +948,10 @@ void JSArray::fillArgList(ExecState* exec, MarkedArgumentBuffer& args) void JSArray::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSize) { - ASSERT(m_storage->m_length == maxSize); + ASSERT(m_storage->m_length >= maxSize); UNUSED_PARAM(maxSize); JSValue* vector = m_storage->m_vector; - unsigned vectorEnd = min(m_storage->m_length, m_vectorLength); + unsigned vectorEnd = min(maxSize, m_vectorLength); unsigned i = 0; for (; i < vectorEnd; ++i) { JSValue& v = vector[i]; @@ -960,7 +960,7 @@ void JSArray::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSiz buffer[i] = v; } - for (; i < m_storage->m_length; ++i) + for (; i < maxSize; ++i) buffer[i] = get(exec, i); } diff --git a/src/3rdparty/webkit/JavaScriptCore/yarr/RegexInterpreter.cpp b/src/3rdparty/webkit/JavaScriptCore/yarr/RegexInterpreter.cpp index c2cb1c2..647b20a 100644 --- a/src/3rdparty/webkit/JavaScriptCore/yarr/RegexInterpreter.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/yarr/RegexInterpreter.cpp @@ -1554,7 +1554,7 @@ public: } case PatternTerm::TypeParentheticalAssertion: { - unsigned alternativeFrameLocation = term.inputPosition + RegexStackSpaceForBackTrackInfoParentheticalAssertion; + unsigned alternativeFrameLocation = term.frameLocation + RegexStackSpaceForBackTrackInfoParentheticalAssertion; atomParentheticalAssertionBegin(term.parentheses.subpatternId, term.invertOrCapture, term.frameLocation, alternativeFrameLocation); emitDisjunction(term.parentheses.disjunction, currentCountAlreadyChecked, 0); diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index f12f6b5..f8403fb 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -4,4 +4,4 @@ This is a snapshot of the Qt port of WebKit from and has the sha1 checksum - 0be9ff9f2b1ec2b748885ac15299bc1c65aca590 + e6e692bb056670e2781dd0bc473a60757ae53992 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index f7f2803..5189eb5 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,169 @@ +2010-07-06 Nikolas Zimmermann + + Reviewed by Dirk Schulze. + + on causes crashes, if SVGUseElement gets detached + https://bugs.webkit.org/show_bug.cgi?id=41621 + + Do not call removeFromMappedElementSheet() from the SVGFontFaceElement destructor, + as that can potentially cause the element to be reattached while destructing. + + In order to fix the crash in the testcase, the order of calling the base-class detach + method in SVGUseElement and the instance/shadow tree destruction has to be reversed, + matching the order in removedFromDocument(). + + Test: svg/custom/use-font-face-crash.svg + + * svg/SVGFontFaceElement.cpp: + (WebCore::SVGFontFaceElement::~SVGFontFaceElement): Remove removeFromMappedElementSheet() call. + * svg/SVGUseElement.cpp: + (WebCore::SVGUseElement::detach): Reverse order of calling base-class detach method and instance/shadow tree destruction. + +2010-07-06 Nikolas Zimmermann + + Reviewed by Darin Adler. + + on causes crashes, if SVGUseElement gets detached + https://bugs.webkit.org/show_bug.cgi?id=41621 + + Do not call removeFromMappedElementSheet() from the destructor, as the call to document()->updateStyleSelector() that can potentially + cause the element to be reattached while destructing. It's not needed at all, because removedFromDocument() is called before destruction, + which already calls removeFromMappedElementSheet() - at this point it's still safe to update the style selector. + + The crash is reproducable when using on . + + Test: svg/custom/use-font-face-crash.svg + + * svg/SVGFontFaceElement.cpp: + (WebCore::SVGFontFaceElement::~SVGFontFaceElement): + +2010-07-05 Nikolas Zimmermann + + Reviewed by Darin Adler. + + Memory corruption with SVG element + https://bugs.webkit.org/show_bug.cgi?id=40994 + + Fix race condition in svgAttributeChanged. Never call svgAttributeChanged() from attributeChanged() + when we're synchronizing SVG attributes. It leads to either unnecessary extra work being done or + crashes. Especially together with / which always synchronize the SVGAnimatedPoints + datastructure with the points attribute, no matter if there are changes are not. This should be + furhter optimized, but this fix is sane and fixes the root of the evil races. + + Test: svg/custom/use-property-synchronization-crash.svg + + * svg/SVGElement.cpp: + (WebCore::SVGElement::attributeChanged): + +2010-06-11 Abhishek Arya + + Reviewed by David Hyatt. + + Don't process floats if parent node is not a RenderBlock. + https://bugs.webkit.org/show_bug.cgi?id=40033 + + Test: svg/text/clear-floats-crash.svg + + * rendering/RenderBlock.cpp: + (WebCore::RenderBlock::clearFloats): + +2010-06-23 Nikolas Zimmermann + + Reviewed by Eric Seidel. + + Reproducible crash in com.apple.WebCore 0x01ed3784 WebCore::RenderLineBoxList::appendLineBox(WebCore::InlineFlowBox*) + 36 + https://bugs.webkit.org/show_bug.cgi?id=40953 + + REGRESSION (r58209-58231): Memory corruption with invalid SVG + https://bugs.webkit.org/show_bug.cgi?id=40173 + + Fix several crashes, all related to and/or invalid SVG documents. + - Only allow nodes, as direct children of a , not any other "partial" SVG content. + - Assure to create RenderSVGRoot objects for nodes in , treat them as "outermost SVG elements". + - Never allow any partial SVG content to appear in any document. Only elements are allowed. + + Tests: svg/custom/bug45331.svg + svg/foreignObject/disallowed-svg-nodes-as-direct-children.svg + svg/foreignObject/no-crash-with-svg-content-in-html-document.svg + svg/foreignObject/svg-document-as-direct-child.svg + svg/foreignObject/svg-document-in-html-document.svg + svg/foreignObject/text-tref-02-b.svg + + * dom/Element.cpp: Added childShouldCreateRenderer, with ENABLE(SVG) guards. + (WebCore::Element::childShouldCreateRenderer): Only create a renderer for a SVG child, if we're a SVG element, or if the child is a element. + * dom/Element.h: Added childShouldCreateRenderer, with ENABLE(SVG) guards. + * svg/SVGForeignObjectElement.cpp: + (WebCore::SVGForeignObjectElement::childShouldCreateRenderer): Disallow arbitary SVG content, only elements are allowed as direct children of a + * svg/SVGSVGElement.cpp: + (WebCore::SVGSVGElement::isOutermostSVG): Be sure to create RenderSVGRoot objects for elements inside + +2010-06-10 Abhishek Arya + + Reviewed by Dave Hyatt. + + Do not render CSS Styles :first-letter and :first-line in a SVG text element context. + https://bugs.webkit.org/show_bug.cgi?id=40031 + + Test: svg/text/text-style-invalid.svg + + * rendering/RenderSVGText.cpp: + (WebCore::RenderSVGText::firstLineBlock): + (WebCore::RenderSVGText::updateFirstLetter): + * rendering/RenderSVGText.h: + +2010-07-01 Justin Schuh + + Reviewed by Dan Bernstein. + + Prevent crash on counter destruction + https://bugs.webkit.org/show_bug.cgi?id=40032 + + Added counter destruction to RenderWidget::destroy() + + Test: fast/css/counters/destroy-counter-crash.html + + * rendering/RenderWidget.cpp: + (WebCore::RenderWidget::destroy): + +2010-06-29 Dan Bernstein + + Reviewed by Darin Adler. + + Certain text is repeated after using splitText() + + Tests: fast/text/setData-dirty-lines.html + fast/text/splitText-dirty-lines.html + + * dom/CharacterData.cpp: + (WebCore::CharacterData::setData): Call RenderText::setTextWithOffset() rather than + setText(), because only the former correctly dirties line boxes. + * dom/Text.cpp: + (WebCore::Text::splitText): Ditto. + +2010-06-25 Dan Bernstein + + Reviewed by Sam Weinig. + + Certain text is repeated before and after a line break + + Test: fast/text/bidi-explicit-embedding-past-end.html + + * platform/text/BidiResolver.h: + (WebCore::::createBidiRunsForLine): Committing explicit embedding past the end of the range + creates BidiRuns up to the end of the range, so at that point, we can stop iterating. + +2010-06-10 Tony Chang + + Reviewed by Kent Tamura. + + crash when focus is changed while trying to focus next element + https://bugs.webkit.org/show_bug.cgi?id=40407 + + Test: fast/events/focus-change-crash.html + + * dom/Element.cpp: + (WebCore::Element::focus): + 2010-07-01 Andreas Kling Reviewed by Tor Arne Vestbø. diff --git a/src/3rdparty/webkit/WebCore/dom/CharacterData.cpp b/src/3rdparty/webkit/WebCore/dom/CharacterData.cpp index 3c3dc37..cb12184 100644 --- a/src/3rdparty/webkit/WebCore/dom/CharacterData.cpp +++ b/src/3rdparty/webkit/WebCore/dom/CharacterData.cpp @@ -46,15 +46,15 @@ void CharacterData::setData(const String& data, ExceptionCode&) int oldLength = length(); RefPtr oldStr = m_data; m_data = dataImpl; - + if ((!renderer() || !rendererIsNeeded(renderer()->style())) && attached()) { detach(); attach(); } else if (renderer()) - toRenderText(renderer())->setText(m_data); - + toRenderText(renderer())->setTextWithOffset(m_data, 0, oldLength); + dispatchModifiedEvent(oldStr.get()); - + document()->textRemoved(this, 0, oldLength); } diff --git a/src/3rdparty/webkit/WebCore/dom/Element.cpp b/src/3rdparty/webkit/WebCore/dom/Element.cpp index a02bb4c..4c93020 100644 --- a/src/3rdparty/webkit/WebCore/dom/Element.cpp +++ b/src/3rdparty/webkit/WebCore/dom/Element.cpp @@ -1311,8 +1311,12 @@ void Element::focus(bool restorePreviousSelection) return; } - if (Page* page = doc->page()) + RefPtr protect; + if (Page* page = doc->page()) { + // Focus and change event handlers can cause us to lose our last ref. + protect = this; page->focusController()->setFocusedNode(this, doc->frame()); + } // Setting the focused node above might have invalidated the layout due to scripts. doc->updateLayoutIgnorePendingStylesheets(); @@ -1535,4 +1539,15 @@ const QualifiedName& Element::rareIDAttributeName() const return rareData()->m_idAttributeName; } +#if ENABLE(SVG) +bool Element::childShouldCreateRenderer(Node* child) const +{ + // Only create renderers for SVG elements whose parents are SVG elements, or for proper subdocuments. + if (child->isSVGElement()) + return child->hasTagName(SVGNames::svgTag) || isSVGElement(); + + return Node::childShouldCreateRenderer(child); +} +#endif + } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/dom/Element.h b/src/3rdparty/webkit/WebCore/dom/Element.h index 348ed1c..36c4f1b 100644 --- a/src/3rdparty/webkit/WebCore/dom/Element.h +++ b/src/3rdparty/webkit/WebCore/dom/Element.h @@ -270,6 +270,10 @@ public: virtual void dispatchFormControlChangeEvent() { } +#if ENABLE(SVG) + virtual bool childShouldCreateRenderer(Node*) const; +#endif + protected: Element(const QualifiedName&, Document*, ConstructionType); diff --git a/src/3rdparty/webkit/WebCore/dom/Text.cpp b/src/3rdparty/webkit/WebCore/dom/Text.cpp index 1ce074a..229fa88 100644 --- a/src/3rdparty/webkit/WebCore/dom/Text.cpp +++ b/src/3rdparty/webkit/WebCore/dom/Text.cpp @@ -77,7 +77,7 @@ PassRefPtr Text::splitText(unsigned offset, ExceptionCode& ec) document()->textNodeSplit(this); if (renderer()) - toRenderText(renderer())->setText(dataImpl()); + toRenderText(renderer())->setTextWithOffset(dataImpl(), 0, oldStr->length()); return newText.release(); } diff --git a/src/3rdparty/webkit/WebCore/platform/text/BidiResolver.h b/src/3rdparty/webkit/WebCore/platform/text/BidiResolver.h index 286cdcd..a99fd01 100644 --- a/src/3rdparty/webkit/WebCore/platform/text/BidiResolver.h +++ b/src/3rdparty/webkit/WebCore/platform/text/BidiResolver.h @@ -806,35 +806,33 @@ void BidiResolver::createBidiRunsForLine(const Iterator& end, boo break; } - if (pastEnd) { - if (eor == current) { - if (!reachedEndOfLine) { - eor = endOfLine; - switch (m_status.eor) { - case LeftToRight: - case RightToLeft: - case ArabicNumber: - m_direction = m_status.eor; - break; - case EuropeanNumber: - m_direction = m_status.lastStrong == LeftToRight ? LeftToRight : EuropeanNumber; - break; - default: - ASSERT(false); - } - appendRun(); + if (pastEnd && eor == current) { + if (!reachedEndOfLine) { + eor = endOfLine; + switch (m_status.eor) { + case LeftToRight: + case RightToLeft: + case ArabicNumber: + m_direction = m_status.eor; + break; + case EuropeanNumber: + m_direction = m_status.lastStrong == LeftToRight ? LeftToRight : EuropeanNumber; + break; + default: + ASSERT(false); } - current = end; - m_status = stateAtEnd.m_status; - sor = stateAtEnd.sor; - eor = stateAtEnd.eor; - last = stateAtEnd.last; - reachedEndOfLine = stateAtEnd.reachedEndOfLine; - lastBeforeET = stateAtEnd.lastBeforeET; - emptyRun = stateAtEnd.emptyRun; - m_direction = OtherNeutral; - break; + appendRun(); } + current = end; + m_status = stateAtEnd.m_status; + sor = stateAtEnd.sor; + eor = stateAtEnd.eor; + last = stateAtEnd.last; + reachedEndOfLine = stateAtEnd.reachedEndOfLine; + lastBeforeET = stateAtEnd.lastBeforeET; + emptyRun = stateAtEnd.emptyRun; + m_direction = OtherNeutral; + break; } // set m_status.last as needed. @@ -887,8 +885,21 @@ void BidiResolver::createBidiRunsForLine(const Iterator& end, boo } increment(); - if (!m_currentExplicitEmbeddingSequence.isEmpty()) + if (!m_currentExplicitEmbeddingSequence.isEmpty()) { commitExplicitEmbedding(); + if (pastEnd) { + current = end; + m_status = stateAtEnd.m_status; + sor = stateAtEnd.sor; + eor = stateAtEnd.eor; + last = stateAtEnd.last; + reachedEndOfLine = stateAtEnd.reachedEndOfLine; + lastBeforeET = stateAtEnd.lastBeforeET; + emptyRun = stateAtEnd.emptyRun; + m_direction = OtherNeutral; + break; + } + } if (emptyRun && (dirCurrent == RightToLeftEmbedding || dirCurrent == LeftToRightEmbedding diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp index 798663e..e7fa753 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderBlock.cpp @@ -2981,6 +2981,12 @@ void RenderBlock::clearFloats() m_floatingObjects->clear(); } + // We should not process floats if the parent node is not a RenderBlock. Otherwise, we will add + // floats in an invalid context. This will cause a crash arising from a bad cast on the parent. + // See , where float property is applied on a text node in a SVG. + if (!parent() || !parent()->isRenderBlock()) + return; + // Attempt to locate a previous sibling with overhanging floats. We skip any elements that are // out of flow (like floating/positioned elements), and we also skip over any objects that may have shifted // to avoid floats. diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGText.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderSVGText.cpp index 76b8b86..de902e0 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGText.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGText.cpp @@ -225,6 +225,19 @@ FloatRect RenderSVGText::repaintRectInLocalCoordinates() const return repaintRect; } +// Fix for . We should not render :first-line CSS Style +// in a SVG text element context. +RenderBlock* RenderSVGText::firstLineBlock() const +{ + return 0; +} + +// Fix for . We should not render :first-letter CSS Style +// in a SVG text element context. +void RenderSVGText::updateFirstLetter() +{ +} + } #endif // ENABLE(SVG) diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderSVGText.h b/src/3rdparty/webkit/WebCore/rendering/RenderSVGText.h index ab4b09b..f09e396 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderSVGText.h +++ b/src/3rdparty/webkit/WebCore/rendering/RenderSVGText.h @@ -72,6 +72,9 @@ private: virtual RootInlineBox* createRootInlineBox(); + virtual RenderBlock* firstLineBlock() const; + virtual void updateFirstLetter(); + AffineTransform m_localTransform; }; diff --git a/src/3rdparty/webkit/WebCore/rendering/RenderWidget.cpp b/src/3rdparty/webkit/WebCore/rendering/RenderWidget.cpp index 561bead..251a65d 100644 --- a/src/3rdparty/webkit/WebCore/rendering/RenderWidget.cpp +++ b/src/3rdparty/webkit/WebCore/rendering/RenderWidget.cpp @@ -27,6 +27,7 @@ #include "AnimationController.h" #include "GraphicsContext.h" #include "HitTestResult.h" +#include "RenderCounter.h" #include "RenderView.h" #include "RenderWidgetProtector.h" @@ -114,6 +115,9 @@ void RenderWidget::destroy() if (RenderView* v = view()) v->removeWidget(this); + if (m_hasCounterNodeMap) + RenderCounter::destroyCounterNodes(this); + if (AXObjectCache::accessibilityEnabled()) { document()->axObjectCache()->childrenChanged(this->parent()); document()->axObjectCache()->remove(this); diff --git a/src/3rdparty/webkit/WebCore/svg/SVGElement.cpp b/src/3rdparty/webkit/WebCore/svg/SVGElement.cpp index 41bbba4..974bf2a 100644 --- a/src/3rdparty/webkit/WebCore/svg/SVGElement.cpp +++ b/src/3rdparty/webkit/WebCore/svg/SVGElement.cpp @@ -304,6 +304,15 @@ void SVGElement::attributeChanged(Attribute* attr, bool preserveDecls) return; StyledElement::attributeChanged(attr, preserveDecls); + + // When an animated SVG property changes through SVG DOM, svgAttributeChanged() is called, not attributeChanged(). + // Next time someone tries to access the XML attributes, the synchronization code starts. During that synchronization + // SVGAnimatedPropertySynchronizer may call NamedNodeMap::removeAttribute(), which in turn calls attributeChanged(). + // At this point we're not allowed to call svgAttributeChanged() again - it may lead to extra work being done, or crashes + // see bug https://bugs.webkit.org/show_bug.cgi?id=40994. + if (m_synchronizingSVGAttributes) + return; + svgAttributeChanged(attr->name()); } diff --git a/src/3rdparty/webkit/WebCore/svg/SVGFontFaceElement.cpp b/src/3rdparty/webkit/WebCore/svg/SVGFontFaceElement.cpp index 25b3aea..de646c6 100644 --- a/src/3rdparty/webkit/WebCore/svg/SVGFontFaceElement.cpp +++ b/src/3rdparty/webkit/WebCore/svg/SVGFontFaceElement.cpp @@ -59,7 +59,6 @@ SVGFontFaceElement::SVGFontFaceElement(const QualifiedName& tagName, Document* d SVGFontFaceElement::~SVGFontFaceElement() { - removeFromMappedElementSheet(); } static int cssPropertyIdForSVGAttributeName(const QualifiedName& attrName) diff --git a/src/3rdparty/webkit/WebCore/svg/SVGForeignObjectElement.cpp b/src/3rdparty/webkit/WebCore/svg/SVGForeignObjectElement.cpp index d28e2a4..e7b5389 100644 --- a/src/3rdparty/webkit/WebCore/svg/SVGForeignObjectElement.cpp +++ b/src/3rdparty/webkit/WebCore/svg/SVGForeignObjectElement.cpp @@ -125,6 +125,10 @@ RenderObject* SVGForeignObjectElement::createRenderer(RenderArena* arena, Render bool SVGForeignObjectElement::childShouldCreateRenderer(Node* child) const { + // Disallow arbitary SVG content. Only allow proper subdocuments. + if (child->isSVGElement()) + return child->hasTagName(SVGNames::svgTag); + // Skip over SVG rules which disallow non-SVG kids return StyledElement::childShouldCreateRenderer(child); } diff --git a/src/3rdparty/webkit/WebCore/svg/SVGSVGElement.cpp b/src/3rdparty/webkit/WebCore/svg/SVGSVGElement.cpp index 4c06008..5237715 100644 --- a/src/3rdparty/webkit/WebCore/svg/SVGSVGElement.cpp +++ b/src/3rdparty/webkit/WebCore/svg/SVGSVGElement.cpp @@ -538,6 +538,10 @@ bool SVGSVGElement::isOutermostSVG() const if (!parentNode()) return true; + // We act like an outermost SVG element, if we're a direct child of a element. + if (parentNode()->hasTagName(SVGNames::foreignObjectTag)) + return true; + // This is true whenever this is the outermost SVG, even if there are HTML elements outside it return !parentNode()->isSVGElement(); } diff --git a/src/3rdparty/webkit/WebCore/svg/SVGUseElement.cpp b/src/3rdparty/webkit/WebCore/svg/SVGUseElement.cpp index 45bab6a..57d56e1 100644 --- a/src/3rdparty/webkit/WebCore/svg/SVGUseElement.cpp +++ b/src/3rdparty/webkit/WebCore/svg/SVGUseElement.cpp @@ -572,8 +572,8 @@ void SVGUseElement::attach() void SVGUseElement::detach() { - SVGStyledTransformableElement::detach(); m_targetElementInstance = 0; + SVGStyledTransformableElement::detach(); } static bool isDirectReference(Node* n) -- cgit v0.12