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

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

Issue 16140011: Don't send PP_Vars/V8 values with cycles across PostMessage (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 6 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
OLDNEW
1 // Copyright (c) 2012 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"
(...skipping 27 matching lines...) Expand all
38 using WebKit::WebPluginContainer; 38 using WebKit::WebPluginContainer;
39 using WebKit::WebSerializedScriptValue; 39 using WebKit::WebSerializedScriptValue;
40 40
41 namespace webkit { 41 namespace webkit {
42 42
43 namespace ppapi { 43 namespace ppapi {
44 44
45 namespace { 45 namespace {
46 46
47 const char kPostMessage[] = "postMessage"; 47 const char kPostMessage[] = "postMessage";
48 const char kV8ToVarConversionError[] = "Failed to convert a PostMessage "
49 "argument from a JavaScript value to a PP_Var. It may have cycles or be of "
50 "an unsupported type: ";
51 const char kVarToV8ConversionError[] = "Failed to convert a PostMessage "
52 "argument from a PP_Var to a Javascript value. It may have cycles or be of "
53 "an unsupported type: ";
54
55 std::string MakeV8ConversionError(v8::Handle<v8::Value> v8_value) {
56 v8::String::Utf8Value utf8(v8_value->ToString());
57 return kV8ToVarConversionError + std::string(*utf8, utf8.length());
dmichael (off chromium) 2013/06/04 16:59:10 Are you actually converting the v8_value to a stri
raymes 2013/06/04 19:36:06 That's ok with me.
58 }
59
60 std::string MakePPVarConversionError(PP_Var var) {
61 return kVarToV8ConversionError + ::ppapi::Var::PPVarToLogString(var);
62 }
48 63
49 // Helper function to get the MessageChannel that is associated with an 64 // Helper function to get the MessageChannel that is associated with an
50 // NPObject*. 65 // NPObject*.
51 MessageChannel* ToMessageChannel(NPObject* object) { 66 MessageChannel* ToMessageChannel(NPObject* object) {
52 return static_cast<MessageChannel::MessageChannelNPObject*>(object)-> 67 return static_cast<MessageChannel::MessageChannelNPObject*>(object)->
53 message_channel; 68 message_channel;
54 } 69 }
55 70
56 NPObject* ToPassThroughObject(NPObject* object) { 71 NPObject* ToPassThroughObject(NPObject* object) {
57 MessageChannel* channel = ToMessageChannel(object); 72 MessageChannel* channel = ToMessageChannel(object);
58 return channel ? channel->passthrough_object() : NULL; 73 return channel ? channel->passthrough_object() : NULL;
59 } 74 }
60 75
61 // Helper function to determine if a given identifier is equal to kPostMessage. 76 // Helper function to determine if a given identifier is equal to kPostMessage.
62 bool IdentifierIsPostMessage(NPIdentifier identifier) { 77 bool IdentifierIsPostMessage(NPIdentifier identifier) {
63 return WebBindings::getStringIdentifier(kPostMessage) == identifier; 78 return WebBindings::getStringIdentifier(kPostMessage) == identifier;
64 } 79 }
65 80
66 bool NPVariantToPPVar(const NPVariant* variant, PP_Var* result) { 81 bool NPVariantToPPVar(const NPVariant* variant,
82 PP_Var* result,
83 std::string* error) {
67 switch (variant->type) { 84 switch (variant->type) {
68 case NPVariantType_Void: 85 case NPVariantType_Void:
69 *result = PP_MakeUndefined(); 86 *result = PP_MakeUndefined();
70 return true; 87 return true;
71 case NPVariantType_Null: 88 case NPVariantType_Null:
72 *result = PP_MakeNull(); 89 *result = PP_MakeNull();
73 return true; 90 return true;
74 case NPVariantType_Bool: 91 case NPVariantType_Bool:
75 *result = PP_MakeBool(PP_FromBool(NPVARIANT_TO_BOOLEAN(*variant))); 92 *result = PP_MakeBool(PP_FromBool(NPVARIANT_TO_BOOLEAN(*variant)));
76 return true; 93 return true;
77 case NPVariantType_Int32: 94 case NPVariantType_Int32:
78 *result = PP_MakeInt32(NPVARIANT_TO_INT32(*variant)); 95 *result = PP_MakeInt32(NPVARIANT_TO_INT32(*variant));
79 return true; 96 return true;
80 case NPVariantType_Double: 97 case NPVariantType_Double:
81 *result = PP_MakeDouble(NPVARIANT_TO_DOUBLE(*variant)); 98 *result = PP_MakeDouble(NPVARIANT_TO_DOUBLE(*variant));
82 return true; 99 return true;
83 case NPVariantType_String: 100 case NPVariantType_String:
84 *result = StringVar::StringToPPVar( 101 *result = StringVar::StringToPPVar(
85 NPVARIANT_TO_STRING(*variant).UTF8Characters, 102 NPVARIANT_TO_STRING(*variant).UTF8Characters,
86 NPVARIANT_TO_STRING(*variant).UTF8Length); 103 NPVARIANT_TO_STRING(*variant).UTF8Length);
87 return true; 104 return true;
88 case NPVariantType_Object: 105 case NPVariantType_Object: {
89 V8VarConverter converter; 106 V8VarConverter converter(false);
90 // Calling WebBindings::toV8Value creates a wrapper around NPVariant so it 107 // Calling WebBindings::toV8Value creates a wrapper around NPVariant so it
91 // shouldn't result in a deep copy. 108 // shouldn't result in a deep copy.
92 return converter.FromV8Value(WebBindings::toV8Value(variant), 109 v8::Handle<v8::Value> v8_value = WebBindings::toV8Value(variant);
93 v8::Context::GetCurrent(), result); 110 if (!converter.FromV8Value(v8_value, v8::Context::GetCurrent(), result)) {
111 *error = MakeV8ConversionError(v8_value);
112 return false;
113 }
114 return true;
115 }
94 } 116 }
117 *error = MakeV8ConversionError(WebBindings::toV8Value(variant));
95 return false; 118 return false;
96 } 119 }
97 120
98 // Copy a PP_Var in to a PP_Var that is appropriate for sending via postMessage. 121 // Copy a PP_Var in to a PP_Var that is appropriate for sending via postMessage.
99 // This currently just copies the value. For a string Var, the result is a 122 // This currently just copies the value. For a string Var, the result is a
100 // PP_Var with the a copy of |var|'s string contents and a reference count of 1. 123 // PP_Var with the a copy of |var|'s string contents and a reference count of 1.
101 PP_Var CopyPPVar(const PP_Var& var) { 124 PP_Var CopyPPVar(const PP_Var& var) {
102 switch (var.type) { 125 switch (var.type) {
103 case PP_VARTYPE_UNDEFINED: 126 case PP_VARTYPE_UNDEFINED:
104 case PP_VARTYPE_NULL: 127 case PP_VARTYPE_NULL:
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 const NPVariant* args, uint32 arg_count, 197 const NPVariant* args, uint32 arg_count,
175 NPVariant* result) { 198 NPVariant* result) {
176 if (!np_obj) 199 if (!np_obj)
177 return false; 200 return false;
178 201
179 // We only handle a function called postMessage. 202 // We only handle a function called postMessage.
180 if (IdentifierIsPostMessage(name) && (arg_count == 1)) { 203 if (IdentifierIsPostMessage(name) && (arg_count == 1)) {
181 MessageChannel* message_channel = ToMessageChannel(np_obj); 204 MessageChannel* message_channel = ToMessageChannel(np_obj);
182 if (message_channel) { 205 if (message_channel) {
183 PP_Var argument = PP_MakeUndefined(); 206 PP_Var argument = PP_MakeUndefined();
184 if (!NPVariantToPPVar(&args[0], &argument)) { 207 std::string error;
185 NOTREACHED(); 208 bool success = NPVariantToPPVar(&args[0], &argument, &error);
186 return false; 209 message_channel->PostMessageToNative(argument, success, error);
187 }
188 message_channel->PostMessageToNative(argument);
189 PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(argument); 210 PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(argument);
190 return true; 211 return success;
191 } else { 212 } else {
192 return false; 213 return false;
193 } 214 }
194 } 215 }
195 // Other method calls we will pass to the passthrough object, if we have one. 216 // Other method calls we will pass to the passthrough object, if we have one.
196 NPObject* passthrough = ToPassThroughObject(np_obj); 217 NPObject* passthrough = ToPassThroughObject(np_obj);
197 if (passthrough) { 218 if (passthrough) {
198 return WebBindings::invoke(NULL, passthrough, name, args, arg_count, 219 return WebBindings::invoke(NULL, passthrough, name, args, arg_count,
199 result); 220 result);
200 } 221 }
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
339 WebPluginContainer* container = instance_->container(); 360 WebPluginContainer* container = instance_->container();
340 // It's possible that container() is NULL if the plugin has been removed from 361 // It's possible that container() is NULL if the plugin has been removed from
341 // the DOM (but the PluginInstance is not destroyed yet). 362 // the DOM (but the PluginInstance is not destroyed yet).
342 if (!container) 363 if (!container)
343 return; 364 return;
344 365
345 v8::Local<v8::Context> context = 366 v8::Local<v8::Context> context =
346 container->element().document().frame()->mainWorldScriptContext(); 367 container->element().document().frame()->mainWorldScriptContext();
347 v8::Context::Scope context_scope(context); 368 v8::Context::Scope context_scope(context);
348 369
349 v8::Local<v8::Value> v8_val; 370 v8::Handle<v8::Value> v8_val;
350 V8VarConverter converter; 371 V8VarConverter converter(false);
351 if (!converter.ToV8Value(message_data, context, &v8_val)) { 372 if (!converter.ToV8Value(message_data, context, &v8_val)) {
352 NOTREACHED(); 373 PpapiGlobals::Get()->LogWithSource(instance_->pp_instance(),
353 return; 374 PP_LOGLEVEL_ERROR, std::string(),
375 MakePPVarConversionError(message_data));
376 v8_val = v8::Undefined();
354 } 377 }
355 378
356 // This is for backward compatibility. It usually makes sense for us to return 379 // This is for backward compatibility. It usually makes sense for us to return
357 // a string object rather than a string primitive because it allows multiple 380 // a string object rather than a string primitive because it allows multiple
358 // references to the same string (as with PP_Var strings). However, prior to 381 // references to the same string (as with PP_Var strings). However, prior to
359 // implementing dictionary and array, vars we would return a string primitive 382 // implementing dictionary and array, vars we would return a string primitive
360 // here. Changing it to an object now will break existing code that uses 383 // here. Changing it to an object now will break existing code that uses
361 // strict comparisons for strings returned from PostMessage. e.g. x === "123" 384 // strict comparisons for strings returned from PostMessage. e.g. x === "123"
362 // will no longer return true. So if the only value to return is a string 385 // will no longer return true. So if the only value to return is a string
363 // object, just return the string primitive. 386 // object, just return the string primitive.
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 // messages: 473 // messages:
451 // http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html 474 // http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html
452 // This currently behaves like Web Workers. On Firefox, Chrome, and Safari 475 // This currently behaves like Web Workers. On Firefox, Chrome, and Safari
453 // at least, postMessage on Workers does not provide the origin or source. 476 // at least, postMessage on Workers does not provide the origin or source.
454 // TODO(dmichael): Add origin if we change to a more iframe-like origin 477 // TODO(dmichael): Add origin if we change to a more iframe-like origin
455 // policy (see crbug.com/81537) 478 // policy (see crbug.com/81537)
456 479
457 container->element().dispatchEvent(msg_event); 480 container->element().dispatchEvent(msg_event);
458 } 481 }
459 482
460 void MessageChannel::PostMessageToNative(PP_Var message_data) { 483 void MessageChannel::PostMessageToNative(PP_Var message_data,
484 bool success,
485 const std::string& error_msg) {
486 if (!success) {
487 PpapiGlobals::Get()->LogWithSource(instance_->pp_instance(),
488 PP_LOGLEVEL_ERROR, std::string(), error_msg);
489 message_data = PP_MakeUndefined();
dmichael (off chromium) 2013/06/04 16:59:10 This feels kind of klugy to me. My first choice is
raymes 2013/06/04 19:36:06 This was kludgy. Hopefully my change seems nicer.
490 }
461 if (instance_->module()->IsProxied()) { 491 if (instance_->module()->IsProxied()) {
462 // In the proxied case, the copy will happen via serializiation, and the 492 // In the proxied case, the copy will happen via serializiation, and the
463 // message is asynchronous. Therefore there's no need to copy the Var, nor 493 // message is asynchronous. Therefore there's no need to copy the Var, nor
464 // to PostTask. 494 // to PostTask.
465 PostMessageToNativeImpl(message_data); 495 PostMessageToNativeImpl(message_data);
466 } else { 496 } else {
467 // Make a copy of the message data for the Task we will run. 497 // Make a copy of the message data for the Task we will run.
468 PP_Var var_copy(CopyPPVar(message_data)); 498 PP_Var var_copy(CopyPPVar(message_data));
469 499
470 base::MessageLoop::current()->PostTask( 500 base::MessageLoop::current()->PostTask(
(...skipping 25 matching lines...) Expand all
496 // invokes: 526 // invokes:
497 // SetPassthroughObject(passthrough_object()); 527 // SetPassthroughObject(passthrough_object());
498 if (passthrough_object_) 528 if (passthrough_object_)
499 WebBindings::releaseObject(passthrough_object_); 529 WebBindings::releaseObject(passthrough_object_);
500 530
501 passthrough_object_ = passthrough; 531 passthrough_object_ = passthrough;
502 } 532 }
503 533
504 } // namespace ppapi 534 } // namespace ppapi
505 } // namespace webkit 535 } // namespace webkit
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698