summaryrefslogtreecommitdiffstats
path: root/webkit/glue/plugins
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-29 22:35:33 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-01-29 22:35:33 +0000
commitea3d1d84be3d6f97bf50e76511c9e26af6895533 (patch)
tree94c73f600dcca23329221ad8c51e6a5158263f7e /webkit/glue/plugins
parent403e46333b43009776a08273501e4ca8c5c06e12 (diff)
downloadchromium_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.cc27
-rw-r--r--webkit/glue/plugins/plugin_instance.cc128
-rw-r--r--webkit/glue/plugins/plugin_instance.h64
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.cc33
-rw-r--r--webkit/glue/plugins/webplugin_delegate_impl.h16
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, &notify, &notify_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, &notify, &notify_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, &notify, &notify_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_ ; }