1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef nsNPAPIPlugin_h_
7 #define nsNPAPIPlugin_h_
8 
9 #include "prlink.h"
10 #include "npfunctions.h"
11 #include "nsPluginHost.h"
12 
13 #include "mozilla/dom/ScriptSettings.h"
14 #include "mozilla/PluginLibrary.h"
15 #include "mozilla/RefCounted.h"
16 
17 #if defined(XP_WIN)
18 #define NS_NPAPIPLUGIN_CALLBACK(_type, _name) _type (__stdcall * _name)
19 #else
20 #define NS_NPAPIPLUGIN_CALLBACK(_type, _name) _type (* _name)
21 #endif
22 
23 typedef NS_NPAPIPLUGIN_CALLBACK(NPError, NP_GETENTRYPOINTS) (NPPluginFuncs* pCallbacks);
24 typedef NS_NPAPIPLUGIN_CALLBACK(NPError, NP_PLUGININIT) (const NPNetscapeFuncs* pCallbacks);
25 typedef NS_NPAPIPLUGIN_CALLBACK(NPError, NP_PLUGINUNIXINIT) (const NPNetscapeFuncs* pCallbacks, NPPluginFuncs* fCallbacks);
26 typedef NS_NPAPIPLUGIN_CALLBACK(NPError, NP_PLUGINSHUTDOWN) ();
27 
28 // nsNPAPIPlugin is held alive both by active nsPluginTag instances and
29 // by active nsNPAPIPluginInstance.
30 class nsNPAPIPlugin final
31 {
32 private:
33   typedef mozilla::PluginLibrary PluginLibrary;
34 
35 public:
36   nsNPAPIPlugin();
37 
38   NS_INLINE_DECL_REFCOUNTING(nsNPAPIPlugin)
39 
40   // Constructs and initializes an nsNPAPIPlugin object. A nullptr file path
41   // will prevent this from calling NP_Initialize.
42   static nsresult CreatePlugin(nsPluginTag *aPluginTag, nsNPAPIPlugin** aResult);
43 
44   PluginLibrary* GetLibrary();
45   // PluginFuncs() can't fail but results are only valid if GetLibrary() succeeds
46   NPPluginFuncs* PluginFuncs();
47 
48 #if defined(XP_MACOSX) && !defined(__LP64__)
49   void SetPluginRefNum(short aRefNum);
50 #endif
51 
52   // The IPC mechanism notifies the nsNPAPIPlugin if the plugin
53   // crashes and is no longer usable. pluginDumpID/browserDumpID are
54   // the IDs of respective minidumps that were written, or empty if no
55   // minidump was written.
56   void PluginCrashed(const nsAString& pluginDumpID,
57                      const nsAString& browserDumpID);
58 
59   static bool RunPluginOOP(const nsPluginTag *aPluginTag);
60 
61   nsresult Shutdown();
62 
63   static nsresult RetainStream(NPStream *pstream, nsISupports **aRetainedPeer);
64 
65 private:
66   ~nsNPAPIPlugin();
67 
68   NPPluginFuncs mPluginFuncs;
69   PluginLibrary* mLibrary;
70 };
71 
72 namespace mozilla {
73 namespace plugins {
74 namespace parent {
75 
76 static_assert(sizeof(NPIdentifier) == sizeof(jsid),
77               "NPIdentifier must be binary compatible with jsid.");
78 
79 inline jsid
NPIdentifierToJSId(NPIdentifier id)80 NPIdentifierToJSId(NPIdentifier id)
81 {
82     jsid tmp;
83     JSID_BITS(tmp) = (size_t)id;
84     return tmp;
85 }
86 
87 inline NPIdentifier
JSIdToNPIdentifier(jsid id)88 JSIdToNPIdentifier(jsid id)
89 {
90     return (NPIdentifier)JSID_BITS(id);
91 }
92 
93 inline bool
NPIdentifierIsString(NPIdentifier id)94 NPIdentifierIsString(NPIdentifier id)
95 {
96     return JSID_IS_STRING(NPIdentifierToJSId(id));
97 }
98 
99 inline JSString *
NPIdentifierToString(NPIdentifier id)100 NPIdentifierToString(NPIdentifier id)
101 {
102     return JSID_TO_STRING(NPIdentifierToJSId(id));
103 }
104 
105 inline NPIdentifier
StringToNPIdentifier(JSContext * cx,JSString * str)106 StringToNPIdentifier(JSContext *cx, JSString *str)
107 {
108     return JSIdToNPIdentifier(INTERNED_STRING_TO_JSID(cx, str));
109 }
110 
111 inline bool
NPIdentifierIsInt(NPIdentifier id)112 NPIdentifierIsInt(NPIdentifier id)
113 {
114     return JSID_IS_INT(NPIdentifierToJSId(id));
115 }
116 
117 inline int
NPIdentifierToInt(NPIdentifier id)118 NPIdentifierToInt(NPIdentifier id)
119 {
120     return JSID_TO_INT(NPIdentifierToJSId(id));
121 }
122 
123 inline NPIdentifier
IntToNPIdentifier(int i)124 IntToNPIdentifier(int i)
125 {
126     return JSIdToNPIdentifier(INT_TO_JSID(i));
127 }
128 
129 JSContext* GetJSContext(NPP npp);
130 
131 inline bool
NPStringIdentifierIsPermanent(NPIdentifier id)132 NPStringIdentifierIsPermanent(NPIdentifier id)
133 {
134   AutoSafeJSContext cx;
135   return JS_StringHasBeenPinned(cx, NPIdentifierToString(id));
136 }
137 
138 #define NPIdentifier_VOID (JSIdToNPIdentifier(JSID_VOID))
139 
140 NPObject*
141 _getwindowobject(NPP npp);
142 
143 NPObject*
144 _getpluginelement(NPP npp);
145 
146 NPIdentifier
147 _getstringidentifier(const NPUTF8* name);
148 
149 void
150 _getstringidentifiers(const NPUTF8** names, int32_t nameCount,
151                       NPIdentifier *identifiers);
152 
153 bool
154 _identifierisstring(NPIdentifier identifiers);
155 
156 NPIdentifier
157 _getintidentifier(int32_t intid);
158 
159 NPUTF8*
160 _utf8fromidentifier(NPIdentifier identifier);
161 
162 int32_t
163 _intfromidentifier(NPIdentifier identifier);
164 
165 NPObject*
166 _createobject(NPP npp, NPClass* aClass);
167 
168 NPObject*
169 _retainobject(NPObject* npobj);
170 
171 void
172 _releaseobject(NPObject* npobj);
173 
174 bool
175 _invoke(NPP npp, NPObject* npobj, NPIdentifier method, const NPVariant *args,
176         uint32_t argCount, NPVariant *result);
177 
178 bool
179 _invokeDefault(NPP npp, NPObject* npobj, const NPVariant *args,
180                uint32_t argCount, NPVariant *result);
181 
182 bool
183 _evaluate(NPP npp, NPObject* npobj, NPString *script, NPVariant *result);
184 
185 bool
186 _getproperty(NPP npp, NPObject* npobj, NPIdentifier property,
187              NPVariant *result);
188 
189 bool
190 _setproperty(NPP npp, NPObject* npobj, NPIdentifier property,
191              const NPVariant *value);
192 
193 bool
194 _removeproperty(NPP npp, NPObject* npobj, NPIdentifier property);
195 
196 bool
197 _hasproperty(NPP npp, NPObject* npobj, NPIdentifier propertyName);
198 
199 bool
200 _hasmethod(NPP npp, NPObject* npobj, NPIdentifier methodName);
201 
202 bool
203 _enumerate(NPP npp, NPObject *npobj, NPIdentifier **identifier,
204            uint32_t *count);
205 
206 bool
207 _construct(NPP npp, NPObject* npobj, const NPVariant *args,
208            uint32_t argCount, NPVariant *result);
209 
210 void
211 _releasevariantvalue(NPVariant *variant);
212 
213 void
214 _setexception(NPObject* npobj, const NPUTF8 *message);
215 
216 void
217 _pushpopupsenabledstate(NPP npp, NPBool enabled);
218 
219 void
220 _poppopupsenabledstate(NPP npp);
221 
222 typedef void(*PluginThreadCallback)(void *);
223 
224 void
225 _pluginthreadasynccall(NPP instance, PluginThreadCallback func,
226                        void *userData);
227 
228 NPError
229 _getvalueforurl(NPP instance, NPNURLVariable variable, const char *url,
230                 char **value, uint32_t *len);
231 
232 NPError
233 _setvalueforurl(NPP instance, NPNURLVariable variable, const char *url,
234                 const char *value, uint32_t len);
235 
236 NPError
237 _getauthenticationinfo(NPP instance, const char *protocol, const char *host,
238                        int32_t port, const char *scheme, const char *realm,
239                        char **username, uint32_t *ulen, char **password,
240                        uint32_t *plen);
241 
242 typedef void(*PluginTimerFunc)(NPP npp, uint32_t timerID);
243 
244 uint32_t
245 _scheduletimer(NPP instance, uint32_t interval, NPBool repeat, PluginTimerFunc timerFunc);
246 
247 void
248 _unscheduletimer(NPP instance, uint32_t timerID);
249 
250 NPError
251 _popupcontextmenu(NPP instance, NPMenu* menu);
252 
253 NPBool
254 _convertpoint(NPP instance, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace);
255 
256 NPError
257 _requestread(NPStream *pstream, NPByteRange *rangeList);
258 
259 NPError
260 _geturlnotify(NPP npp, const char* relativeURL, const char* target,
261               void* notifyData);
262 
263 NPError
264 _getvalue(NPP npp, NPNVariable variable, void *r_value);
265 
266 NPError
267 _setvalue(NPP npp, NPPVariable variable, void *r_value);
268 
269 NPError
270 _geturl(NPP npp, const char* relativeURL, const char* target);
271 
272 NPError
273 _posturlnotify(NPP npp, const char* relativeURL, const char *target,
274                uint32_t len, const char *buf, NPBool file, void* notifyData);
275 
276 NPError
277 _posturl(NPP npp, const char* relativeURL, const char *target, uint32_t len,
278             const char *buf, NPBool file);
279 
280 NPError
281 _newstream(NPP npp, NPMIMEType type, const char* window, NPStream** pstream);
282 
283 int32_t
284 _write(NPP npp, NPStream *pstream, int32_t len, void *buffer);
285 
286 NPError
287 _destroystream(NPP npp, NPStream *pstream, NPError reason);
288 
289 void
290 _status(NPP npp, const char *message);
291 
292 void
293 _memfree (void *ptr);
294 
295 uint32_t
296 _memflush(uint32_t size);
297 
298 void
299 _reloadplugins(NPBool reloadPages);
300 
301 void
302 _invalidaterect(NPP npp, NPRect *invalidRect);
303 
304 void
305 _invalidateregion(NPP npp, NPRegion invalidRegion);
306 
307 void
308 _forceredraw(NPP npp);
309 
310 const char*
311 _useragent(NPP npp);
312 
313 void*
314 _memalloc (uint32_t size);
315 
316 // Deprecated entry points for the old Java plugin.
317 void* /* OJI type: JRIEnv* */
318 _getJavaEnv();
319 
320 void* /* OJI type: jref */
321 _getJavaPeer(NPP npp);
322 
323 void
324 _urlredirectresponse(NPP instance, void* notifyData, NPBool allow);
325 
326 NPError
327 _initasyncsurface(NPP instance, NPSize *size, NPImageFormat format, void *initData, NPAsyncSurface *surface);
328 
329 NPError
330 _finalizeasyncsurface(NPP instance, NPAsyncSurface *surface);
331 
332 void
333 _setcurrentasyncsurface(NPP instance, NPAsyncSurface *surface, NPRect *changed);
334 
335 } /* namespace parent */
336 } /* namespace plugins */
337 } /* namespace mozilla */
338 
339 const char *
340 PeekException();
341 
342 void
343 PopException();
344 
345 void
346 OnPluginDestroy(NPP instance);
347 
348 void
349 OnShutdown();
350 
351 /**
352  * within a lexical scope, locks and unlocks the mutex used to
353  * serialize modifications to plugin async callback state.
354  */
355 struct MOZ_STACK_CLASS AsyncCallbackAutoLock
356 {
357   AsyncCallbackAutoLock();
358   ~AsyncCallbackAutoLock();
359 };
360 
361 class NPPStack
362 {
363 public:
Peek()364   static NPP Peek()
365   {
366     return sCurrentNPP;
367   }
368 
369 protected:
370   static NPP sCurrentNPP;
371 };
372 
373 // XXXjst: The NPPAutoPusher stack is a bit redundant now that
374 // PluginDestructionGuard exists, and could thus be replaced by code
375 // that uses the PluginDestructionGuard list of plugins on the
376 // stack. But they're not identical, and to minimize code changes
377 // we're keeping both for the moment, and making NPPAutoPusher inherit
378 // the PluginDestructionGuard class to avoid having to keep two
379 // separate objects on the stack since we always want a
380 // PluginDestructionGuard where we use an NPPAutoPusher.
381 
382 class MOZ_STACK_CLASS NPPAutoPusher : public NPPStack,
383                                       protected PluginDestructionGuard
384 {
385 public:
NPPAutoPusher(NPP aNpp)386   explicit NPPAutoPusher(NPP aNpp)
387     : PluginDestructionGuard(aNpp),
388       mOldNPP(sCurrentNPP)
389   {
390     NS_ASSERTION(aNpp, "Uh, null aNpp passed to NPPAutoPusher!");
391 
392     sCurrentNPP = aNpp;
393   }
394 
~NPPAutoPusher()395   ~NPPAutoPusher()
396   {
397     sCurrentNPP = mOldNPP;
398   }
399 
400 private:
401   NPP mOldNPP;
402 };
403 
404 class NPPExceptionAutoHolder
405 {
406 public:
407   NPPExceptionAutoHolder();
408   ~NPPExceptionAutoHolder();
409 
410 protected:
411   char *mOldException;
412 };
413 
414 #endif // nsNPAPIPlugin_h_
415