diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-29 22:35:33 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-29 22:35:33 +0000 |
commit | ea3d1d84be3d6f97bf50e76511c9e26af6895533 (patch) | |
tree | 94c73f600dcca23329221ad8c51e6a5158263f7e /webkit/glue/plugins | |
parent | 403e46333b43009776a08273501e4ca8c5c06e12 (diff) | |
download | chromium_src-ea3d1d84be3d6f97bf50e76511c9e26af6895533.zip chromium_src-ea3d1d84be3d6f97bf50e76511c9e26af6895533.tar.gz chromium_src-ea3d1d84be3d6f97bf50e76511c9e26af6895533.tar.bz2 |
Fix passing pointers between processes.
BUG=31880
Review URL: http://codereview.chromium.org/558036
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@37555 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue/plugins')
-rw-r--r-- | webkit/glue/plugins/plugin_host.cc | 27 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_instance.cc | 128 | ||||
-rw-r--r-- | webkit/glue/plugins/plugin_instance.h | 64 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl.cc | 33 | ||||
-rw-r--r-- | webkit/glue/plugins/webplugin_delegate_impl.h | 16 |
5 files changed, 154 insertions, 114 deletions
diff --git a/webkit/glue/plugins/plugin_host.cc b/webkit/glue/plugins/plugin_host.cc index 544597b..c8c652d 100644 --- a/webkit/glue/plugins/plugin_host.cc +++ b/webkit/glue/plugins/plugin_host.cc @@ -313,12 +313,7 @@ NPError NPN_RequestRead(NPStream* stream, NPByteRange* range_list) { return NPERR_NO_ERROR; } -static bool IsJavaScriptUrl(const std::string& url) { - return StartsWithASCII(url, "javascript:", false); -} - -// Generic form of GetURL for common code between -// GetURL() and GetURLNotify(). +// Generic form of GetURL for common code between GetURL and GetURLNotify. static NPError GetURLNotify(NPP id, const char* url, const char* target, @@ -327,18 +322,13 @@ static NPError GetURLNotify(NPP id, if (!url) return NPERR_INVALID_URL; - bool is_javascript_url = IsJavaScriptUrl(url); - scoped_refptr<NPAPI::PluginInstance> plugin = FindInstance(id); - if (plugin.get()) { - plugin->webplugin()->HandleURLRequest( - "GET", is_javascript_url, target, 0, 0, false, - notify, url, reinterpret_cast<intptr_t>(notify_data), - plugin->popups_allowed()); - } else { + if (!plugin.get()) { NOTREACHED(); return NPERR_GENERIC_ERROR; } + + plugin->RequestURL(url, "GET", target, NULL, 0, notify, notify_data); return NPERR_NO_ERROR; } @@ -385,8 +375,7 @@ NPError NPN_GetURL(NPP id, const char* url, const char* target) { return GetURLNotify(id, url, target, false, 0); } -// Generic form of PostURL for common code between -// PostURL() and PostURLNotify(). +// Generic form of PostURL for common code between PostURL and PostURLNotify. static NPError PostURLNotify(NPP id, const char* url, const char* target, @@ -460,8 +449,6 @@ static NPError PostURLNotify(NPP id, len = post_file_contents.size(); } - bool is_javascript_url = IsJavaScriptUrl(url); - // The post data sent by a plugin contains both headers // and post data. Example: // Content-type: text/html @@ -472,9 +459,7 @@ static NPError PostURLNotify(NPP id, // Unfortunately, our stream needs these broken apart, // so we need to parse the data and set headers and data // separately. - plugin->webplugin()->HandleURLRequest( - "POST", is_javascript_url, target, len, buf, false, notify, url, - reinterpret_cast<intptr_t>(notify_data), plugin->popups_allowed()); + plugin->RequestURL(url, "POST", target, buf, len, notify, notify_data); return NPERR_NO_ERROR; } diff --git a/webkit/glue/plugins/plugin_instance.cc b/webkit/glue/plugins/plugin_instance.cc index d560d42..1d01f8e 100644 --- a/webkit/glue/plugins/plugin_instance.cc +++ b/webkit/glue/plugins/plugin_instance.cc @@ -40,16 +40,16 @@ PluginInstance::PluginInstance(PluginLib *plugin, const std::string &mime_type) event_model_(0), currently_handled_event_(NULL), #endif - message_loop_(MessageLoop::current()), load_manually_(false), in_close_streams_(false), - next_timer_id_(1) { + next_timer_id_(1), + next_notify_id_(0), + next_range_request_id_(0) { npp_ = new NPP_t(); npp_->ndata = 0; npp_->pdata = 0; memset(&zero_padding_, 0, sizeof(zero_padding_)); - DCHECK(message_loop_); } PluginInstance::~PluginInstance() { @@ -67,10 +67,13 @@ PluginInstance::~PluginInstance() { PluginStreamUrl* PluginInstance::CreateStream(unsigned long resource_id, const GURL& url, const std::string& mime_type, - bool notify_needed, - void* notify_data) { + int notify_id) { + + bool notify; + void* notify_data; + GetNotifyData(notify_id, ¬ify, ¬ify_data); PluginStreamUrl* stream = new PluginStreamUrl( - resource_id, url, this, notify_needed, notify_data); + resource_id, url, this, notify, notify_data); AddStream(stream); return stream; @@ -115,6 +118,19 @@ void PluginInstance::CloseStreams() { in_close_streams_ = false; } +webkit_glue::WebPluginResourceClient* PluginInstance::GetRangeRequest( + int id) { + PendingRangeRequestMap::iterator iter = pending_range_requests_.find(id); + if (iter == pending_range_requests_.end()) { + NOTREACHED(); + return NULL; + } + + webkit_glue::WebPluginResourceClient* rv = iter->second->AsResourceClient(); + pending_range_requests_.erase(iter); + return rv; +} + bool PluginInstance::Start(const GURL& url, char** const param_names, char** const param_values, @@ -138,8 +154,16 @@ NPObject *PluginInstance::GetPluginScriptableObject() { } // WebPluginLoadDelegate methods -void PluginInstance::DidFinishLoadWithReason(const GURL& url, NPReason reason, - void* notify_data) { +void PluginInstance::DidFinishLoadWithReason( + const GURL& url, NPReason reason, int notify_id) { + bool notify; + void* notify_data; + GetNotifyData(notify_id, ¬ify, ¬ify_data); + if (!notify) { + NOTREACHED(); + return; + } + NPP_URLNotify(url.spec().c_str(), reason, notify_data); } @@ -305,21 +329,21 @@ bool PluginInstance::NPP_Print(NPPrint* platform_print) { void PluginInstance::SendJavaScriptStream(const GURL& url, const std::string& result, bool success, - bool notify_needed, - intptr_t notify_data) { + int notify_id) { + bool notify; + void* notify_data; + GetNotifyData(notify_id, ¬ify, ¬ify_data); + if (success) { PluginStringStream *stream = - new PluginStringStream(this, url, notify_needed, - reinterpret_cast<void*>(notify_data)); + new PluginStringStream(this, url, notify, notify_data); AddStream(stream); stream->SendToPlugin(result, "text/html"); } else { // NOTE: Sending an empty stream here will crash MacroMedia // Flash 9. Just send the URL Notify. - if (notify_needed) { - this->NPP_URLNotify(url.spec().c_str(), NPRES_DONE, - reinterpret_cast<void*>(notify_data)); - } + if (notify) + NPP_URLNotify(url.spec().c_str(), NPRES_DONE, notify_data); } } @@ -330,8 +354,7 @@ void PluginInstance::DidReceiveManualResponse(const GURL& url, uint32 last_modified) { DCHECK(load_manually_); - plugin_data_stream_ = CreateStream(-1, url, mime_type, false, NULL); - + plugin_data_stream_ = CreateStream(-1, url, mime_type, 0); plugin_data_stream_->DidReceiveResponse(mime_type, headers, expected_length, last_modified, true); } @@ -362,8 +385,9 @@ void PluginInstance::DidManualLoadFail() { void PluginInstance::PluginThreadAsyncCall(void (*func)(void *), void *user_data) { - message_loop_->PostTask(FROM_HERE, NewRunnableMethod( - this, &PluginInstance::OnPluginThreadAsyncCall, func, user_data)); + MessageLoop::current()->PostTask( + FROM_HERE, NewRunnableMethod( + this, &PluginInstance::OnPluginThreadAsyncCall, func, user_data)); } void PluginInstance::OnPluginThreadAsyncCall(void (*func)(void *), @@ -389,13 +413,11 @@ uint32 PluginInstance::ScheduleTimer(uint32 interval, timers_[timer_id] = info; // Schedule the callback. - message_loop_->PostDelayedTask(FROM_HERE, - NewRunnableMethod(this, - &PluginInstance::OnTimerCall, - func, - npp_, - timer_id), - interval); + MessageLoop::current()->PostDelayedTask( + FROM_HERE, + NewRunnableMethod( + this, &PluginInstance::OnTimerCall, func, npp_, timer_id), + interval); return timer_id; } @@ -434,14 +456,11 @@ void PluginInstance::OnTimerCall(void (*func)(NPP id, uint32 timer_id), // Reschedule repeating timers after invoking the callback so callback is not // re-entered if it pumps the messager loop. if (info.repeat) { - message_loop_->PostDelayedTask(FROM_HERE, - NewRunnableMethod( - this, - &PluginInstance::OnTimerCall, - func, - npp_, - timer_id), - info.interval); + MessageLoop::current()->PostDelayedTask( + FROM_HERE, + NewRunnableMethod( + this, &PluginInstance::OnTimerCall, func, npp_, timer_id), + info.interval); } else { timers_.erase(it); } @@ -490,14 +509,30 @@ void PluginInstance::RequestRead(NPStream* stream, NPByteRange* range_list) { // is called on it. plugin_stream->set_seekable(true); + pending_range_requests_[++next_range_request_id_] = plugin_stream; webplugin_->InitiateHTTPRangeRequest( - stream->url, range_info.c_str(), - reinterpret_cast<intptr_t>(plugin_stream), - plugin_stream->notify_needed(), - reinterpret_cast<intptr_t>(plugin_stream->notify_data())); - break; + stream->url, range_info.c_str(), next_range_request_id_); + return; } } + NOTREACHED(); +} + +void PluginInstance::RequestURL(const char* url, + const char* method, + const char* target, + const char* buf, + unsigned int len, + bool notify, + void* notify_data) { + int notify_id = 0; + if (notify) { + notify_id = ++next_notify_id_; + pending_requests_[notify_id] = notify_data; + } + + webplugin_->HandleURLRequest( + url, method, target, buf, len, notify_id, popups_allowed()); } bool PluginInstance::ConvertPoint(double source_x, double source_y, @@ -566,4 +601,17 @@ bool PluginInstance::ConvertPoint(double source_x, double source_y, #endif } +void PluginInstance::GetNotifyData( + int notify_id, bool* notify, void** notify_data) { + PendingRequestMap::iterator iter = pending_requests_.find(notify_id); + if (iter != pending_requests_.end()) { + *notify = true; + *notify_data = iter->second; + pending_requests_.erase(iter); + } else { + *notify = false; + *notify_data = NULL; + } +} + } // namespace NPAPI diff --git a/webkit/glue/plugins/plugin_instance.h b/webkit/glue/plugins/plugin_instance.h index 4043ed4..7cb72aa 100644 --- a/webkit/glue/plugins/plugin_instance.h +++ b/webkit/glue/plugins/plugin_instance.h @@ -24,10 +24,10 @@ #include "googleurl/src/gurl.h" #include "third_party/npapi/bindings/npapi.h" -class MessageLoop; namespace webkit_glue { class WebPlugin; +class WebPluginResourceClient; } namespace NPAPI @@ -116,17 +116,15 @@ class PluginInstance : public base::RefCountedThreadSafe<PluginInstance> { void set_plugin_origin(gfx::Point origin) { plugin_origin_ = origin; } #endif - // Creates a stream for sending an URL. If notify_needed - // is true, it will send a notification to the plugin - // when the stream is complete; otherwise it will not. - // Set object_url to true if the load is for the object tag's - // url, or false if it's for a url that the plugin - // fetched through NPN_GetUrl[Notify]. + // Creates a stream for sending an URL. If notify_id is non-zero, it will + // send a notification to the plugin when the stream is complete; otherwise it + // will not. Set object_url to true if the load is for the object tag's url, + // or false if it's for a url that the plugin fetched through + // NPN_GetUrl[Notify]. PluginStreamUrl* CreateStream(unsigned long resource_id, const GURL& url, const std::string& mime_type, - bool notify_needed, - void* notify_data); + int notify_id); // For each instance, we track all streams. When the // instance closes, all remaining streams are also @@ -142,13 +140,16 @@ class PluginInstance : public base::RefCountedThreadSafe<PluginInstance> { // Closes all open streams on this instance. void CloseStreams(); + // Returns the WebPluginResourceClient object for a stream that has become + // seekable. + webkit_glue::WebPluginResourceClient* GetRangeRequest(int id); + // Have the plugin create it's script object. NPObject *GetPluginScriptableObject(); // WebViewDelegate methods that we implement. This is for handling // callbacks during getURLNotify. - virtual void DidFinishLoadWithReason(const GURL& url, NPReason reason, - void* notify_data); + void DidFinishLoadWithReason(const GURL& url, NPReason reason, int notify_id); // If true, send the Mozilla user agent instead of Chrome's to the plugin. bool use_mozilla_user_agent() { return use_mozilla_user_agent_; } @@ -188,9 +189,10 @@ class PluginInstance : public base::RefCountedThreadSafe<PluginInstance> { void NPP_Destroy(); bool NPP_Print(NPPrint* platform_print); - void SendJavaScriptStream(const GURL& url, const std::string& result, - bool success, bool notify_needed, - intptr_t notify_data); + void SendJavaScriptStream(const GURL& url, + const std::string& result, + bool success, + int notify_id); void DidReceiveManualResponse(const GURL& url, const std::string& mime_type, @@ -211,6 +213,16 @@ class PluginInstance : public base::RefCountedThreadSafe<PluginInstance> { // Initiates byte range reads for plugins. void RequestRead(NPStream* stream, NPByteRange* range_list); + // Handles GetURL/GetURLNotify/PostURL/PostURLNotify requests initiated + // by plugins. + void RequestURL(const char* url, + const char* method, + const char* target, + const char* buf, + unsigned int len, + bool notify, + void* notify_data); + private: friend class base::RefCountedThreadSafe<PluginInstance>; @@ -225,15 +237,12 @@ class PluginInstance : public base::RefCountedThreadSafe<PluginInstance> { } #endif - virtual ~PluginInstance(); - - void OnPluginThreadAsyncCall(void (*func)(void *), - void *userData); + ~PluginInstance(); + void OnPluginThreadAsyncCall(void (*func)(void *), void *userData); void OnTimerCall(void (*func)(NPP id, uint32 timer_id), - NPP id, - uint32 timer_id); - + NPP id, uint32 timer_id); bool IsValidStream(const NPStream* stream); + void GetNotifyData(int notify_id, bool* notify, void** notify_data); // This is a hack to get the real player plugin to work with chrome // The real player plugin dll(nppl3260) when loaded by firefox is loaded via @@ -275,7 +284,6 @@ class PluginInstance : public base::RefCountedThreadSafe<PluginInstance> { gfx::Point plugin_origin_; NPCocoaEvent* currently_handled_event_; // weak #endif - MessageLoop* message_loop_; scoped_refptr<PluginStreamUrl> plugin_data_stream_; // This flag if true indicates that the plugin data would be passed from @@ -304,6 +312,18 @@ class PluginInstance : public base::RefCountedThreadSafe<PluginInstance> { typedef std::map<uint32, TimerInfo> TimerMap; TimerMap timers_; + // Tracks pending GET/POST requests so that the plugin-given data doesn't + // cross process boundaries to an untrusted process. + typedef std::map<int, void*> PendingRequestMap; + PendingRequestMap pending_requests_; + int next_notify_id_; + + // Used to track pending range requests so that when WebPlugin replies to us + // we can match the reply to the stream. + typedef std::map<int, scoped_refptr<PluginStream> > PendingRangeRequestMap; + PendingRangeRequestMap pending_range_requests_; + int next_range_request_id_; + DISALLOW_EVIL_CONSTRUCTORS(PluginInstance); }; diff --git a/webkit/glue/plugins/webplugin_delegate_impl.cc b/webkit/glue/plugins/webplugin_delegate_impl.cc index 4d3b43c..d2ecbc7 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl.cc +++ b/webkit/glue/plugins/webplugin_delegate_impl.cc @@ -143,15 +143,14 @@ NPObject* WebPluginDelegateImpl::GetPluginScriptableObject() { void WebPluginDelegateImpl::DidFinishLoadWithReason(const GURL& url, NPReason reason, - intptr_t notify_data) { + int notify_id) { if (quirks_ & PLUGIN_QUIRK_ALWAYS_NOTIFY_SUCCESS && reason == NPRES_NETWORK_ERR) { // Flash needs this or otherwise it unloads the launching swf object. reason = NPRES_DONE; } - instance()->DidFinishLoadWithReason( - url, reason, reinterpret_cast<void*>(notify_data)); + instance()->DidFinishLoadWithReason(url, reason, notify_id); } int WebPluginDelegateImpl::GetProcessId() { @@ -162,10 +161,8 @@ int WebPluginDelegateImpl::GetProcessId() { void WebPluginDelegateImpl::SendJavaScriptStream(const GURL& url, const std::string& result, bool success, - bool notify_needed, - intptr_t notify_data) { - instance()->SendJavaScriptStream(url, result, success, notify_needed, - notify_data); + int notify_id) { + instance()->SendJavaScriptStream(url, result, success, notify_id); } void WebPluginDelegateImpl::DidReceiveManualResponse( @@ -209,20 +206,12 @@ void WebPluginDelegateImpl::WindowedUpdateGeometry( } WebPluginResourceClient* WebPluginDelegateImpl::CreateResourceClient( - unsigned long resource_id, const GURL& url, bool notify_needed, - intptr_t notify_data, intptr_t existing_stream) { - // Stream already exists. This typically happens for range requests - // initiated via NPN_RequestRead. - if (existing_stream) { - NPAPI::PluginStream* plugin_stream = - reinterpret_cast<NPAPI::PluginStream*>(existing_stream); - - return plugin_stream->AsResourceClient(); - } + unsigned long resource_id, const GURL& url, int notify_id) { + return instance()->CreateStream( + resource_id, url, std::string(), notify_id); +} - std::string mime_type; - NPAPI::PluginStreamUrl *stream = instance()->CreateStream( - resource_id, url, mime_type, notify_needed, - reinterpret_cast<void*>(notify_data)); - return stream; +WebPluginResourceClient* WebPluginDelegateImpl::CreateSeekableResourceClient( + unsigned long resource_id, int range_request_id) { + return instance()->GetRangeRequest(range_request_id); } diff --git a/webkit/glue/plugins/webplugin_delegate_impl.h b/webkit/glue/plugins/webplugin_delegate_impl.h index 6864e31..ce19bb5 100644 --- a/webkit/glue/plugins/webplugin_delegate_impl.h +++ b/webkit/glue/plugins/webplugin_delegate_impl.h @@ -79,13 +79,13 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { virtual bool HandleInputEvent(const WebKit::WebInputEvent& event, WebKit::WebCursorInfo* cursor); virtual NPObject* GetPluginScriptableObject(); - virtual void DidFinishLoadWithReason(const GURL& url, NPReason reason, - intptr_t notify_data); + virtual void DidFinishLoadWithReason( + const GURL& url, NPReason reason, int notify_id); virtual int GetProcessId(); virtual void SendJavaScriptStream(const GURL& url, const std::string& result, - bool success, bool notify_needed, - intptr_t notify_data); + bool success, + int notify_id); virtual void DidReceiveManualResponse(const GURL& url, const std::string& mime_type, const std::string& headers, @@ -96,11 +96,9 @@ class WebPluginDelegateImpl : public webkit_glue::WebPluginDelegate { virtual void DidManualLoadFail(); virtual void InstallMissingPlugin(); virtual webkit_glue::WebPluginResourceClient* CreateResourceClient( - unsigned long resource_id, - const GURL& url, - bool notify_needed, - intptr_t notify_data, - intptr_t stream); + unsigned long resource_id, const GURL& url, int notify_id); + virtual webkit_glue::WebPluginResourceClient* CreateSeekableResourceClient( + unsigned long resource_id, int range_request_id); // End of WebPluginDelegate implementation. bool IsWindowless() const { return windowless_ ; } |