Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/plugins/ipc/PluginScriptableObjectUtils.h
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
#ifndef dom_plugins_PluginScriptableObjectUtils_h
8
#define dom_plugins_PluginScriptableObjectUtils_h
9
10
#include "PluginModuleParent.h"
11
#include "PluginModuleChild.h"
12
#include "PluginInstanceParent.h"
13
#include "PluginInstanceChild.h"
14
#include "PluginScriptableObjectParent.h"
15
#include "PluginScriptableObjectChild.h"
16
17
#include "npapi.h"
18
#include "npfunctions.h"
19
#include "npruntime.h"
20
21
#include "nsDebug.h"
22
23
namespace mozilla {
24
namespace plugins {
25
26
inline PluginInstanceParent*
27
GetInstance(NPObject* aObject)
28
0
{
29
0
  NS_ASSERTION(aObject->_class == PluginScriptableObjectParent::GetClass(),
30
0
               "Bad class!");
31
0
32
0
  ParentNPObject* object = reinterpret_cast<ParentNPObject*>(aObject);
33
0
  if (object->invalidated) {
34
0
    NS_WARNING("Calling method on an invalidated object!");
35
0
    return nullptr;
36
0
  }
37
0
  if (!object->parent) {
38
0
    return nullptr;
39
0
  }
40
0
  return object->parent->GetInstance();
41
0
}
42
43
inline NPObject*
44
NPObjectFromVariant(const Variant& aRemoteVariant)
45
0
{
46
0
  switch (aRemoteVariant.type()) {
47
0
    case Variant::TPPluginScriptableObjectParent: {
48
0
      PluginScriptableObjectParent* actor =
49
0
        const_cast<PluginScriptableObjectParent*>(
50
0
          reinterpret_cast<const PluginScriptableObjectParent*>(
51
0
            aRemoteVariant.get_PPluginScriptableObjectParent()));
52
0
      return actor->GetObject(true);
53
0
    }
54
0
55
0
    case Variant::TPPluginScriptableObjectChild: {
56
0
      PluginScriptableObjectChild* actor =
57
0
        const_cast<PluginScriptableObjectChild*>(
58
0
          reinterpret_cast<const PluginScriptableObjectChild*>(
59
0
            aRemoteVariant.get_PPluginScriptableObjectChild()));
60
0
      return actor->GetObject(true);
61
0
    }
62
0
63
0
    default:
64
0
      MOZ_ASSERT_UNREACHABLE("Shouldn't get here!");
65
0
      return nullptr;
66
0
  }
67
0
}
68
69
inline NPObject*
70
NPObjectFromVariant(const NPVariant& aVariant)
71
0
{
72
0
  NS_ASSERTION(NPVARIANT_IS_OBJECT(aVariant), "Wrong variant type!");
73
0
  return NPVARIANT_TO_OBJECT(aVariant);
74
0
}
75
76
inline const NPNetscapeFuncs*
77
GetNetscapeFuncs(PluginInstanceParent* aInstance)
78
0
{
79
0
  PluginModuleParent* module = aInstance->Module();
80
0
  if (!module) {
81
0
    NS_WARNING("Null module?!");
82
0
    return nullptr;
83
0
  }
84
0
  return module->GetNetscapeFuncs();
85
0
}
86
87
inline const NPNetscapeFuncs*
88
GetNetscapeFuncs(NPObject* aObject)
89
0
{
90
0
  NS_ASSERTION(aObject->_class == PluginScriptableObjectParent::GetClass(),
91
0
               "Bad class!");
92
0
93
0
  PluginInstanceParent* instance = GetInstance(aObject);
94
0
  if (!instance) {
95
0
    return nullptr;
96
0
  }
97
0
98
0
  return GetNetscapeFuncs(instance);
99
0
}
100
101
inline void
102
ReleaseRemoteVariant(Variant& aVariant)
103
0
{
104
0
  switch (aVariant.type()) {
105
0
    case Variant::TPPluginScriptableObjectParent: {
106
0
      PluginScriptableObjectParent* actor =
107
0
        const_cast<PluginScriptableObjectParent*>(
108
0
          reinterpret_cast<const PluginScriptableObjectParent*>(
109
0
            aVariant.get_PPluginScriptableObjectParent()));
110
0
      actor->Unprotect();
111
0
      break;
112
0
    }
113
0
114
0
    case Variant::TPPluginScriptableObjectChild: {
115
0
      NS_ASSERTION(XRE_GetProcessType() == GeckoProcessType_Plugin,
116
0
                   "Should only be running in the child!");
117
0
      PluginScriptableObjectChild* actor =
118
0
        const_cast<PluginScriptableObjectChild*>(
119
0
          reinterpret_cast<const PluginScriptableObjectChild*>(
120
0
            aVariant.get_PPluginScriptableObjectChild()));
121
0
      actor->Unprotect();
122
0
      break;
123
0
    }
124
0
125
0
  default:
126
0
    break; // Intentional fall-through for other variant types.
127
0
  }
128
0
129
0
  aVariant = mozilla::void_t();
130
0
}
131
132
bool
133
ConvertToVariant(const Variant& aRemoteVariant,
134
                 NPVariant& aVariant,
135
                 PluginInstanceParent* aInstance = nullptr);
136
137
template <class InstanceType>
138
bool
139
ConvertToRemoteVariant(const NPVariant& aVariant,
140
                       Variant& aRemoteVariant,
141
                       InstanceType* aInstance,
142
                       bool aProtectActors = false);
143
144
class ProtectedVariant
145
{
146
public:
147
  ProtectedVariant(const NPVariant& aVariant,
148
                   PluginInstanceParent* aInstance)
149
0
  {
150
0
    mOk = ConvertToRemoteVariant(aVariant, mVariant, aInstance, true);
151
0
  }
152
153
  ProtectedVariant(const NPVariant& aVariant,
154
                   PluginInstanceChild* aInstance)
155
0
  {
156
0
    mOk = ConvertToRemoteVariant(aVariant, mVariant, aInstance, true);
157
0
  }
158
159
0
  ~ProtectedVariant() {
160
0
    ReleaseRemoteVariant(mVariant);
161
0
  }
162
163
0
  bool IsOk() {
164
0
    return mOk;
165
0
  }
166
167
0
  operator const Variant&() {
168
0
    return mVariant;
169
0
  }
170
171
private:
172
  Variant mVariant;
173
  bool mOk;
174
};
175
176
class ProtectedVariantArray
177
{
178
public:
179
  ProtectedVariantArray(const NPVariant* aArgs,
180
                        uint32_t aCount,
181
                        PluginInstanceParent* aInstance)
182
    : mUsingShadowArray(false)
183
0
  {
184
0
    for (uint32_t index = 0; index < aCount; index++) {
185
0
      Variant* remoteVariant = mArray.AppendElement();
186
0
      if (!(remoteVariant &&
187
0
            ConvertToRemoteVariant(aArgs[index], *remoteVariant, aInstance,
188
0
                                   true))) {
189
0
        mOk = false;
190
0
        return;
191
0
      }
192
0
    }
193
0
    mOk = true;
194
0
  }
195
196
  ProtectedVariantArray(const NPVariant* aArgs,
197
                        uint32_t aCount,
198
                        PluginInstanceChild* aInstance)
199
    : mUsingShadowArray(false)
200
0
  {
201
0
    for (uint32_t index = 0; index < aCount; index++) {
202
0
      Variant* remoteVariant = mArray.AppendElement();
203
0
      if (!(remoteVariant &&
204
0
            ConvertToRemoteVariant(aArgs[index], *remoteVariant, aInstance,
205
0
                                   true))) {
206
0
        mOk = false;
207
0
        return;
208
0
      }
209
0
    }
210
0
    mOk = true;
211
0
  }
212
213
  ~ProtectedVariantArray()
214
0
  {
215
0
    InfallibleTArray<Variant>& vars = EnsureAndGetShadowArray();
216
0
    uint32_t count = vars.Length();
217
0
    for (uint32_t index = 0; index < count; index++) {
218
0
      ReleaseRemoteVariant(vars[index]);
219
0
    }
220
0
  }
221
222
  operator const InfallibleTArray<Variant>&()
223
0
  {
224
0
    return EnsureAndGetShadowArray();
225
0
  }
226
227
  bool IsOk()
228
0
  {
229
0
    return mOk;
230
0
  }
231
232
private:
233
  InfallibleTArray<Variant>&
234
  EnsureAndGetShadowArray()
235
0
  {
236
0
    if (!mUsingShadowArray) {
237
0
      mShadowArray.SwapElements(mArray);
238
0
      mUsingShadowArray = true;
239
0
    }
240
0
    return mShadowArray;
241
0
  }
242
243
  // We convert the variants fallibly, but pass them to Call*()
244
  // methods as an infallible array
245
  nsTArray<Variant> mArray;
246
  InfallibleTArray<Variant> mShadowArray;
247
  bool mOk;
248
  bool mUsingShadowArray;
249
};
250
251
template<class ActorType>
252
struct ProtectedActorTraits
253
{
254
  static bool Nullable();
255
};
256
257
template<class ActorType, class Traits=ProtectedActorTraits<ActorType> >
258
class ProtectedActor
259
{
260
public:
261
  explicit ProtectedActor(ActorType* aActor) : mActor(aActor)
262
0
  {
263
0
    if (!Traits::Nullable()) {
264
0
      NS_ASSERTION(mActor, "This should never be null!");
265
0
    }
266
0
  }
Unexecuted instantiation: mozilla::plugins::ProtectedActor<mozilla::plugins::PluginScriptableObjectChild, mozilla::plugins::ProtectedActorTraits<mozilla::plugins::PluginScriptableObjectChild> >::ProtectedActor(mozilla::plugins::PluginScriptableObjectChild*)
Unexecuted instantiation: mozilla::plugins::ProtectedActor<mozilla::plugins::PluginScriptableObjectParent, mozilla::plugins::ProtectedActorTraits<mozilla::plugins::PluginScriptableObjectParent> >::ProtectedActor(mozilla::plugins::PluginScriptableObjectParent*)
267
268
  ~ProtectedActor()
269
0
  {
270
0
    if (Traits::Nullable() && !mActor)
271
0
      return;
272
0
    mActor->Unprotect();
273
0
  }
Unexecuted instantiation: mozilla::plugins::ProtectedActor<mozilla::plugins::PluginScriptableObjectChild, mozilla::plugins::ProtectedActorTraits<mozilla::plugins::PluginScriptableObjectChild> >::~ProtectedActor()
Unexecuted instantiation: mozilla::plugins::ProtectedActor<mozilla::plugins::PluginScriptableObjectParent, mozilla::plugins::ProtectedActorTraits<mozilla::plugins::PluginScriptableObjectParent> >::~ProtectedActor()
274
275
  ActorType* operator->()
276
0
  {
277
0
    return mActor;
278
0
  }
Unexecuted instantiation: mozilla::plugins::ProtectedActor<mozilla::plugins::PluginScriptableObjectChild, mozilla::plugins::ProtectedActorTraits<mozilla::plugins::PluginScriptableObjectChild> >::operator->()
Unexecuted instantiation: mozilla::plugins::ProtectedActor<mozilla::plugins::PluginScriptableObjectParent, mozilla::plugins::ProtectedActorTraits<mozilla::plugins::PluginScriptableObjectParent> >::operator->()
279
280
  explicit operator bool()
281
0
  {
282
0
    return !!mActor;
283
0
  }
284
285
private:
286
  ActorType* mActor;
287
};
288
289
template<>
290
struct ProtectedActorTraits<PluginScriptableObjectParent>
291
{
292
0
  static bool Nullable() { return true; }
293
};
294
295
template<>
296
struct ProtectedActorTraits<PluginScriptableObjectChild>
297
{
298
0
  static bool Nullable() { return false; }
299
};
300
301
} /* namespace plugins */
302
} /* namespace mozilla */
303
304
#include "PluginScriptableObjectUtils-inl.h"
305
306
#endif /* dom_plugins_PluginScriptableObjectUtils_h */