diff options
Diffstat (limited to 'src/3rdparty/webkit/WebCore/page')
36 files changed, 599 insertions, 219 deletions
diff --git a/src/3rdparty/webkit/WebCore/page/ChromeClient.h b/src/3rdparty/webkit/WebCore/page/ChromeClient.h index 2d11275..5231603 100644 --- a/src/3rdparty/webkit/WebCore/page/ChromeClient.h +++ b/src/3rdparty/webkit/WebCore/page/ChromeClient.h @@ -203,6 +203,10 @@ namespace WebCore { virtual void scheduleCompositingLayerSync() = 0; #endif + virtual bool supportsFullscreenForNode(const Node*) { return false; } + virtual void enterFullscreenForNode(Node*) { } + virtual void exitFullscreenForNode(Node*) { } + #if PLATFORM(MAC) virtual KeyboardUIMode keyboardUIMode() { return KeyboardAccessDefault; } diff --git a/src/3rdparty/webkit/WebCore/page/ContextMenuController.cpp b/src/3rdparty/webkit/WebCore/page/ContextMenuController.cpp index a3a86a5..7d773ca 100644 --- a/src/3rdparty/webkit/WebCore/page/ContextMenuController.cpp +++ b/src/3rdparty/webkit/WebCore/page/ContextMenuController.cpp @@ -166,10 +166,12 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item) frame->editor()->copy(); break; case ContextMenuItemTagGoBack: - frame->loader()->goBackOrForward(-1); + if (Page* page = frame->page()) + page->goBackOrForward(-1); break; case ContextMenuItemTagGoForward: - frame->loader()->goBackOrForward(1); + if (Page* page = frame->page()) + page->goBackOrForward(1); break; case ContextMenuItemTagStop: frame->loader()->stop(); @@ -215,7 +217,7 @@ void ContextMenuController::contextMenuItemSelected(ContextMenuItem* item) break; case ContextMenuItemTagOpenLink: if (Frame* targetFrame = result.targetFrame()) - targetFrame->loader()->loadFrameRequest(FrameLoadRequest(ResourceRequest(result.absoluteLinkURL(), frame->loader()->outgoingReferrer())), false, false, 0, 0); + targetFrame->loader()->loadFrameRequest(FrameLoadRequest(ResourceRequest(result.absoluteLinkURL(), frame->loader()->outgoingReferrer())), false, false, 0, 0, SendReferrer); else openNewWindow(result.absoluteLinkURL(), frame); break; diff --git a/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp b/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp index 5ac4049..c30b6b9 100644 --- a/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp +++ b/src/3rdparty/webkit/WebCore/page/DOMWindow.cpp @@ -64,6 +64,7 @@ #include "PlatformString.h" #include "Screen.h" #include "SecurityOrigin.h" +#include "SerializedScriptValue.h" #include "Settings.h" #include "Storage.h" #include "StorageArea.h" @@ -80,7 +81,7 @@ namespace WebCore { class PostMessageTimer : public TimerBase { public: - PostMessageTimer(DOMWindow* window, const String& message, const String& sourceOrigin, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortChannelArray> channels, SecurityOrigin* targetOrigin) + PostMessageTimer(DOMWindow* window, PassRefPtr<SerializedScriptValue> message, const String& sourceOrigin, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortChannelArray> channels, SecurityOrigin* targetOrigin) : m_window(window) , m_message(message) , m_origin(sourceOrigin) @@ -104,7 +105,7 @@ private: } RefPtr<DOMWindow> m_window; - String m_message; + RefPtr<SerializedScriptValue> m_message; String m_origin; RefPtr<DOMWindow> m_source; OwnPtr<MessagePortChannelArray> m_channels; @@ -635,7 +636,7 @@ NotificationCenter* DOMWindow::webkitNotifications() const } #endif -void DOMWindow::postMessage(const String& message, MessagePort* port, const String& targetOrigin, DOMWindow* source, ExceptionCode& ec) +void DOMWindow::postMessage(PassRefPtr<SerializedScriptValue> message, MessagePort* port, const String& targetOrigin, DOMWindow* source, ExceptionCode& ec) { MessagePortArray ports; if (port) @@ -643,7 +644,7 @@ void DOMWindow::postMessage(const String& message, MessagePort* port, const Stri postMessage(message, &ports, targetOrigin, source, ec); } -void DOMWindow::postMessage(const String& message, const MessagePortArray* ports, const String& targetOrigin, DOMWindow* source, ExceptionCode& ec) +void DOMWindow::postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray* ports, const String& targetOrigin, DOMWindow* source, ExceptionCode& ec) { if (!m_frame) return; @@ -739,12 +740,9 @@ void DOMWindow::close() return; Settings* settings = m_frame->settings(); - bool allowScriptsToCloseWindows = - settings && settings->allowScriptsToCloseWindows(); + bool allowScriptsToCloseWindows = settings && settings->allowScriptsToCloseWindows(); - if (m_frame->loader()->openedByDOM() - || m_frame->loader()->getHistoryLength() <= 1 - || allowScriptsToCloseWindows) + if (page->openedByDOM() || page->getHistoryLength() <= 1 || allowScriptsToCloseWindows) m_frame->scheduleClose(); } @@ -1296,6 +1294,14 @@ void DOMWindow::dispatchLoadEvent() ownerEvent->setTarget(ownerElement); ownerElement->dispatchGenericEvent(ownerEvent.release()); } + +#if ENABLE(INSPECTOR) + if (!frame() || !frame()->page()) + return; + + if (InspectorController* controller = frame()->page()->inspectorController()) + controller->mainResourceFiredLoadEvent(frame()->loader()->documentLoader(), url()); +#endif } bool DOMWindow::dispatchEvent(PassRefPtr<Event> prpEvent, PassRefPtr<EventTarget> prpTarget) diff --git a/src/3rdparty/webkit/WebCore/page/DOMWindow.h b/src/3rdparty/webkit/WebCore/page/DOMWindow.h index f2177ee..25eadc8 100644 --- a/src/3rdparty/webkit/WebCore/page/DOMWindow.h +++ b/src/3rdparty/webkit/WebCore/page/DOMWindow.h @@ -59,6 +59,7 @@ namespace WebCore { class NotificationCenter; class PostMessageTimer; class ScheduledAction; + class SerializedScriptValue; class Screen; class WebKitPoint; @@ -214,9 +215,9 @@ namespace WebCore { NotificationCenter* webkitNotifications() const; #endif - void postMessage(const String& message, const MessagePortArray*, const String& targetOrigin, DOMWindow* source, ExceptionCode&); + void postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray*, const String& targetOrigin, DOMWindow* source, ExceptionCode&); // FIXME: remove this when we update the ObjC bindings (bug #28774). - void postMessage(const String& message, MessagePort*, const String& targetOrigin, DOMWindow* source, ExceptionCode&); + void postMessage(PassRefPtr<SerializedScriptValue> message, MessagePort*, const String& targetOrigin, DOMWindow* source, ExceptionCode&); void postMessageTimerFired(PostMessageTimer*); void scrollBy(int x, int y) const; diff --git a/src/3rdparty/webkit/WebCore/page/DOMWindow.idl b/src/3rdparty/webkit/WebCore/page/DOMWindow.idl index 4e3a03e..4587001 100644 --- a/src/3rdparty/webkit/WebCore/page/DOMWindow.idl +++ b/src/3rdparty/webkit/WebCore/page/DOMWindow.idl @@ -182,11 +182,11 @@ module window { // cross-document messaging #if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT - [DoNotCheckDomainSecurity, Custom] void postMessage(in DOMString message, in [Optional] Array messagePorts, in DOMString targetOrigin) + [DoNotCheckDomainSecurity, Custom] void postMessage(in SerializedScriptValue message, in [Optional] Array messagePorts, in DOMString targetOrigin) raises(DOMException); #else // There's no good way to expose an array via the ObjC bindings, so for now just allow passing in a single port. - [DoNotCheckDomainSecurity, Custom] void postMessage(in DOMString message, in [Optional] MessagePort messagePort, in DOMString targetOrigin) + [DoNotCheckDomainSecurity, Custom] void postMessage(in SerializedScriptValue message, in [Optional] MessagePort messagePort, in DOMString targetOrigin) raises(DOMException); #endif @@ -434,16 +434,17 @@ module window { attribute [Conditional=3D_CANVAS] CanvasRenderingContext3DConstructor CanvasRenderingContext3D; attribute TextMetricsConstructor TextMetrics; - attribute [CustomGetter,Conditional=3D_CANVAS] CanvasArrayBufferConstructor CanvasArrayBuffer; // Usable with new operator - attribute [CustomGetter,Conditional=3D_CANVAS] CanvasByteArrayConstructor CanvasByteArray; // Usable with new operator - attribute [CustomGetter,Conditional=3D_CANVAS] CanvasUnsignedByteArrayConstructor CanvasUnsignedByteArray; // Usable with new operator - attribute [CustomGetter,Conditional=3D_CANVAS] CanvasShortArrayConstructor CanvasShortArray; // Usable with new operator - attribute [CustomGetter,Conditional=3D_CANVAS] CanvasUnsignedShortArrayConstructor CanvasUnsignedShortArray; // Usable with new operator - attribute [CustomGetter,Conditional=3D_CANVAS] CanvasIntArrayConstructor CanvasIntArray; // Usable with new operator - attribute [CustomGetter,Conditional=3D_CANVAS] CanvasUnsignedIntArrayConstructor CanvasUnsignedIntArray; // Usable with new operator - attribute [CustomGetter,Conditional=3D_CANVAS] CanvasFloatArrayConstructor CanvasFloatArray; // Usable with new operator + attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasArrayBufferConstructor CanvasArrayBuffer; // Usable with new operator + attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasByteArrayConstructor CanvasByteArray; // Usable with new operator + attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasUnsignedByteArrayConstructor CanvasUnsignedByteArray; // Usable with new operator + attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasShortArrayConstructor CanvasShortArray; // Usable with new operator + attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasUnsignedShortArrayConstructor CanvasUnsignedShortArray; // Usable with new operator + attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasIntArrayConstructor CanvasIntArray; // Usable with new operator + attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasUnsignedIntArrayConstructor CanvasUnsignedIntArray; // Usable with new operator + attribute [JSCCustomGetter,Conditional=3D_CANVAS] CanvasFloatArrayConstructor CanvasFloatArray; // Usable with new operator attribute EventConstructor Event; + attribute BeforeLoadEventConstructor BeforeLoadEvent; attribute KeyboardEventConstructor KeyboardEvent; attribute MouseEventConstructor MouseEvent; attribute MutationEventConstructor MutationEvent; @@ -501,11 +502,11 @@ module window { #endif #if defined(ENABLE_SHARED_WORKERS) && ENABLE_SHARED_WORKERS - attribute [JSCCustomGetter] SharedWorkerConstructor SharedWorker; // Usable with the new operator + attribute [JSCCustomGetter, EnabledAtRuntime] SharedWorkerConstructor SharedWorker; // Usable with the new operator #endif #if defined(ENABLE_WEB_SOCKETS) && ENABLE_WEB_SOCKETS - attribute [JSCCustomGetter] WebSocketConstructor WebSocket; // Usable with the new operator + attribute [JSCCustomGetter,EnabledAtRuntime] WebSocketConstructor WebSocket; // Usable with the new operator #endif attribute PluginConstructor Plugin; @@ -522,11 +523,11 @@ module window { attribute StorageEventConstructor StorageEvent; #endif - attribute [CustomGetter,Conditional=VIDEO] HTMLAudioElementConstructor Audio; // Usable with the new operator - attribute [Conditional=VIDEO] HTMLAudioElementConstructor HTMLAudioElement; - attribute [Conditional=VIDEO] HTMLMediaElementConstructor HTMLMediaElement; - attribute [Conditional=VIDEO] HTMLVideoElementConstructor HTMLVideoElement; - attribute [Conditional=VIDEO] MediaErrorConstructor MediaError; + attribute [CustomGetter, Conditional=VIDEO, EnabledAtRuntime] HTMLAudioElementConstructor Audio; // Usable with the new operator + attribute [Conditional=VIDEO, EnabledAtRuntime] HTMLAudioElementConstructor HTMLAudioElement; + attribute [Conditional=VIDEO, EnabledAtRuntime] HTMLMediaElementConstructor HTMLMediaElement; + attribute [Conditional=VIDEO, EnabledAtRuntime] HTMLVideoElementConstructor HTMLVideoElement; + attribute [Conditional=VIDEO, EnabledAtRuntime] MediaErrorConstructor MediaError; #if defined(ENABLE_XPATH) && ENABLE_XPATH attribute XPathEvaluatorConstructor XPathEvaluator; @@ -559,7 +560,7 @@ module window { attribute SVGFECompositeElementConstructor SVGFECompositeElement; // attribute SVGFEConvolveMatrixElementConstructor SVGFEConvolveMatrixElement; attribute SVGFEDisplacementMapElementConstructor SVGFEDisplacementMapElement; -// attribute SVGFEMorphologyElementConstructor SVGFEMorphologyElement; + attribute SVGFEMorphologyElementConstructor SVGFEMorphologyElement; attribute SVGFETurbulenceElementConstructor SVGFETurbulenceElement; #endif #endif diff --git a/src/3rdparty/webkit/WebCore/page/DragController.cpp b/src/3rdparty/webkit/WebCore/page/DragController.cpp index ab3a653..634595a 100644 --- a/src/3rdparty/webkit/WebCore/page/DragController.cpp +++ b/src/3rdparty/webkit/WebCore/page/DragController.cpp @@ -649,6 +649,12 @@ bool DragController::startDrag(Frame* src, Clipboard* clipboard, DragOperation s if (isDHTMLDrag) dragImage = clipboard->createDragImage(dragImageOffset); + else { + // This drag operation is not a DHTML drag and may go outside the WebView. + // We provide a default set of allowed drag operations that follows from: + // http://trac.webkit.org/browser/trunk/WebKit/mac/WebView/WebHTMLView.mm?rev=48526#L3430 + m_sourceDragOperation = (DragOperation)(DragOperationGeneric | DragOperationCopy); + } // We allow DHTML/JS to set the drag image, even if its a link, image or text we're dragging. // This is in the spirit of the IE API, which allows overriding of pasteboard data and DragOp. diff --git a/src/3rdparty/webkit/WebCore/page/EventHandler.cpp b/src/3rdparty/webkit/WebCore/page/EventHandler.cpp index 1075e72..4e97aba 100644 --- a/src/3rdparty/webkit/WebCore/page/EventHandler.cpp +++ b/src/3rdparty/webkit/WebCore/page/EventHandler.cpp @@ -127,10 +127,12 @@ inline bool EventHandler::eventLoopHandleMouseUp(const MouseEventWithHitTestResu return false; } +#if ENABLE(DRAG_SUPPORT) inline bool EventHandler::eventLoopHandleMouseDragged(const MouseEventWithHitTestResults&) { return false; } +#endif #endif @@ -1528,15 +1530,15 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard* // it is sometimes incorrect when dragging within subframes, as seen with // LayoutTests/fast/events/drag-in-frames.html. if (newTarget) { - if (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag)) - accept = static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame()->eventHandler()->updateDragAndDrop(event, clipboard); + Frame* frame = (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag)) ? static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame() : 0; + if (frame) + accept = frame->eventHandler()->updateDragAndDrop(event, clipboard); else accept = dispatchDragEvent(eventNames().dragenterEvent, newTarget, event, clipboard); } if (m_dragTarget) { - Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag)) - ? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0; + Frame* frame = (m_dragTarget->hasTagName(frameTag) || m_dragTarget->hasTagName(iframeTag)) ? static_cast<HTMLFrameElementBase*>(m_dragTarget.get())->contentFrame() : 0; if (frame) accept = frame->eventHandler()->updateDragAndDrop(event, clipboard); else @@ -1544,8 +1546,9 @@ bool EventHandler::updateDragAndDrop(const PlatformMouseEvent& event, Clipboard* } } else { if (newTarget) { - if (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag)) - accept = static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame()->eventHandler()->updateDragAndDrop(event, clipboard); + Frame* frame = (newTarget->hasTagName(frameTag) || newTarget->hasTagName(iframeTag)) ? static_cast<HTMLFrameElementBase*>(newTarget)->contentFrame() : 0; + if (frame) + accept = frame->eventHandler()->updateDragAndDrop(event, clipboard); else accept = dispatchDragEvent(eventNames().dragoverEvent, newTarget, event, clipboard); } @@ -2178,7 +2181,7 @@ void EventHandler::freeClipboard() bool EventHandler::shouldDragAutoNode(Node* node, const IntPoint& point) const { - if (!node || node->hasChildNodes() || !m_frame->view()) + if (!node || !m_frame->view()) return false; Page* page = m_frame->page(); return page && page->dragController()->mayStartDragAtEventLocation(m_frame, point); diff --git a/src/3rdparty/webkit/WebCore/page/EventSource.cpp b/src/3rdparty/webkit/WebCore/page/EventSource.cpp index ae3c0c3..2c9a343 100644 --- a/src/3rdparty/webkit/WebCore/page/EventSource.cpp +++ b/src/3rdparty/webkit/WebCore/page/EventSource.cpp @@ -45,6 +45,7 @@ #include "ResourceRequest.h" #include "ResourceResponse.h" #include "ScriptExecutionContext.h" +#include "SerializedScriptValue.h" #include "TextResourceDecoder.h" #include "ThreadableLoader.h" @@ -294,7 +295,7 @@ void EventSource::stop() PassRefPtr<MessageEvent> EventSource::createMessageEvent() { RefPtr<MessageEvent> event = MessageEvent::create(); - event->initMessageEvent(m_eventName.isEmpty() ? eventNames().messageEvent : AtomicString(m_eventName), false, false, String::adopt(m_data), m_origin, m_lastEventId, 0, 0); + event->initMessageEvent(m_eventName.isEmpty() ? eventNames().messageEvent : AtomicString(m_eventName), false, false, SerializedScriptValue::create(String::adopt(m_data)), m_origin, m_lastEventId, 0, 0); return event.release(); } diff --git a/src/3rdparty/webkit/WebCore/page/Frame.cpp b/src/3rdparty/webkit/WebCore/page/Frame.cpp index e8e796f..fab7e3f 100644 --- a/src/3rdparty/webkit/WebCore/page/Frame.cpp +++ b/src/3rdparty/webkit/WebCore/page/Frame.cpp @@ -123,6 +123,7 @@ Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* : m_page(page) , m_treeNode(this, parentFromOwnerElement(ownerElement)) , m_loader(this, frameLoaderClient) + , m_redirectScheduler(this) , m_ownerElement(ownerElement) , m_script(this) , m_selectionGranularity(CharacterGranularity) @@ -197,6 +198,7 @@ Frame::~Frame() if (m_domWindow) m_domWindow->disconnectFrame(); + script()->clearWindowShell(); HashSet<DOMWindow*>::iterator end = m_liveFormerWindows.end(); for (HashSet<DOMWindow*>::iterator it = m_liveFormerWindows.begin(); it != end; ++it) @@ -220,6 +222,11 @@ FrameLoader* Frame::loader() const return &m_loader; } +RedirectScheduler* Frame::redirectScheduler() const +{ + return &m_redirectScheduler; +} + FrameView* Frame::view() const { return m_view.get(); @@ -875,12 +882,11 @@ void Frame::injectUserScriptsForWorld(unsigned worldID, const UserScriptVector& if (!doc) return; - // FIXME: Need to implement pattern checking. Vector<ScriptSourceCode> sourceCode; unsigned count = userScripts.size(); for (unsigned i = 0; i < count; ++i) { UserScript* script = userScripts[i].get(); - if (script->injectionTime() == injectionTime && UserContentURLPattern::matchesPatterns(doc->url(), script->patterns())) + if (script->injectionTime() == injectionTime && UserContentURLPattern::matchesPatterns(doc->url(), script->whitelist(), script->blacklist())) sourceCode.append(ScriptSourceCode(script->source(), script->url())); } script()->evaluateInIsolatedWorld(worldID, sourceCode); diff --git a/src/3rdparty/webkit/WebCore/page/Frame.h b/src/3rdparty/webkit/WebCore/page/Frame.h index b98dbc4..6208bbd 100644 --- a/src/3rdparty/webkit/WebCore/page/Frame.h +++ b/src/3rdparty/webkit/WebCore/page/Frame.h @@ -67,6 +67,7 @@ namespace WebCore { class Editor; class EventHandler; class FrameLoader; + class RedirectScheduler; class FrameLoaderClient; class FrameTree; class FrameView; @@ -110,6 +111,7 @@ namespace WebCore { Editor* editor() const; EventHandler* eventHandler() const; FrameLoader* loader() const; + RedirectScheduler* redirectScheduler() const; SelectionController* selection() const; FrameTree* tree() const; AnimationController* animation() const; @@ -334,6 +336,7 @@ namespace WebCore { Page* m_page; mutable FrameTree m_treeNode; mutable FrameLoader m_loader; + mutable RedirectScheduler m_redirectScheduler; mutable RefPtr<DOMWindow> m_domWindow; HashSet<DOMWindow*> m_liveFormerWindows; diff --git a/src/3rdparty/webkit/WebCore/page/FrameView.cpp b/src/3rdparty/webkit/WebCore/page/FrameView.cpp index 675cba1..bc4e4f2 100644 --- a/src/3rdparty/webkit/WebCore/page/FrameView.cpp +++ b/src/3rdparty/webkit/WebCore/page/FrameView.cpp @@ -52,12 +52,24 @@ #include "RenderTheme.h" #include "RenderView.h" #include "Settings.h" +#include "TextResourceDecoder.h" #include <wtf/CurrentTime.h> #if USE(ACCELERATED_COMPOSITING) #include "RenderLayerCompositor.h" #endif +#if ENABLE(SVG) +#include "SVGDocument.h" +#include "SVGLocatable.h" +#include "SVGNames.h" +#include "SVGPreserveAspectRatio.h" +#include "SVGSVGElement.h" +#include "SVGViewElement.h" +#include "SVGViewSpec.h" +#endif + + namespace WebCore { using namespace HTMLNames; @@ -640,6 +652,7 @@ void FrameView::layout(bool allowSubtree) beginDeferredRepaints(); layer->updateLayerPositions((m_doFullRepaint ? RenderLayer::DoFullRepaint : 0) | RenderLayer::CheckForRepaint + | RenderLayer::IsCompositingUpdateRoot | RenderLayer::UpdateCompositingLayers); endDeferredRepaints(); @@ -769,6 +782,72 @@ void FrameView::restoreScrollbar() setScrollbarsSuppressed(false); } +bool FrameView::scrollToFragment(const KURL& url) +{ + // If our URL has no ref, then we have no place we need to jump to. + // OTOH If CSS target was set previously, we want to set it to 0, recalc + // and possibly repaint because :target pseudo class may have been + // set (see bug 11321). + if (!url.hasFragmentIdentifier() && !m_frame->document()->cssTarget()) + return false; + + String fragmentIdentifier = url.fragmentIdentifier(); + if (scrollToAnchor(fragmentIdentifier)) + return true; + + // Try again after decoding the ref, based on the document's encoding. + if (TextResourceDecoder* decoder = m_frame->document()->decoder()) + return scrollToAnchor(decodeURLEscapeSequences(fragmentIdentifier, decoder->encoding())); + + return false; +} + +bool FrameView::scrollToAnchor(const String& name) +{ + ASSERT(m_frame->document()); + + if (!m_frame->document()->haveStylesheetsLoaded()) { + m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(true); + return false; + } + + m_frame->document()->setGotoAnchorNeededAfterStylesheetsLoad(false); + + Element* anchorNode = m_frame->document()->findAnchor(name); + +#if ENABLE(SVG) + if (m_frame->document()->isSVGDocument()) { + if (name.startsWith("xpointer(")) { + // We need to parse the xpointer reference here + } else if (name.startsWith("svgView(")) { + RefPtr<SVGSVGElement> svg = static_cast<SVGDocument*>(m_frame->document())->rootElement(); + if (!svg->currentView()->parseViewSpec(name)) + return false; + svg->setUseCurrentView(true); + } else { + if (anchorNode && anchorNode->hasTagName(SVGNames::viewTag)) { + RefPtr<SVGViewElement> viewElement = anchorNode->hasTagName(SVGNames::viewTag) ? static_cast<SVGViewElement*>(anchorNode) : 0; + if (viewElement.get()) { + RefPtr<SVGSVGElement> svg = static_cast<SVGSVGElement*>(SVGLocatable::nearestViewportElement(viewElement.get())); + svg->inheritViewAttributes(viewElement.get()); + } + } + } + // FIXME: need to decide which <svg> to focus on, and zoom to that one + // FIXME: need to actually "highlight" the viewTarget(s) + } +#endif + + m_frame->document()->setCSSTarget(anchorNode); // Setting to null will clear the current target. + + // Implement the rule that "" and "top" both mean top of page as in other browsers. + if (!anchorNode && !(name.isEmpty() || equalIgnoringCase(name, "top"))) + return false; + + maintainScrollPositionAtAnchor(anchorNode ? static_cast<Node*>(anchorNode) : m_frame->document()); + return true; +} + void FrameView::maintainScrollPositionAtAnchor(Node* anchorNode) { m_maintainScrollPositionAnchor = anchorNode; diff --git a/src/3rdparty/webkit/WebCore/page/FrameView.h b/src/3rdparty/webkit/WebCore/page/FrameView.h index 4c900ae..3d17d2c 100644 --- a/src/3rdparty/webkit/WebCore/page/FrameView.h +++ b/src/3rdparty/webkit/WebCore/page/FrameView.h @@ -183,6 +183,8 @@ public: void adjustPageHeight(float* newBottom, float oldTop, float oldBottom, float bottomLimit); + bool scrollToFragment(const KURL&); + bool scrollToAnchor(const String&); void maintainScrollPositionAtAnchor(Node*); // Methods to convert points and rects between the coordinate space of the renderer, and this view. diff --git a/src/3rdparty/webkit/WebCore/page/History.cpp b/src/3rdparty/webkit/WebCore/page/History.cpp index 2527132..9a27f1c 100644 --- a/src/3rdparty/webkit/WebCore/page/History.cpp +++ b/src/3rdparty/webkit/WebCore/page/History.cpp @@ -50,28 +50,30 @@ unsigned History::length() const { if (!m_frame) return 0; - return m_frame->loader()->getHistoryLength(); + if (!m_frame->page()) + return 0; + return m_frame->page()->getHistoryLength(); } void History::back() { if (!m_frame) return; - m_frame->loader()->scheduleHistoryNavigation(-1); + m_frame->redirectScheduler()->scheduleHistoryNavigation(-1); } void History::forward() { if (!m_frame) return; - m_frame->loader()->scheduleHistoryNavigation(1); + m_frame->redirectScheduler()->scheduleHistoryNavigation(1); } void History::go(int distance) { if (!m_frame) return; - m_frame->loader()->scheduleHistoryNavigation(distance); + m_frame->redirectScheduler()->scheduleHistoryNavigation(distance); } } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/page/Page.cpp b/src/3rdparty/webkit/WebCore/page/Page.cpp index 2d0c91c..8a685f4 100644 --- a/src/3rdparty/webkit/WebCore/page/Page.cpp +++ b/src/3rdparty/webkit/WebCore/page/Page.cpp @@ -119,6 +119,7 @@ Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, Edi , m_theme(RenderTheme::themeForPage(this)) , m_editorClient(editorClient) , m_frameCount(0) + , m_openedByDOM(false) , m_tabKeyCyclesThroughElements(true) , m_defersLoading(false) , m_inLowQualityInterpolationMode(false) @@ -136,7 +137,6 @@ Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, Edi , m_customHTMLTokenizerTimeDelay(-1) , m_customHTMLTokenizerChunkSize(-1) , m_canStartPlugins(true) - , m_pluginHalterClient(pluginHalterClient) { #if !ENABLE(CONTEXT_MENUS) UNUSED_PARAM(contextMenuClient); @@ -156,7 +156,10 @@ Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, Edi ASSERT(!allPages->contains(this)); allPages->add(this); - pluginHalterEnabledStateChanged(); + if (pluginHalterClient) { + m_pluginHalter.set(new PluginHalter(pluginHalterClient)); + m_pluginHalter->setPluginAllowedRunTime(m_settings->pluginAllowedRunTime()); + } #if ENABLE(JAVASCRIPT_DEBUGGER) JavaScriptDebugServer::shared().pageCreated(this); @@ -201,6 +204,16 @@ void Page::setMainFrame(PassRefPtr<Frame> mainFrame) m_mainFrame = mainFrame; } +bool Page::openedByDOM() const +{ + return m_openedByDOM; +} + +void Page::setOpenedByDOM() +{ + m_openedByDOM = true; +} + BackForwardList* Page::backForwardList() { return m_backForwardList.get(); @@ -228,6 +241,40 @@ bool Page::goForward() return false; } +bool Page::canGoBackOrForward(int distance) const +{ + if (distance == 0) + return true; + if (distance > 0 && distance <= m_backForwardList->forwardListCount()) + return true; + if (distance < 0 && -distance <= m_backForwardList->backListCount()) + return true; + return false; +} + +void Page::goBackOrForward(int distance) +{ + if (distance == 0) + return; + + HistoryItem* item = m_backForwardList->itemAtIndex(distance); + if (!item) { + if (distance > 0) { + int forwardListCount = m_backForwardList->forwardListCount(); + if (forwardListCount > 0) + item = m_backForwardList->itemAtIndex(forwardListCount); + } else { + int backListCount = m_backForwardList->backListCount(); + if (backListCount > 0) + item = m_backForwardList->itemAtIndex(-backListCount); + } + } + + ASSERT(item); // we should not reach this line with an empty back/forward list + if (item) + goToItem(item, FrameLoadTypeIndexedBackForward); +} + void Page::goToItem(HistoryItem* item, FrameLoadType type) { // Abort any current load if we're going to a history item @@ -244,7 +291,12 @@ void Page::goToItem(HistoryItem* item, FrameLoadType type) databasePolicy = DatabasePolicyContinue; #endif m_mainFrame->loader()->stopAllLoaders(databasePolicy); - m_mainFrame->loader()->goToItem(item, type); + m_mainFrame->loader()->history()->goToItem(item, type); +} + +int Page::getHistoryLength() +{ + return m_backForwardList->backListCount() + 1; } void Page::setGlobalHistoryItem(HistoryItem* item) @@ -683,16 +735,6 @@ InspectorTimelineAgent* Page::inspectorTimelineAgent() const } #endif -void Page::pluginHalterEnabledStateChanged() -{ - if (m_settings->pluginHalterEnabled()) { - ASSERT(!m_pluginHalter); - m_pluginHalter.set(new PluginHalter(m_pluginHalterClient)); - m_pluginHalter->setPluginAllowedRunTime(m_settings->pluginAllowedRunTime()); - } else - m_pluginHalter = 0; -} - void Page::pluginAllowedRunTimeChanged() { if (m_pluginHalter) diff --git a/src/3rdparty/webkit/WebCore/page/Page.h b/src/3rdparty/webkit/WebCore/page/Page.h index 602d99b..4886464 100644 --- a/src/3rdparty/webkit/WebCore/page/Page.h +++ b/src/3rdparty/webkit/WebCore/page/Page.h @@ -103,6 +103,9 @@ namespace WebCore { void setMainFrame(PassRefPtr<Frame>); Frame* mainFrame() const { return m_mainFrame.get(); } + bool openedByDOM() const; + void setOpenedByDOM(); + BackForwardList* backForwardList(); // FIXME: The following three methods don't fall under the responsibilities of the Page object @@ -111,7 +114,10 @@ namespace WebCore { // makes more sense when that class exists. bool goBack(); bool goForward(); + bool canGoBackOrForward(int distance) const; + void goBackOrForward(int distance); void goToItem(HistoryItem*, FrameLoadType); + int getHistoryLength(); HistoryItem* globalHistoryItem() const { return m_globalHistoryItem.get(); } void setGlobalHistoryItem(HistoryItem*); @@ -187,7 +193,6 @@ namespace WebCore { void didStartPlugin(HaltablePlugin*); void didStopPlugin(HaltablePlugin*); void pluginAllowedRunTimeChanged(); - void pluginHalterEnabledStateChanged(); static void setDebuggerForAllPages(JSC::Debugger*); void setDebugger(JSC::Debugger*); @@ -261,6 +266,7 @@ namespace WebCore { int m_frameCount; String m_groupName; + bool m_openedByDOM; bool m_tabKeyCyclesThroughElements; bool m_defersLoading; @@ -293,7 +299,6 @@ namespace WebCore { HashSet<PluginView*> m_unstartedPlugins; OwnPtr<PluginHalter> m_pluginHalter; - PluginHalterClient* m_pluginHalterClient; #if ENABLE(DOM_STORAGE) RefPtr<StorageNamespace> m_sessionStorage; diff --git a/src/3rdparty/webkit/WebCore/page/PageGroup.cpp b/src/3rdparty/webkit/WebCore/page/PageGroup.cpp index f9855a7..427c240 100644 --- a/src/3rdparty/webkit/WebCore/page/PageGroup.cpp +++ b/src/3rdparty/webkit/WebCore/page/PageGroup.cpp @@ -191,20 +191,21 @@ StorageNamespace* PageGroup::localStorage() if (!m_localStorage) { // Need a page in this page group to query the settings for the local storage database path. Page* page = *m_pages.begin(); - ASSERT(page); - m_localStorage = StorageNamespace::localStorageNamespace(page->settings()->localStorageDatabasePath()); + const String& path = page->settings()->localStorageDatabasePath(); + unsigned quota = page->settings()->localStorageQuota(); + m_localStorage = StorageNamespace::localStorageNamespace(path, quota); } return m_localStorage.get(); } #endif -void PageGroup::addUserScript(const String& source, const KURL& url, const Vector<String>& patterns, - unsigned worldID, UserScriptInjectionTime injectionTime) +void PageGroup::addUserScriptToWorld(unsigned worldID, const String& source, const KURL& url, PassOwnPtr<Vector<String> > whitelist, + PassOwnPtr<Vector<String> > blacklist, UserScriptInjectionTime injectionTime) { if (worldID == UINT_MAX) return; - OwnPtr<UserScript> userScript(new UserScript(source, url, patterns, worldID, injectionTime)); + OwnPtr<UserScript> userScript(new UserScript(source, url, whitelist, blacklist, worldID, injectionTime)); if (!m_userScripts) m_userScripts.set(new UserScriptMap); UserScriptVector*& scriptsInWorld = m_userScripts->add(worldID, 0).first->second; @@ -213,11 +214,12 @@ void PageGroup::addUserScript(const String& source, const KURL& url, const Vecto scriptsInWorld->append(userScript.release()); } -void PageGroup::addUserStyleSheet(const String& source, const KURL& url, const Vector<String>& patterns, unsigned worldID) +void PageGroup::addUserStyleSheetToWorld(unsigned worldID, const String& source, const KURL& url, PassOwnPtr<Vector<String> > whitelist, + PassOwnPtr<Vector<String> > blacklist) { if (worldID == UINT_MAX) return; - OwnPtr<UserStyleSheet> userStyleSheet(new UserStyleSheet(source, url, patterns, worldID)); + OwnPtr<UserStyleSheet> userStyleSheet(new UserStyleSheet(source, url, whitelist, blacklist, worldID)); if (!m_userStyleSheets) m_userStyleSheets.set(new UserStyleSheetMap); UserStyleSheetVector*& styleSheetsInWorld = m_userStyleSheets->add(worldID, 0).first->second; @@ -233,23 +235,93 @@ void PageGroup::addUserStyleSheet(const String& source, const KURL& url, const V } } -void PageGroup::removeUserContentForWorld(unsigned worldID) +void PageGroup::removeUserScriptFromWorld(unsigned worldID, const KURL& url) { - if (m_userScripts) { - UserScriptMap::iterator it = m_userScripts->find(worldID); - if (it != m_userScripts->end()) { - m_userScripts->remove(it); - delete it->second; - } + if (!m_userScripts) + return; + + UserScriptMap::iterator it = m_userScripts->find(worldID); + if (it == m_userScripts->end()) + return; + + UserScriptVector* scripts = it->second; + for (int i = scripts->size() - 1; i >= 0; --i) { + if (scripts->at(i)->url() == url) + scripts->remove(i); } - if (m_userStyleSheets) { - UserStyleSheetMap::iterator it = m_userStyleSheets->find(worldID); - if (it != m_userStyleSheets->end()) { - m_userStyleSheets->remove(it); - delete it->second; + if (!scripts->isEmpty()) + return; + + delete it->second; + m_userScripts->remove(it); +} + +void PageGroup::removeUserStyleSheetFromWorld(unsigned worldID, const KURL& url) +{ + if (!m_userStyleSheets) + return; + + UserStyleSheetMap::iterator it = m_userStyleSheets->find(worldID); + bool sheetsChanged = false; + if (it == m_userStyleSheets->end()) + return; + + UserStyleSheetVector* stylesheets = it->second; + for (int i = stylesheets->size() - 1; i >= 0; --i) { + if (stylesheets->at(i)->url() == url) { + stylesheets->remove(i); + sheetsChanged = true; } } + + if (!sheetsChanged) + return; + + if (!stylesheets->isEmpty()) { + delete it->second; + m_userStyleSheets->remove(it); + } + + // Clear our cached sheets and have them just reparse. + HashSet<Page*>::const_iterator end = m_pages.end(); + for (HashSet<Page*>::const_iterator it = m_pages.begin(); it != end; ++it) { + for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) + frame->document()->clearPageGroupUserSheets(); + } +} + +void PageGroup::removeUserScriptsFromWorld(unsigned worldID) +{ + if (!m_userScripts) + return; + + UserScriptMap::iterator it = m_userScripts->find(worldID); + if (it == m_userScripts->end()) + return; + + delete it->second; + m_userScripts->remove(it); +} + +void PageGroup::removeUserStyleSheetsFromWorld(unsigned worldID) +{ + if (!m_userStyleSheets) + return; + + UserStyleSheetMap::iterator it = m_userStyleSheets->find(worldID); + if (it == m_userStyleSheets->end()) + return; + + delete it->second; + m_userStyleSheets->remove(it); + + // Clear our cached sheets and have them just reparse. + HashSet<Page*>::const_iterator end = m_pages.end(); + for (HashSet<Page*>::const_iterator it = m_pages.begin(); it != end; ++it) { + for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree()->traverseNext()) + frame->document()->clearPageGroupUserSheets(); + } } void PageGroup::removeAllUserContent() diff --git a/src/3rdparty/webkit/WebCore/page/PageGroup.h b/src/3rdparty/webkit/WebCore/page/PageGroup.h index 0bf3fbc..c233cd1 100644 --- a/src/3rdparty/webkit/WebCore/page/PageGroup.h +++ b/src/3rdparty/webkit/WebCore/page/PageGroup.h @@ -70,16 +70,23 @@ namespace WebCore { bool hasLocalStorage() { return m_localStorage; } #endif - void addUserScript(const String& source, const KURL&, const Vector<String>& patterns, - unsigned worldID, UserScriptInjectionTime); - const UserScriptMap* userScripts() const { return m_userScripts.get(); } + void addUserScriptToWorld(unsigned worldID, const String& source, const KURL&, + PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist, + UserScriptInjectionTime); + void addUserStyleSheetToWorld(unsigned worldID, const String& source, const KURL&, + PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist); - void addUserStyleSheet(const String& source, const KURL&, const Vector<String>& patterns, unsigned worldID); - const UserStyleSheetMap* userStyleSheets() const { return m_userStyleSheets.get(); } + void removeUserScriptFromWorld(unsigned, const KURL&); + void removeUserStyleSheetFromWorld(unsigned, const KURL&); - void removeUserContentForWorld(unsigned); + void removeUserScriptsFromWorld(unsigned); + void removeUserStyleSheetsFromWorld(unsigned); + void removeAllUserContent(); + const UserScriptMap* userScripts() const { return m_userScripts.get(); } + const UserStyleSheetMap* userStyleSheets() const { return m_userStyleSheets.get(); } + private: void addVisitedLink(LinkHash stringHash); diff --git a/src/3rdparty/webkit/WebCore/page/PluginHalter.cpp b/src/3rdparty/webkit/WebCore/page/PluginHalter.cpp index 8025337..63f5469 100644 --- a/src/3rdparty/webkit/WebCore/page/PluginHalter.cpp +++ b/src/3rdparty/webkit/WebCore/page/PluginHalter.cpp @@ -28,7 +28,6 @@ #include "PluginHalter.h" #include "HaltablePlugin.h" -#include "PluginHalterClient.h" #include <wtf/CurrentTime.h> #include <wtf/Vector.h> @@ -49,6 +48,9 @@ void PluginHalter::didStartPlugin(HaltablePlugin* obj) ASSERT_ARG(obj, obj); ASSERT_ARG(obj, !m_plugins.contains(obj)); + if (!m_client->enabled()) + return; + double currentTime = WTF::currentTime(); m_plugins.add(obj, currentTime); @@ -61,6 +63,9 @@ void PluginHalter::didStartPlugin(HaltablePlugin* obj) void PluginHalter::didStopPlugin(HaltablePlugin* obj) { + if (!m_client->enabled()) + return; + m_plugins.remove(obj); } diff --git a/src/3rdparty/webkit/WebCore/page/PluginHalter.h b/src/3rdparty/webkit/WebCore/page/PluginHalter.h index 26f5101..eddce34 100644 --- a/src/3rdparty/webkit/WebCore/page/PluginHalter.h +++ b/src/3rdparty/webkit/WebCore/page/PluginHalter.h @@ -26,13 +26,14 @@ #ifndef PluginHalter_h #define PluginHalter_h +#include "PluginHalterClient.h" #include "Timer.h" #include <wtf/HashMap.h> +#include <wtf/OwnPtr.h> namespace WebCore { class HaltablePlugin; -class PluginHalterClient; class PluginHalter { public: @@ -47,7 +48,7 @@ private: void timerFired(Timer<PluginHalter>*); void startTimerIfNecessary(); - PluginHalterClient* m_client; + OwnPtr<PluginHalterClient> m_client; Timer<PluginHalter> m_timer; unsigned m_pluginAllowedRunTime; double m_oldestStartTime; diff --git a/src/3rdparty/webkit/WebCore/page/PluginHalterClient.h b/src/3rdparty/webkit/WebCore/page/PluginHalterClient.h index 7ea460a..f77091f 100644 --- a/src/3rdparty/webkit/WebCore/page/PluginHalterClient.h +++ b/src/3rdparty/webkit/WebCore/page/PluginHalterClient.h @@ -35,6 +35,7 @@ public: virtual ~PluginHalterClient() { } virtual bool shouldHaltPlugin(Node*) const = 0; + virtual bool enabled() const = 0; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/page/PrintContext.cpp b/src/3rdparty/webkit/WebCore/page/PrintContext.cpp index 4d3a839..bba678a 100644 --- a/src/3rdparty/webkit/WebCore/page/PrintContext.cpp +++ b/src/3rdparty/webkit/WebCore/page/PrintContext.cpp @@ -25,6 +25,7 @@ #include "Frame.h" #include "FrameView.h" #include "RenderView.h" +#include "Settings.h" using namespace WebCore; @@ -95,18 +96,23 @@ void PrintContext::computePageRects(const FloatRect& printRect, float headerHeig void PrintContext::begin(float width) { - // By imaging to a width a little wider than the available pixels, - // thin pages will be scaled down a little, matching the way they - // print in IE and Camino. This lets them use fewer sheets than they - // would otherwise, which is presumably why other browsers do this. - // Wide pages will be scaled down more than this. - const float PrintingMinimumShrinkFactor = 1.25f; - - // This number determines how small we are willing to reduce the page content - // in order to accommodate the widest line. If the page would have to be - // reduced smaller to make the widest line fit, we just clip instead (this - // behavior matches MacIE and Mozilla, at least) - const float PrintingMaximumShrinkFactor = 2.0f; + float PrintingMinimumShrinkFactor = m_frame->settings() ? m_frame->settings()->printingMinimumShrinkFactor() : 0.0f; + float PrintingMaximumShrinkFactor = m_frame->settings() ? m_frame->settings()->printingMaximumShrinkFactor() : 0.0f; + + if (PrintingMaximumShrinkFactor < PrintingMinimumShrinkFactor || PrintingMinimumShrinkFactor <= 0.0f) { + // By imaging to a width a little wider than the available pixels, + // thin pages will be scaled down a little, matching the way they + // print in IE and Camino. This lets them use fewer sheets than they + // would otherwise, which is presumably why other browsers do this. + // Wide pages will be scaled down more than this. + PrintingMinimumShrinkFactor = 1.25f; + + // This number determines how small we are willing to reduce the page content + // in order to accommodate the widest line. If the page would have to be + // reduced smaller to make the widest line fit, we just clip instead (this + // behavior matches MacIE and Mozilla, at least) + PrintingMaximumShrinkFactor = 2.0f; + } float minLayoutWidth = width * PrintingMinimumShrinkFactor; float maxLayoutWidth = width * PrintingMaximumShrinkFactor; diff --git a/src/3rdparty/webkit/WebCore/page/SecurityOrigin.cpp b/src/3rdparty/webkit/WebCore/page/SecurityOrigin.cpp index b91c1f1..338bf9f 100644 --- a/src/3rdparty/webkit/WebCore/page/SecurityOrigin.cpp +++ b/src/3rdparty/webkit/WebCore/page/SecurityOrigin.cpp @@ -30,13 +30,15 @@ #include "SecurityOrigin.h" #include "CString.h" -#include "FrameLoader.h" +#include "Document.h" #include "KURL.h" #include "OriginAccessEntry.h" #include <wtf/StdLibExtras.h> namespace WebCore { +static SecurityOrigin::LocalLoadPolicy localLoadPolicy = SecurityOrigin::AllowLocalLoadsForLocalOnly; + typedef Vector<OriginAccessEntry> OriginAccessWhiteList; typedef HashMap<String, OriginAccessWhiteList*> OriginAccessMap; @@ -116,9 +118,9 @@ SecurityOrigin::SecurityOrigin(const KURL& url) } SecurityOrigin::SecurityOrigin(const SecurityOrigin* other) - : m_protocol(other->m_protocol.copy()) - , m_host(other->m_host.copy()) - , m_domain(other->m_domain.copy()) + : m_protocol(other->m_protocol.threadsafeCopy()) + , m_host(other->m_host.threadsafeCopy()) + , m_domain(other->m_domain.threadsafeCopy()) , m_port(other->m_port) , m_noAccess(other->m_noAccess) , m_universalAccess(other->m_universalAccess) @@ -144,7 +146,7 @@ PassRefPtr<SecurityOrigin> SecurityOrigin::createEmpty() return create(KURL()); } -PassRefPtr<SecurityOrigin> SecurityOrigin::copy() +PassRefPtr<SecurityOrigin> SecurityOrigin::threadsafeCopy() { return adoptRef(new SecurityOrigin(this)); } @@ -237,6 +239,20 @@ bool SecurityOrigin::taintsCanvas(const KURL& url) const return true; } +bool SecurityOrigin::canLoad(const KURL& url, const String& referrer, Document* document) +{ + if (!shouldTreatURLAsLocal(url.string())) + return true; + + // If we were provided a document, we let its local file policy dictate the result, + // otherwise we allow local loads only if the supplied referrer is also local. + if (document) + return document->securityOrigin()->canLoadLocalResources(); + if (!referrer.isEmpty()) + return shouldTreatURLAsLocal(referrer); + return false; +} + void SecurityOrigin::grantLoadLocalResources() { // This method exists only to support backwards compatibility with older @@ -244,7 +260,7 @@ void SecurityOrigin::grantLoadLocalResources() // in a SecurityOrigin is a security hazard because the documents without // the privilege can obtain the privilege by injecting script into the // documents that have been granted the privilege. - ASSERT(FrameLoader::allowSubstituteDataAccessToLocal()); + ASSERT(allowSubstituteDataAccessToLocal()); m_canLoadLocalResources = true; } @@ -370,13 +386,11 @@ bool SecurityOrigin::isSameSchemeHostPort(const SecurityOrigin* other) const return true; } -// static void SecurityOrigin::registerURLSchemeAsLocal(const String& scheme) { localSchemes().add(scheme); } -// static void SecurityOrigin::removeURLSchemeRegisteredAsLocal(const String& scheme) { if (scheme == "file") @@ -392,13 +406,11 @@ void SecurityOrigin::removeURLSchemeRegisteredAsLocal(const String& scheme) localSchemes().remove(scheme); } -// static const URLSchemesMap& SecurityOrigin::localURLSchemes() { return localSchemes(); } -// static bool SecurityOrigin::shouldTreatURLAsLocal(const String& url) { // This avoids an allocation of another String and the HashSet contains() @@ -419,7 +431,6 @@ bool SecurityOrigin::shouldTreatURLAsLocal(const String& url) return localSchemes().contains(scheme); } -// static bool SecurityOrigin::shouldTreatURLSchemeAsLocal(const String& scheme) { // This avoids an allocation of another String and the HashSet contains() @@ -438,18 +449,47 @@ bool SecurityOrigin::shouldTreatURLSchemeAsLocal(const String& scheme) return localSchemes().contains(scheme); } -// static void SecurityOrigin::registerURLSchemeAsNoAccess(const String& scheme) { noAccessSchemes().add(scheme); } -// static bool SecurityOrigin::shouldTreatURLSchemeAsNoAccess(const String& scheme) { return noAccessSchemes().contains(scheme); } +bool SecurityOrigin::shouldHideReferrer(const KURL& url, const String& referrer) +{ + bool referrerIsSecureURL = protocolIs(referrer, "https"); + bool referrerIsWebURL = referrerIsSecureURL || protocolIs(referrer, "http"); + + if (!referrerIsWebURL) + return true; + + if (!referrerIsSecureURL) + return false; + + bool URLIsSecureURL = url.protocolIs("https"); + + return !URLIsSecureURL; +} + +void SecurityOrigin::setLocalLoadPolicy(LocalLoadPolicy policy) +{ + localLoadPolicy = policy; +} + +bool SecurityOrigin::restrictAccessToLocal() +{ + return localLoadPolicy != SecurityOrigin::AllowLocalLoadsForAll; +} + +bool SecurityOrigin::allowSubstituteDataAccessToLocal() +{ + return localLoadPolicy != SecurityOrigin::AllowLocalLoadsForLocalOnly; +} + void SecurityOrigin::whiteListAccessFromOrigin(const SecurityOrigin& sourceOrigin, const String& destinationProtocol, const String& destinationDomains, bool allowDestinationSubdomains) { ASSERT(isMainThread()); diff --git a/src/3rdparty/webkit/WebCore/page/SecurityOrigin.h b/src/3rdparty/webkit/WebCore/page/SecurityOrigin.h index 732afa8..46e6fad 100644 --- a/src/3rdparty/webkit/WebCore/page/SecurityOrigin.h +++ b/src/3rdparty/webkit/WebCore/page/SecurityOrigin.h @@ -40,7 +40,8 @@ namespace WebCore { typedef HashSet<String, CaseFoldingHash> URLSchemesMap; - + + class Document; class KURL; class SecurityOrigin : public ThreadSafeShared<SecurityOrigin> { @@ -52,7 +53,7 @@ namespace WebCore { // Create a deep copy of this SecurityOrigin. This method is useful // when marshalling a SecurityOrigin to another thread. - PassRefPtr<SecurityOrigin> copy(); + PassRefPtr<SecurityOrigin> threadsafeCopy(); // Set the domain property of this security origin to newDomain. This // function does not check whether newDomain is a suffix of the current @@ -81,6 +82,11 @@ namespace WebCore { // drawing an image onto an HTML canvas element with the drawImage API. bool taintsCanvas(const KURL&) const; + // Returns true for any non-local URL. If document parameter is supplied, + // its local load policy dictates, otherwise if referrer is non-empty and + // represents a local file, then the local load is allowed. + static bool canLoad(const KURL&, const String& referrer, Document* document); + // Returns true if this SecurityOrigin can load local resources, such // as images, iframes, and style sheets, and can link to local URLs. // For example, call this function before creating an iframe to a @@ -143,6 +149,17 @@ namespace WebCore { static bool shouldTreatURLAsLocal(const String&); static bool shouldTreatURLSchemeAsLocal(const String&); + static bool shouldHideReferrer(const KURL&, const String& referrer); + + enum LocalLoadPolicy { + AllowLocalLoadsForAll, // No restriction on local loads. + AllowLocalLoadsForLocalAndSubstituteData, + AllowLocalLoadsForLocalOnly, + }; + static void setLocalLoadPolicy(LocalLoadPolicy); + static bool restrictAccessToLocal(); + static bool allowSubstituteDataAccessToLocal(); + static void registerURLSchemeAsNoAccess(const String&); static bool shouldTreatURLSchemeAsNoAccess(const String&); diff --git a/src/3rdparty/webkit/WebCore/page/Settings.cpp b/src/3rdparty/webkit/WebCore/page/Settings.cpp index ab438a1..48f310b 100644 --- a/src/3rdparty/webkit/WebCore/page/Settings.cpp +++ b/src/3rdparty/webkit/WebCore/page/Settings.cpp @@ -61,7 +61,10 @@ Settings::Settings(Page* page) , m_defaultFontSize(0) , m_defaultFixedFontSize(0) , m_maximumDecodedImageSize(numeric_limits<size_t>::max()) + , m_localStorageQuota(5 * 1024 * 1024) // Suggested by the HTML5 spec. , m_pluginAllowedRunTime(numeric_limits<unsigned>::max()) + , m_printingMinimumShrinkFactor(0.0f) + , m_printingMaximumShrinkFactor(0.0f) , m_isJavaEnabled(false) , m_loadsImagesAutomatically(false) , m_privateBrowsingEnabled(false) @@ -116,11 +119,7 @@ Settings::Settings(Page* page) , m_xssAuditorEnabled(false) , m_acceleratedCompositingEnabled(true) , m_experimentalNotificationsEnabled(false) - , m_pluginHalterEnabled(false) - , m_experimentalWebGLEnabled(false) -#if ENABLE(WEB_SOCKETS) - , m_experimentalWebSocketsEnabled(false) -#endif + , m_webGLEnabled(false) { // A Frame may not have been created yet, so we initialize the AtomicString // hash before trying to use it. @@ -262,6 +261,11 @@ void Settings::setSessionStorageEnabled(bool sessionStorageEnabled) m_sessionStorageEnabled = sessionStorageEnabled; } +void Settings::setLocalStorageQuota(unsigned localStorageQuota) +{ + m_localStorageQuota = localStorageQuota; +} + void Settings::setPrivateBrowsingEnabled(bool privateBrowsingEnabled) { m_privateBrowsingEnabled = privateBrowsingEnabled; @@ -509,16 +513,6 @@ void Settings::setExperimentalNotificationsEnabled(bool enabled) m_experimentalNotificationsEnabled = enabled; } -void Settings::setPluginHalterEnabled(bool enabled) -{ - if (m_pluginHalterEnabled == enabled) - return; - - m_pluginHalterEnabled = enabled; - - m_page->pluginHalterEnabledStateChanged(); -} - void Settings::setPluginAllowedRunTime(unsigned runTime) { m_pluginAllowedRunTime = runTime; @@ -532,16 +526,19 @@ void Settings::setShouldUseHighResolutionTimers(bool shouldUseHighResolutionTime } #endif -void Settings::setExperimentalWebGLEnabled(bool enabled) +void Settings::setWebGLEnabled(bool enabled) { - m_experimentalWebGLEnabled = enabled; + m_webGLEnabled = enabled; } -#if ENABLE(WEB_SOCKETS) -void Settings::setExperimentalWebSocketsEnabled(bool enabled) +void Settings::setPrintingMinimumShrinkFactor(float printingMinimumShrinkFactor) { - m_experimentalWebSocketsEnabled = enabled; -} -#endif + m_printingMinimumShrinkFactor = printingMinimumShrinkFactor; +} + +void Settings::setPrintingMaximumShrinkFactor(float printingMaximumShrinkFactor) +{ + m_printingMaximumShrinkFactor = printingMaximumShrinkFactor; +} } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/page/Settings.h b/src/3rdparty/webkit/WebCore/page/Settings.h index ec9c8f9..bdb07b9 100644 --- a/src/3rdparty/webkit/WebCore/page/Settings.h +++ b/src/3rdparty/webkit/WebCore/page/Settings.h @@ -128,6 +128,9 @@ namespace WebCore { void setSessionStorageEnabled(bool); bool sessionStorageEnabled() const { return m_sessionStorageEnabled; } + void setLocalStorageQuota(unsigned); + unsigned localStorageQuota() const { return m_localStorageQuota; } + void setPrivateBrowsingEnabled(bool); bool privateBrowsingEnabled() const { return m_privateBrowsingEnabled; } @@ -261,21 +264,17 @@ namespace WebCore { static bool shouldUseHighResolutionTimers() { return gShouldUseHighResolutionTimers; } #endif - void setPluginHalterEnabled(bool); - bool pluginHalterEnabled() const { return m_pluginHalterEnabled; } - void setPluginAllowedRunTime(unsigned); unsigned pluginAllowedRunTime() const { return m_pluginAllowedRunTime; } - // This run-time flag is only temporary while the WebGL - // specification is being developed. - void setExperimentalWebGLEnabled(bool); - bool experimentalWebGLEnabled() const { return m_experimentalWebGLEnabled; } + void setWebGLEnabled(bool); + bool webGLEnabled() const { return m_webGLEnabled; } -#if ENABLE(WEB_SOCKETS) - void setExperimentalWebSocketsEnabled(bool); - bool experimentalWebSocketsEnabled() const { return m_experimentalWebSocketsEnabled; } -#endif + void setPrintingMinimumShrinkFactor(float); + float printingMinimumShrinkFactor() const { return m_printingMinimumShrinkFactor; } + + void setPrintingMaximumShrinkFactor(float); + float printingMaximumShrinkFactor() const { return m_printingMaximumShrinkFactor; } private: Page* m_page; @@ -297,7 +296,10 @@ namespace WebCore { int m_defaultFontSize; int m_defaultFixedFontSize; size_t m_maximumDecodedImageSize; + unsigned m_localStorageQuota; unsigned m_pluginAllowedRunTime; + float m_printingMinimumShrinkFactor; + float m_printingMaximumShrinkFactor; bool m_isJavaEnabled : 1; bool m_loadsImagesAutomatically : 1; bool m_privateBrowsingEnabled : 1; @@ -343,12 +345,7 @@ namespace WebCore { bool m_xssAuditorEnabled : 1; bool m_acceleratedCompositingEnabled : 1; bool m_experimentalNotificationsEnabled : 1; - bool m_pluginHalterEnabled : 1; - bool m_experimentalWebGLEnabled : 1; - -#if ENABLE(WEB_SOCKETS) - bool m_experimentalWebSocketsEnabled : 1; -#endif + bool m_webGLEnabled : 1; #if USE(SAFARI_THEME) static bool gShouldPaintNativeControls; diff --git a/src/3rdparty/webkit/WebCore/page/UserContentURLPattern.cpp b/src/3rdparty/webkit/WebCore/page/UserContentURLPattern.cpp index 1960131..5f0a311 100644 --- a/src/3rdparty/webkit/WebCore/page/UserContentURLPattern.cpp +++ b/src/3rdparty/webkit/WebCore/page/UserContentURLPattern.cpp @@ -30,19 +30,33 @@ namespace WebCore { -bool UserContentURLPattern::matchesPatterns(const KURL& url, const Vector<String>& patterns) +bool UserContentURLPattern::matchesPatterns(const KURL& url, const Vector<String>* whitelist, const Vector<String>* blacklist) { - // Treat no patterns at all as though a pattern of * was specified. - if (patterns.isEmpty()) - return true; + // In order for a URL to be a match it has to be present in the whitelist and not present in the blacklist. + // If there is no whitelist at all, then all URLs are assumed to be in the whitelist. + bool matchesWhitelist = !whitelist || whitelist->isEmpty(); + if (!matchesWhitelist) { + for (unsigned i = 0; i < whitelist->size(); ++i) { + UserContentURLPattern contentPattern(whitelist->at(i)); + if (contentPattern.matches(url)) { + matchesWhitelist = true; + break; + } + } + } - for (unsigned i = 0; i < patterns.size(); ++i) { - UserContentURLPattern contentPattern(patterns[i]); - if (contentPattern.matches(url)) - return true; + bool matchesBlacklist = false; + if (blacklist) { + for (unsigned i = 0; i < blacklist->size(); ++i) { + UserContentURLPattern contentPattern(blacklist->at(i)); + if (contentPattern.matches(url)) { + matchesBlacklist = true; + break; + } + } } - return false; + return matchesWhitelist && !matchesBlacklist; } bool UserContentURLPattern::parse(const String& pattern) diff --git a/src/3rdparty/webkit/WebCore/page/UserContentURLPattern.h b/src/3rdparty/webkit/WebCore/page/UserContentURLPattern.h index bc87f55..0b1a248 100644 --- a/src/3rdparty/webkit/WebCore/page/UserContentURLPattern.h +++ b/src/3rdparty/webkit/WebCore/page/UserContentURLPattern.h @@ -49,7 +49,7 @@ public: bool matchSubdomains() const { return m_matchSubdomains; } - static bool matchesPatterns(const KURL&, const Vector<String>&); + static bool matchesPatterns(const KURL&, const Vector<String>* whitelist, const Vector<String>* blacklist); private: bool parse(const String& pattern); diff --git a/src/3rdparty/webkit/WebCore/page/UserScript.h b/src/3rdparty/webkit/WebCore/page/UserScript.h index 51031ab..dbbb879 100644 --- a/src/3rdparty/webkit/WebCore/page/UserScript.h +++ b/src/3rdparty/webkit/WebCore/page/UserScript.h @@ -29,6 +29,7 @@ #include "KURL.h" #include "UserScriptTypes.h" #include <wtf/OwnPtr.h> +#include <wtf/PassOwnPtr.h> #include <wtf/Vector.h> namespace WebCore { @@ -36,11 +37,12 @@ namespace WebCore { class UserScript { public: UserScript(const String& source, const KURL& url, - const Vector<String>& patterns, unsigned worldID, - UserScriptInjectionTime injectionTime) + PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist, + unsigned worldID, UserScriptInjectionTime injectionTime) : m_source(source) , m_url(url) - , m_patterns(patterns) + , m_whitelist(whitelist) + , m_blacklist(blacklist) , m_worldID(worldID) , m_injectionTime(injectionTime) { @@ -48,14 +50,16 @@ public: const String& source() const { return m_source; } const KURL& url() const { return m_url; } - const Vector<String>& patterns() const { return m_patterns; } + const Vector<String>* whitelist() const { return m_whitelist.get(); } + const Vector<String>* blacklist() const { return m_blacklist.get(); } unsigned worldID() const { return m_worldID; } UserScriptInjectionTime injectionTime() const { return m_injectionTime; } private: String m_source; KURL m_url; - Vector<String> m_patterns; + OwnPtr<Vector<String> > m_whitelist; + OwnPtr<Vector<String> > m_blacklist; unsigned m_worldID; UserScriptInjectionTime m_injectionTime; }; diff --git a/src/3rdparty/webkit/WebCore/page/UserStyleSheet.h b/src/3rdparty/webkit/WebCore/page/UserStyleSheet.h index 5ae95c3..56bec40 100644 --- a/src/3rdparty/webkit/WebCore/page/UserStyleSheet.h +++ b/src/3rdparty/webkit/WebCore/page/UserStyleSheet.h @@ -29,6 +29,7 @@ #include "KURL.h" #include "UserStyleSheetTypes.h" #include <wtf/OwnPtr.h> +#include <wtf/PassOwnPtr.h> #include <wtf/Vector.h> namespace WebCore { @@ -36,23 +37,27 @@ namespace WebCore { class UserStyleSheet { public: UserStyleSheet(const String& source, const KURL& url, - const Vector<String>& patterns, unsigned worldID) + PassOwnPtr<Vector<String> > whitelist, PassOwnPtr<Vector<String> > blacklist, + unsigned worldID) : m_source(source) , m_url(url) - , m_patterns(patterns) + , m_whitelist(whitelist) + , m_blacklist(blacklist) , m_worldID(worldID) { } const String& source() const { return m_source; } const KURL& url() const { return m_url; } - const Vector<String>& patterns() const { return m_patterns; } + const Vector<String>* whitelist() const { return m_whitelist.get(); } + const Vector<String>* blacklist() const { return m_blacklist.get(); } unsigned worldID() const { return m_worldID; } private: String m_source; KURL m_url; - Vector<String> m_patterns; + OwnPtr<Vector<String> > m_whitelist; + OwnPtr<Vector<String> > m_blacklist; unsigned m_worldID; }; diff --git a/src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp b/src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp index 4fcc53c..890c3fa 100644 --- a/src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp +++ b/src/3rdparty/webkit/WebCore/page/XSSAuditor.cpp @@ -58,15 +58,30 @@ static bool isNonCanonicalCharacter(UChar c) return (c == '\\' || c == '0' || c < ' ' || c >= 127); } -String XSSAuditor::CachingURLCanonicalizer::canonicalizeURL(const String& url, const TextEncoding& encoding, bool decodeEntities) +static bool isIllegalURICharacter(UChar c) { - if (decodeEntities == m_decodeEntities && encoding == m_encoding && url == m_inputURL) + // The characters described in section 2.4.3 of RFC 2396 <http://www.faqs.org/rfcs/rfc2396.html> in addition to the + // single quote character "'" are considered illegal URI characters. That is, the following characters cannot appear + // in a valid URI: ', ", <, > + // + // If the request does not contain these characters then we can assume that no inline scripts have been injected + // into the response page, because it is impossible to write an inline script of the form <script>...</script> + // without "<", ">". + return (c == '\'' || c == '"' || c == '<' || c == '>'); +} + +String XSSAuditor::CachingURLCanonicalizer::canonicalizeURL(const String& url, const TextEncoding& encoding, bool decodeEntities, + bool decodeURLEscapeSequencesTwice) +{ + if (decodeEntities == m_decodeEntities && decodeURLEscapeSequencesTwice == m_decodeURLEscapeSequencesTwice + && encoding == m_encoding && url == m_inputURL) return m_cachedCanonicalizedURL; - m_cachedCanonicalizedURL = canonicalize(decodeURL(url, encoding, decodeEntities)); + m_cachedCanonicalizedURL = canonicalize(decodeURL(url, encoding, decodeEntities, decodeURLEscapeSequencesTwice)); m_inputURL = url; m_encoding = encoding; m_decodeEntities = decodeEntities; + m_decodeURLEscapeSequencesTwice = decodeURLEscapeSequencesTwice; return m_cachedCanonicalizedURL; } @@ -90,7 +105,7 @@ bool XSSAuditor::canEvaluate(const String& code) const if (!isEnabled()) return true; - if (findInRequest(code, false)) { + if (findInRequest(code, false, true)) { DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n")); m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String()); return false; @@ -103,7 +118,7 @@ bool XSSAuditor::canEvaluateJavaScriptURL(const String& code) const if (!isEnabled()) return true; - if (findInRequest(code)) { + if (findInRequest(code, true, false, true)) { DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n")); m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String()); return false; @@ -116,7 +131,7 @@ bool XSSAuditor::canCreateInlineEventListener(const String&, const String& code) if (!isEnabled()) return true; - if (findInRequest(code)) { + if (findInRequest(code, true, true)) { DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n")); m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String()); return false; @@ -129,6 +144,16 @@ bool XSSAuditor::canLoadExternalScriptFromSrc(const String& context, const Strin if (!isEnabled()) return true; + // If the script is loaded from the same URL as the enclosing page, it's + // probably not an XSS attack, so we reduce false positives by allowing the + // script. If the script has a query string, we're more suspicious, + // however, because that's pretty rare and the attacker might be able to + // trick a server-side script into doing something dangerous with the query + // string. + KURL scriptURL(m_frame->document()->url(), url); + if (m_frame->document()->url().host() == scriptURL.host() && scriptURL.query().isEmpty()) + return true; + if (findInRequest(context + url)) { DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute a JavaScript script. Source code of script found within request.\n")); m_frame->domWindow()->console()->addMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, consoleMessage, 1, String()); @@ -170,7 +195,7 @@ String XSSAuditor::canonicalize(const String& string) return result.removeCharacters(&isNonCanonicalCharacter); } -String XSSAuditor::decodeURL(const String& string, const TextEncoding& encoding, bool decodeEntities) +String XSSAuditor::decodeURL(const String& string, const TextEncoding& encoding, bool decodeEntities, bool decodeURLEscapeSequencesTwice) { String result; String url = string; @@ -181,6 +206,13 @@ String XSSAuditor::decodeURL(const String& string, const TextEncoding& encoding, String decodedResult = encoding.decode(utf8Url.data(), utf8Url.length()); if (!decodedResult.isEmpty()) result = decodedResult; + if (decodeURLEscapeSequencesTwice) { + result = decodeURLEscapeSequences(result); + utf8Url = result.utf8(); + decodedResult = encoding.decode(utf8Url.data(), utf8Url.length()); + if (!decodedResult.isEmpty()) + result = decodedResult; + } if (decodeEntities) result = decodeHTMLEntities(result); return result; @@ -223,18 +255,20 @@ String XSSAuditor::decodeHTMLEntities(const String& string, bool leaveUndecodabl return String::adopt(result); } -bool XSSAuditor::findInRequest(const String& string, bool decodeEntities) const +bool XSSAuditor::findInRequest(const String& string, bool decodeEntities, bool allowRequestIfNoIllegalURICharacters, + bool decodeURLEscapeSequencesTwice) const { bool result = false; Frame* parentFrame = m_frame->tree()->parent(); if (parentFrame && m_frame->document()->url() == blankURL()) - result = findInRequest(parentFrame, string, decodeEntities); + result = findInRequest(parentFrame, string, decodeEntities, allowRequestIfNoIllegalURICharacters, decodeURLEscapeSequencesTwice); if (!result) - result = findInRequest(m_frame, string, decodeEntities); + result = findInRequest(m_frame, string, decodeEntities, allowRequestIfNoIllegalURICharacters, decodeURLEscapeSequencesTwice); return result; } -bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeEntities) const +bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeEntities, bool allowRequestIfNoIllegalURICharacters, + bool decodeURLEscapeSequencesTwice) const { ASSERT(frame->document()); @@ -273,9 +307,14 @@ bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeEn if (string.length() < pageURL.length()) { // The string can actually fit inside the pageURL. - String decodedPageURL = m_cache.canonicalizeURL(pageURL, frame->document()->decoder()->encoding(), decodeEntities); + String decodedPageURL = m_cache.canonicalizeURL(pageURL, frame->document()->decoder()->encoding(), decodeEntities, decodeURLEscapeSequencesTwice); + + if (allowRequestIfNoIllegalURICharacters && (!formDataObj || formDataObj->isEmpty()) + && decodedPageURL.find(&isIllegalURICharacter, 0) == -1) + return false; // Injection is impossible because the request does not contain any illegal URI characters. + if (decodedPageURL.find(canonicalizedString, 0, false) != -1) - return true; // We've found the smoking gun. + return true; // We've found the smoking gun. } if (formDataObj && !formDataObj->isEmpty()) { @@ -285,7 +324,7 @@ bool XSSAuditor::findInRequest(Frame* frame, const String& string, bool decodeEn // the url-encoded POST data because the length of the url-decoded // code is less than or equal to the length of the url-encoded // string. - String decodedFormData = m_cache.canonicalizeURL(formData, frame->document()->decoder()->encoding(), decodeEntities); + String decodedFormData = m_cache.canonicalizeURL(formData, frame->document()->decoder()->encoding(), decodeEntities, decodeURLEscapeSequencesTwice); if (decodedFormData.find(canonicalizedString, 0, false) != -1) return true; // We found the string in the POST data. } diff --git a/src/3rdparty/webkit/WebCore/page/XSSAuditor.h b/src/3rdparty/webkit/WebCore/page/XSSAuditor.h index 58b2cc2..adfa5c7 100644 --- a/src/3rdparty/webkit/WebCore/page/XSSAuditor.h +++ b/src/3rdparty/webkit/WebCore/page/XSSAuditor.h @@ -102,25 +102,30 @@ namespace WebCore { class CachingURLCanonicalizer { public: - CachingURLCanonicalizer() : m_decodeEntities(false) { } - String canonicalizeURL(const String& url, const TextEncoding& encoding, bool decodeEntities); + CachingURLCanonicalizer() : m_decodeEntities(false), m_decodeURLEscapeSequencesTwice(false) { } + String canonicalizeURL(const String& url, const TextEncoding& encoding, bool decodeEntities, + bool decodeURLEscapeSequencesTwice); private: // The parameters we were called with last. String m_inputURL; TextEncoding m_encoding; bool m_decodeEntities; + bool m_decodeURLEscapeSequencesTwice; // The cached result. String m_cachedCanonicalizedURL; }; static String canonicalize(const String&); - static String decodeURL(const String& url, const TextEncoding& encoding, bool decodeEntities); + static String decodeURL(const String& url, const TextEncoding& encoding, bool decodeEntities, + bool decodeURLEscapeSequencesTwice = false); static String decodeHTMLEntities(const String&, bool leaveUndecodableEntitiesUntouched = true); - bool findInRequest(const String&, bool decodeEntities = true) const; - bool findInRequest(Frame*, const String&, bool decodeEntities = true) const; + bool findInRequest(const String&, bool decodeEntities = true, bool allowRequestIfNoIllegalURICharacters = false, + bool decodeURLEscapeSequencesTwice = false) const; + bool findInRequest(Frame*, const String&, bool decodeEntities = true, bool allowRequestIfNoIllegalURICharacters = false, + bool decodeURLEscapeSequencesTwice = false) const; // The frame to audit. Frame* m_frame; diff --git a/src/3rdparty/webkit/WebCore/page/animation/AnimationBase.cpp b/src/3rdparty/webkit/WebCore/page/animation/AnimationBase.cpp index e54be8b..ec0e284 100644 --- a/src/3rdparty/webkit/WebCore/page/animation/AnimationBase.cpp +++ b/src/3rdparty/webkit/WebCore/page/animation/AnimationBase.cpp @@ -361,6 +361,10 @@ public: { Color fromColor = (a->*m_getter)(); Color toColor = (b->*m_getter)(); + + if (!fromColor.isValid() && !toColor.isValid()) + return true; + if (!fromColor.isValid()) fromColor = a->color(); if (!toColor.isValid()) @@ -373,6 +377,10 @@ public: { Color fromColor = (a->*m_getter)(); Color toColor = (b->*m_getter)(); + + if (!fromColor.isValid() && !toColor.isValid()) + return; + if (!fromColor.isValid()) fromColor = a->color(); if (!toColor.isValid()) @@ -635,7 +643,7 @@ static void ensurePropertyMap() gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyOutlineColor, &RenderStyle::outlineColor, &RenderStyle::setOutlineColor)); // These are for shadows - gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyBoxShadow, &RenderStyle::boxShadow, &RenderStyle::setBoxShadow)); + gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyWebkitBoxShadow, &RenderStyle::boxShadow, &RenderStyle::setBoxShadow)); gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyTextShadow, &RenderStyle::textShadow, &RenderStyle::setTextShadow)); #if ENABLE(SVG) diff --git a/src/3rdparty/webkit/WebCore/page/animation/AnimationController.cpp b/src/3rdparty/webkit/WebCore/page/animation/AnimationController.cpp index 691932e..aa5de2c 100644 --- a/src/3rdparty/webkit/WebCore/page/animation/AnimationController.cpp +++ b/src/3rdparty/webkit/WebCore/page/animation/AnimationController.cpp @@ -55,7 +55,7 @@ AnimationControllerPrivate::AnimationControllerPrivate(Frame* frame) , m_lastStyleAvailableWaiter(0) , m_responseWaiters(0) , m_lastResponseWaiter(0) - , m_waitingForAResponse(false) + , m_waitingForResponse(false) { } @@ -279,6 +279,19 @@ double AnimationControllerPrivate::beginAnimationUpdateTime() return m_beginAnimationUpdateTime; } +void AnimationControllerPrivate::endAnimationUpdate() +{ + styleAvailable(); + if (!m_waitingForResponse) + startTimeResponse(beginAnimationUpdateTime()); +} + +void AnimationControllerPrivate::receivedStartTimeResponse(double time) +{ + m_waitingForResponse = false; + startTimeResponse(time); +} + PassRefPtr<RenderStyle> AnimationControllerPrivate::getAnimatedStyleForRenderer(RenderObject* renderer) { if (!renderer) @@ -378,7 +391,7 @@ void AnimationControllerPrivate::addToStartTimeResponseWaitList(AnimationBase* a ASSERT(!animation->next()); if (willGetResponse) - m_waitingForAResponse = true; + m_waitingForResponse = true; if (m_responseWaiters) m_lastResponseWaiter->setNext(animation); @@ -408,13 +421,13 @@ void AnimationControllerPrivate::removeFromStartTimeResponseWaitList(AnimationBa } } -void AnimationControllerPrivate::startTimeResponse(double t) +void AnimationControllerPrivate::startTimeResponse(double time) { // Go through list of waiters and send them on their way for (AnimationBase* animation = m_responseWaiters; animation; ) { AnimationBase* nextAnimation = animation->next(); animation->setNext(0); - animation->onAnimationStartResponse(t); + animation->onAnimationStartResponse(time); animation = nextAnimation; } diff --git a/src/3rdparty/webkit/WebCore/page/animation/AnimationControllerPrivate.h b/src/3rdparty/webkit/WebCore/page/animation/AnimationControllerPrivate.h index 359b9b5..7db3803 100644 --- a/src/3rdparty/webkit/WebCore/page/animation/AnimationControllerPrivate.h +++ b/src/3rdparty/webkit/WebCore/page/animation/AnimationControllerPrivate.h @@ -80,18 +80,8 @@ public: double beginAnimationUpdateTime(); void setBeginAnimationUpdateTime(double t) { m_beginAnimationUpdateTime = t; } - void endAnimationUpdate() - { - styleAvailable(); - if (!m_waitingForAResponse) - startTimeResponse(beginAnimationUpdateTime()); - } - - void receivedStartTimeResponse(double t) - { - m_waitingForAResponse = false; - startTimeResponse(t); - } + void endAnimationUpdate(); + void receivedStartTimeResponse(double); void addToStyleAvailableWaitList(AnimationBase*); void removeFromStyleAvailableWaitList(AnimationBase*); @@ -127,7 +117,7 @@ private: AnimationBase* m_responseWaiters; AnimationBase* m_lastResponseWaiter; - bool m_waitingForAResponse; + bool m_waitingForResponse; }; } // namespace WebCore diff --git a/src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.cpp b/src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.cpp index 8e6349d..50fc781 100644 --- a/src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.cpp +++ b/src/3rdparty/webkit/WebCore/page/animation/ImplicitAnimation.cpp @@ -142,10 +142,8 @@ void ImplicitAnimation::onAnimationEnd(double elapsedTime) if (keyframeAnim) keyframeAnim->setUnanimatedStyle(m_toStyle); - if (!sendTransitionEvent(eventNames().webkitTransitionEndEvent, elapsedTime)) { - // We didn't dispatch an event, which would call endAnimation(), so we'll just call it here. - endAnimation(true); - } + sendTransitionEvent(eventNames().webkitTransitionEndEvent, elapsedTime); + endAnimation(true); } bool ImplicitAnimation::sendTransitionEvent(const AtomicString& eventType, double elapsedTime) diff --git a/src/3rdparty/webkit/WebCore/page/animation/KeyframeAnimation.cpp b/src/3rdparty/webkit/WebCore/page/animation/KeyframeAnimation.cpp index 39ae1e7..7e37e5f 100644 --- a/src/3rdparty/webkit/WebCore/page/animation/KeyframeAnimation.cpp +++ b/src/3rdparty/webkit/WebCore/page/animation/KeyframeAnimation.cpp @@ -244,10 +244,8 @@ void KeyframeAnimation::onAnimationIteration(double elapsedTime) void KeyframeAnimation::onAnimationEnd(double elapsedTime) { - if (!sendAnimationEvent(eventNames().webkitAnimationEndEvent, elapsedTime)) { - // We didn't dispatch an event, which would call endAnimation(), so we'll just call it here. - endAnimation(true); - } + sendAnimationEvent(eventNames().webkitAnimationEndEvent, elapsedTime); + endAnimation(true); } bool KeyframeAnimation::sendAnimationEvent(const AtomicString& eventType, double elapsedTime) |