Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/plugins/ipc/PluginScriptableObjectParent.cpp
Line
Count
Source (jump to first uncovered line)
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
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
StackIdentifier::StackIdentifier(const PluginIdentifier& aIdentifier, bool aAtomizeAndPin)
54
: mFailed(false),
55
  mId(mCx)
56
0
{
57
0
  if (aIdentifier.type() == PluginIdentifier::TnsCString) {
58
0
    // 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
0
    }
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
0
      }
73
0
    }
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
0
    }
79
0
    mIdentifier = JSIdToNPIdentifier(mId);
80
0
    return;
81
0
  }
82
0
83
0
  mIdentifier = mozilla::plugins::parent::_getintidentifier(aIdentifier.get_int32_t());
84
0
}
85
86
static bool
87
FromNPIdentifier(NPIdentifier aIdentifier, PluginIdentifier* aResult)
88
0
{
89
0
  if (mozilla::plugins::parent::_identifierisstring(aIdentifier)) {
90
0
    nsCString string;
91
0
    NPUTF8* chars =
92
0
      mozilla::plugins::parent::_utf8fromidentifier(aIdentifier);
93
0
    if (!chars) {
94
0
      return false;
95
0
    }
96
0
    string.Adopt(chars);
97
0
    *aResult = PluginIdentifier(string);
98
0
    return true;
99
0
  }
100
0
  else {
101
0
    int32_t intval = mozilla::plugins::parent::_intfromidentifier(aIdentifier);
102
0
    *aResult = PluginIdentifier(intval);
103
0
    return true;
104
0
  }
105
0
}
106
107
namespace {
108
109
inline void
110
ReleaseVariant(NPVariant& aVariant,
111
               PluginInstanceParent* aInstance)
112
0
{
113
0
  const NPNetscapeFuncs* npn = GetNetscapeFuncs(aInstance);
114
0
  if (npn) {
115
0
    npn->releasevariantvalue(&aVariant);
116
0
  }
117
0
}
118
119
} // namespace
120
121
// static
122
NPObject*
123
PluginScriptableObjectParent::ScriptableAllocate(NPP aInstance,
124
                                                 NPClass* aClass)
125
0
{
126
0
  if (aClass != GetClass()) {
127
0
    NS_ERROR("Huh?! Wrong class!");
128
0
    return nullptr;
129
0
  }
130
0
131
0
  return new ParentNPObject();
132
0
}
133
134
// static
135
void
136
PluginScriptableObjectParent::ScriptableInvalidate(NPObject* aObject)
137
0
{
138
0
  if (aObject->_class != GetClass()) {
139
0
    NS_ERROR("Don't know what kind of object this is!");
140
0
    return;
141
0
  }
142
0
143
0
  ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
144
0
  if (object->invalidated) {
145
0
    // This can happen more than once, and is just fine.
146
0
    return;
147
0
  }
148
0
149
0
  object->invalidated = true;
150
0
151
0
  // |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
0
  }
155
0
}
156
157
// static
158
void
159
PluginScriptableObjectParent::ScriptableDeallocate(NPObject* aObject)
160
0
{
161
0
  if (aObject->_class != GetClass()) {
162
0
    NS_ERROR("Don't know what kind of object this is!");
163
0
    return;
164
0
  }
165
0
166
0
  ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
167
0
168
0
  if (object->asyncWrapperCount > 0) {
169
0
    // In this case we should just drop the refcount to the asyncWrapperCount
170
0
    // instead of deallocating because there are still some async wrappers
171
0
    // out there that are referencing this object.
172
0
    object->referenceCount = object->asyncWrapperCount;
173
0
    return;
174
0
  }
175
0
176
0
  PluginScriptableObjectParent* actor = object->parent;
177
0
  if (actor) {
178
0
    NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
179
0
    actor->DropNPObject();
180
0
  }
181
0
182
0
  delete object;
183
0
}
184
185
// static
186
bool
187
PluginScriptableObjectParent::ScriptableHasMethod(NPObject* aObject,
188
                                                  NPIdentifier aName)
189
0
{
190
0
  if (aObject->_class != GetClass()) {
191
0
    NS_ERROR("Don't know what kind of object this is!");
192
0
    return false;
193
0
  }
194
0
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
0
  }
200
0
201
0
  ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
202
0
  if (!actor) {
203
0
    return false;
204
0
  }
205
0
206
0
  PluginIdentifier identifier;
207
0
  if (!FromNPIdentifier(aName, &identifier)) {
208
0
    return false;
209
0
  }
210
0
211
0
  NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
