diff options
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/render_view.cc | 6 | ||||
-rw-r--r-- | chrome/renderer/renderer_logging.h | 55 | ||||
-rw-r--r-- | chrome/renderer/renderer_logging_linux.cc | 24 | ||||
-rw-r--r-- | chrome/renderer/renderer_logging_mac.mm | 71 | ||||
-rw-r--r-- | chrome/renderer/renderer_logging_mac_unittest.mm | 138 | ||||
-rw-r--r-- | chrome/renderer/renderer_logging_win.cc | 33 | ||||
-rw-r--r-- | chrome/renderer/webplugin_delegate_proxy.cc | 17 | ||||
-rw-r--r-- | chrome/renderer/webplugin_delegate_proxy.h | 5 |
8 files changed, 331 insertions, 18 deletions
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index d94f484..c960798 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -23,7 +23,6 @@ #include "base/string_util.h" #include "build/build_config.h" #include "chrome/common/bindings_policy.h" -#include "chrome/common/child_process_logging.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/jstemplate_builder.h" @@ -43,6 +42,7 @@ #include "chrome/renderer/navigation_state.h" #include "chrome/renderer/print_web_view_helper.h" #include "chrome/renderer/render_process.h" +#include "chrome/renderer/renderer_logging.h" #include "chrome/renderer/user_script_slave.h" #include "chrome/renderer/visitedlink_slave.h" #include "chrome/renderer/webplugin_delegate_proxy.h" @@ -325,7 +325,7 @@ void RenderView::Init(gfx::NativeViewId parent_hwnd, void RenderView::OnMessageReceived(const IPC::Message& message) { WebFrame* main_frame = webview() ? webview()->GetMainFrame() : NULL; - child_process_logging::ScopedActiveURLSetter url_setter( + renderer_logging::ScopedActiveRenderingURLSetter url_setter( main_frame ? main_frame->GetURL() : GURL()); // If this is developer tools renderer intercept tools messages first. @@ -626,7 +626,7 @@ void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) { if (!webview()) return; - child_process_logging::ScopedActiveURLSetter url_setter(params.url); + renderer_logging::ScopedActiveRenderingURLSetter url_setter(params.url); AboutHandler::MaybeHandle(params.url); diff --git a/chrome/renderer/renderer_logging.h b/chrome/renderer/renderer_logging.h new file mode 100644 index 0000000..d7c91a5 --- /dev/null +++ b/chrome/renderer/renderer_logging.h @@ -0,0 +1,55 @@ +// Copyright (c) 2009 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. + +#ifndef CHROME_RENDERER_RENDERER_LOGGING_H_ +#define CHROME_RENDERER_RENDERER_LOGGING_H_ + +#include "base/basictypes.h" +#include "googleurl/src/gurl.h" + +namespace renderer_logging { + +// Sets the URL that is logged if the renderer crashes. Use GURL() to clear +// the URL. +void SetActiveRendererURL(const GURL& url); + +// Simple wrapper class that sets the active rendering URL in it's constructor +// and clears the active rendering URL in the destructor. +class ScopedActiveRenderingURLSetter { + public: + explicit ScopedActiveRenderingURLSetter(const GURL& url) { + SetActiveRendererURL(url); + } + + ~ScopedActiveRenderingURLSetter() { + SetActiveRendererURL(GURL()); + } + + private: + DISALLOW_COPY_AND_ASSIGN(ScopedActiveRenderingURLSetter); +}; + +} // namespace renderer_logging + +#if defined(OS_MACOSX) && __OBJC__ +// Exported for testing purposes. + +@class NSString; + +typedef void (*SetCrashKeyValueFuncPtr)(NSString*, NSString*); +typedef void (*ClearCrashKeyValueFuncPtr)(NSString*); + +namespace renderer_logging { +void SetActiveRendererURLImpl(const GURL& url, + SetCrashKeyValueFuncPtr set_key_func, + ClearCrashKeyValueFuncPtr clear_key_func); + +extern const int kMaxNumCrashURLChunks; +extern const int kMaxNumURLChunkValueLength; +extern const char *kUrlChunkFormatStr; +} // namespace renderer_logging + +#endif // defined(OS_MACOSX) && __OBJC__ + +#endif // CHROME_RENDERER_RENDERER_LOGGING_H_ diff --git a/chrome/renderer/renderer_logging_linux.cc b/chrome/renderer/renderer_logging_linux.cc new file mode 100644 index 0000000..7812da1 --- /dev/null +++ b/chrome/renderer/renderer_logging_linux.cc @@ -0,0 +1,24 @@ +// Copyright (c) 2009 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. + +#include "chrome/renderer/renderer_logging.h" + +#include <string> + +#include "base/logging.h" +#include "googleurl/src/gurl.h" + +namespace renderer_logging { + +// We use a static string to hold the most recent active url. If we crash, the +// crash handler code will send the contents of this string to the browser. +std::string active_url; + +// Sets the URL that is logged if the renderer crashes. Use GURL() to clear +// the URL. +void SetActiveRendererURL(const GURL& url) { + active_url = url.possibly_invalid_spec(); +} + +} // namespace renderer_logging diff --git a/chrome/renderer/renderer_logging_mac.mm b/chrome/renderer/renderer_logging_mac.mm new file mode 100644 index 0000000..bb0ea92 --- /dev/null +++ b/chrome/renderer/renderer_logging_mac.mm @@ -0,0 +1,71 @@ +// Copyright (c) 2009 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. + +#include "chrome/renderer/renderer_logging.h" + +#import <Foundation/Foundation.h> + +#include "base/string_util.h" +#include "googleurl/src/gurl.h" +#import "chrome/app/breakpad_mac.h" + +namespace renderer_logging { + +const int kMaxNumCrashURLChunks = 8; +const int kMaxNumURLChunkValueLength = 255; +const char *kUrlChunkFormatStr = "url-chunk-%d"; + +void SetActiveRendererURLImpl(const GURL& url, + SetCrashKeyValueFuncPtr set_key_func, + ClearCrashKeyValueFuncPtr clear_key_func) { + + NSString *kUrlChunkFormatStr_utf8 = [NSString + stringWithUTF8String:kUrlChunkFormatStr]; + + // First remove any old url chunks we might have lying around. + for (int i = 0; i < kMaxNumCrashURLChunks; i++) { + // On Windows the url-chunk items are 1-based, so match that. + NSString *key = [NSString stringWithFormat:kUrlChunkFormatStr_utf8, i+1]; + clear_key_func(key); + } + + const std::string& raw_url_utf8 = url.possibly_invalid_spec(); + NSString *raw_url = [NSString stringWithUTF8String:raw_url_utf8.c_str()]; + size_t raw_url_length = [raw_url length]; + + // Bail on zero-length URLs. + if (raw_url_length == 0) { + return; + } + + // Parcel the URL up into up to 8, 255 byte segments. + size_t start_ofs = 0; + for (int i = 0; + i < kMaxNumCrashURLChunks && start_ofs < raw_url_length; + ++i) { + + // On Windows the url-chunk items are 1-based, so match that. + NSString *key = [NSString stringWithFormat:kUrlChunkFormatStr_utf8, i+1]; + NSRange range; + range.location = start_ofs; + range.length = std::min((size_t)kMaxNumURLChunkValueLength, + raw_url_length - start_ofs); + NSString *value = [raw_url substringWithRange:range]; + set_key_func(key, value); + + // Next chunk. + start_ofs += kMaxNumURLChunkValueLength; + } +} + +void SetActiveRendererURL(const GURL& url) { + // If Breakpad isn't initialized then bail. + if (IsCrashReporterDisabled()) { + return; + } + + SetActiveRendererURLImpl(url, SetCrashKeyValue, ClearCrashKeyValue); +} + +} // namespace renderer_logging diff --git a/chrome/renderer/renderer_logging_mac_unittest.mm b/chrome/renderer/renderer_logging_mac_unittest.mm new file mode 100644 index 0000000..6aece64 --- /dev/null +++ b/chrome/renderer/renderer_logging_mac_unittest.mm @@ -0,0 +1,138 @@ +// Copyright (c) 2009 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. + +#include "chrome/renderer/renderer_logging.h" + +#import <Foundation/Foundation.h> + +#include "base/logging.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "testing/platform_test.h" + +typedef PlatformTest RendererLoggingTest; + +namespace { + +// Class to mock breakpad's setkeyvalue/clearkeyvalue functions needed for +// SetActiveRendererURLImpl. +// The Keys are stored in a static dictionary and methods are provided to +// verify correctness. +class MockBreakpadKeyValueStore { + public: + MockBreakpadKeyValueStore() { + // Only one of these objects can be active at once. + DCHECK(dict == NULL); + dict = [[NSMutableDictionary alloc] init]; + } + + ~MockBreakpadKeyValueStore() { + // Only one of these objects can be active at once. + DCHECK(dict != NULL); + [dict release]; + dict = NULL; + } + + static void SetKeyValue(NSString* key, NSString* value) { + DCHECK(dict != NULL); + [dict setObject:value forKey:key]; + } + + static void ClearKeyValue(NSString *key) { + DCHECK(dict != NULL); + [dict removeObjectForKey:key]; + } + + int CountDictionaryEntries() { + return [dict count]; + } + + bool VerifyDictionaryContents(const std::string &url) { + using renderer_logging::kMaxNumCrashURLChunks; + using renderer_logging::kMaxNumURLChunkValueLength; + using renderer_logging::kUrlChunkFormatStr; + + int num_url_chunks = CountDictionaryEntries(); + EXPECT_TRUE(num_url_chunks <= kMaxNumCrashURLChunks); + + NSString *kUrlChunkFormatStr_utf8 = [NSString + stringWithUTF8String:kUrlChunkFormatStr]; + + NSString *accumulated_url = @""; + for (int i = 0; i < num_url_chunks; ++i) { + // URL chunk names are 1-based. + NSString *key = [NSString stringWithFormat:kUrlChunkFormatStr_utf8, i+1]; + EXPECT_TRUE(key != NULL); + NSString *value = [dict objectForKey:key]; + EXPECT_TRUE([value length] > 0); + EXPECT_TRUE([value length] <= (unsigned)kMaxNumURLChunkValueLength); + accumulated_url = [accumulated_url stringByAppendingString:value]; + } + + NSString *expected_url = [NSString stringWithUTF8String:url.c_str()]; + return([accumulated_url isEqualToString:expected_url]); + } + + private: + static NSMutableDictionary* dict; + DISALLOW_COPY_AND_ASSIGN(MockBreakpadKeyValueStore); +}; + +} // namespace + +// Call through to SetActiveRendererURLImpl using the functions from +// MockBreakpadKeyValueStore. +void SetActiveRendererURLWithMock(const GURL& url) { + using renderer_logging::SetActiveRendererURLImpl; + + SetCrashKeyValueFuncPtr setFunc = MockBreakpadKeyValueStore::SetKeyValue; + ClearCrashKeyValueFuncPtr clearFunc = + MockBreakpadKeyValueStore::ClearKeyValue; + + SetActiveRendererURLImpl(url, setFunc, clearFunc); +} + +TEST_F(RendererLoggingTest, TestUrlSplitting) { + using renderer_logging::kMaxNumCrashURLChunks; + using renderer_logging::kMaxNumURLChunkValueLength; + + const std::string short_url("http://abc/"); + std::string long_url("http://"); + std::string overflow_url("http://"); + + long_url += std::string(kMaxNumURLChunkValueLength * 2, 'a'); + long_url += "/"; + + int max_num_chars_stored_in_dump = kMaxNumURLChunkValueLength * + kMaxNumCrashURLChunks; + overflow_url += std::string(max_num_chars_stored_in_dump + 1, 'a'); + overflow_url += "/"; + + // Check that Clearing NULL URL works. + MockBreakpadKeyValueStore mock; + SetActiveRendererURLWithMock(GURL()); + EXPECT_EQ(mock.CountDictionaryEntries(), 0); + + // Check that we can set a URL. + SetActiveRendererURLWithMock(GURL(short_url.c_str())); + EXPECT_TRUE(mock.VerifyDictionaryContents(short_url)); + EXPECT_EQ(mock.CountDictionaryEntries(), 1); + SetActiveRendererURLWithMock(GURL()); + EXPECT_EQ(mock.CountDictionaryEntries(), 0); + + // Check that we can replace a long url with a short url. + SetActiveRendererURLWithMock(GURL(long_url.c_str())); + EXPECT_TRUE(mock.VerifyDictionaryContents(long_url)); + SetActiveRendererURLWithMock(GURL(short_url.c_str())); + EXPECT_TRUE(mock.VerifyDictionaryContents(short_url)); + SetActiveRendererURLWithMock(GURL()); + EXPECT_EQ(mock.CountDictionaryEntries(), 0); + + + // Check that overflow works correctly. + SetActiveRendererURLWithMock(GURL(overflow_url.c_str())); + EXPECT_TRUE(mock.VerifyDictionaryContents( + overflow_url.substr(0, max_num_chars_stored_in_dump))); + SetActiveRendererURLWithMock(GURL()); + EXPECT_EQ(mock.CountDictionaryEntries(), 0); +} diff --git a/chrome/renderer/renderer_logging_win.cc b/chrome/renderer/renderer_logging_win.cc new file mode 100644 index 0000000..6d1b758 --- /dev/null +++ b/chrome/renderer/renderer_logging_win.cc @@ -0,0 +1,33 @@ +// Copyright (c) 2009 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. + +#include "chrome/renderer/renderer_logging.h" + +#include <windows.h> + +#include "base/string_util.h" +#include "chrome/common/chrome_constants.h" +#include "googleurl/src/gurl.h" + +namespace renderer_logging { + +typedef void (__cdecl *MainSetActiveRendererURL)(const wchar_t*); + +// Sets the URL that is logged if the renderer crashes. Use GURL() to clear +// the URL. +void SetActiveRendererURL(const GURL& url) { + HMODULE exe_module = GetModuleHandle(chrome::kBrowserProcessExecutableName); + if (!exe_module) + return; + + MainSetActiveRendererURL set_active_renderer_url = + reinterpret_cast<MainSetActiveRendererURL>( + GetProcAddress(exe_module, "SetActiveRendererURL")); + if (!set_active_renderer_url) + return; + + (set_active_renderer_url)(UTF8ToWide(url.possibly_invalid_spec()).c_str()); +} + +} // namespace renderer_logging diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc index e7650a7..ad70db1 100644 --- a/chrome/renderer/webplugin_delegate_proxy.cc +++ b/chrome/renderer/webplugin_delegate_proxy.cc @@ -19,7 +19,6 @@ #include "base/gfx/size.h" #include "base/gfx/native_widget_types.h" #include "chrome/app/chrome_dll_resource.h" -#include "chrome/common/child_process_logging.h" #include "chrome/common/plugin_messages.h" #include "chrome/common/render_messages.h" #include "chrome/plugin/npobject_proxy.h" @@ -27,6 +26,7 @@ #include "chrome/plugin/npobject_util.h" #include "chrome/renderer/render_thread.h" #include "chrome/renderer/render_view.h" +#include "googleurl/src/gurl.h" #include "grit/generated_resources.h" #include "net/base/mime_util.h" #include "printing/native_metafile.h" @@ -170,8 +170,7 @@ WebPluginDelegateProxy::WebPluginDelegateProxy(const std::string& mime_type, window_script_object_(NULL), sad_plugin_(NULL), invalidate_pending_(false), - transparent_(false), - page_url_(render_view_->webview()->GetMainFrame()->GetURL()) { + transparent_(false) { } WebPluginDelegateProxy::~WebPluginDelegateProxy() { @@ -246,7 +245,6 @@ bool WebPluginDelegateProxy::Initialize(const GURL& url, char** argn, PluginMsg_Init_Params params; params.containing_window = render_view_->host_window(); params.url = url; - params.page_url = page_url_; for (int i = 0; i < argc; ++i) { params.arg_names.push_back(argn[i]); params.arg_values.push_back(argv[i]); @@ -331,8 +329,6 @@ void WebPluginDelegateProxy::InstallMissingPlugin() { } void WebPluginDelegateProxy::OnMessageReceived(const IPC::Message& msg) { - child_process_logging::ScopedActiveURLSetter url_setter(page_url_); - IPC_BEGIN_MESSAGE_MAP(WebPluginDelegateProxy, msg) IPC_MESSAGE_HANDLER(PluginHostMsg_SetWindow, OnSetWindow) #if defined(OS_LINUX) @@ -612,7 +608,7 @@ NPObject* WebPluginDelegateProxy::GetPluginScriptableObject() { npobject_ = NPObjectProxy::Create( channel_host_.get(), route_id, npobject_ptr, - render_view_->modal_dialog_event(), page_url_); + render_view_->modal_dialog_event()); return NPN_RetainObject(npobject_); } @@ -702,7 +698,7 @@ void WebPluginDelegateProxy::OnGetWindowScriptNPObject( // otherwise when the channel is closed. NPObjectStub* stub = new NPObjectStub( npobject, channel_host_.get(), route_id, - render_view_->modal_dialog_event(), page_url_); + render_view_->modal_dialog_event()); window_script_object_ = stub; window_script_object_->set_proxy(this); *success = true; @@ -722,7 +718,7 @@ void WebPluginDelegateProxy::OnGetPluginElement( // otherwise when the channel is closed. new NPObjectStub( npobject, channel_host_.get(), route_id, - render_view_->modal_dialog_event(), page_url_); + render_view_->modal_dialog_event()); *success = true; *npobject_ptr = reinterpret_cast<intptr_t>(npobject); } @@ -813,8 +809,7 @@ void WebPluginDelegateProxy::OnGetDragData(const NPVariant_Param& object, for (size_t i = 0; i < arraysize(results); ++i) { values->push_back(NPVariant_Param()); - CreateNPVariantParam( - results[i], NULL, &values->back(), false, NULL, page_url_); + CreateNPVariantParam(results[i], NULL, &values->back(), false, NULL); } *success = true; diff --git a/chrome/renderer/webplugin_delegate_proxy.h b/chrome/renderer/webplugin_delegate_proxy.h index b665015..e720815 100644 --- a/chrome/renderer/webplugin_delegate_proxy.h +++ b/chrome/renderer/webplugin_delegate_proxy.h @@ -14,11 +14,11 @@ #include "base/ref_counted.h" #include "chrome/common/ipc_message.h" #include "chrome/renderer/plugin_channel_host.h" -#include "googleurl/src/gurl.h" #include "skia/ext/platform_canvas.h" #include "webkit/glue/webplugin.h" #include "webkit/glue/webplugin_delegate.h" +class GURL; struct NPObject; class NPObjectStub; struct NPVariant_Param; @@ -204,9 +204,6 @@ class WebPluginDelegateProxy : public WebPluginDelegate, // This lets us know which portion of the backing store has been painted into. gfx::Rect backing_store_painted_; - // The url of the main frame hosting the plugin. - GURL page_url_; - DISALLOW_EVIL_CONSTRUCTORS(WebPluginDelegateProxy); }; |