Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 : * vim: sw=2 ts=2 et :
3 : * This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "PluginScriptableObjectParent.h"
8 :
9 : #include "jsapi.h"
10 : #include "mozilla/DebugOnly.h"
11 : #include "mozilla/dom/ScriptSettings.h"
12 : #include "mozilla/plugins/PluginTypes.h"
13 : #include "mozilla/Unused.h"
14 : #include "nsNPAPIPlugin.h"
15 : #include "PluginScriptableObjectUtils.h"
16 :
17 : using namespace mozilla;
18 : using namespace mozilla::plugins;
19 : using namespace mozilla::plugins::parent;
20 :
21 : /**
22 : * NPIdentifiers in the chrome process are stored as jsids. The difficulty is in
23 : * ensuring that string identifiers are rooted without pinning them all. We
24 : * assume that all NPIdentifiers passed into nsJSNPRuntime will not be used
25 : * outside the scope of the NPAPI call (i.e., they won't be stored in the
26 : * heap). Rooting is done using the StackIdentifier class, which roots the
27 : * identifier via RootedId.
28 : *
29 : * This system does not allow jsids to be moved, as would be needed for
30 : * generational or compacting GC. When Firefox implements a moving GC for
31 : * strings, we will need to ensure that no movement happens while NPAPI code is
32 : * on the stack: although StackIdentifier roots all identifiers used, the GC has
33 : * no way to know that a jsid cast to an NPIdentifier needs to be fixed up if it
34 : * is moved.
35 : */
36 :
37 0 : class MOZ_STACK_CLASS StackIdentifier
38 : {
39 : public:
40 : explicit StackIdentifier(const PluginIdentifier& aIdentifier,
41 : bool aAtomizeAndPin = false);
42 :
43 0 : bool Failed() const { return mFailed; }
44 0 : NPIdentifier ToNPIdentifier() const { return mIdentifier; }
45 :
46 : private:
47 : bool mFailed;
48 : NPIdentifier mIdentifier;
49 : AutoSafeJSContext mCx;
50 : JS::RootedId mId;
51 : };
52 :
53 0 : StackIdentifier::StackIdentifier(const PluginIdentifier& aIdentifier, bool aAtomizeAndPin)
54 : : mFailed(false),
55 0 : mId(mCx)
56 : {
57 0 : if (aIdentifier.type() == PluginIdentifier::TnsCString) {
58 : // We don't call _getstringidentifier because we may not want to intern the string.
59 0 : NS_ConvertUTF8toUTF16 utf16name(aIdentifier.get_nsCString());
60 0 : JS::RootedString str(mCx, JS_NewUCStringCopyN(mCx, utf16name.get(), utf16name.Length()));
61 0 : if (!str) {
62 0 : NS_ERROR("Id can't be allocated");
63 0 : mFailed = true;
64 0 : return;
65 : }
66 0 : if (aAtomizeAndPin) {
67 0 : str = JS_AtomizeAndPinJSString(mCx, str);
68 0 : if (!str) {
69 0 : NS_ERROR("Id can't be allocated");
70 0 : mFailed = true;
71 0 : return;
72 : }
73 : }
74 0 : if (!JS_StringToId(mCx, str, &mId)) {
75 0 : NS_ERROR("Id can't be allocated");
76 0 : mFailed = true;
77 0 : return;
78 : }
79 0 : mIdentifier = JSIdToNPIdentifier(mId);
80 0 : return;
81 : }
82 :
83 0 : mIdentifier = mozilla::plugins::parent::_getintidentifier(aIdentifier.get_int32_t());
84 : }
85 :
86 : static bool
87 0 : FromNPIdentifier(NPIdentifier aIdentifier, PluginIdentifier* aResult)
88 : {
89 0 : if (mozilla::plugins::parent::_identifierisstring(aIdentifier)) {
90 0 : nsCString string;
91 : NPUTF8* chars =
92 0 : mozilla::plugins::parent::_utf8fromidentifier(aIdentifier);
93 0 : if (!chars) {
94 0 : return false;
95 : }
96 0 : string.Adopt(chars);
97 0 : *aResult = PluginIdentifier(string);
98 0 : return true;
99 : }
100 : else {
101 0 : int32_t intval = mozilla::plugins::parent::_intfromidentifier(aIdentifier);
102 0 : *aResult = PluginIdentifier(intval);
103 0 : return true;
104 : }
105 : }
106 :
107 : namespace {
108 :
109 : inline void
110 0 : ReleaseVariant(NPVariant& aVariant,
111 : PluginInstanceParent* aInstance)
112 : {
113 0 : const NPNetscapeFuncs* npn = GetNetscapeFuncs(aInstance);
114 0 : if (npn) {
115 0 : npn->releasevariantvalue(&aVariant);
116 : }
117 0 : }
118 :
119 : } // namespace
120 :
121 : // static
122 : NPObject*
123 0 : PluginScriptableObjectParent::ScriptableAllocate(NPP aInstance,
124 : NPClass* aClass)
125 : {
126 0 : if (aClass != GetClass()) {
127 0 : NS_ERROR("Huh?! Wrong class!");
128 0 : return nullptr;
129 : }
130 :
131 0 : return new ParentNPObject();
132 : }
133 :
134 : // static
135 : void
136 0 : PluginScriptableObjectParent::ScriptableInvalidate(NPObject* aObject)
137 : {
138 0 : if (aObject->_class != GetClass()) {
139 0 : NS_ERROR("Don't know what kind of object this is!");
140 0 : return;
141 : }
142 :
143 0 : ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
144 0 : if (object->invalidated) {
145 : // This can happen more than once, and is just fine.
146 0 : return;
147 : }
148 :
149 0 : object->invalidated = true;
150 :
151 : // |object->parent| may be null already if the instance has gone away.
152 0 : if (object->parent && !object->parent->CallInvalidate()) {
153 0 : NS_ERROR("Failed to send message!");
154 : }
155 : }
156 :
157 : // static
158 : void
159 0 : PluginScriptableObjectParent::ScriptableDeallocate(NPObject* aObject)
160 : {
161 0 : if (aObject->_class != GetClass()) {
162 0 : NS_ERROR("Don't know what kind of object this is!");
163 0 : return;
164 : }
165 :
166 0 : ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
167 :
168 0 : if (object->asyncWrapperCount > 0) {
169 : // In this case we should just drop the refcount to the asyncWrapperCount
170 : // instead of deallocating because there are still some async wrappers
171 : // out there that are referencing this object.
172 0 : object->referenceCount = object->asyncWrapperCount;
173 0 : return;
174 : }
175 :
176 0 : PluginScriptableObjectParent* actor = object->parent;
177 0 : if (actor) {
178 0 : NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
179 0 : actor->DropNPObject();
180 : }
181 :
182 : delete object;
183 : }
184 :
185 : // static
186 : bool
187 0 : PluginScriptableObjectParent::ScriptableHasMethod(NPObject* aObject,
188 : NPIdentifier aName)
189 : {
190 0 : if (aObject->_class != GetClass()) {
191 0 : NS_ERROR("Don't know what kind of object this is!");
192 0 : return false;
193 : }
194 :
195 0 : ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
196 0 : if (object->invalidated) {
197 0 : NS_WARNING("Calling method on an invalidated object!");
198 0 : return false;
199 : }
200 :
201 0 : ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
202 0 : if (!actor) {
203 0 : return false;
204 : }
205 :
206 0 : PluginIdentifier identifier;
207 0 : if (!FromNPIdentifier(aName, &identifier)) {
208 0 : return false;
209 : }
210 :
211 0 : NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
212 :
213 : bool result;
214 0 : if (!actor->CallHasMethod(identifier, &result)) {
215 0 : NS_WARNING("Failed to send message!");
216 0 : return false;
217 : }
218 :
219 0 : return result;
220 : }
221 :
222 : // static
223 : bool
224 0 : PluginScriptableObjectParent::ScriptableInvoke(NPObject* aObject,
225 : NPIdentifier aName,
226 : const NPVariant* aArgs,
227 : uint32_t aArgCount,
228 : NPVariant* aResult)
229 : {
230 0 : if (aObject->_class != GetClass()) {
231 0 : NS_ERROR("Don't know what kind of object this is!");
232 0 : return false;
233 : }
234 :
235 0 : ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
236 0 : if (object->invalidated) {
237 0 : NS_WARNING("Calling method on an invalidated object!");
238 0 : return false;
239 : }
240 :
241 0 : ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
242 0 : if (!actor) {
243 0 : return false;
244 : }
245 :
246 0 : PluginIdentifier identifier;
247 0 : if (!FromNPIdentifier(aName, &identifier)) {
248 0 : return false;
249 : }
250 :
251 0 : NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
252 :
253 0 : ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
254 0 : if (!args.IsOk()) {
255 0 : NS_ERROR("Failed to convert arguments!");
256 0 : return false;
257 : }
258 :
259 0 : Variant remoteResult;
260 : bool success;
261 0 : if (!actor->CallInvoke(identifier, args, &remoteResult,
262 0 : &success)) {
263 0 : NS_WARNING("Failed to send message!");
264 0 : return false;
265 : }
266 :
267 0 : if (!success) {
268 0 : return false;
269 : }
270 :
271 0 : if (!ConvertToVariant(remoteResult, *aResult, actor->GetInstance())) {
272 0 : NS_WARNING("Failed to convert result!");
273 0 : return false;
274 : }
275 0 : return true;
276 : }
277 :
278 : // static
279 : bool
280 0 : PluginScriptableObjectParent::ScriptableInvokeDefault(NPObject* aObject,
281 : const NPVariant* aArgs,
282 : uint32_t aArgCount,
283 : NPVariant* aResult)
284 : {
285 0 : if (aObject->_class != GetClass()) {
286 0 : NS_ERROR("Don't know what kind of object this is!");
287 0 : return false;
288 : }
289 :
290 0 : ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
291 0 : if (object->invalidated) {
292 0 : NS_WARNING("Calling method on an invalidated object!");
293 0 : return false;
294 : }
295 :
296 0 : ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
297 0 : if (!actor) {
298 0 : return false;
299 : }
300 :
301 0 : NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
302 :
303 0 : ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
304 0 : if (!args.IsOk()) {
305 0 : NS_ERROR("Failed to convert arguments!");
306 0 : return false;
307 : }
308 :
309 0 : Variant remoteResult;
310 : bool success;
311 0 : if (!actor->CallInvokeDefault(args, &remoteResult, &success)) {
312 0 : NS_WARNING("Failed to send message!");
313 0 : return false;
314 : }
315 :
316 0 : if (!success) {
317 0 : return false;
318 : }
319 :
320 0 : if (!ConvertToVariant(remoteResult, *aResult, actor->GetInstance())) {
321 0 : NS_WARNING("Failed to convert result!");
322 0 : return false;
323 : }
324 0 : return true;
325 : }
326 :
327 : // static
328 : bool
329 0 : PluginScriptableObjectParent::ScriptableHasProperty(NPObject* aObject,
330 : NPIdentifier aName)
331 : {
332 0 : if (aObject->_class != GetClass()) {
333 0 : NS_ERROR("Don't know what kind of object this is!");
334 0 : return false;
335 : }
336 :
337 0 : ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
338 0 : if (object->invalidated) {
339 0 : NS_WARNING("Calling method on an invalidated object!");
340 0 : return false;
341 : }
342 :
343 0 : ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
344 0 : if (!actor) {
345 0 : return false;
346 : }
347 :
348 0 : PluginIdentifier identifier;
349 0 : if (!FromNPIdentifier(aName, &identifier)) {
350 0 : return false;
351 : }
352 :
353 0 : NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
354 :
355 : bool result;
356 0 : if (!actor->CallHasProperty(identifier, &result)) {
357 0 : NS_WARNING("Failed to send message!");
358 0 : return false;
359 : }
360 :
361 0 : return result;
362 : }
363 :
364 : // static
365 : bool
366 0 : PluginScriptableObjectParent::ScriptableGetProperty(NPObject* aObject,
367 : NPIdentifier aName,
368 : NPVariant* aResult)
369 : {
370 : // See GetPropertyHelper below.
371 0 : NS_NOTREACHED("Shouldn't ever call this directly!");
372 0 : return false;
373 : }
374 :
375 : // static
376 : bool
377 0 : PluginScriptableObjectParent::ScriptableSetProperty(NPObject* aObject,
378 : NPIdentifier aName,
379 : const NPVariant* aValue)
380 : {
381 0 : if (aObject->_class != GetClass()) {
382 0 : NS_ERROR("Don't know what kind of object this is!");
383 0 : return false;
384 : }
385 :
386 0 : ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
387 0 : if (object->invalidated) {
388 0 : NS_WARNING("Calling method on an invalidated object!");
389 0 : return false;
390 : }
391 :
392 0 : ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
393 0 : if (!actor) {
394 0 : return false;
395 : }
396 :
397 0 : PluginIdentifier identifier;
398 0 : if (!FromNPIdentifier(aName, &identifier)) {
399 0 : return false;
400 : }
401 :
402 0 : NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
403 :
404 0 : ProtectedVariant value(*aValue, actor->GetInstance());
405 0 : if (!value.IsOk()) {
406 0 : NS_WARNING("Failed to convert variant!");
407 0 : return false;
408 : }
409 :
410 : bool success;
411 0 : if (!actor->CallSetProperty(identifier, value, &success)) {
412 0 : NS_WARNING("Failed to send message!");
413 0 : return false;
414 : }
415 :
416 0 : return success;
417 : }
418 :
419 : // static
420 : bool
421 0 : PluginScriptableObjectParent::ScriptableRemoveProperty(NPObject* aObject,
422 : NPIdentifier aName)
423 : {
424 0 : if (aObject->_class != GetClass()) {
425 0 : NS_ERROR("Don't know what kind of object this is!");
426 0 : return false;
427 : }
428 :
429 0 : ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
430 0 : if (object->invalidated) {
431 0 : NS_WARNING("Calling method on an invalidated object!");
432 0 : return false;
433 : }
434 :
435 0 : ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
436 0 : if (!actor) {
437 0 : return false;
438 : }
439 :
440 0 : PluginIdentifier identifier;
441 0 : if (!FromNPIdentifier(aName, &identifier)) {
442 0 : return false;
443 : }
444 :
445 0 : NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
446 :
447 : bool success;
448 0 : if (!actor->CallRemoveProperty(identifier, &success)) {
449 0 : NS_WARNING("Failed to send message!");
450 0 : return false;
451 : }
452 :
453 0 : return success;
454 : }
455 :
456 : // static
457 : bool
458 0 : PluginScriptableObjectParent::ScriptableEnumerate(NPObject* aObject,
459 : NPIdentifier** aIdentifiers,
460 : uint32_t* aCount)
461 : {
462 0 : if (aObject->_class != GetClass()) {
463 0 : NS_ERROR("Don't know what kind of object this is!");
464 0 : return false;
465 : }
466 :
467 0 : ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
468 0 : if (object->invalidated) {
469 0 : NS_WARNING("Calling method on an invalidated object!");
470 0 : return false;
471 : }
472 :
473 0 : ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
474 0 : if (!actor) {
475 0 : return false;
476 : }
477 :
478 0 : NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
479 :
480 0 : const NPNetscapeFuncs* npn = GetNetscapeFuncs(aObject);
481 0 : if (!npn) {
482 0 : NS_ERROR("No netscape funcs!");
483 0 : return false;
484 : }
485 :
486 0 : AutoTArray<PluginIdentifier, 10> identifiers;
487 : bool success;
488 0 : if (!actor->CallEnumerate(&identifiers, &success)) {
489 0 : NS_WARNING("Failed to send message!");
490 0 : return false;
491 : }
492 :
493 0 : if (!success) {
494 0 : return false;
495 : }
496 :
497 0 : *aCount = identifiers.Length();
498 0 : if (!*aCount) {
499 0 : *aIdentifiers = nullptr;
500 0 : return true;
501 : }
502 :
503 0 : *aIdentifiers = (NPIdentifier*)npn->memalloc(*aCount * sizeof(NPIdentifier));
504 0 : if (!*aIdentifiers) {
505 0 : NS_ERROR("Out of memory!");
506 0 : return false;
507 : }
508 :
509 0 : for (uint32_t index = 0; index < *aCount; index++) {
510 : // We pin the ID to avoid a GC hazard here. This could probably be fixed
511 : // if the interface with nsJSNPRuntime were smarter.
512 0 : StackIdentifier stackID(identifiers[index], true /* aAtomizeAndPin */);
513 0 : if (stackID.Failed()) {
514 0 : return false;
515 : }
516 0 : (*aIdentifiers)[index] = stackID.ToNPIdentifier();
517 : }
518 0 : return true;
519 : }
520 :
521 : // static
522 : bool
523 0 : PluginScriptableObjectParent::ScriptableConstruct(NPObject* aObject,
524 : const NPVariant* aArgs,
525 : uint32_t aArgCount,
526 : NPVariant* aResult)
527 : {
528 0 : if (aObject->_class != GetClass()) {
529 0 : NS_ERROR("Don't know what kind of object this is!");
530 0 : return false;
531 : }
532 :
533 0 : ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
534 0 : if (object->invalidated) {
535 0 : NS_WARNING("Calling method on an invalidated object!");
536 0 : return false;
537 : }
538 :
539 0 : ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
540 0 : if (!actor) {
541 0 : return false;
542 : }
543 :
544 0 : NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
545 :
546 0 : ProtectedVariantArray args(aArgs, aArgCount, actor->GetInstance());
547 0 : if (!args.IsOk()) {
548 0 : NS_ERROR("Failed to convert arguments!");
549 0 : return false;
550 : }
551 :
552 0 : Variant remoteResult;
553 : bool success;
554 0 : if (!actor->CallConstruct(args, &remoteResult, &success)) {
555 0 : NS_WARNING("Failed to send message!");
556 0 : return false;
557 : }
558 :
559 0 : if (!success) {
560 0 : return false;
561 : }
562 :
563 0 : if (!ConvertToVariant(remoteResult, *aResult, actor->GetInstance())) {
564 0 : NS_WARNING("Failed to convert result!");
565 0 : return false;
566 : }
567 0 : return true;
568 : }
569 :
570 : const NPClass PluginScriptableObjectParent::sNPClass = {
571 : NP_CLASS_STRUCT_VERSION,
572 : PluginScriptableObjectParent::ScriptableAllocate,
573 : PluginScriptableObjectParent::ScriptableDeallocate,
574 : PluginScriptableObjectParent::ScriptableInvalidate,
575 : PluginScriptableObjectParent::ScriptableHasMethod,
576 : PluginScriptableObjectParent::ScriptableInvoke,
577 : PluginScriptableObjectParent::ScriptableInvokeDefault,
578 : PluginScriptableObjectParent::ScriptableHasProperty,
579 : PluginScriptableObjectParent::ScriptableGetProperty,
580 : PluginScriptableObjectParent::ScriptableSetProperty,
581 : PluginScriptableObjectParent::ScriptableRemoveProperty,
582 : PluginScriptableObjectParent::ScriptableEnumerate,
583 : PluginScriptableObjectParent::ScriptableConstruct
584 : };
585 :
586 0 : PluginScriptableObjectParent::PluginScriptableObjectParent(
587 0 : ScriptableObjectType aType)
588 : : mInstance(nullptr),
589 : mObject(nullptr),
590 : mProtectCount(0),
591 0 : mType(aType)
592 : {
593 0 : }
594 :
595 0 : PluginScriptableObjectParent::~PluginScriptableObjectParent()
596 : {
597 0 : if (mObject) {
598 0 : if (mObject->_class == GetClass()) {
599 0 : NS_ASSERTION(mType == Proxy, "Wrong type!");
600 0 : static_cast<ParentNPObject*>(mObject)->parent = nullptr;
601 : }
602 : else {
603 0 : NS_ASSERTION(mType == LocalObject, "Wrong type!");
604 0 : GetInstance()->GetNPNIface()->releaseobject(mObject);
605 : }
606 : }
607 0 : }
608 :
609 : void
610 0 : PluginScriptableObjectParent::InitializeProxy()
611 : {
612 0 : NS_ASSERTION(mType == Proxy, "Bad type!");
613 0 : NS_ASSERTION(!mObject, "Calling Initialize more than once!");
614 :
615 0 : mInstance = static_cast<PluginInstanceParent*>(Manager());
616 0 : NS_ASSERTION(mInstance, "Null manager?!");
617 :
618 0 : NPObject* object = CreateProxyObject();
619 0 : NS_ASSERTION(object, "Failed to create object!");
620 :
621 0 : if (!mInstance->RegisterNPObjectForActor(object, this)) {
622 0 : NS_ERROR("Out of memory?");
623 : }
624 :
625 0 : mObject = object;
626 0 : }
627 :
628 : void
629 0 : PluginScriptableObjectParent::InitializeLocal(NPObject* aObject)
630 : {
631 0 : NS_ASSERTION(mType == LocalObject, "Bad type!");
632 0 : NS_ASSERTION(!(mInstance && mObject), "Calling Initialize more than once!");
633 :
634 0 : mInstance = static_cast<PluginInstanceParent*>(Manager());
635 0 : NS_ASSERTION(mInstance, "Null manager?!");
636 :
637 0 : mInstance->GetNPNIface()->retainobject(aObject);
638 :
639 0 : NS_ASSERTION(!mProtectCount, "Should be zero!");
640 0 : mProtectCount++;
641 :
642 0 : if (!mInstance->RegisterNPObjectForActor(aObject, this)) {
643 0 : NS_ERROR("Out of memory?");
644 : }
645 :
646 0 : mObject = aObject;
647 0 : }
648 :
649 : NPObject*
650 0 : PluginScriptableObjectParent::CreateProxyObject()
651 : {
652 0 : NS_ASSERTION(mInstance, "Must have an instance!");
653 0 : NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
654 :
655 0 : const NPNetscapeFuncs* npn = GetNetscapeFuncs(mInstance);
656 :
657 0 : NPObject* npobject = npn->createobject(mInstance->GetNPP(),
658 0 : const_cast<NPClass*>(GetClass()));
659 0 : NS_ASSERTION(npobject, "Failed to create object?!");
660 0 : NS_ASSERTION(npobject->_class == GetClass(), "Wrong kind of object!");
661 0 : NS_ASSERTION(npobject->referenceCount == 1, "Some kind of live object!");
662 :
663 0 : ParentNPObject* object = static_cast<ParentNPObject*>(npobject);
664 0 : NS_ASSERTION(!object->invalidated, "Bad object!");
665 0 : NS_ASSERTION(!object->parent, "Bad object!");
666 :
667 : // We don't want to have the actor own this object but rather let the object
668 : // own this actor. Set the reference count to 0 here so that when the object
669 : // dies we will send the destructor message to the child.
670 0 : object->referenceCount = 0;
671 0 : NS_LOG_RELEASE(object, 0, "BrowserNPObject");
672 :
673 0 : object->parent = const_cast<PluginScriptableObjectParent*>(this);
674 0 : return object;
675 : }
676 :
677 : bool
678 0 : PluginScriptableObjectParent::ResurrectProxyObject()
679 : {
680 0 : NS_ASSERTION(mInstance, "Must have an instance already!");
681 0 : NS_ASSERTION(!mObject, "Should not have an object already!");
682 0 : NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
683 :
684 0 : InitializeProxy();
685 0 : NS_ASSERTION(mObject, "Initialize failed!");
686 :
687 0 : if (!SendProtect()) {
688 0 : NS_WARNING("Failed to send message!");
689 0 : return false;
690 : }
691 :
692 0 : return true;
693 : }
694 :
695 : NPObject*
696 0 : PluginScriptableObjectParent::GetObject(bool aCanResurrect)
697 : {
698 0 : if (!mObject && aCanResurrect && !ResurrectProxyObject()) {
699 0 : NS_ERROR("Null object!");
700 0 : return nullptr;
701 : }
702 0 : return mObject;
703 : }
704 :
705 : void
706 0 : PluginScriptableObjectParent::Protect()
707 : {
708 0 : NS_ASSERTION(mObject, "No object!");
709 0 : NS_ASSERTION(mProtectCount >= 0, "Negative protect count?!");
710 :
711 0 : if (mType == LocalObject) {
712 0 : ++mProtectCount;
713 : }
714 0 : }
715 :
716 : void
717 0 : PluginScriptableObjectParent::Unprotect()
718 : {
719 0 : NS_ASSERTION(mObject, "No object!");
720 0 : NS_ASSERTION(mProtectCount >= 0, "Negative protect count?!");
721 :
722 0 : if (mType == LocalObject) {
723 0 : if (--mProtectCount == 0) {
724 0 : Unused << PluginScriptableObjectParent::Send__delete__(this);
725 : }
726 : }
727 0 : }
728 :
729 : void
730 0 : PluginScriptableObjectParent::DropNPObject()
731 : {
732 0 : NS_ASSERTION(mObject, "Invalidated object!");
733 0 : NS_ASSERTION(mObject->_class == GetClass(), "Wrong type of object!");
734 0 : NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
735 :
736 : // We think we're about to be deleted, but we could be racing with the other
737 : // process.
738 0 : PluginInstanceParent* instance = GetInstance();
739 0 : NS_ASSERTION(instance, "Must have an instance!");
740 :
741 0 : instance->UnregisterNPObject(mObject);
742 0 : mObject = nullptr;
743 :
744 0 : Unused << SendUnprotect();
745 0 : }
746 :
747 : void
748 0 : PluginScriptableObjectParent::ActorDestroy(ActorDestroyReason aWhy)
749 : {
750 : // Implement me! Bug 1005163
751 0 : }
752 :
753 : mozilla::ipc::IPCResult
754 0 : PluginScriptableObjectParent::AnswerHasMethod(const PluginIdentifier& aId,
755 : bool* aHasMethod)
756 : {
757 0 : if (!mObject) {
758 0 : NS_WARNING("Calling AnswerHasMethod with an invalidated object!");
759 0 : *aHasMethod = false;
760 0 : return IPC_OK();
761 : }
762 :
763 0 : NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
764 0 : NS_ASSERTION(mType == LocalObject, "Bad type!");
765 :
766 0 : PluginInstanceParent* instance = GetInstance();
767 0 : if (!instance) {
768 0 : NS_ERROR("No instance?!");
769 0 : *aHasMethod = false;
770 0 : return IPC_OK();
771 : }
772 :
773 0 : const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
774 0 : if (!npn) {
775 0 : NS_ERROR("No netscape funcs?!");
776 0 : *aHasMethod = false;
777 0 : return IPC_OK();
778 : }
779 :
780 0 : StackIdentifier stackID(aId);
781 0 : if (stackID.Failed()) {
782 0 : *aHasMethod = false;
783 0 : return IPC_OK();
784 : }
785 0 : *aHasMethod = npn->hasmethod(instance->GetNPP(), mObject, stackID.ToNPIdentifier());
786 0 : return IPC_OK();
787 : }
788 :
789 : mozilla::ipc::IPCResult
790 0 : PluginScriptableObjectParent::AnswerInvoke(const PluginIdentifier& aId,
791 : InfallibleTArray<Variant>&& aArgs,
792 : Variant* aResult,
793 : bool* aSuccess)
794 : {
795 0 : if (!mObject) {
796 0 : NS_WARNING("Calling AnswerInvoke with an invalidated object!");
797 0 : *aResult = void_t();
798 0 : *aSuccess = false;
799 0 : return IPC_OK();
800 : }
801 :
802 0 : NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
803 0 : NS_ASSERTION(mType == LocalObject, "Bad type!");
804 :
805 0 : PluginInstanceParent* instance = GetInstance();
806 0 : if (!instance) {
807 0 : NS_ERROR("No instance?!");
808 0 : *aResult = void_t();
809 0 : *aSuccess = false;
810 0 : return IPC_OK();
811 : }
812 :
813 0 : const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
814 0 : if (!npn) {
815 0 : NS_ERROR("No netscape funcs?!");
816 0 : *aResult = void_t();
817 0 : *aSuccess = false;
818 0 : return IPC_OK();
819 : }
820 :
821 0 : StackIdentifier stackID(aId);
822 0 : if (stackID.Failed()) {
823 0 : *aResult = void_t();
824 0 : *aSuccess = false;
825 0 : return IPC_OK();
826 : }
827 :
828 0 : AutoTArray<NPVariant, 10> convertedArgs;
829 0 : uint32_t argCount = aArgs.Length();
830 :
831 0 : if (!convertedArgs.SetLength(argCount, fallible)) {
832 0 : *aResult = void_t();
833 0 : *aSuccess = false;
834 0 : return IPC_OK();
835 : }
836 :
837 0 : for (uint32_t index = 0; index < argCount; index++) {
838 0 : if (!ConvertToVariant(aArgs[index], convertedArgs[index], instance)) {
839 : // Don't leak things we've already converted!
840 0 : while (index-- > 0) {
841 0 : ReleaseVariant(convertedArgs[index], instance);
842 : }
843 0 : *aResult = void_t();
844 0 : *aSuccess = false;
845 0 : return IPC_OK();
846 : }
847 : }
848 :
849 : NPVariant result;
850 0 : bool success = npn->invoke(instance->GetNPP(), mObject, stackID.ToNPIdentifier(),
851 0 : convertedArgs.Elements(), argCount, &result);
852 :
853 0 : for (uint32_t index = 0; index < argCount; index++) {
854 0 : ReleaseVariant(convertedArgs[index], instance);
855 : }
856 :
857 0 : if (!success) {
858 0 : *aResult = void_t();
859 0 : *aSuccess = false;
860 0 : return IPC_OK();
861 : }
862 :
863 0 : Variant convertedResult;
864 0 : success = ConvertToRemoteVariant(result, convertedResult, GetInstance());
865 :
866 0 : DeferNPVariantLastRelease(npn, &result);
867 :
868 0 : if (!success) {
869 0 : *aResult = void_t();
870 0 : *aSuccess = false;
871 0 : return IPC_OK();
872 : }
873 :
874 0 : *aResult = convertedResult;
875 0 : *aSuccess = true;
876 0 : return IPC_OK();
877 : }
878 :
879 : mozilla::ipc::IPCResult
880 0 : PluginScriptableObjectParent::AnswerInvokeDefault(InfallibleTArray<Variant>&& aArgs,
881 : Variant* aResult,
882 : bool* aSuccess)
883 : {
884 0 : if (!mObject) {
885 0 : NS_WARNING("Calling AnswerInvoke with an invalidated object!");
886 0 : *aResult = void_t();
887 0 : *aSuccess = false;
888 0 : return IPC_OK();
889 : }
890 :
891 0 : NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
892 0 : NS_ASSERTION(mType == LocalObject, "Bad type!");
893 :
894 0 : PluginInstanceParent* instance = GetInstance();
895 0 : if (!instance) {
896 0 : NS_ERROR("No instance?!");
897 0 : *aResult = void_t();
898 0 : *aSuccess = false;
899 0 : return IPC_OK();
900 : }
901 :
902 0 : const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
903 0 : if (!npn) {
904 0 : NS_ERROR("No netscape funcs?!");
905 0 : *aResult = void_t();
906 0 : *aSuccess = false;
907 0 : return IPC_OK();
908 : }
909 :
910 0 : AutoTArray<NPVariant, 10> convertedArgs;
911 0 : uint32_t argCount = aArgs.Length();
912 :
913 0 : if (!convertedArgs.SetLength(argCount, fallible)) {
914 0 : *aResult = void_t();
915 0 : *aSuccess = false;
916 0 : return IPC_OK();
917 : }
918 :
919 0 : for (uint32_t index = 0; index < argCount; index++) {
920 0 : if (!ConvertToVariant(aArgs[index], convertedArgs[index], instance)) {
921 : // Don't leak things we've already converted!
922 0 : while (index-- > 0) {
923 0 : ReleaseVariant(convertedArgs[index], instance);
924 : }
925 0 : *aResult = void_t();
926 0 : *aSuccess = false;
927 0 : return IPC_OK();
928 : }
929 : }
930 :
931 : NPVariant result;
932 0 : bool success = npn->invokeDefault(instance->GetNPP(), mObject,
933 0 : convertedArgs.Elements(), argCount,
934 0 : &result);
935 :
936 0 : for (uint32_t index = 0; index < argCount; index++) {
937 0 : ReleaseVariant(convertedArgs[index], instance);
938 : }
939 :
940 0 : if (!success) {
941 0 : *aResult = void_t();
942 0 : *aSuccess = false;
943 0 : return IPC_OK();
944 : }
945 :
946 0 : Variant convertedResult;
947 0 : success = ConvertToRemoteVariant(result, convertedResult, GetInstance());
948 :
949 0 : DeferNPVariantLastRelease(npn, &result);
950 :
951 0 : if (!success) {
952 0 : *aResult = void_t();
953 0 : *aSuccess = false;
954 0 : return IPC_OK();
955 : }
956 :
957 0 : *aResult = convertedResult;
958 0 : *aSuccess = true;
959 0 : return IPC_OK();
960 : }
961 :
962 : mozilla::ipc::IPCResult
963 0 : PluginScriptableObjectParent::AnswerHasProperty(const PluginIdentifier& aId,
964 : bool* aHasProperty)
965 : {
966 0 : if (!mObject) {
967 0 : NS_WARNING("Calling AnswerHasProperty with an invalidated object!");
968 0 : *aHasProperty = false;
969 0 : return IPC_OK();
970 : }
971 :
972 0 : NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
973 0 : NS_ASSERTION(mType == LocalObject, "Bad type!");
974 :
975 0 : PluginInstanceParent* instance = GetInstance();
976 0 : if (!instance) {
977 0 : NS_ERROR("No instance?!");
978 0 : *aHasProperty = false;
979 0 : return IPC_OK();
980 : }
981 :
982 0 : const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
983 0 : if (!npn) {
984 0 : NS_ERROR("No netscape funcs?!");
985 0 : *aHasProperty = false;
986 0 : return IPC_OK();
987 : }
988 :
989 0 : StackIdentifier stackID(aId);
990 0 : if (stackID.Failed()) {
991 0 : *aHasProperty = false;
992 0 : return IPC_OK();
993 : }
994 :
995 0 : *aHasProperty = npn->hasproperty(instance->GetNPP(), mObject,
996 : stackID.ToNPIdentifier());
997 0 : return IPC_OK();
998 : }
999 :
1000 : mozilla::ipc::IPCResult
1001 0 : PluginScriptableObjectParent::AnswerGetParentProperty(
1002 : const PluginIdentifier& aId,
1003 : Variant* aResult,
1004 : bool* aSuccess)
1005 : {
1006 0 : if (!mObject) {
1007 0 : NS_WARNING("Calling AnswerGetProperty with an invalidated object!");
1008 0 : *aResult = void_t();
1009 0 : *aSuccess = false;
1010 0 : return IPC_OK();
1011 : }
1012 :
1013 0 : NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
1014 0 : NS_ASSERTION(mType == LocalObject, "Bad type!");
1015 :
1016 0 : PluginInstanceParent* instance = GetInstance();
1017 0 : if (!instance) {
1018 0 : NS_ERROR("No instance?!");
1019 0 : *aResult = void_t();
1020 0 : *aSuccess = false;
1021 0 : return IPC_OK();
1022 : }
1023 :
1024 0 : const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
1025 0 : if (!npn) {
1026 0 : NS_ERROR("No netscape funcs?!");
1027 0 : *aResult = void_t();
1028 0 : *aSuccess = false;
1029 0 : return IPC_OK();
1030 : }
1031 :
1032 0 : StackIdentifier stackID(aId);
1033 0 : if (stackID.Failed()) {
1034 0 : *aResult = void_t();
1035 0 : *aSuccess = false;
1036 0 : return IPC_OK();
1037 : }
1038 :
1039 : NPVariant result;
1040 0 : if (!npn->getproperty(instance->GetNPP(), mObject, stackID.ToNPIdentifier(),
1041 : &result)) {
1042 0 : *aResult = void_t();
1043 0 : *aSuccess = false;
1044 0 : return IPC_OK();
1045 : }
1046 :
1047 0 : Variant converted;
1048 0 : if ((*aSuccess = ConvertToRemoteVariant(result, converted, instance))) {
1049 0 : DeferNPVariantLastRelease(npn, &result);
1050 0 : *aResult = converted;
1051 : }
1052 : else {
1053 0 : *aResult = void_t();
1054 : }
1055 :
1056 0 : return IPC_OK();
1057 : }
1058 :
1059 : mozilla::ipc::IPCResult
1060 0 : PluginScriptableObjectParent::AnswerSetProperty(const PluginIdentifier& aId,
1061 : const Variant& aValue,
1062 : bool* aSuccess)
1063 : {
1064 0 : if (!mObject) {
1065 0 : NS_WARNING("Calling AnswerSetProperty with an invalidated object!");
1066 0 : *aSuccess = false;
1067 0 : return IPC_OK();
1068 : }
1069 :
1070 0 : NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
1071 0 : NS_ASSERTION(mType == LocalObject, "Bad type!");
1072 :
1073 0 : PluginInstanceParent* instance = GetInstance();
1074 0 : if (!instance) {
1075 0 : NS_ERROR("No instance?!");
1076 0 : *aSuccess = false;
1077 0 : return IPC_OK();
1078 : }
1079 :
1080 0 : const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
1081 0 : if (!npn) {
1082 0 : NS_ERROR("No netscape funcs?!");
1083 0 : *aSuccess = false;
1084 0 : return IPC_OK();
1085 : }
1086 :
1087 : NPVariant converted;
1088 0 : if (!ConvertToVariant(aValue, converted, instance)) {
1089 0 : *aSuccess = false;
1090 0 : return IPC_OK();
1091 : }
1092 :
1093 0 : StackIdentifier stackID(aId);
1094 0 : if (stackID.Failed()) {
1095 0 : *aSuccess = false;
1096 0 : return IPC_OK();
1097 : }
1098 :
1099 0 : if ((*aSuccess = npn->setproperty(instance->GetNPP(), mObject,
1100 : stackID.ToNPIdentifier(), &converted))) {
1101 0 : ReleaseVariant(converted, instance);
1102 : }
1103 0 : return IPC_OK();
1104 : }
1105 :
1106 : mozilla::ipc::IPCResult
1107 0 : PluginScriptableObjectParent::AnswerRemoveProperty(const PluginIdentifier& aId,
1108 : bool* aSuccess)
1109 : {
1110 0 : if (!mObject) {
1111 0 : NS_WARNING("Calling AnswerRemoveProperty with an invalidated object!");
1112 0 : *aSuccess = false;
1113 0 : return IPC_OK();
1114 : }
1115 :
1116 0 : NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
1117 0 : NS_ASSERTION(mType == LocalObject, "Bad type!");
1118 :
1119 0 : PluginInstanceParent* instance = GetInstance();
1120 0 : if (!instance) {
1121 0 : NS_ERROR("No instance?!");
1122 0 : *aSuccess = false;
1123 0 : return IPC_OK();
1124 : }
1125 :
1126 0 : const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
1127 0 : if (!npn) {
1128 0 : NS_ERROR("No netscape funcs?!");
1129 0 : *aSuccess = false;
1130 0 : return IPC_OK();
1131 : }
1132 :
1133 0 : StackIdentifier stackID(aId);
1134 0 : if (stackID.Failed()) {
1135 0 : *aSuccess = false;
1136 0 : return IPC_OK();
1137 : }
1138 :
1139 0 : *aSuccess = npn->removeproperty(instance->GetNPP(), mObject,
1140 : stackID.ToNPIdentifier());
1141 0 : return IPC_OK();
1142 : }
1143 :
1144 : mozilla::ipc::IPCResult
1145 0 : PluginScriptableObjectParent::AnswerEnumerate(InfallibleTArray<PluginIdentifier>* aProperties,
1146 : bool* aSuccess)
1147 : {
1148 0 : if (!mObject) {
1149 0 : NS_WARNING("Calling AnswerEnumerate with an invalidated object!");
1150 0 : *aSuccess = false;
1151 0 : return IPC_OK();
1152 : }
1153 :
1154 0 : NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
1155 0 : NS_ASSERTION(mType == LocalObject, "Bad type!");
1156 :
1157 0 : PluginInstanceParent* instance = GetInstance();
1158 0 : if (!instance) {
1159 0 : NS_ERROR("No instance?!");
1160 0 : *aSuccess = false;
1161 0 : return IPC_OK();
1162 : }
1163 :
1164 0 : const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
1165 0 : if (!npn) {
1166 0 : NS_WARNING("No netscape funcs?!");
1167 0 : *aSuccess = false;
1168 0 : return IPC_OK();
1169 : }
1170 :
1171 : NPIdentifier* ids;
1172 : uint32_t idCount;
1173 0 : if (!npn->enumerate(instance->GetNPP(), mObject, &ids, &idCount)) {
1174 0 : *aSuccess = false;
1175 0 : return IPC_OK();
1176 : }
1177 :
1178 0 : aProperties->SetCapacity(idCount);
1179 :
1180 0 : for (uint32_t index = 0; index < idCount; index++) {
1181 0 : PluginIdentifier id;
1182 0 : if (!FromNPIdentifier(ids[index], &id)) {
1183 0 : return IPC_FAIL_NO_REASON(this);
1184 : }
1185 0 : aProperties->AppendElement(id);
1186 : }
1187 :
1188 0 : npn->memfree(ids);
1189 0 : *aSuccess = true;
1190 0 : return IPC_OK();
1191 : }
1192 :
1193 : mozilla::ipc::IPCResult
1194 0 : PluginScriptableObjectParent::AnswerConstruct(InfallibleTArray<Variant>&& aArgs,
1195 : Variant* aResult,
1196 : bool* aSuccess)
1197 : {
1198 0 : if (!mObject) {
1199 0 : NS_WARNING("Calling AnswerConstruct with an invalidated object!");
1200 0 : *aResult = void_t();
1201 0 : *aSuccess = false;
1202 0 : return IPC_OK();
1203 : }
1204 :
1205 0 : NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
1206 0 : NS_ASSERTION(mType == LocalObject, "Bad type!");
1207 :
1208 0 : PluginInstanceParent* instance = GetInstance();
1209 0 : if (!instance) {
1210 0 : NS_ERROR("No instance?!");
1211 0 : *aResult = void_t();
1212 0 : *aSuccess = false;
1213 0 : return IPC_OK();
1214 : }
1215 :
1216 0 : const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
1217 0 : if (!npn) {
1218 0 : NS_ERROR("No netscape funcs?!");
1219 0 : *aResult = void_t();
1220 0 : *aSuccess = false;
1221 0 : return IPC_OK();
1222 : }
1223 :
1224 0 : AutoTArray<NPVariant, 10> convertedArgs;
1225 0 : uint32_t argCount = aArgs.Length();
1226 :
1227 0 : if (!convertedArgs.SetLength(argCount, fallible)) {
1228 0 : *aResult = void_t();
1229 0 : *aSuccess = false;
1230 0 : return IPC_OK();
1231 : }
1232 :
1233 0 : for (uint32_t index = 0; index < argCount; index++) {
1234 0 : if (!ConvertToVariant(aArgs[index], convertedArgs[index], instance)) {
1235 : // Don't leak things we've already converted!
1236 0 : while (index-- > 0) {
1237 0 : ReleaseVariant(convertedArgs[index], instance);
1238 : }
1239 0 : *aResult = void_t();
1240 0 : *aSuccess = false;
1241 0 : return IPC_OK();
1242 : }
1243 : }
1244 :
1245 : NPVariant result;
1246 0 : bool success = npn->construct(instance->GetNPP(), mObject,
1247 0 : convertedArgs.Elements(), argCount, &result);
1248 :
1249 0 : for (uint32_t index = 0; index < argCount; index++) {
1250 0 : ReleaseVariant(convertedArgs[index], instance);
1251 : }
1252 :
1253 0 : if (!success) {
1254 0 : *aResult = void_t();
1255 0 : *aSuccess = false;
1256 0 : return IPC_OK();
1257 : }
1258 :
1259 0 : Variant convertedResult;
1260 0 : success = ConvertToRemoteVariant(result, convertedResult, instance);
1261 :
1262 0 : DeferNPVariantLastRelease(npn, &result);
1263 :
1264 0 : if (!success) {
1265 0 : *aResult = void_t();
1266 0 : *aSuccess = false;
1267 0 : return IPC_OK();
1268 : }
1269 :
1270 0 : *aSuccess = true;
1271 0 : *aResult = convertedResult;
1272 0 : return IPC_OK();
1273 : }
1274 :
1275 : mozilla::ipc::IPCResult
1276 0 : PluginScriptableObjectParent::RecvProtect()
1277 : {
1278 0 : NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
1279 0 : NS_ASSERTION(mType == LocalObject, "Bad type!");
1280 :
1281 0 : Protect();
1282 0 : return IPC_OK();
1283 : }
1284 :
1285 : mozilla::ipc::IPCResult
1286 0 : PluginScriptableObjectParent::RecvUnprotect()
1287 : {
1288 0 : NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
1289 0 : NS_ASSERTION(mType == LocalObject, "Bad type!");
1290 :
1291 0 : Unprotect();
1292 0 : return IPC_OK();
1293 : }
1294 :
1295 : mozilla::ipc::IPCResult
1296 0 : PluginScriptableObjectParent::AnswerNPN_Evaluate(const nsCString& aScript,
1297 : Variant* aResult,
1298 : bool* aSuccess)
1299 : {
1300 0 : PluginInstanceParent* instance = GetInstance();
1301 0 : if (!instance) {
1302 0 : NS_ERROR("No instance?!");
1303 0 : *aResult = void_t();
1304 0 : *aSuccess = false;
1305 0 : return IPC_OK();
1306 : }
1307 :
1308 0 : const NPNetscapeFuncs* npn = GetNetscapeFuncs(instance);
1309 0 : if (!npn) {
1310 0 : NS_ERROR("No netscape funcs?!");
1311 0 : *aResult = void_t();
1312 0 : *aSuccess = false;
1313 0 : return IPC_OK();
1314 : }
1315 :
1316 0 : NPString script = { aScript.get(), aScript.Length() };
1317 :
1318 : NPVariant result;
1319 0 : bool success = npn->evaluate(instance->GetNPP(), mObject, &script, &result);
1320 0 : if (!success) {
1321 0 : *aResult = void_t();
1322 0 : *aSuccess = false;
1323 0 : return IPC_OK();
1324 : }
1325 :
1326 0 : Variant convertedResult;
1327 0 : success = ConvertToRemoteVariant(result, convertedResult, instance);
1328 :
1329 0 : DeferNPVariantLastRelease(npn, &result);
1330 :
1331 0 : if (!success) {
1332 0 : *aResult = void_t();
1333 0 : *aSuccess = false;
1334 0 : return IPC_OK();
1335 : }
1336 :
1337 0 : *aSuccess = true;
1338 0 : *aResult = convertedResult;
1339 0 : return IPC_OK();
1340 : }
1341 :
1342 : bool
1343 0 : PluginScriptableObjectParent::GetPropertyHelper(NPIdentifier aName,
1344 : bool* aHasProperty,
1345 : bool* aHasMethod,
1346 : NPVariant* aResult)
1347 : {
1348 0 : NS_ASSERTION(Type() == Proxy, "Bad type!");
1349 :
1350 0 : ParentNPObject* object = static_cast<ParentNPObject*>(mObject);
1351 0 : if (object->invalidated) {
1352 0 : NS_WARNING("Calling method on an invalidated object!");
1353 0 : return false;
1354 : }
1355 :
1356 0 : PluginIdentifier identifier;
1357 0 : if (!FromNPIdentifier(aName, &identifier)) {
1358 0 : return false;
1359 : }
1360 :
1361 : bool hasProperty, hasMethod, success;
1362 0 : Variant result;
1363 0 : if (!CallGetChildProperty(identifier, &hasProperty, &hasMethod, &result,
1364 : &success)) {
1365 0 : return false;
1366 : }
1367 :
1368 0 : if (!success) {
1369 0 : return false;
1370 : }
1371 :
1372 0 : if (!ConvertToVariant(result, *aResult, GetInstance())) {
1373 0 : NS_WARNING("Failed to convert result!");
1374 0 : return false;
1375 : }
1376 :
1377 0 : *aHasProperty = hasProperty;
1378 0 : *aHasMethod = hasMethod;
1379 0 : return true;
1380 9 : }
|