212
0
213
0
  bool result;
214
0
  if (!actor->CallHasMethod(identifier, &result)) {
215
0
    NS_WARNING("Failed to send message!");
216
0
    return false;
217
0
  }
218
0
219
0
  return result;
220
0
}
221
222
// static
223
bool
224
PluginScriptableObjectParent::ScriptableInvoke(NPObject* aObject,
225
                                               NPIdentifier aName,
226
                                               const NPVariant* aArgs,
227
                                               uint32_t aArgCount,
228
                                               NPVariant* aResult)
229
0
{
230
0
  if (aObject->_class != GetClass()) {
231
0
    NS_ERROR("Don't know what kind of object this is!");
232
0
    return false;
233
0
  }
234
0
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
0
  }
240
0
241
0
  ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
242
0
  if (!actor) {
243
0
    return false;
244
0
  }
245
0
246
0
  PluginIdentifier identifier;
247
0
  if (!FromNPIdentifier(aName, &identifier)) {
248
0
    return false;
249
0
  }
250
0
251
0
  NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
252
0
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
0
  }
258
0
259
0
  Variant remoteResult;
260
0
  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
0
  }
266
0
267
0
  if (!success) {
268
0
    return false;
269
0
  }
270
0
271
0
  if (!ConvertToVariant(remoteResult, *aResult, actor->GetInstance())) {
272
0
    NS_WARNING("Failed to convert result!");
273
0
    return false;
274
0
  }
275
0
  return true;
276
0
}
277
278
// static
279
bool
280
PluginScriptableObjectParent::ScriptableInvokeDefault(NPObject* aObject,
281
                                                      const NPVariant* aArgs,
282
                                                      uint32_t aArgCount,
283
                                                      NPVariant* aResult)
284
0
{
285
0
  if (aObject->_class != GetClass()) {
286
0
    NS_ERROR("Don't know what kind of object this is!");
287
0
    return false;
288
0
  }
289
0
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
0
  }
295
0
296
0
  ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
297
0
  if (!actor) {
298
0
    return false;
299
0
  }
300
0
301
0
  NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
302
0
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
0
  }
308
0
309
0
  Variant remoteResult;
310
0
  bool success;
311
0
  if (!actor->CallInvokeDefault(args, &remoteResult, &success)) {
312
0
    NS_WARNING("Failed to send message!");
313
0
    return false;
314
0
  }
315
0
316
0
  if (!success) {
317
0
    return false;
318
0
  }
319
0
320
0
  if (!ConvertToVariant(remoteResult, *aResult, actor->GetInstance())) {
321
0
    NS_WARNING("Failed to convert result!");
322
0
    return false;
323
0
  }
324
0
  return true;
325
0
}
326
327
// static
328
bool
329
PluginScriptableObjectParent::ScriptableHasProperty(NPObject* aObject,
330
                                                    NPIdentifier aName)
331
0
{
332
0
  if (aObject->_class != GetClass()) {
333
0
    NS_ERROR("Don't know what kind of object this is!");
334
0
    return false;
335
0
  }
336
0
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
0
  }
342
0
343
0
  ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
344
0
  if (!actor) {
345
0
    return false;
346
0
  }
347
0
348
0
  PluginIdentifier identifier;
349
0
  if (!FromNPIdentifier(aName, &identifier)) {
350
0
    return false;
351
0
  }
352
0
353
0
  NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
354
0
355
0
  bool result;
356
0
  if (!actor->CallHasProperty(identifier, &result)) {
357
0
    NS_WARNING("Failed to send message!");
358
0
    return false;
359
0
  }
360
0
361
0
  return result;
362
0
}
363
364
// static
365
bool
366
PluginScriptableObjectParent::ScriptableGetProperty(NPObject* aObject,
367
                                                    NPIdentifier aName,
368
                                                    NPVariant* aResult)
369
0
{
370
0
  // See GetPropertyHelper below.
371
0
  MOZ_ASSERT_UNREACHABLE("Shouldn't ever call this directly!");
372
0
  return false;
373
0
}
374
375
// static
376
bool
377
PluginScriptableObjectParent::ScriptableSetProperty(NPObject* aObject,
378
                                                    NPIdentifier aName,
379
                                                    const NPVariant* aValue)
380
0
{
381
0
  if (aObject->_class != GetClass()) {
382
0
    NS_ERROR("Don't know what kind of object this is!");
383
0
    return false;
384
0
  }
385
0
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
0
  }
391
0
392
0
  ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
393
0
  if (!actor) {
394
0
    return false;
395
0
  }
