diff options
author | isherman@chromium.org <isherman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-30 22:56:44 +0000 |
---|---|---|
committer | isherman@chromium.org <isherman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-30 22:56:44 +0000 |
commit | 088949998b215841d9fc42a6aa425b3f56160464 (patch) | |
tree | 44597ef285e8ea5667700e5219e4c0062354cfc5 /content/browser | |
parent | 43ed3a7d4a4a043220dd01677ec2fc39451df852 (diff) | |
download | chromium_src-088949998b215841d9fc42a6aa425b3f56160464.zip chromium_src-088949998b215841d9fc42a6aa425b3f56160464.tar.gz chromium_src-088949998b215841d9fc42a6aa425b3f56160464.tar.bz2 |
[Mac] Ensure that JavaScript URLs are always properly escaped for drag 'n drop.
This fixes a crash -- or, more precisely, prevents an exception from being thrown -- when dragging poorly escaped bookmarklets.
BUG=128371
TEST=Dragging a bookmarklet with the URL "javascript:%" should not induce a crash
Review URL: https://chromiumcodereview.appspot.com/10450032
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@139665 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser')
-rw-r--r-- | content/browser/web_contents/web_drag_source_mac.mm | 25 | ||||
-rw-r--r-- | content/browser/web_contents/web_drag_source_mac_unittest.mm | 42 |
2 files changed, 57 insertions, 10 deletions
diff --git a/content/browser/web_contents/web_drag_source_mac.mm b/content/browser/web_contents/web_drag_source_mac.mm index 21e05c3..32fc4e0 100644 --- a/content/browser/web_contents/web_drag_source_mac.mm +++ b/content/browser/web_contents/web_drag_source_mac.mm @@ -22,6 +22,7 @@ #include "content/public/browser/content_browser_client.h" #include "content/public/common/content_client.h" #include "content/public/common/url_constants.h" +#include "net/base/escape.h" #include "net/base/file_stream.h" #include "net/base/net_util.h" #include "ui/base/clipboard/custom_data_helper.h" @@ -143,7 +144,7 @@ void PromiseWriterHelper(const WebDropData& drop_data, // Be extra paranoid; avoid crashing. if (!dropData_.get()) { - NOTREACHED() << "No drag-and-drop data available for lazy write."; + NOTREACHED(); return; } @@ -157,16 +158,19 @@ void PromiseWriterHelper(const WebDropData& drop_data, // URL. } else if ([type isEqualToString:NSURLPboardType]) { DCHECK(dropData_->url.is_valid()); - NSString* urlStr = SysUTF8ToNSString(dropData_->url.spec()); - NSURL* url = [NSURL URLWithString:urlStr]; + NSURL* url = [NSURL URLWithString:SysUTF8ToNSString(dropData_->url.spec())]; // If NSURL creation failed, check for a badly-escaped JavaScript URL. // Strip out any existing escapes and then re-escape uniformly. - if (!url && urlStr && dropData_->url.SchemeIs(chrome::kJavaScriptScheme)) { - NSString* unEscapedStr = [urlStr - stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; - NSString* escapedStr = [unEscapedStr - stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; - url = [NSURL URLWithString:escapedStr]; + if (!url && dropData_->url.SchemeIs(chrome::kJavaScriptScheme)) { + net::UnescapeRule::Type unescapeRules = + net::UnescapeRule::SPACES | + net::UnescapeRule::URL_SPECIAL_CHARS | + net::UnescapeRule::CONTROL_CHARS; + std::string unescapedUrlString = + net::UnescapeURLComponent(dropData_->url.spec(), unescapeRules); + std::string escapedUrlString = + net::EscapeUrlEncodedData(unescapedUrlString, false); + url = [NSURL URLWithString:SysUTF8ToNSString(escapedUrlString)]; } [url writeToPasteboard:pboard]; // URL title. @@ -214,7 +218,8 @@ void PromiseWriterHelper(const WebDropData& drop_data, // Oops! } else { - NOTREACHED() << "Asked for a drag pasteboard type we didn't offer."; + // Unknown drag pasteboard type. + NOTREACHED(); } } diff --git a/content/browser/web_contents/web_drag_source_mac_unittest.mm b/content/browser/web_contents/web_drag_source_mac_unittest.mm new file mode 100644 index 0000000..d355e16 --- /dev/null +++ b/content/browser/web_contents/web_drag_source_mac_unittest.mm @@ -0,0 +1,42 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "content/browser/web_contents/web_drag_source_mac.h" + +#include "content/browser/web_contents/web_contents_impl.h" +#include "content/test/test_renderer_host.h" +#include "googleurl/src/gurl.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "webkit/glue/webdropdata.h" + +namespace content { + +typedef RenderViewHostTestHarness WebDragSourceMacTest; + +TEST_F(WebDragSourceMacTest, DragInvalidlyEscapedBookmarklet) { + scoped_ptr<WebContents> contents(CreateTestWebContents()); + scoped_nsobject<NSView> view( + [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 10, 10)]); + + scoped_ptr<WebDropData> dropData(new WebDropData); + dropData->url = GURL("javascript:%"); + + WebContentsImpl* contentsImpl = static_cast<WebContentsImpl*>(contents.get()); + scoped_nsobject<WebDragSource> source( + [[WebDragSource alloc] + initWithContents:contentsImpl + view:view + dropData:dropData.release() + image:nil + offset:NSMakePoint(0, 0) + pasteboard:[NSPasteboard pasteboardWithUniqueName] + dragOperationMask:NSDragOperationCopy]); + + // Test that this call doesn't throw any exceptions: http://crbug.com/128371 + scoped_nsobject<NSPasteboard> pasteboard( + [NSPasteboard pasteboardWithUniqueName]); + [source lazyWriteToPasteboard:pasteboard forType:NSURLPboardType]; +} + +} // namespace content |