Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(547)

Side by Side Diff: webkit/plugins/ppapi/message_channel.cc

Issue 9655019: Fix a crash related to PPAPI scripting. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/plugins/ppapi/message_channel.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webkit/plugins/ppapi/message_channel.h" 5 #include "webkit/plugins/ppapi/message_channel.h"
6 6
7 #include <cstdlib> 7 #include <cstdlib>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
(...skipping 27 matching lines...) Expand all
39 namespace webkit { 39 namespace webkit {
40 40
41 namespace ppapi { 41 namespace ppapi {
42 42
43 namespace { 43 namespace {
44 44
45 const char kPostMessage[] = "postMessage"; 45 const char kPostMessage[] = "postMessage";
46 46
47 // Helper function to get the MessageChannel that is associated with an 47 // Helper function to get the MessageChannel that is associated with an
48 // NPObject*. 48 // NPObject*.
49 MessageChannel& ToMessageChannel(NPObject* object) { 49 MessageChannel* ToMessageChannel(NPObject* object) {
50 return *(static_cast<MessageChannel::MessageChannelNPObject*>(object)-> 50 return static_cast<MessageChannel::MessageChannelNPObject*>(object)->
51 message_channel); 51 message_channel;
52 }
53
54 NPObject* ToPassThroughObject(NPObject* object) {
55 MessageChannel* channel = ToMessageChannel(object);
56 return channel ? channel->passthrough_object() : NULL;
52 } 57 }
53 58
54 // Helper function to determine if a given identifier is equal to kPostMessage. 59 // Helper function to determine if a given identifier is equal to kPostMessage.
55 bool IdentifierIsPostMessage(NPIdentifier identifier) { 60 bool IdentifierIsPostMessage(NPIdentifier identifier) {
56 return WebBindings::getStringIdentifier(kPostMessage) == identifier; 61 return WebBindings::getStringIdentifier(kPostMessage) == identifier;
57 } 62 }
58 63
59 // Converts the given PP_Var to a v8::Value, returning true on success. 64 // Converts the given PP_Var to a v8::Value, returning true on success.
60 // False means that the given variant is invalid. In this case, |result| will 65 // False means that the given variant is invalid. In this case, |result| will
61 // be set to an empty handle. 66 // be set to an empty handle.
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 171
167 bool MessageChannelHasMethod(NPObject* np_obj, NPIdentifier name) { 172 bool MessageChannelHasMethod(NPObject* np_obj, NPIdentifier name) {
168 if (!np_obj) 173 if (!np_obj)
169 return false; 174 return false;
170 175
171 // We only handle a function called postMessage. 176 // We only handle a function called postMessage.
172 if (IdentifierIsPostMessage(name)) 177 if (IdentifierIsPostMessage(name))
173 return true; 178 return true;
174 179
175 // Other method names we will pass to the passthrough object, if we have one. 180 // Other method names we will pass to the passthrough object, if we have one.
176 NPObject* passthrough = ToMessageChannel(np_obj).passthrough_object(); 181 NPObject* passthrough = ToPassThroughObject(np_obj);
177 if (passthrough) 182 if (passthrough)
178 return WebBindings::hasMethod(NULL, passthrough, name); 183 return WebBindings::hasMethod(NULL, passthrough, name);
179 return false; 184 return false;
180 } 185 }
181 186
182 bool MessageChannelInvoke(NPObject* np_obj, NPIdentifier name, 187 bool MessageChannelInvoke(NPObject* np_obj, NPIdentifier name,
183 const NPVariant* args, uint32 arg_count, 188 const NPVariant* args, uint32 arg_count,
184 NPVariant* result) { 189 NPVariant* result) {
185 if (!np_obj) 190 if (!np_obj)
186 return false; 191 return false;
187 192
188 // We only handle a function called postMessage. 193 // We only handle a function called postMessage.
189 if (IdentifierIsPostMessage(name) && (arg_count == 1)) { 194 if (IdentifierIsPostMessage(name) && (arg_count == 1)) {
190 MessageChannel& message_channel(ToMessageChannel(np_obj)); 195 MessageChannel* message_channel = ToMessageChannel(np_obj);
191 PP_Var argument(NPVariantToPPVar(message_channel.instance(), &args[0])); 196 if (message_channel) {
192 message_channel.PostMessageToNative(argument); 197 PP_Var argument(NPVariantToPPVar(message_channel->instance(), &args[0]));
193 PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(argument); 198 message_channel->PostMessageToNative(argument);
194 return true; 199 PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(argument);
200 return true;
201 } else {
202 return false;
203 }
195 } 204 }
196 // Other method calls we will pass to the passthrough object, if we have one. 205 // Other method calls we will pass to the passthrough object, if we have one.
197 NPObject* passthrough = ToMessageChannel(np_obj).passthrough_object(); 206 NPObject* passthrough = ToPassThroughObject(np_obj);
198 if (passthrough) { 207 if (passthrough) {
199 return WebBindings::invoke(NULL, passthrough, name, args, arg_count, 208 return WebBindings::invoke(NULL, passthrough, name, args, arg_count,
200 result); 209 result);
201 } 210 }
202 return false; 211 return false;
203 } 212 }
204 213
205 bool MessageChannelInvokeDefault(NPObject* np_obj, 214 bool MessageChannelInvokeDefault(NPObject* np_obj,
206 const NPVariant* args, 215 const NPVariant* args,
207 uint32 arg_count, 216 uint32 arg_count,
208 NPVariant* result) { 217 NPVariant* result) {
209 if (!np_obj) 218 if (!np_obj)
210 return false; 219 return false;
211 220
212 // Invoke on the passthrough object, if we have one. 221 // Invoke on the passthrough object, if we have one.
213 NPObject* passthrough = ToMessageChannel(np_obj).passthrough_object(); 222 NPObject* passthrough = ToPassThroughObject(np_obj);
214 if (passthrough) { 223 if (passthrough) {
215 return WebBindings::invokeDefault(NULL, passthrough, args, arg_count, 224 return WebBindings::invokeDefault(NULL, passthrough, args, arg_count,
216 result); 225 result);
217 } 226 }
218 return false; 227 return false;
219 } 228 }
220 229
221 bool MessageChannelHasProperty(NPObject* np_obj, NPIdentifier name) { 230 bool MessageChannelHasProperty(NPObject* np_obj, NPIdentifier name) {
222 if (!np_obj) 231 if (!np_obj)
223 return false; 232 return false;
224 233
225 // Invoke on the passthrough object, if we have one. 234 // Invoke on the passthrough object, if we have one.
226 NPObject* passthrough = ToMessageChannel(np_obj).passthrough_object(); 235 NPObject* passthrough = ToPassThroughObject(np_obj);
227 if (passthrough) 236 if (passthrough)
228 return WebBindings::hasProperty(NULL, passthrough, name); 237 return WebBindings::hasProperty(NULL, passthrough, name);
229 return false; 238 return false;
230 } 239 }
231 240
232 bool MessageChannelGetProperty(NPObject* np_obj, NPIdentifier name, 241 bool MessageChannelGetProperty(NPObject* np_obj, NPIdentifier name,
233 NPVariant* result) { 242 NPVariant* result) {
234 if (!np_obj) 243 if (!np_obj)
235 return false; 244 return false;
236 245
237 // Don't allow getting the postMessage function. 246 // Don't allow getting the postMessage function.
238 if (IdentifierIsPostMessage(name)) 247 if (IdentifierIsPostMessage(name))
239 return false; 248 return false;
240 249
241 // Invoke on the passthrough object, if we have one. 250 // Invoke on the passthrough object, if we have one.
242 NPObject* passthrough = ToMessageChannel(np_obj).passthrough_object(); 251 NPObject* passthrough = ToPassThroughObject(np_obj);
243 if (passthrough) 252 if (passthrough)
244 return WebBindings::getProperty(NULL, passthrough, name, result); 253 return WebBindings::getProperty(NULL, passthrough, name, result);
245 return false; 254 return false;
246 } 255 }
247 256
248 bool MessageChannelSetProperty(NPObject* np_obj, NPIdentifier name, 257 bool MessageChannelSetProperty(NPObject* np_obj, NPIdentifier name,
249 const NPVariant* variant) { 258 const NPVariant* variant) {
250 if (!np_obj) 259 if (!np_obj)
251 return false; 260 return false;
252 261
253 // Don't allow setting the postMessage function. 262 // Don't allow setting the postMessage function.
254 if (IdentifierIsPostMessage(name)) 263 if (IdentifierIsPostMessage(name))
255 return false; 264 return false;
256 265
257 // Invoke on the passthrough object, if we have one. 266 // Invoke on the passthrough object, if we have one.
258 NPObject* passthrough = ToMessageChannel(np_obj).passthrough_object(); 267 NPObject* passthrough = ToPassThroughObject(np_obj);
259 if (passthrough) 268 if (passthrough)
260 return WebBindings::setProperty(NULL, passthrough, name, variant); 269 return WebBindings::setProperty(NULL, passthrough, name, variant);
261 return false; 270 return false;
262 } 271 }
263 272
264 bool MessageChannelEnumerate(NPObject *np_obj, NPIdentifier **value, 273 bool MessageChannelEnumerate(NPObject *np_obj, NPIdentifier **value,
265 uint32_t *count) { 274 uint32_t *count) {
266 if (!np_obj) 275 if (!np_obj)
267 return false; 276 return false;
268 277
269 // Invoke on the passthrough object, if we have one, to enumerate its 278 // Invoke on the passthrough object, if we have one, to enumerate its
270 // properties. 279 // properties.
271 NPObject* passthrough = ToMessageChannel(np_obj).passthrough_object(); 280 NPObject* passthrough = ToPassThroughObject(np_obj);
272 if (passthrough) { 281 if (passthrough) {
273 bool success = WebBindings::enumerate(NULL, passthrough, value, count); 282 bool success = WebBindings::enumerate(NULL, passthrough, value, count);
274 if (success) { 283 if (success) {
275 // Add postMessage to the list and return it. 284 // Add postMessage to the list and return it.
276 if (std::numeric_limits<size_t>::max() / sizeof(NPIdentifier) <= 285 if (std::numeric_limits<size_t>::max() / sizeof(NPIdentifier) <=
277 (*count + 1)) 286 (*count + 1))
278 return false; 287 return false;
279 NPIdentifier* new_array = static_cast<NPIdentifier*>( 288 NPIdentifier* new_array = static_cast<NPIdentifier*>(
280 std::malloc(sizeof(NPIdentifier) * (*count + 1))); 289 std::malloc(sizeof(NPIdentifier) * (*count + 1)));
281 std::memcpy(new_array, *value, sizeof(NPIdentifier)*(*count)); 290 std::memcpy(new_array, *value, sizeof(NPIdentifier)*(*count));
(...skipping 23 matching lines...) Expand all
305 &MessageChannelHasProperty, 314 &MessageChannelHasProperty,
306 &MessageChannelGetProperty, 315 &MessageChannelGetProperty,
307 &MessageChannelSetProperty, 316 &MessageChannelSetProperty,
308 NULL, 317 NULL,
309 &MessageChannelEnumerate, 318 &MessageChannelEnumerate,
310 }; 319 };
311 320
312 } // namespace 321 } // namespace
313 322
314 // MessageChannel -------------------------------------------------------------- 323 // MessageChannel --------------------------------------------------------------
315 MessageChannel::MessageChannelNPObject::MessageChannelNPObject() 324 MessageChannel::MessageChannelNPObject::MessageChannelNPObject() {
316 : message_channel(NULL) {
317 } 325 }
318 326
319 MessageChannel::MessageChannelNPObject::~MessageChannelNPObject() {} 327 MessageChannel::MessageChannelNPObject::~MessageChannelNPObject() {}
320 328
321 MessageChannel::MessageChannel(PluginInstance* instance) 329 MessageChannel::MessageChannel(PluginInstance* instance)
322 : instance_(instance), 330 : instance_(instance),
323 passthrough_object_(NULL), 331 passthrough_object_(NULL),
324 np_object_(NULL), 332 np_object_(NULL),
325 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { 333 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
326 // Now create an NPObject for receiving calls to postMessage. This sets the 334 // Now create an NPObject for receiving calls to postMessage. This sets the
327 // reference count to 1. We release it in the destructor. 335 // reference count to 1. We release it in the destructor.
328 NPObject* obj = WebBindings::createObject(NULL, &message_channel_class); 336 NPObject* obj = WebBindings::createObject(NULL, &message_channel_class);
329 DCHECK(obj); 337 DCHECK(obj);
330 np_object_ = static_cast<MessageChannel::MessageChannelNPObject*>(obj); 338 np_object_ = static_cast<MessageChannel::MessageChannelNPObject*>(obj);
331 np_object_->message_channel = this; 339 np_object_->message_channel = weak_ptr_factory_.GetWeakPtr();
332 } 340 }
333 341
334 void MessageChannel::PostMessageToJavaScript(PP_Var message_data) { 342 void MessageChannel::PostMessageToJavaScript(PP_Var message_data) {
335 // Serialize the message data. 343 // Serialize the message data.
336 v8::HandleScope scope; 344 v8::HandleScope scope;
337 // Because V8 is probably not on the stack for Native->JS calls, we need to 345 // Because V8 is probably not on the stack for Native->JS calls, we need to
338 // enter the appropriate context for the plugin. 346 // enter the appropriate context for the plugin.
339 v8::Local<v8::Context> context = 347 v8::Local<v8::Context> context =
340 instance_->container()->element().document().frame()-> 348 instance_->container()->element().document().frame()->
341 mainWorldScriptContext(); 349 mainWorldScriptContext();
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
419 // invokes: 427 // invokes:
420 // SetPassthroughObject(passthrough_object()); 428 // SetPassthroughObject(passthrough_object());
421 if (passthrough_object_) 429 if (passthrough_object_)
422 WebBindings::releaseObject(passthrough_object_); 430 WebBindings::releaseObject(passthrough_object_);
423 431
424 passthrough_object_ = passthrough; 432 passthrough_object_ = passthrough;
425 } 433 }
426 434
427 } // namespace ppapi 435 } // namespace ppapi
428 } // namespace webkit 436 } // namespace webkit
OLDNEW
« no previous file with comments | « webkit/plugins/ppapi/message_channel.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698