396
0
397
0
  PluginIdentifier identifier;
398
0
  if (!FromNPIdentifier(aName, &identifier)) {
399
0
    return false;
400
0
  }
401
0
402
0
  NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
403
0
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
0
  }
409
0
410
0
  bool success;
411
0
  if (!actor->CallSetProperty(identifier, value, &success)) {
412
0
    NS_WARNING("Failed to send message!");
413
0
    return false;
414
0
  }
415
0
416
0
  return success;
417
0
}
418
419
// static
420
bool
421
PluginScriptableObjectParent::ScriptableRemoveProperty(NPObject* aObject,
422
                                                       NPIdentifier aName)
423
0
{
424
0
  if (aObject->_class != GetClass()) {
425
0
    NS_ERROR("Don't know what kind of object this is!");
426
0
    return false;
427
0
  }
428
0
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
0
  }
434
0
435
0
  ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
436
0
  if (!actor) {
437
0
    return false;
438
0
  }
439
0
440
0
  PluginIdentifier identifier;
441
0
  if (!FromNPIdentifier(aName, &identifier)) {
442
0
    return false;
443
0
  }
444
0
445
0
  NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
446
0
447
0
  bool success;
448
0
  if (!actor->CallRemoveProperty(identifier, &success)) {
449
0
    NS_WARNING("Failed to send message!");
450
0
    return false;
451
0
  }
452
0
453
0
  return success;
454
0
}
455
456
// static
457
bool
458
PluginScriptableObjectParent::ScriptableEnumerate(NPObject* aObject,
459
                                                  NPIdentifier** aIdentifiers,
460
                                                  uint32_t* aCount)
461
0
{
462
0
  if (aObject->_class != GetClass()) {
463
0
    NS_ERROR("Don't know what kind of object this is!");
464
0
    return false;
465
0
  }
466
0
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
0
  }
472
0
473
0
  ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
474
0
  if (!actor) {
475
0
    return false;
476
0
  }
477
0
478
0
  NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
479
0
480
0
  const NPNetscapeFuncs* npn = GetNetscapeFuncs(aObject);
481
0
  if (!npn) {
482
0
    NS_ERROR("No netscape funcs!");
483
0
    return false;
484
0
  }
485
0
486
0
  AutoTArray<PluginIdentifier, 10> identifiers;
487
0
  bool success;
488
0
  if (!actor->CallEnumerate(&identifiers, &success)) {
489
0
    NS_WARNING("Failed to send message!");
490
0
    return false;
491
0
  }
492
0
493
0
  if (!success) {
494
0
    return false;
495
0
  }
496
0
497
0
  *aCount = identifiers.Length();
498
0
  if (!*aCount) {
499
0
    *aIdentifiers = nullptr;
500
0
    return true;
501
0
  }
502
0
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
0
  }
508
0
509
0
  for (uint32_t index = 0; index < *aCount; index++) {
510
0
    // We pin the ID to avoid a GC hazard here. This could probably be fixed
511
0
    // 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
0
    }
516
0
    (*aIdentifiers)[index] = stackID.ToNPIdentifier();
517
0
  }
518
0
  return true;
519
0
}
520
521
// static
522
bool
523
PluginScriptableObjectParent::ScriptableConstruct(NPObject* aObject,
524
                                                  const NPVariant* aArgs,
525
                                                  uint32_t aArgCount,
526
                                                  NPVariant* aResult)
527
0
{
528
0
  if (aObject->_class != GetClass()) {
529
0
    NS_ERROR("Don't know what kind of object this is!");
530
0
    return false;
531
0
  }
532
0
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
0
  }
538
0
539
0
  ProtectedActor<PluginScriptableObjectParent> actor(object->parent);
540
0
  if (!actor) {
541
0
    return false;
542
0
  }
543
0
544
0
  NS_ASSERTION(actor->Type() == Proxy, "Bad type!");
545
0
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
0
  }
551
0
552
0
  Variant remoteResult;
553
0
  bool success;
554
0
  if (!actor->CallConstruct(args, &remoteResult, &success)) {
555
0
    NS_WARNING("Failed to send message!");
556
0
    return false;
557
0
  }
558
0
559
0
  if (!success) {
560
0
    return false;
561
0
  }
562
0
563
0
  if (!ConvertToVariant(remoteResult, *aResult, actor->GetInstance())) {
564
0
    NS_WARNING("Failed to convert result!");
565
0
    return false;
566
0
  }
567
0
  return true;
568
0
}
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
PluginScriptableObjectParent::PluginScriptableObjectParent(
587
                                                     ScriptableObjectType aType)
