+2005-02-19 Kevin Decker <kdecker@apple.com>
+
+ Reviewed by Chris.
+
+ Fixed <rdar://problem/4010765> Flash player can be used to arbitrarily open popup windows without user permission
+
+ Our window.open() policy is to refuse the <script>window.open(...)</script> case and allow the inline the <a href="javascript:window.open('foo')> case. Clever advertisers at some point realized that by executing their Javascript through the Flash plugin, Safari would always treat their code as the inline case, and thus, they were able to work around our popup blocker.
+
+ * Plugins.subproj/WebBaseNetscapePluginView.h: Addded currentEventIsUserGesture boolean ivar.
+ * Plugins.subproj/WebBaseNetscapePluginView.m:
+ (-[WebBaseNetscapePluginView sendEvent:]): If at any point the user clicks or presses a key from within a plugin, set the currentEventIsUserGesture flag to true. This is important to differentiate legitimate window.open() calls originating from plugins; we still want to allow those.
+ (-[WebBaseNetscapePluginView initWithFrame:]): In our asynchronous load, pass along currentEventIsUserGesture to the PluginRequest.
+ (-[WebBaseNetscapePluginView evaluateJavaScriptPluginRequest:]): Inform WebCore if this was a user originated gesture when calling executeScript().
+ (-[WebBaseNetscapePluginView loadRequest:inTarget:withNotifyData:sendNotification:]):
+ (-[WebPluginRequest initWithRequest:frameName:notifyData:sendNotification:didStartFromUserGesture:]):
+ (-[WebPluginRequest isCurrentEventUserGesture]): Added.
+
2005-02-18 Chris Blumenberg <cblu@apple.com>
Fixed: <rdar://problem/3945271> REGRESSION (Mail): pasted plain text should pick up typing style instead of being unstyled
NSURLRequest *_request;
NSString *_frameName;
void *_notifyData;
+ BOOL _didStartFromUserGesture;
BOOL _sendNotification;
}
-- (id)initWithRequest:(NSURLRequest *)request frameName:(NSString *)frameName notifyData:(void *)notifyData sendNotification:(BOOL)sendNotification;
+- (id)initWithRequest:(NSURLRequest *)request frameName:(NSString *)frameName notifyData:(void *)notifyData sendNotification:(BOOL)sendNotification didStartFromUserGesture:(BOOL)currentEventIsUserGesture;
- (NSURLRequest *)request;
- (NSString *)frameName;
- (void *)notifyData;
+- (BOOL)isCurrentEventUserGesture;
- (BOOL)sendNotification;
@end
- (BOOL)sendEvent:(EventRecord *)event
{
ASSERT([self window]);
-
+ ASSERT(event);
+
+ // If at any point the user clicks or presses a key from within a plugin, set the
+ // currentEventIsUserGesture flag to true. This is important to differentiate legitimate
+ // window.open() calls; we still want to allow those. See rdar://problem/4010765
+ if(event->what == mouseDown || event->what == keyDown || event->what == mouseUp || event->what == autoKey) {
+ currentEventIsUserGesture = YES;
+ }
+
suspendKeyUpEvents = NO;
if (!isStarted) {
BOOL acceptedEvent = NPP_HandleEvent(instance, event);
+ currentEventIsUserGesture = NO;
+
if ([self currentWindow]) {
[self restorePortState:portState];
}
instance = &instanceStruct;
instance->ndata = self;
-
streams = [[NSMutableArray alloc] init];
pendingFrameLoads = [[NSMutableDictionary alloc] init];
NSString *JSString = [URL _web_scriptIfJavaScriptURL];
ASSERT(JSString);
- NSString *result = [[[self webFrame] _bridge] stringByEvaluatingJavaScriptFromString:JSString];
+ NSString *result = [[[self webFrame] _bridge] stringByEvaluatingJavaScriptFromString:JSString forceUserGesture:[JSPluginRequest isCurrentEventUserGesture]];
// Don't continue if stringByEvaluatingJavaScriptFromString caused the plug-in to stop.
if (!isStarted) {
return NPERR_INVALID_PARAM;
}
- WebPluginRequest *pluginRequest = [[WebPluginRequest alloc] initWithRequest:request frameName:target notifyData:notifyData sendNotification:sendNotification];
+ WebPluginRequest *pluginRequest = [[WebPluginRequest alloc] initWithRequest:request frameName:target notifyData:notifyData sendNotification:sendNotification didStartFromUserGesture:currentEventIsUserGesture];
[self performSelector:@selector(loadPluginRequest:) withObject:pluginRequest afterDelay:0];
[pluginRequest release];
if (target) {
@implementation WebPluginRequest
-- (id)initWithRequest:(NSURLRequest *)request frameName:(NSString *)frameName notifyData:(void *)notifyData sendNotification:(BOOL)sendNotification
+- (id)initWithRequest:(NSURLRequest *)request frameName:(NSString *)frameName notifyData:(void *)notifyData sendNotification:(BOOL)sendNotification didStartFromUserGesture:(BOOL)currentEventIsUserGesture
{
[super init];
+ _didStartFromUserGesture = currentEventIsUserGesture;
_request = [request retain];
_frameName = [frameName retain];
_notifyData = notifyData;
return _frameName;
}
+- (BOOL)isCurrentEventUserGesture
+{
+ return _didStartFromUserGesture;
+}
+
- (BOOL)sendNotification
{
return _sendNotification;