~jconti/ubuntu/oneiric/webkit/fix_doc_path

« back to all changes in this revision

Viewing changes to WebCore/page/mac/EventHandlerMac.mm

  • Committer: Bazaar Package Importer
  • Author(s): Mike Hommey
  • Date: 2008-09-27 08:57:48 UTC
  • mfrom: (3.1.6 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080927085748-yhzld00w0rekp961
Tags: 1.0.1-4
WebCore/dom/Document.*, WebCore/loader/DocLoader.*: Avoid DoS via
crafted CSS import statements. Fixes: CVE-2008-3632. Closes: #499771.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
 
2
 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
3
3
 *
4
4
 * Redistribution and use in source and binary forms, with or without
5
5
 * modification, are permitted provided that the following conditions
27
27
#include "EventHandler.h"
28
28
 
29
29
#include "BlockExceptions.h"
 
30
#include "ChromeClient.h"
30
31
#include "ClipboardMac.h"
31
 
#include "Cursor.h"
32
 
#include "Document.h"
33
 
#include "DragController.h"
34
32
#include "EventNames.h"
35
 
#include "FloatPoint.h"
36
33
#include "FocusController.h"
37
 
#include "FoundationExtras.h"
38
34
#include "FrameLoader.h"
39
35
#include "Frame.h"
40
 
#include "FrameTree.h"
41
36
#include "FrameView.h"
42
 
#include "HTMLFrameOwnerElement.h"
43
 
#include "HTMLFrameSetElement.h"
44
 
#include "HitTestRequest.h"
45
 
#include "HitTestResult.h"
46
37
#include "KeyboardEvent.h"
47
38
#include "MouseEventWithHitTestResults.h"
48
39
#include "Page.h"
50
41
#include "PlatformScrollBar.h"
51
42
#include "PlatformWheelEvent.h"
52
43
#include "RenderWidget.h"
53
 
#include "WebCoreFrameBridge.h"
 
44
#include "Settings.h"
54
45
 
55
46
namespace WebCore {
56
47
 
57
48
using namespace EventNames;
58
49
 
 
50
unsigned EventHandler::s_accessKeyModifiers = PlatformKeyboardEvent::CtrlKey | PlatformKeyboardEvent::AltKey;
 
51
 
 
52
const double EventHandler::TextDragDelay = 0.15;
 
53
 
59
54
static RetainPtr<NSEvent>& currentEvent()
60
55
{
61
56
    static RetainPtr<NSEvent> event;
87
82
    if (!event)
88
83
        return 0;
89
84
    switch ([event type]) {
90
 
        case NSKeyDown:
 
85
        case NSKeyDown: {
 
86
            PlatformKeyboardEvent platformEvent(event);
 
87
            platformEvent.disambiguateKeyDownEvent(PlatformKeyboardEvent::RawKeyDown);
 
88
            return KeyboardEvent::create(platformEvent, m_frame->document() ? m_frame->document()->defaultView() : 0);
 
89
        }
91
90
        case NSKeyUp:
92
 
            return new KeyboardEvent(event, m_frame->document() ? m_frame->document()->defaultView() : 0);
 
91
            return KeyboardEvent::create(event, m_frame->document() ? m_frame->document()->defaultView() : 0);
93
92
        default:
94
93
            return 0;
95
94
    }
98
97
static inline bool isKeyboardOptionTab(KeyboardEvent* event)
99
98
{
100
99
    return event
101
 
    && (event->type() == keydownEvent || event->type() == keypressEvent)
102
 
    && event->altKey()
103
 
    && event->keyIdentifier() == "U+0009";    
 
100
        && (event->type() == keydownEvent || event->type() == keypressEvent)
 
101
        && event->altKey()
 
102
        && event->keyIdentifier() == "U+0009";    
104
103
}
105
104
 
106
105
bool EventHandler::invertSenseOfTabsToLinks(KeyboardEvent* event) const
110
109
 
111
110
bool EventHandler::tabsToAllControls(KeyboardEvent* event) const
112
111
{
113
 
    KeyboardUIMode keyboardUIMode = [m_frame->bridge() keyboardUIMode];
 
112
    Page* page = m_frame->page();
 
113
    if (!page)
 
114
        return false;
 
115
 
 
116
    KeyboardUIMode keyboardUIMode = page->chrome()->client()->keyboardUIMode();
114
117
    bool handlingOptionTab = isKeyboardOptionTab(event);
115
118
 
116
119
    // If tab-to-links is off, option-tab always highlights all controls
128
131
    return handlingOptionTab;
129
132
}
130
133
 
 
134
bool EventHandler::needsKeyboardEventDisambiguationQuirks() const
 
135
{
 
136
    static BOOL checkedSafari = NO;
 
137
    static BOOL isSafari = NO;
 
138
 
 
139
    if (!checkedSafari) {
 
140
        isSafari = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.Safari"];
 
141
        checkedSafari = YES;
 
142
    }
 
143
    
 
144
    Document* document = m_frame->document();
 
145
    if (!document)
 
146
        return false;
 
147
 
 
148
    // RSS view needs arrow key keypress events.
 
149
    if (isSafari && document->url().protocolIs("feed") || document->url().protocolIs("feeds"))
 
150
        return true;
 
151
    Settings* settings = m_frame->settings();
 
152
    if (!settings)
 
153
        return false;
 
154
 
 
155
#if ENABLE(DASHBOARD_SUPPORT)
 
156
    if (settings->usesDashboardBackwardCompatibilityMode())
 
157
        return true;
 
158
#endif
 
159
        
 
160
    if (settings->needsKeyboardEventDisambiguationQuirks())
 
161
        return true;
 
162
 
 
163
    return false;
 
164
}
 
165
 
131
166
bool EventHandler::keyEvent(NSEvent *event)
132
167
{
133
168
    bool result;
156
191
    if (!page)
157
192
        return;
158
193
 
159
 
    if (FrameView* frameView = m_frame->view())
160
 
        if (NSView *documentView = frameView->getDocumentView())
 
194
    if (FrameView* frameView = m_frame->view()) {
 
195
        if (NSView *documentView = frameView->documentView())
161
196
            page->chrome()->focusNSView(documentView);
162
 
    
 
197
    }
 
198
 
163
199
    page->focusController()->setFocusedFrame(m_frame);
164
200
}
165
201
 
215
251
    ASSERT(nodeView);
216
252
    ASSERT([nodeView superview]);
217
253
    NSView *view = [nodeView hitTest:[[nodeView superview] convertPoint:[currentEvent().get() locationInWindow] fromView:nil]];
218
 
    if (!view)
 
254
    if (!view) {
219
255
        // We probably hit the border of a RenderWidget
220
256
        return true;
 
257
    }
221
258
    
222
 
    if ([m_frame->bridge() firstResponder] == view) {
223
 
        // In the case where we just became first responder, we should send the mouseDown:
224
 
        // to the NSTextField, not the NSTextField's editor. This code makes sure that happens.
225
 
        // If we don't do this, we see a flash of selected text when clicking in a text field.
226
 
        // FIXME: This is the only caller of textViewWasFirstResponderAtMouseDownTime. When we
227
 
        // eliminate all use of NSTextField/NSTextView in form fields we can eliminate this code,
228
 
        // and textViewWasFirstResponderAtMouseDownTime:, and the instance variable WebHTMLView
229
 
        // keeps solely to support textViewWasFirstResponderAtMouseDownTime:.
230
 
        if ([view isKindOfClass:[NSTextView class]] && ![m_frame->bridge() textViewWasFirstResponderAtMouseDownTime:(NSTextView *)view]) {
231
 
            NSView *superview = view;
232
 
            while (superview != nodeView) {
233
 
                superview = [superview superview];
234
 
                ASSERT(superview);
235
 
                if ([superview isKindOfClass:[NSControl class]]) {
236
 
                    NSControl *control = static_cast<NSControl*>(superview);
237
 
                    if ([control currentEditor] == view)
238
 
                        view = superview;
239
 
                    break;
240
 
                }
241
 
            }
242
 
        }
243
 
    } else {
 
259
    Page* page = m_frame->page();
 
260
    if (!page)
 
261
        return true;
 
262
 
 
263
    if (page->chrome()->client()->firstResponder() != view) {
244
264
        // Normally [NSWindow sendEvent:] handles setting the first responder.
245
265
        // But in our case, the event was sent to the view representing the entire web page.
246
 
        if ([currentEvent().get() clickCount] <= 1 && [view acceptsFirstResponder] && [view needsPanelToBecomeKey]) {
247
 
            [m_frame->bridge() makeFirstResponder:view];
248
 
        }
 
266
        if ([currentEvent().get() clickCount] <= 1 && [view acceptsFirstResponder] && [view needsPanelToBecomeKey])
 
267
            page->chrome()->client()->makeFirstResponder(view);
249
268
    }
250
269
 
251
270
    // We need to "defer loading" while tracking the mouse, because tearing down the
255
274
    // mouse. We should confirm that, and then remove the deferrsLoading
256
275
    // hack entirely.
257
276
    
258
 
    bool wasDeferringLoading = m_frame->page()->defersLoading();
 
277
    bool wasDeferringLoading = page->defersLoading();
259
278
    if (!wasDeferringLoading)
260
 
        m_frame->page()->setDefersLoading(true);
 
279
        page->setDefersLoading(true);
261
280
 
262
281
    ASSERT(!m_sendingEventToSubview);
263
282
    m_sendingEventToSubview = true;
265
284
    m_sendingEventToSubview = false;
266
285
    
267
286
    if (!wasDeferringLoading)
268
 
        m_frame->page()->setDefersLoading(false);
 
287
        page->setDefersLoading(false);
269
288
 
270
289
    // Remember which view we sent the event to, so we can direct the release event properly.
271
290
    m_mouseDownView = view;
343
362
    return true;
344
363
}
345
364
    
346
 
Clipboard* EventHandler::createDraggingClipboard() const 
 
365
PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const 
347
366
{
348
367
    NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
349
368
    // Must be done before ondragstart adds types and data to the pboard,
350
369
    // also done for security, as it erases data from the last drag
351
370
    [pasteboard declareTypes:[NSArray array] owner:nil];
352
 
    return new ClipboardMac(true, pasteboard, ClipboardWritable, m_frame);
 
371
    return ClipboardMac::create(true, pasteboard, ClipboardWritable, m_frame);
353
372
}
354
373
    
355
374
bool EventHandler::eventLoopHandleMouseUp(const MouseEventWithHitTestResults&)
463
482
    m_frame->loader()->resetMultipleFormSubmissionProtection();
464
483
 
465
484
    m_mouseDownView = nil;
466
 
    dragState().m_dragSrc = 0;
467
485
    
468
486
    RetainPtr<NSEvent> oldCurrentEvent = currentEvent();
469
487
    currentEvent() = event;
539
557
 */
540
558
void EventHandler::sendFakeEventsAfterWidgetTracking(NSEvent *initiatingEvent)
541
559
{
 
560
    FrameView* view = m_frame->view();
 
561
    if (!view)
 
562
        return;
 
563
 
542
564
    BEGIN_BLOCK_OBJC_EXCEPTIONS;
543
565
 
544
566
    m_sendingEventToSubview = false;
547
569
        NSEvent *fakeEvent = nil;
548
570
        if (eventType == NSLeftMouseDown) {
549
571
            fakeEvent = [NSEvent mouseEventWithType:NSLeftMouseUp
550
 
                                    location:[initiatingEvent locationInWindow]
551
 
                                modifierFlags:[initiatingEvent modifierFlags]
552
 
                                    timestamp:[initiatingEvent timestamp]
553
 
                                windowNumber:[initiatingEvent windowNumber]
554
 
                                        context:[initiatingEvent context]
555
 
                                    eventNumber:[initiatingEvent eventNumber]
556
 
                                    clickCount:[initiatingEvent clickCount]
557
 
                                    pressure:[initiatingEvent pressure]];
 
572
                                           location:[initiatingEvent locationInWindow]
 
573
                                      modifierFlags:[initiatingEvent modifierFlags]
 
574
                                          timestamp:[initiatingEvent timestamp]
 
575
                                       windowNumber:[initiatingEvent windowNumber]
 
576
                                            context:[initiatingEvent context]
 
577
                                        eventNumber:[initiatingEvent eventNumber]
 
578
                                         clickCount:[initiatingEvent clickCount]
 
579
                                           pressure:[initiatingEvent pressure]];
558
580
        
559
581
            [NSApp postEvent:fakeEvent atStart:YES];
560
582
        } else { // eventType == NSKeyDown
561
583
            fakeEvent = [NSEvent keyEventWithType:NSKeyUp
562
 
                                    location:[initiatingEvent locationInWindow]
563
 
                               modifierFlags:[initiatingEvent modifierFlags]
564
 
                                   timestamp:[initiatingEvent timestamp]
565
 
                                windowNumber:[initiatingEvent windowNumber]
566
 
                                     context:[initiatingEvent context]
567
 
                                  characters:[initiatingEvent characters] 
568
 
                 charactersIgnoringModifiers:[initiatingEvent charactersIgnoringModifiers] 
569
 
                                   isARepeat:[initiatingEvent isARepeat] 
570
 
                                     keyCode:[initiatingEvent keyCode]];
 
584
                                         location:[initiatingEvent locationInWindow]
 
585
                                    modifierFlags:[initiatingEvent modifierFlags]
 
586
                                        timestamp:[initiatingEvent timestamp]
 
587
                                     windowNumber:[initiatingEvent windowNumber]
 
588
                                          context:[initiatingEvent context]
 
589
                                       characters:[initiatingEvent characters] 
 
590
                      charactersIgnoringModifiers:[initiatingEvent charactersIgnoringModifiers] 
 
591
                                        isARepeat:[initiatingEvent isARepeat] 
 
592
                                          keyCode:[initiatingEvent keyCode]];
571
593
            [NSApp postEvent:fakeEvent atStart:YES];
572
594
        }
573
 
        // FIXME:  We should really get the current modifierFlags here, but there's no way to poll
 
595
        // FIXME: We should really get the current modifierFlags here, but there's no way to poll
574
596
        // them in Cocoa, and because the event stream was stolen by the Carbon menu code we have
575
597
        // no up-to-date cache of them anywhere.
576
598
        fakeEvent = [NSEvent mouseEventWithType:NSMouseMoved
577
 
                                       location:[[m_frame->bridge() window] convertScreenToBase:[NSEvent mouseLocation]]
 
599
                                       location:[[view->getView() window] convertScreenToBase:[NSEvent mouseLocation]]
578
600
                                  modifierFlags:[initiatingEvent modifierFlags]
579
601
                                      timestamp:[initiatingEvent timestamp]
580
602
                                   windowNumber:[initiatingEvent windowNumber]