588
: mInstance(nullptr),
589
  mObject(nullptr),
590
  mProtectCount(0),
591
  mType(aType)
592
0
{
593
0
}
594
595
PluginScriptableObjectParent::~PluginScriptableObjectParent()
596
0
{
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
0
    }
602
0
    else {
603
0
      NS_ASSERTION(mType == LocalObject, "Wrong type!");
604
0
      GetInstance()->GetNPNIface()->releaseobject(mObject);
605
0
    }
606
0
  }
607
0
}
608
609
void
610
PluginScriptableObjectParent::InitializeProxy()
611
0
{
612
0
  NS_ASSERTION(mType == Proxy, "Bad type!");
613
0
  NS_ASSERTION(!mObject, "Calling Initialize more than once!");
614
0
615
0
  mInstance = static_cast<PluginInstanceParent*>(Manager());
616
0
  NS_ASSERTION(mInstance, "Null manager?!");
617
0
618
0
  NPObject* object = CreateProxyObject();
619
0
  NS_ASSERTION(object, "Failed to create object!");
620
0
621
0
  if (!mInstance->RegisterNPObjectForActor(object, this)) {
622
0
    NS_ERROR("Out of memory?");
623
0
  }
624
0
625
0
  mObject = object;
626
0
}
627
628
void
629
PluginScriptableObjectParent::InitializeLocal(NPObject* aObject)
630
0
{
631
0
  NS_ASSERTION(mType == LocalObject, "Bad type!");
632
0
  NS_ASSERTION(!(mInstance && mObject), "Calling Initialize more than once!");
633
0
634
0
  mInstance = static_cast<PluginInstanceParent*>(Manager());
635
0
  NS_ASSERTION(mInstance, "Null manager?!");
636
0
637
0
  mInstance->GetNPNIface()->retainobject(aObject);
638
0
639
0
  NS_ASSERTION(!mProtectCount, "Should be zero!");
640
0
  mProtectCount++;
641
0
642
0
  if (!mInstance->RegisterNPObjectForActor(aObject, this)) {
643
0
    NS_ERROR("Out of memory?");
644
0
  }
645
0
646
0
  mObject = aObject;
647
0
}
648
649
NPObject*
650
PluginScriptableObjectParent::CreateProxyObject()
651
0
{
652
0
  NS_ASSERTION(mInstance, "Must have an instance!");
653
0
  NS_ASSERTION(mType == Proxy, "Shouldn't call this for non-proxy object!");
654
0
655
0
  const NPNetscapeFuncs* npn = GetNetscapeFuncs(mInstance);
656
0
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
0
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
0
667
0
  // We don't want to have the actor own this object but rather let the object
668
0
  // own this actor. Set the reference count to 0 here so that when the object
669
0
  // dies we will send the destructor message to the child.
670
0
  object->referenceCount = 0;
671
0
  NS_LOG_RELEASE(object, 0, "BrowserNPObject");
672
0
673
0
  object->parent = const_cast<PluginScriptableObjectParent*>(this);
674
0
  return object;
675
0
}
676
677
bool
678
PluginScriptableObjectParent::ResurrectProxyObject()
679
0
{
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
0
684
0
  InitializeProxy();
685
0
  NS_ASSERTION(mObject, "Initialize failed!");
686
0
687
0
  if (!SendProtect()) {
688
0
    NS_WARNING("Failed to send message!");
689
0
    return false;
690
0
  }
691
0
692
0
  return true;
693
0
}
694
695
NPObject*
696
PluginScriptableObjectParent::GetObject(bool aCanResurrect)
697
0
{
698
0
  if (!mObject && aCanResurrect && !ResurrectProxyObject()) {
699
0
    NS_ERROR("Null object!");
700
0
    return nullptr;
701
0
  }
702
0
  return mObject;
703
0
}
704
705
void
706
PluginScriptableObjectParent::Protect()
707
0
{
708
0
  NS_ASSERTION(mObject, "No object!");
709
0
  NS_ASSERTION(mProtectCount >= 0, "Negative protect count?!");
710
0
711
0
  if (mType == LocalObject) {
712
0
    ++mProtectCount;
713
0
  }
714
0
}
715
716
void
717
PluginScriptableObjectParent::Unprotect()
718
0
{
719
0
  NS_ASSERTION(mObject, "No object!");
720
0
  NS_ASSERTION(mProtectCount >= 0, "Negative protect count?!");
721
0
722
0
  if (mType == LocalObject) {
723
0
    if (--mProtectCount == 0) {
724
0
      Unused << PluginScriptableObjectParent::Send__delete__(this);
725
0
    }
726
0
  }
727
0
}
728
729
void
730
PluginScriptableObjectParent::DropNPObject()
731
0
{
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
0
736
0
  // We think we're about to be deleted, but we could be racing with the other
737
0
  // process.
738
0
  PluginInstanceParent* instance = GetInstance();
739
0
  NS_ASSERTION(instance, "Must have an instance!");
740
0
741
0
  instance->UnregisterNPObject(mObject);
742
0
  mObject = nullptr;
743
0
744
0
  Unused << SendUnprotect();
745
0
}
746
747
void
748
PluginScriptableObjectParent::ActorDestroy(ActorDestroyReason aWhy)
749
0
{
750
0
  // Implement me! Bug 1005163
751
0
}
752
753
mozilla::ipc::IPCResult
754
PluginScriptableObjectParent::AnswerHasMethod(const PluginIdentifier& aId,
755
                                              bool* aHasMethod)
756
0
{
757
0
  if (!mObject) {
758
0
    NS_WARNING("Calling AnswerHasMethod with an invalidated object!");
759
0
    *aHasMethod = false;
760
0
    return IPC_OK();
761
0
  }
762
0
763
0
  NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
764
0
  NS_ASSERTION(mType == LocalObject, "Bad type!");
765
0
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
0
  }
772
0
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
0
  }
779
0
780
0
  StackIdentifier stackID(aId);
781
0
  if (stackID.Failed()) {
782
0
    *aHasMethod = false;
783
0
    return IPC_OK();
784
0
  }
785
0
  *aHasMethod = npn->hasmethod(instance->GetNPP(), mObject, stackID.ToNPIdentifier());
786
0
  return IPC_OK();
787
0
}
788
789
mozilla::ipc::IPCResult
790
PluginScriptableObjectParent::AnswerInvoke(const PluginIdentifier& aId,
791
                                           InfallibleTArray<Variant>&& aArgs,
792
                                           Variant* aResult,
793
                                           bool* aSuccess)
794
0
{
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
0
  }
801
0
802
0
  NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
803
0
  NS_ASSERTION(mType == LocalObject, "Bad type!");
804
0
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
0
  }
812
0
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
0
  }
820
0
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
0
  }
827
0
828
0
  AutoTArray<NPVariant, 10> convertedArgs;
829
0
  uint32_t argCount = aArgs.Length();
830
0
831
0
  if (!convertedArgs.SetLength(argCount, fallible)) {
832
0
    *aResult = void_t();
833
0
    *aSuccess = false;
834
0
    return IPC_OK();
835
0
  }
836
0
837
0
  for (uint32_t index = 0; index < argCount; index++) {
838
0
    if (!ConvertToVariant(aArgs[index], convertedArgs[index], instance)) {
839
0
      // Don't leak things we've already converted!
840
0
      while (index-- > 0) {
841
0
        ReleaseVariant(convertedArgs[index], instance);
842
0
      }
843
0
      *aResult = void_t();
844
0
      *aSuccess = false;
845
0
      return IPC_OK();
846
0
    }
847
0
  }
848
0
849
0
  NPVariant result;
850
0
  bool success = npn->invoke(instance->GetNPP(), mObject, stackID.ToNPIdentifier(),
851
0
                             convertedArgs.Elements(), argCount, &result);
852
0
853
0
  for (uint32_t index = 0; index < argCount; index++) {
854
0
    ReleaseVariant(convertedArgs[index], instance);
855
0
  }
856
0
857
0
  if (!success) {
858
0
    *aResult = void_t();
859
0
    *aSuccess = false;
860
0
    return IPC_OK();
861
0
  }
862
0
863
0
  Variant convertedResult;
864
0
  success = ConvertToRemoteVariant(result, convertedResult, GetInstance());
865
0
866
0
  DeferNPVariantLastRelease(npn, &result);
867
0
868
0
  if (!success) {
869
0
    *aResult = void_t();
870
0
    *aSuccess = false;
871
0
    return IPC_OK();
872
0
  }
873
0
874
0
  *aResult = convertedResult;
875
0
  *aSuccess = true;
876
0
  return IPC_OK();
877
0
}
878
879
mozilla::ipc::IPCResult
880
PluginScriptableObjectParent::AnswerInvokeDefault(InfallibleTArray<Variant>&& aArgs,
881
                                                  Variant* aResult,
882
                                                  bool* aSuccess)
883
0
{
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
0
  }
890
0
891
0
  NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
892
0
  NS_ASSERTION(mType == LocalObject, "Bad type!");
893
0
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
0
  }
901
0
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
0
  }
909
0
910
0
  AutoTArray<NPVariant, 10> convertedArgs;
911
0
  uint32_t argCount = aArgs.Length();
912
0
913
0
  if (!convertedArgs.SetLength(argCount, fallible)) {
914
0
    *aResult = void_t();
915
0
    *aSuccess = false;
916
0
    return IPC_OK();
917
0
  }
918
0
919
0
  for (uint32_t index = 0; index < argCount; index++) {
920
0
    if (!ConvertToVariant(aArgs[index], convertedArgs[index], instance)) {
921
0
      // Don't leak things we've already converted!
922
0
      while (index-- > 0) {
923
0
        ReleaseVariant(convertedArgs[index], instance);
924
0
      }
925
0
      *aResult = void_t();
926
0
      *aSuccess = false;
927
0
      return IPC_OK();
928
0
    }
929
0
  }
930
0
931
0
  NPVariant result;
932
0
  bool success = npn->invokeDefault(instance->GetNPP(), mObject,
933
0
                                    convertedArgs.Elements(), argCount,
934
0
                                    &result);
935
0
936
0
  for (uint32_t index = 0; index < argCount; index++) {
937
0
    ReleaseVariant(convertedArgs[index], instance);
938
0
  }
939
0
940
0
  if (!success) {
941
0
    *aResult = void_t();
942
0
    *aSuccess = false;
943
0
    return IPC_OK();
944
0
  }
945
0
946
0
  Variant convertedResult;
947
0
  success = ConvertToRemoteVariant(result, convertedResult, GetInstance());
948
0
949
0
  DeferNPVariantLastRelease(npn, &result);
950
0
951
0
  if (!success) {
952
0
    *aResult = void_t();
953
0
    *aSuccess = false;
954
0
    return IPC_OK();
955
0
  }
956
0
957
0
  *aResult = convertedResult;
958
0
  *aSuccess = true;
959
0
  return IPC_OK();
960
0
}
961
962
mozilla::ipc::IPCResult
963
PluginScriptableObjectParent::AnswerHasProperty(const PluginIdentifier& aId,
964
                                                bool* aHasProperty)
965
0
{
966
0
  if (!mObject) {
967
0
    NS_WARNING("Calling AnswerHasProperty with an invalidated object!");
968
0
    *aHasProperty = false;
969
0
    return IPC_OK();
970
0
  }
971
0
972
0
  NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
973
0
  NS_ASSERTION(mType == LocalObject, "Bad type!");
974
0
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
0
  }
981
0
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
0
  }
988
0
989
0
  StackIdentifier stackID(aId);
990
0
  if (stackID.Failed()) {
991
0
    *aHasProperty = false;
992
0
    return IPC_OK();
993
0
  }
994
0
995
0
  *aHasProperty = npn->hasproperty(instance->GetNPP(), mObject,
996
0
                                   stackID.ToNPIdentifier());
997
0
  return IPC_OK();
998
0
}
999
1000
mozilla::ipc::IPCResult
1001
PluginScriptableObjectParent::AnswerGetParentProperty(
1002
                                                   const PluginIdentifier& aId,
1003
                                                   Variant* aResult,
1004
                                                   bool* aSuccess)
1005
0
{
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
0
  }
1012
0
1013
0
  NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
1014
0
  NS_ASSERTION(mType == LocalObject, "Bad type!");
1015
0
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
0
  }
1023
0
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
0
  }
1031
0
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
0
  }
1038
0
1039
0
  NPVariant result;
1040
0
  if (!npn->getproperty(instance->GetNPP(), mObject, stackID.ToNPIdentifier(),
1041
0
                        &result)) {
1042
0
    *aResult = void_t();
1043
0
    *aSuccess = false;
1044
0
    return IPC_OK();
1045
0
  }
1046
0
1047
0
  Variant converted;
1048
0
  if ((*aSuccess = ConvertToRemoteVariant(result, converted, instance))) {
1049
0
    DeferNPVariantLastRelease(npn, &result);
1050
0
    *aResult = converted;
1051
0
  }
1052
0
  else {
1053
0
    *aResult = void_t();
1054
0
  }
1055
0
1056
0
  return IPC_OK();
1057
0
}
1058
1059
mozilla::ipc::IPCResult
1060
PluginScriptableObjectParent::AnswerSetProperty(const PluginIdentifier& aId,
1061
                                                const Variant& aValue,
1062
                                                bool* aSuccess)
1063
0
{
1064
0
  if (!mObject) {
1065
0
    NS_WARNING("Calling AnswerSetProperty with an invalidated object!");
1066
0
    *aSuccess = false;
1067
0
    return IPC_OK();
1068
0
  }
1069
0
1070
0
  NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
1071
0
  NS_ASSERTION(mType == LocalObject, "Bad type!");
1072
0
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
0
  }
1079
0
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
0
  }
1086
0
1087
0
  NPVariant converted;
1088
0
  if (!ConvertToVariant(aValue, converted, instance)) {
1089
0
    *aSuccess = false;
1090
0
    return IPC_OK();
1091
0
  }
1092
0
1093
0
  StackIdentifier stackID(aId);
1094
0
  if (stackID.Failed()) {
1095
0
    *aSuccess = false;
1096
0
    return IPC_OK();
1097
0
  }
1098
0
1099
0
  if ((*aSuccess = npn->setproperty(instance->GetNPP(), mObject,
1100
0
                                    stackID.ToNPIdentifier(), &converted))) {
1101
0
    ReleaseVariant(converted, instance);
1102
0
  }
1103
0
  return IPC_OK();
1104
0
}
1105
1106
mozilla::ipc::IPCResult
1107
PluginScriptableObjectParent::AnswerRemoveProperty(const PluginIdentifier& aId,
1108
                                                   bool* aSuccess)
1109
0
{
1110
0
  if (!mObject) {
1111
0
    NS_WARNING("Calling AnswerRemoveProperty with an invalidated object!");
1112
0
    *aSuccess = false;
1113
0
    return IPC_OK();
1114
0
  }
1115
0
1116
0
  NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
1117
0
  NS_ASSERTION(mType == LocalObject, "Bad type!");
1118
0
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
0
  }
1125
0
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
0
  }
1132
0
1133
0
  StackIdentifier stackID(aId);
1134
0
  if (stackID.Failed()) {
1135
0
    *aSuccess = false;
1136
0
    return IPC_OK();
1137
0
  }
1138
0
1139
0
  *aSuccess = npn->removeproperty(instance->GetNPP(), mObject,
1140
0
                                  stackID.ToNPIdentifier());
1141
0
  return IPC_OK();
1142
0
}
1143
1144
mozilla::ipc::IPCResult
1145
PluginScriptableObjectParent::AnswerEnumerate(InfallibleTArray<PluginIdentifier>* aProperties,
1146
                                              bool* aSuccess)
1147
0
{
1148
0
  if (!mObject) {
1149
0
    NS_WARNING("Calling AnswerEnumerate with an invalidated object!");
1150
0
    *aSuccess = false;
1151
0
    return IPC_OK();
1152
0
  }
1153
0
1154
0
  NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
1155
0
  NS_ASSERTION(mType == LocalObject, "Bad type!");
1156
0
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
0
  }
1163
0
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
0
  }
1170
0
1171
0
  NPIdentifier* ids;
1172
0
  uint32_t idCount;
1173
0
  if (!npn->enumerate(instance->GetNPP(), mObject, &ids, &idCount)) {
1174
0
    *aSuccess = false;
1175
0
    return IPC_OK();
1176
0
  }
1177
0
1178
0
  aProperties->SetCapacity(idCount);
1179
0
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
0
    }
1185
0
    aProperties->AppendElement(id);
1186
0
  }
1187
0
1188
0
  npn->memfree(ids);
1189
0
  *aSuccess = true;
1190
0
  return IPC_OK();
1191
0
}
1192
1193
mozilla::ipc::IPCResult
1194
PluginScriptableObjectParent::AnswerConstruct(InfallibleTArray<Variant>&& aArgs,
1195
                                              Variant* aResult,
1196
                                              bool* aSuccess)
1197
0
{
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
0
  }
1204
0
1205
0
  NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
1206
0
  NS_ASSERTION(mType == LocalObject, "Bad type!");
1207
0
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
0
  }
1215
0
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
0
  }
1223
0
1224
0
  AutoTArray<NPVariant, 10> convertedArgs;
1225
0
  uint32_t argCount = aArgs.Length();
1226
0
1227
0
  if (!convertedArgs.SetLength(argCount, fallible)) {
1228
0
    *aResult = void_t();
1229
0
    *aSuccess = false;
1230
0
    return IPC_OK();
1231
0
  }
1232
0
1233
0
  for (uint32_t index = 0; index < argCount; index++) {
1234
0
    if (!ConvertToVariant(aArgs[index], convertedArgs[index], instance)) {
1235
0
      // Don't leak things we've already converted!
1236
0
      while (index-- > 0) {
1237
0
        ReleaseVariant(convertedArgs[index], instance);
1238
0
      }
1239
0
      *aResult = void_t();
1240
0
      *aSuccess = false;
1241
0
      return IPC_OK();
1242
0
    }
1243
0
  }
1244
0
1245
0
  NPVariant result;
1246
0
  bool success = npn->construct(instance->GetNPP(), mObject,
1247
0
                                convertedArgs.Elements(), argCount, &result);
1248
0
1249
0
  for (uint32_t index = 0; index < argCount; index++) {
1250
0
    ReleaseVariant(convertedArgs[index], instance);
1251
0
  }
1252
0
1253
0
  if (!success) {
1254
0
    *aResult = void_t();
1255
0
    *aSuccess = false;
1256
0
    return IPC_OK();
1257
0
  }
1258
0
1259
0
  Variant convertedResult;
1260
0
  success = ConvertToRemoteVariant(result, convertedResult, instance);
1261
0
1262
0
  DeferNPVariantLastRelease(npn, &result);
1263
0
1264
0
  if (!success) {
1265
0
    *aResult = void_t();
1266
0
    *aSuccess = false;
1267
0
    return IPC_OK();
1268
0
  }
1269
0
1270
0
  *aSuccess = true;
1271
0
  *aResult = convertedResult;
1272
0
  return IPC_OK();
1273
0
}
1274
1275
mozilla::ipc::IPCResult
1276
PluginScriptableObjectParent::RecvProtect()
1277
0
{
1278
0
  NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
1279
0
  NS_ASSERTION(mType == LocalObject, "Bad type!");
1280
0
1281
0
  Protect();
1282
0
  return IPC_OK();
1283
0
}
1284
1285
mozilla::ipc::IPCResult
1286
PluginScriptableObjectParent::RecvUnprotect()
1287
0
{
1288
0
  NS_ASSERTION(mObject->_class != GetClass(), "Bad object type!");
1289
0
  NS_ASSERTION(mType == LocalObject, "Bad type!");
1290
0
1291
0
  Unprotect();
1292
0
  return IPC_OK();
1293
0
}
1294
1295
mozilla::ipc::IPCResult
1296
PluginScriptableObjectParent::AnswerNPN_Evaluate(const nsCString& aScript,
1297
                                                 Variant* aResult,
1298
                                                 bool* aSuccess)
1299
0
{
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
0
  }
1307
0
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
0
  }
1315
0
1316
0
  NPString script = { aScript.get(), aScript.Length() };
1317
0
1318
0
  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
0
  }
1325
0
1326
0
  Variant convertedResult;
1327
0
  success = ConvertToRemoteVariant(result, convertedResult, instance);
1328
0
1329
0
  DeferNPVariantLastRelease(npn, &result);
1330
0
1331
0
  if (!success) {
1332
0
    *aResult = void_t();
1333
0
    *aSuccess = false;
1334
0
    return IPC_OK();
1335
0
  }
1336
0
1337
0
  *aSuccess = true;
1338
0
  *aResult = convertedResult;
1339
0
  return IPC_OK();
1340
0
}
1341
1342
bool
1343
PluginScriptableObjectParent::GetPropertyHelper(NPIdentifier aName,
1344
                                                bool* aHasProperty,
1345
                                                bool* aHasMethod,
1346
                                                NPVariant* aResult)
1347
0
{
1348
0
  NS_ASSERTION(Type() == Proxy, "Bad type!");
1349
0
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
0
  }
1355
0
1356
0
  PluginIdentifier identifier;
1357
0
  if (!FromNPIdentifier(aName, &identifier)) {
1358
0
    return false;
1359
0
  }
1360
0
1361
0
  bool hasProperty, hasMethod, success;
1362
0
  Variant result;
1363
0
  if (!CallGetChildProperty(identifier, &hasProperty, &hasMethod, &result,
1364
0
                            &success)) {
1365
0
    return false;
1366
0
  }
1367
0
1368
0
  if (!success) {
1369
0
    return false;
1370
0
  }
1371
0
1372
0
  if (!ConvertToVariant(result, *aResult, GetInstance())) {
1373
0
    NS_WARNING("Failed to convert result!");
1374
0
    return false;
1375
0
  }
1376
0
1377
0
  *aHasProperty = hasProperty;
1378
0
  *aHasMethod = hasMethod;
1379
0
  return true;
1380
0
}