Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* vim: set ts=8 sts=4 et sw=4 tw=99: */
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 : /* The "Components" xpcom objects for JavaScript. */
8 :
9 : #include "xpcprivate.h"
10 : #include "xpc_make_class.h"
11 : #include "xpcIJSModuleLoader.h"
12 : #include "XPCJSWeakReference.h"
13 : #include "WrapperFactory.h"
14 : #include "nsJSUtils.h"
15 : #include "mozJSComponentLoader.h"
16 : #include "nsContentUtils.h"
17 : #include "nsCycleCollector.h"
18 : #include "jsfriendapi.h"
19 : #include "js/StructuredClone.h"
20 : #include "mozilla/Attributes.h"
21 : #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
22 : #include "mozilla/Preferences.h"
23 : #include "nsJSEnvironment.h"
24 : #include "mozilla/TimeStamp.h"
25 : #include "mozilla/XPTInterfaceInfoManager.h"
26 : #include "mozilla/dom/DOMException.h"
27 : #include "mozilla/dom/DOMExceptionBinding.h"
28 : #include "mozilla/dom/BindingUtils.h"
29 : #include "mozilla/dom/StructuredCloneTags.h"
30 : #include "mozilla/dom/WindowBinding.h"
31 : #include "nsZipArchive.h"
32 : #include "nsIDOMFileList.h"
33 : #include "nsWindowMemoryReporter.h"
34 : #include "nsDOMClassInfo.h"
35 : #include "ShimInterfaceInfo.h"
36 : #include "nsIAddonInterposition.h"
37 : #include "nsIScriptError.h"
38 : #include "nsISimpleEnumerator.h"
39 : #include "nsPIDOMWindow.h"
40 : #include "nsGlobalWindow.h"
41 : #include "nsScriptError.h"
42 : #include "GeckoProfiler.h"
43 :
44 : using namespace mozilla;
45 : using namespace JS;
46 : using namespace js;
47 : using namespace xpc;
48 : using mozilla::dom::Exception;
49 :
50 : /***************************************************************************/
51 : // stuff used by all
52 :
53 : nsresult
54 0 : xpc::ThrowAndFail(nsresult errNum, JSContext* cx, bool* retval)
55 : {
56 0 : XPCThrower::Throw(errNum, cx);
57 0 : *retval = false;
58 0 : return NS_OK;
59 : }
60 :
61 : static bool
62 57 : JSValIsInterfaceOfType(JSContext* cx, HandleValue v, REFNSIID iid)
63 : {
64 :
65 114 : nsCOMPtr<nsIXPConnectWrappedNative> wn;
66 114 : nsCOMPtr<nsISupports> iface;
67 :
68 57 : if (v.isPrimitive())
69 0 : return false;
70 :
71 57 : nsXPConnect* xpc = nsXPConnect::XPConnect();
72 114 : RootedObject obj(cx, &v.toObject());
73 399 : return NS_SUCCEEDED(xpc->GetWrappedNativeOfJSObject(cx, obj, getter_AddRefs(wn))) && wn &&
74 342 : NS_SUCCEEDED(wn->Native()->QueryInterface(iid, getter_AddRefs(iface))) && iface;
75 : }
76 :
77 : char*
78 0 : xpc::CloneAllAccess()
79 : {
80 : static const char allAccess[] = "AllAccess";
81 0 : return (char*)nsMemory::Clone(allAccess, sizeof(allAccess));
82 : }
83 :
84 : char*
85 0 : xpc::CheckAccessList(const char16_t* wideName, const char* const list[])
86 : {
87 0 : nsAutoCString asciiName;
88 0 : CopyUTF16toUTF8(nsDependentString(wideName), asciiName);
89 :
90 0 : for (const char* const* p = list; *p; p++)
91 0 : if (!strcmp(*p, asciiName.get()))
92 0 : return CloneAllAccess();
93 :
94 0 : return nullptr;
95 : }
96 :
97 : /***************************************************************************/
98 : /***************************************************************************/
99 : /***************************************************************************/
100 :
101 :
102 : class nsXPCComponents_Interfaces final :
103 : public nsIXPCComponents_Interfaces,
104 : public nsIXPCScriptable,
105 : public nsIClassInfo
106 : {
107 : public:
108 : // all the interface method declarations...
109 : NS_DECL_ISUPPORTS
110 : NS_DECL_NSIXPCCOMPONENTS_INTERFACES
111 : NS_DECL_NSIXPCSCRIPTABLE
112 : NS_DECL_NSICLASSINFO
113 :
114 : public:
115 : nsXPCComponents_Interfaces();
116 :
117 : private:
118 : virtual ~nsXPCComponents_Interfaces();
119 :
120 : nsCOMArray<nsIInterfaceInfo> mInterfaces;
121 : };
122 :
123 : NS_IMETHODIMP
124 237 : nsXPCComponents_Interfaces::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
125 : {
126 237 : const uint32_t count = 2;
127 237 : *aCount = count;
128 : nsIID** array;
129 237 : *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
130 237 : if (!array)
131 0 : return NS_ERROR_OUT_OF_MEMORY;
132 :
133 237 : uint32_t index = 0;
134 : nsIID* clone;
135 : #define PUSH_IID(id) \
136 : clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ), \
137 : sizeof(nsIID))); \
138 : if (!clone) \
139 : goto oom; \
140 : array[index++] = clone;
141 :
142 237 : PUSH_IID(nsIXPCComponents_Interfaces)
143 237 : PUSH_IID(nsIXPCScriptable)
144 : #undef PUSH_IID
145 :
146 237 : return NS_OK;
147 : oom:
148 0 : while (index)
149 0 : free(array[--index]);
150 0 : free(array);
151 0 : *aArray = nullptr;
152 0 : return NS_ERROR_OUT_OF_MEMORY;
153 : }
154 :
155 : NS_IMETHODIMP
156 238 : nsXPCComponents_Interfaces::GetScriptableHelper(nsIXPCScriptable** retval)
157 : {
158 238 : *retval = nullptr;
159 238 : return NS_OK;
160 : }
161 :
162 : NS_IMETHODIMP
163 0 : nsXPCComponents_Interfaces::GetContractID(char * *aContractID)
164 : {
165 0 : *aContractID = nullptr;
166 0 : return NS_ERROR_NOT_AVAILABLE;
167 : }
168 :
169 : NS_IMETHODIMP
170 0 : nsXPCComponents_Interfaces::GetClassDescription(char * *aClassDescription)
171 : {
172 : static const char classDescription[] = "XPCComponents_Interfaces";
173 0 : *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
174 0 : return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
175 : }
176 :
177 : NS_IMETHODIMP
178 0 : nsXPCComponents_Interfaces::GetClassID(nsCID * *aClassID)
179 : {
180 0 : *aClassID = nullptr;
181 0 : return NS_OK;
182 : }
183 :
184 : NS_IMETHODIMP
185 238 : nsXPCComponents_Interfaces::GetFlags(uint32_t* aFlags)
186 : {
187 : // Mark ourselves as a DOM object so that instances may be created in
188 : // unprivileged scopes.
189 238 : *aFlags = nsIClassInfo::DOM_OBJECT;
190 238 : return NS_OK;
191 : }
192 :
193 : NS_IMETHODIMP
194 0 : nsXPCComponents_Interfaces::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
195 : {
196 0 : return NS_ERROR_NOT_AVAILABLE;
197 : }
198 :
199 237 : nsXPCComponents_Interfaces::nsXPCComponents_Interfaces()
200 : {
201 237 : }
202 :
203 0 : nsXPCComponents_Interfaces::~nsXPCComponents_Interfaces()
204 : {
205 : // empty
206 0 : }
207 :
208 :
209 5585 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Interfaces)
210 5585 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Interfaces)
211 5338 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
212 2361 : NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
213 1885 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Interfaces)
214 1416 : NS_INTERFACE_MAP_END
215 :
216 7847 : NS_IMPL_ADDREF(nsXPCComponents_Interfaces)
217 6658 : NS_IMPL_RELEASE(nsXPCComponents_Interfaces)
218 :
219 : // The nsIXPCScriptable map declaration that will generate stubs for us...
220 : #define XPC_MAP_CLASSNAME nsXPCComponents_Interfaces
221 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Interfaces"
222 : #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_RESOLVE | \
223 : XPC_SCRIPTABLE_WANT_NEWENUMERATE | \
224 : XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
225 : #include "xpc_map_end.h" /* This will #undef the above */
226 :
227 :
228 : NS_IMETHODIMP
229 0 : nsXPCComponents_Interfaces::NewEnumerate(nsIXPConnectWrappedNative* wrapper,
230 : JSContext* cx, JSObject* obj,
231 : JS::AutoIdVector& properties,
232 : bool* _retval)
233 : {
234 :
235 : // Lazily init the list of interfaces when someone tries to
236 : // enumerate them.
237 0 : if (mInterfaces.IsEmpty()) {
238 : XPTInterfaceInfoManager::GetSingleton()->
239 0 : GetScriptableInterfaces(mInterfaces);
240 : }
241 :
242 0 : if (!properties.reserve(mInterfaces.Length())) {
243 0 : *_retval = false;
244 0 : return NS_OK;
245 : }
246 :
247 0 : for (uint32_t index = 0; index < mInterfaces.Length(); index++) {
248 0 : nsIInterfaceInfo* interface = mInterfaces.SafeElementAt(index);
249 0 : if (!interface)
250 0 : continue;
251 :
252 : const char* name;
253 0 : if (NS_SUCCEEDED(interface->GetNameShared(&name)) && name) {
254 0 : RootedString idstr(cx, JS_NewStringCopyZ(cx, name));
255 0 : if (!idstr) {
256 0 : *_retval = false;
257 0 : return NS_OK;
258 : }
259 :
260 0 : RootedId id(cx);
261 0 : if (!JS_StringToId(cx, idstr, &id)) {
262 0 : *_retval = false;
263 0 : return NS_OK;
264 : }
265 :
266 0 : properties.infallibleAppend(id);
267 : }
268 : }
269 :
270 0 : return NS_OK;
271 : }
272 :
273 : NS_IMETHODIMP
274 754 : nsXPCComponents_Interfaces::Resolve(nsIXPConnectWrappedNative* wrapper,
275 : JSContext* cx, JSObject* objArg,
276 : jsid idArg, bool* resolvedp,
277 : bool* _retval)
278 : {
279 1508 : RootedObject obj(cx, objArg);
280 1508 : RootedId id(cx, idArg);
281 :
282 754 : if (!JSID_IS_STRING(id))
283 0 : return NS_OK;
284 :
285 1508 : JSAutoByteString name;
286 1508 : RootedString str(cx, JSID_TO_STRING(id));
287 :
288 : // we only allow interfaces by name here
289 754 : if (name.encodeLatin1(cx, str) && name.ptr()[0] != '{') {
290 : nsCOMPtr<nsIInterfaceInfo> info =
291 1505 : ShimInterfaceInfo::MaybeConstruct(name.ptr(), cx);
292 754 : if (!info) {
293 : XPTInterfaceInfoManager::GetSingleton()->
294 744 : GetInfoForName(name.ptr(), getter_AddRefs(info));
295 : }
296 754 : if (!info)
297 3 : return NS_OK;
298 :
299 1502 : nsCOMPtr<nsIJSIID> nsid = nsJSIID::NewID(info);
300 :
301 751 : if (nsid) {
302 751 : nsXPConnect* xpc = nsXPConnect::XPConnect();
303 1502 : RootedObject idobj(cx);
304 751 : if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
305 : static_cast<nsIJSIID*>(nsid),
306 : NS_GET_IID(nsIJSIID),
307 : idobj.address()))) {
308 751 : if (idobj) {
309 751 : *resolvedp = true;
310 751 : *_retval = JS_DefinePropertyById(cx, obj, id, idobj,
311 : JSPROP_ENUMERATE |
312 : JSPROP_READONLY |
313 : JSPROP_PERMANENT |
314 : JSPROP_RESOLVING);
315 : }
316 : }
317 : }
318 : }
319 751 : return NS_OK;
320 : }
321 :
322 : /***************************************************************************/
323 : /***************************************************************************/
324 : /***************************************************************************/
325 :
326 : class nsXPCComponents_InterfacesByID final :
327 : public nsIXPCComponents_InterfacesByID,
328 : public nsIXPCScriptable,
329 : public nsIClassInfo
330 : {
331 : public:
332 : // all the interface method declarations...
333 : NS_DECL_ISUPPORTS
334 : NS_DECL_NSIXPCCOMPONENTS_INTERFACESBYID
335 : NS_DECL_NSIXPCSCRIPTABLE
336 : NS_DECL_NSICLASSINFO
337 :
338 : public:
339 : nsXPCComponents_InterfacesByID();
340 :
341 : private:
342 : virtual ~nsXPCComponents_InterfacesByID();
343 :
344 : nsCOMArray<nsIInterfaceInfo> mInterfaces;
345 : };
346 :
347 : /***************************************************************************/
348 : NS_IMETHODIMP
349 0 : nsXPCComponents_InterfacesByID::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
350 : {
351 0 : const uint32_t count = 2;
352 0 : *aCount = count;
353 : nsIID** array;
354 0 : *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
355 0 : if (!array)
356 0 : return NS_ERROR_OUT_OF_MEMORY;
357 :
358 0 : uint32_t index = 0;
359 : nsIID* clone;
360 : #define PUSH_IID(id) \
361 : clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ), \
362 : sizeof(nsIID))); \
363 : if (!clone) \
364 : goto oom; \
365 : array[index++] = clone;
366 :
367 0 : PUSH_IID(nsIXPCComponents_InterfacesByID)
368 0 : PUSH_IID(nsIXPCScriptable)
369 : #undef PUSH_IID
370 :
371 0 : return NS_OK;
372 : oom:
373 0 : while (index)
374 0 : free(array[--index]);
375 0 : free(array);
376 0 : *aArray = nullptr;
377 0 : return NS_ERROR_OUT_OF_MEMORY;
378 : }
379 :
380 : NS_IMETHODIMP
381 0 : nsXPCComponents_InterfacesByID::GetScriptableHelper(nsIXPCScriptable** retval)
382 : {
383 0 : *retval = nullptr;
384 0 : return NS_OK;
385 : }
386 :
387 : NS_IMETHODIMP
388 0 : nsXPCComponents_InterfacesByID::GetContractID(char * *aContractID)
389 : {
390 0 : *aContractID = nullptr;
391 0 : return NS_ERROR_NOT_AVAILABLE;
392 : }
393 :
394 : NS_IMETHODIMP
395 0 : nsXPCComponents_InterfacesByID::GetClassDescription(char * *aClassDescription)
396 : {
397 : static const char classDescription[] = "XPCComponents_InterfacesByID";
398 0 : *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
399 0 : return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
400 : }
401 :
402 : NS_IMETHODIMP
403 0 : nsXPCComponents_InterfacesByID::GetClassID(nsCID * *aClassID)
404 : {
405 0 : *aClassID = nullptr;
406 0 : return NS_OK;
407 : }
408 :
409 : NS_IMETHODIMP
410 0 : nsXPCComponents_InterfacesByID::GetFlags(uint32_t* aFlags)
411 : {
412 : // Mark ourselves as a DOM object so that instances may be created in
413 : // unprivileged scopes.
414 0 : *aFlags = nsIClassInfo::DOM_OBJECT;
415 0 : return NS_OK;
416 : }
417 :
418 : NS_IMETHODIMP
419 0 : nsXPCComponents_InterfacesByID::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
420 : {
421 0 : return NS_ERROR_NOT_AVAILABLE;
422 : }
423 :
424 0 : nsXPCComponents_InterfacesByID::nsXPCComponents_InterfacesByID()
425 : {
426 0 : }
427 :
428 0 : nsXPCComponents_InterfacesByID::~nsXPCComponents_InterfacesByID()
429 : {
430 : // empty
431 0 : }
432 :
433 0 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_InterfacesByID)
434 0 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_InterfacesByID)
435 0 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
436 0 : NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
437 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_InterfacesByID)
438 0 : NS_INTERFACE_MAP_END
439 :
440 0 : NS_IMPL_ADDREF(nsXPCComponents_InterfacesByID)
441 0 : NS_IMPL_RELEASE(nsXPCComponents_InterfacesByID)
442 :
443 : // The nsIXPCScriptable map declaration that will generate stubs for us...
444 : #define XPC_MAP_CLASSNAME nsXPCComponents_InterfacesByID
445 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_InterfacesByID"
446 : #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_RESOLVE | \
447 : XPC_SCRIPTABLE_WANT_NEWENUMERATE | \
448 : XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
449 : #include "xpc_map_end.h" /* This will #undef the above */
450 :
451 : NS_IMETHODIMP
452 0 : nsXPCComponents_InterfacesByID::NewEnumerate(nsIXPConnectWrappedNative* wrapper,
453 : JSContext* cx, JSObject* obj,
454 : JS::AutoIdVector& properties,
455 : bool* _retval)
456 : {
457 :
458 0 : if (mInterfaces.IsEmpty()) {
459 : XPTInterfaceInfoManager::GetSingleton()->
460 0 : GetScriptableInterfaces(mInterfaces);
461 : }
462 :
463 0 : if (!properties.reserve(mInterfaces.Length())) {
464 0 : *_retval = false;
465 0 : return NS_OK;
466 : }
467 :
468 0 : for (uint32_t index = 0; index < mInterfaces.Length(); index++) {
469 0 : nsIInterfaceInfo* interface = mInterfaces.SafeElementAt(index);
470 0 : if (!interface)
471 0 : continue;
472 :
473 : nsIID const* iid;
474 0 : if (NS_SUCCEEDED(interface->GetIIDShared(&iid))) {
475 : char idstr[NSID_LENGTH];
476 0 : iid->ToProvidedString(idstr);
477 0 : RootedString jsstr(cx, JS_NewStringCopyZ(cx, idstr));
478 0 : if (!jsstr) {
479 0 : *_retval = false;
480 0 : return NS_OK;
481 : }
482 :
483 0 : RootedId id(cx);
484 0 : if (!JS_StringToId(cx, jsstr, &id)) {
485 0 : *_retval = false;
486 0 : return NS_OK;
487 : }
488 :
489 0 : properties.infallibleAppend(id);
490 : }
491 : }
492 :
493 0 : return NS_OK;
494 : }
495 :
496 : NS_IMETHODIMP
497 0 : nsXPCComponents_InterfacesByID::Resolve(nsIXPConnectWrappedNative* wrapper,
498 : JSContext* cx, JSObject* objArg,
499 : jsid idArg, bool* resolvedp,
500 : bool* _retval)
501 : {
502 0 : RootedObject obj(cx, objArg);
503 0 : RootedId id(cx, idArg);
504 :
505 0 : if (!JSID_IS_STRING(id))
506 0 : return NS_OK;
507 :
508 0 : RootedString str(cx, JSID_TO_STRING(id));
509 0 : if (38 != JS_GetStringLength(str))
510 0 : return NS_OK;
511 :
512 0 : JSAutoByteString utf8str;
513 0 : if (utf8str.encodeUtf8(cx, str)) {
514 : nsID iid;
515 0 : if (!iid.Parse(utf8str.ptr()))
516 0 : return NS_OK;
517 :
518 0 : nsCOMPtr<nsIInterfaceInfo> info;
519 : XPTInterfaceInfoManager::GetSingleton()->
520 0 : GetInfoForIID(&iid, getter_AddRefs(info));
521 0 : if (!info)
522 0 : return NS_OK;
523 :
524 0 : nsCOMPtr<nsIJSIID> nsid = nsJSIID::NewID(info);
525 :
526 0 : if (!nsid)
527 0 : return NS_ERROR_OUT_OF_MEMORY;
528 :
529 0 : nsXPConnect* xpc = nsXPConnect::XPConnect();
530 0 : RootedObject idobj(cx);
531 0 : if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
532 : static_cast<nsIJSIID*>(nsid),
533 : NS_GET_IID(nsIJSIID),
534 : idobj.address()))) {
535 0 : if (idobj) {
536 0 : *resolvedp = true;
537 0 : *_retval =
538 0 : JS_DefinePropertyById(cx, obj, id, idobj,
539 : JSPROP_ENUMERATE |
540 : JSPROP_READONLY |
541 : JSPROP_PERMANENT |
542 : JSPROP_RESOLVING);
543 : }
544 : }
545 : }
546 0 : return NS_OK;
547 : }
548 :
549 : /***************************************************************************/
550 : /***************************************************************************/
551 : /***************************************************************************/
552 :
553 :
554 :
555 : class nsXPCComponents_Classes final :
556 : public nsIXPCComponents_Classes,
557 : public nsIXPCScriptable,
558 : public nsIClassInfo
559 : {
560 : public:
561 : // all the interface method declarations...
562 : NS_DECL_ISUPPORTS
563 : NS_DECL_NSIXPCCOMPONENTS_CLASSES
564 : NS_DECL_NSIXPCSCRIPTABLE
565 : NS_DECL_NSICLASSINFO
566 :
567 : public:
568 : nsXPCComponents_Classes();
569 :
570 : private:
571 : virtual ~nsXPCComponents_Classes();
572 : };
573 :
574 : /***************************************************************************/
575 : NS_IMETHODIMP
576 214 : nsXPCComponents_Classes::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
577 : {
578 214 : const uint32_t count = 2;
579 214 : *aCount = count;
580 : nsIID** array;
581 214 : *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
582 214 : if (!array)
583 0 : return NS_ERROR_OUT_OF_MEMORY;
584 :
585 214 : uint32_t index = 0;
586 : nsIID* clone;
587 : #define PUSH_IID(id) \
588 : clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ), \
589 : sizeof(nsIID))); \
590 : if (!clone) \
591 : goto oom; \
592 : array[index++] = clone;
593 :
594 214 : PUSH_IID(nsIXPCComponents_Classes)
595 214 : PUSH_IID(nsIXPCScriptable)
596 : #undef PUSH_IID
597 :
598 214 : return NS_OK;
599 : oom:
600 0 : while (index)
601 0 : free(array[--index]);
602 0 : free(array);
603 0 : *aArray = nullptr;
604 0 : return NS_ERROR_OUT_OF_MEMORY;
605 : }
606 :
607 : NS_IMETHODIMP
608 215 : nsXPCComponents_Classes::GetScriptableHelper(nsIXPCScriptable** retval)
609 : {
610 215 : *retval = nullptr;
611 215 : return NS_OK;
612 : }
613 :
614 : NS_IMETHODIMP
615 0 : nsXPCComponents_Classes::GetContractID(char * *aContractID)
616 : {
617 0 : *aContractID = nullptr;
618 0 : return NS_ERROR_NOT_AVAILABLE;
619 : }
620 :
621 : NS_IMETHODIMP
622 0 : nsXPCComponents_Classes::GetClassDescription(char * *aClassDescription)
623 : {
624 : static const char classDescription[] = "XPCComponents_Classes";
625 0 : *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
626 0 : return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
627 : }
628 :
629 : NS_IMETHODIMP
630 0 : nsXPCComponents_Classes::GetClassID(nsCID * *aClassID)
631 : {
632 0 : *aClassID = nullptr;
633 0 : return NS_OK;
634 : }
635 :
636 : NS_IMETHODIMP
637 215 : nsXPCComponents_Classes::GetFlags(uint32_t* aFlags)
638 : {
639 215 : *aFlags = 0;
640 215 : return NS_OK;
641 : }
642 :
643 : NS_IMETHODIMP
644 0 : nsXPCComponents_Classes::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
645 : {
646 0 : return NS_ERROR_NOT_AVAILABLE;
647 : }
648 :
649 214 : nsXPCComponents_Classes::nsXPCComponents_Classes()
650 : {
651 214 : }
652 :
653 0 : nsXPCComponents_Classes::~nsXPCComponents_Classes()
654 : {
655 : // empty
656 0 : }
657 :
658 3189 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Classes)
659 3189 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Classes)
660 2965 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
661 1712 : NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
662 1282 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Classes)
663 998 : NS_INTERFACE_MAP_END
664 :
665 3939 : NS_IMPL_ADDREF(nsXPCComponents_Classes)
666 2865 : NS_IMPL_RELEASE(nsXPCComponents_Classes)
667 :
668 : // The nsIXPCScriptable map declaration that will generate stubs for us...
669 : #define XPC_MAP_CLASSNAME nsXPCComponents_Classes
670 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Classes"
671 : #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_RESOLVE | \
672 : XPC_SCRIPTABLE_WANT_NEWENUMERATE | \
673 : XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
674 : #include "xpc_map_end.h" /* This will #undef the above */
675 :
676 : NS_IMETHODIMP
677 3 : nsXPCComponents_Classes::NewEnumerate(nsIXPConnectWrappedNative* wrapper,
678 : JSContext* cx, JSObject* obj,
679 : JS::AutoIdVector& properties,
680 : bool* _retval)
681 : {
682 6 : nsCOMPtr<nsIComponentRegistrar> compMgr;
683 3 : if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || !compMgr)
684 0 : return NS_ERROR_UNEXPECTED;
685 :
686 6 : nsCOMPtr<nsISimpleEnumerator> e;
687 3 : if (NS_FAILED(compMgr->EnumerateContractIDs(getter_AddRefs(e))) || !e)
688 0 : return NS_ERROR_UNEXPECTED;
689 :
690 : bool hasMore;
691 6 : nsCOMPtr<nsISupports> isup;
692 16185 : while(NS_SUCCEEDED(e->HasMoreElements(&hasMore)) && hasMore &&
693 16179 : NS_SUCCEEDED(e->GetNext(getter_AddRefs(isup))) && isup) {
694 4620 : nsCOMPtr<nsISupportsCString> holder(do_QueryInterface(isup));
695 2310 : if (!holder)
696 0 : continue;
697 :
698 4620 : nsAutoCString name;
699 2310 : if (NS_SUCCEEDED(holder->GetData(name))) {
700 4620 : RootedString idstr(cx, JS_NewStringCopyN(cx, name.get(), name.Length()));
701 2310 : if (!idstr) {
702 0 : *_retval = false;
703 0 : return NS_OK;
704 : }
705 :
706 4620 : RootedId id(cx);
707 2310 : if (!JS_StringToId(cx, idstr, &id)) {
708 0 : *_retval = false;
709 0 : return NS_OK;
710 : }
711 :
712 2310 : if (!properties.append(id)) {
713 0 : *_retval = false;
714 0 : return NS_OK;
715 : }
716 : }
717 : }
718 :
719 3 : return NS_OK;
720 : }
721 :
722 : NS_IMETHODIMP
723 200 : nsXPCComponents_Classes::Resolve(nsIXPConnectWrappedNative* wrapper,
724 : JSContext* cx, JSObject* objArg,
725 : jsid idArg, bool* resolvedp,
726 : bool* _retval)
727 :
728 : {
729 400 : RootedId id(cx, idArg);
730 400 : RootedObject obj(cx, objArg);
731 :
732 400 : JSAutoByteString name;
733 600 : if (JSID_IS_STRING(id) &&
734 400 : name.encodeLatin1(cx, JSID_TO_STRING(id)) &&
735 200 : name.ptr()[0] != '{') { // we only allow contractids here
736 400 : nsCOMPtr<nsIJSCID> nsid = nsJSCID::NewID(name.ptr());
737 200 : if (nsid) {
738 197 : nsXPConnect* xpc = nsXPConnect::XPConnect();
739 394 : RootedObject idobj(cx);
740 197 : if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
741 : static_cast<nsIJSCID*>(nsid),
742 : NS_GET_IID(nsIJSCID),
743 : idobj.address()))) {
744 197 : if (idobj) {
745 197 : *resolvedp = true;
746 197 : *_retval = JS_DefinePropertyById(cx, obj, id, idobj,
747 : JSPROP_ENUMERATE |
748 : JSPROP_READONLY |
749 : JSPROP_PERMANENT |
750 : JSPROP_RESOLVING);
751 : }
752 : }
753 : }
754 : }
755 400 : return NS_OK;
756 : }
757 :
758 : /***************************************************************************/
759 : /***************************************************************************/
760 : /***************************************************************************/
761 :
762 : class nsXPCComponents_ClassesByID final :
763 : public nsIXPCComponents_ClassesByID,
764 : public nsIXPCScriptable,
765 : public nsIClassInfo
766 : {
767 : public:
768 : // all the interface method declarations...
769 : NS_DECL_ISUPPORTS
770 : NS_DECL_NSIXPCCOMPONENTS_CLASSESBYID
771 : NS_DECL_NSIXPCSCRIPTABLE
772 : NS_DECL_NSICLASSINFO
773 :
774 : public:
775 : nsXPCComponents_ClassesByID();
776 :
777 : private:
778 : virtual ~nsXPCComponents_ClassesByID();
779 : };
780 :
781 : /***************************************************************************/
782 : NS_IMETHODIMP
783 0 : nsXPCComponents_ClassesByID::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
784 : {
785 0 : const uint32_t count = 2;
786 0 : *aCount = count;
787 : nsIID** array;
788 0 : *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
789 0 : if (!array)
790 0 : return NS_ERROR_OUT_OF_MEMORY;
791 :
792 0 : uint32_t index = 0;
793 : nsIID* clone;
794 : #define PUSH_IID(id) \
795 : clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ), \
796 : sizeof(nsIID))); \
797 : if (!clone) \
798 : goto oom; \
799 : array[index++] = clone;
800 :
801 0 : PUSH_IID(nsIXPCComponents_ClassesByID)
802 0 : PUSH_IID(nsIXPCScriptable)
803 : #undef PUSH_IID
804 :
805 0 : return NS_OK;
806 : oom:
807 0 : while (index)
808 0 : free(array[--index]);
809 0 : free(array);
810 0 : *aArray = nullptr;
811 0 : return NS_ERROR_OUT_OF_MEMORY;
812 : }
813 :
814 : NS_IMETHODIMP
815 0 : nsXPCComponents_ClassesByID::GetScriptableHelper(nsIXPCScriptable** retval)
816 : {
817 0 : *retval = nullptr;
818 0 : return NS_OK;
819 : }
820 :
821 : NS_IMETHODIMP
822 0 : nsXPCComponents_ClassesByID::GetContractID(char * *aContractID)
823 : {
824 0 : *aContractID = nullptr;
825 0 : return NS_ERROR_NOT_AVAILABLE;
826 : }
827 :
828 : NS_IMETHODIMP
829 0 : nsXPCComponents_ClassesByID::GetClassDescription(char * *aClassDescription)
830 : {
831 : static const char classDescription[] = "XPCComponents_ClassesByID";
832 0 : *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
833 0 : return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
834 : }
835 :
836 : NS_IMETHODIMP
837 0 : nsXPCComponents_ClassesByID::GetClassID(nsCID * *aClassID)
838 : {
839 0 : *aClassID = nullptr;
840 0 : return NS_OK;
841 : }
842 :
843 : NS_IMETHODIMP
844 0 : nsXPCComponents_ClassesByID::GetFlags(uint32_t* aFlags)
845 : {
846 0 : *aFlags = 0;
847 0 : return NS_OK;
848 : }
849 :
850 : NS_IMETHODIMP
851 0 : nsXPCComponents_ClassesByID::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
852 : {
853 0 : return NS_ERROR_NOT_AVAILABLE;
854 : }
855 :
856 0 : nsXPCComponents_ClassesByID::nsXPCComponents_ClassesByID()
857 : {
858 0 : }
859 :
860 0 : nsXPCComponents_ClassesByID::~nsXPCComponents_ClassesByID()
861 : {
862 : // empty
863 0 : }
864 :
865 0 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_ClassesByID)
866 0 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_ClassesByID)
867 0 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
868 0 : NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
869 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_ClassesByID)
870 0 : NS_INTERFACE_MAP_END
871 :
872 0 : NS_IMPL_ADDREF(nsXPCComponents_ClassesByID)
873 0 : NS_IMPL_RELEASE(nsXPCComponents_ClassesByID)
874 :
875 : // The nsIXPCScriptable map declaration that will generate stubs for us...
876 : #define XPC_MAP_CLASSNAME nsXPCComponents_ClassesByID
877 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_ClassesByID"
878 : #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_RESOLVE | \
879 : XPC_SCRIPTABLE_WANT_NEWENUMERATE | \
880 : XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
881 : #include "xpc_map_end.h" /* This will #undef the above */
882 :
883 : NS_IMETHODIMP
884 0 : nsXPCComponents_ClassesByID::NewEnumerate(nsIXPConnectWrappedNative* wrapper,
885 : JSContext* cx, JSObject* obj,
886 : JS::AutoIdVector& properties,
887 : bool* _retval)
888 : {
889 :
890 0 : nsCOMPtr<nsIComponentRegistrar> compMgr;
891 0 : if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || !compMgr)
892 0 : return NS_ERROR_UNEXPECTED;
893 :
894 : nsISimpleEnumerator* e;
895 0 : if (NS_FAILED(compMgr->EnumerateCIDs(&e)) || !e)
896 0 : return NS_ERROR_UNEXPECTED;
897 :
898 : bool hasMore;
899 0 : nsCOMPtr<nsISupports> isup;
900 0 : while(NS_SUCCEEDED(e->HasMoreElements(&hasMore)) && hasMore &&
901 0 : NS_SUCCEEDED(e->GetNext(getter_AddRefs(isup))) && isup) {
902 0 : nsCOMPtr<nsISupportsID> holder(do_QueryInterface(isup));
903 0 : if (!holder)
904 0 : continue;
905 :
906 : char* name;
907 0 : if (NS_SUCCEEDED(holder->ToString(&name)) && name) {
908 0 : RootedString idstr(cx, JS_NewStringCopyZ(cx, name));
909 0 : if (!idstr) {
910 0 : *_retval = false;
911 0 : return NS_OK;
912 : }
913 :
914 0 : RootedId id(cx);
915 0 : if (!JS_StringToId(cx, idstr, &id)) {
916 0 : *_retval = false;
917 0 : return NS_OK;
918 : }
919 :
920 0 : if (!properties.append(id)) {
921 0 : *_retval = false;
922 0 : return NS_OK;
923 : }
924 : }
925 : }
926 :
927 0 : return NS_OK;
928 : }
929 :
930 : static bool
931 0 : IsRegisteredCLSID(const char* str)
932 : {
933 : bool registered;
934 : nsID id;
935 :
936 0 : if (!id.Parse(str))
937 0 : return false;
938 :
939 0 : nsCOMPtr<nsIComponentRegistrar> compMgr;
940 0 : if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || !compMgr ||
941 0 : NS_FAILED(compMgr->IsCIDRegistered(id, ®istered)))
942 0 : return false;
943 :
944 0 : return registered;
945 : }
946 :
947 : NS_IMETHODIMP
948 0 : nsXPCComponents_ClassesByID::Resolve(nsIXPConnectWrappedNative* wrapper,
949 : JSContext* cx, JSObject* objArg,
950 : jsid idArg, bool* resolvedp,
951 : bool* _retval)
952 : {
953 0 : RootedObject obj(cx, objArg);
954 0 : RootedId id(cx, idArg);
955 :
956 0 : if (!JSID_IS_STRING(id))
957 0 : return NS_OK;
958 :
959 0 : JSAutoByteString name;
960 0 : RootedString str(cx, JSID_TO_STRING(id));
961 0 : if (name.encodeLatin1(cx, str) && name.ptr()[0] == '{' &&
962 0 : IsRegisteredCLSID(name.ptr())) // we only allow canonical CLSIDs here
963 : {
964 0 : nsCOMPtr<nsIJSCID> nsid = nsJSCID::NewID(name.ptr());
965 0 : if (nsid) {
966 0 : nsXPConnect* xpc = nsXPConnect::XPConnect();
967 0 : RootedObject idobj(cx);
968 0 : if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
969 : static_cast<nsIJSCID*>(nsid),
970 : NS_GET_IID(nsIJSCID),
971 : idobj.address()))) {
972 0 : if (idobj) {
973 0 : *resolvedp = true;
974 0 : *_retval = JS_DefinePropertyById(cx, obj, id, idobj,
975 : JSPROP_ENUMERATE |
976 : JSPROP_READONLY |
977 : JSPROP_PERMANENT |
978 : JSPROP_RESOLVING);
979 : }
980 : }
981 : }
982 : }
983 0 : return NS_OK;
984 : }
985 :
986 :
987 : /***************************************************************************/
988 :
989 : // Currently the possible results do not change at runtime, so they are only
990 : // cached once (unlike ContractIDs, CLSIDs, and IIDs)
991 :
992 : class nsXPCComponents_Results final :
993 : public nsIXPCComponents_Results,
994 : public nsIXPCScriptable,
995 : public nsIClassInfo
996 : {
997 : public:
998 : // all the interface method declarations...
999 : NS_DECL_ISUPPORTS
1000 : NS_DECL_NSIXPCCOMPONENTS_RESULTS
1001 : NS_DECL_NSIXPCSCRIPTABLE
1002 : NS_DECL_NSICLASSINFO
1003 :
1004 : public:
1005 : nsXPCComponents_Results();
1006 :
1007 : private:
1008 : virtual ~nsXPCComponents_Results();
1009 : };
1010 :
1011 : /***************************************************************************/
1012 : NS_IMETHODIMP
1013 128 : nsXPCComponents_Results::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
1014 : {
1015 128 : const uint32_t count = 2;
1016 128 : *aCount = count;
1017 : nsIID** array;
1018 128 : *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
1019 128 : if (!array)
1020 0 : return NS_ERROR_OUT_OF_MEMORY;
1021 :
1022 128 : uint32_t index = 0;
1023 : nsIID* clone;
1024 : #define PUSH_IID(id) \
1025 : clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ), \
1026 : sizeof(nsIID))); \
1027 : if (!clone) \
1028 : goto oom; \
1029 : array[index++] = clone;
1030 :
1031 128 : PUSH_IID(nsIXPCComponents_Results)
1032 128 : PUSH_IID(nsIXPCScriptable)
1033 : #undef PUSH_IID
1034 :
1035 128 : return NS_OK;
1036 : oom:
1037 0 : while (index)
1038 0 : free(array[--index]);
1039 0 : free(array);
1040 0 : *aArray = nullptr;
1041 0 : return NS_ERROR_OUT_OF_MEMORY;
1042 : }
1043 :
1044 : NS_IMETHODIMP
1045 128 : nsXPCComponents_Results::GetScriptableHelper(nsIXPCScriptable** retval)
1046 : {
1047 128 : *retval = nullptr;
1048 128 : return NS_OK;
1049 : }
1050 :
1051 : NS_IMETHODIMP
1052 0 : nsXPCComponents_Results::GetContractID(char * *aContractID)
1053 : {
1054 0 : *aContractID = nullptr;
1055 0 : return NS_ERROR_NOT_AVAILABLE;
1056 : }
1057 :
1058 : NS_IMETHODIMP
1059 0 : nsXPCComponents_Results::GetClassDescription(char * *aClassDescription)
1060 : {
1061 : static const char classDescription[] = "XPCComponents_Results";
1062 0 : *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
1063 0 : return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
1064 : }
1065 :
1066 : NS_IMETHODIMP
1067 0 : nsXPCComponents_Results::GetClassID(nsCID * *aClassID)
1068 : {
1069 0 : *aClassID = nullptr;
1070 0 : return NS_OK;
1071 : }
1072 :
1073 : NS_IMETHODIMP
1074 128 : nsXPCComponents_Results::GetFlags(uint32_t* aFlags)
1075 : {
1076 : // Mark ourselves as a DOM object so that instances may be created in
1077 : // unprivileged scopes.
1078 128 : *aFlags = nsIClassInfo::DOM_OBJECT;
1079 128 : return NS_OK;
1080 : }
1081 :
1082 : NS_IMETHODIMP
1083 0 : nsXPCComponents_Results::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
1084 : {
1085 0 : return NS_ERROR_NOT_AVAILABLE;
1086 : }
1087 :
1088 128 : nsXPCComponents_Results::nsXPCComponents_Results()
1089 : {
1090 128 : }
1091 :
1092 0 : nsXPCComponents_Results::~nsXPCComponents_Results()
1093 : {
1094 : // empty
1095 0 : }
1096 :
1097 1498 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Results)
1098 1498 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Results)
1099 1370 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
1100 953 : NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
1101 697 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Results)
1102 550 : NS_INTERFACE_MAP_END
1103 :
1104 1640 : NS_IMPL_ADDREF(nsXPCComponents_Results)
1105 1000 : NS_IMPL_RELEASE(nsXPCComponents_Results)
1106 :
1107 : // The nsIXPCScriptable map declaration that will generate stubs for us...
1108 : #define XPC_MAP_CLASSNAME nsXPCComponents_Results
1109 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Results"
1110 : #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_RESOLVE | \
1111 : XPC_SCRIPTABLE_WANT_NEWENUMERATE | \
1112 : XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
1113 : #include "xpc_map_end.h" /* This will #undef the above */
1114 :
1115 : NS_IMETHODIMP
1116 0 : nsXPCComponents_Results::NewEnumerate(nsIXPConnectWrappedNative* wrapper,
1117 : JSContext* cx, JSObject* obj,
1118 : JS::AutoIdVector& properties,
1119 : bool* _retval)
1120 : {
1121 : const char* name;
1122 0 : const void* iter = nullptr;
1123 0 : while (nsXPCException::IterateNSResults(nullptr, &name, nullptr, &iter)) {
1124 0 : RootedString idstr(cx, JS_NewStringCopyZ(cx, name));
1125 0 : if (!idstr) {
1126 0 : *_retval = false;
1127 0 : return NS_OK;
1128 : }
1129 :
1130 0 : RootedId id(cx);
1131 0 : if (!JS_StringToId(cx, idstr, &id)) {
1132 0 : *_retval = false;
1133 0 : return NS_OK;
1134 : }
1135 :
1136 0 : if (!properties.append(id)) {
1137 0 : *_retval = false;
1138 0 : return NS_OK;
1139 : }
1140 : }
1141 :
1142 0 : return NS_OK;
1143 : }
1144 :
1145 : NS_IMETHODIMP
1146 11 : nsXPCComponents_Results::Resolve(nsIXPConnectWrappedNative* wrapper,
1147 : JSContext* cx, JSObject* objArg,
1148 : jsid idArg, bool* resolvedp,
1149 : bool* _retval)
1150 : {
1151 22 : RootedObject obj(cx, objArg);
1152 22 : RootedId id(cx, idArg);
1153 22 : JSAutoByteString name;
1154 :
1155 11 : if (JSID_IS_STRING(id) && name.encodeLatin1(cx, JSID_TO_STRING(id))) {
1156 : const char* rv_name;
1157 11 : const void* iter = nullptr;
1158 : nsresult rv;
1159 4169 : while (nsXPCException::IterateNSResults(&rv, &rv_name, nullptr, &iter)) {
1160 2079 : if (!strcmp(name.ptr(), rv_name)) {
1161 11 : *resolvedp = true;
1162 11 : if (!JS_DefinePropertyById(cx, obj, id, (uint32_t)rv,
1163 : JSPROP_ENUMERATE |
1164 : JSPROP_READONLY |
1165 : JSPROP_PERMANENT |
1166 : JSPROP_RESOLVING)) {
1167 0 : return NS_ERROR_UNEXPECTED;
1168 : }
1169 : }
1170 : }
1171 : }
1172 11 : return NS_OK;
1173 : }
1174 :
1175 : /***************************************************************************/
1176 : // JavaScript Constructor for nsIJSID objects (Components.ID)
1177 :
1178 : class nsXPCComponents_ID final :
1179 : public nsIXPCComponents_ID,
1180 : public nsIXPCScriptable,
1181 : public nsIClassInfo
1182 : {
1183 : public:
1184 : // all the interface method declarations...
1185 : NS_DECL_ISUPPORTS
1186 : NS_DECL_NSIXPCCOMPONENTS_ID
1187 : NS_DECL_NSIXPCSCRIPTABLE
1188 : NS_DECL_NSICLASSINFO
1189 :
1190 :
1191 : public:
1192 : nsXPCComponents_ID();
1193 :
1194 : private:
1195 : virtual ~nsXPCComponents_ID();
1196 : static nsresult CallOrConstruct(nsIXPConnectWrappedNative* wrapper,
1197 : JSContext* cx, HandleObject obj,
1198 : const CallArgs& args, bool* _retval);
1199 : };
1200 :
1201 : /***************************************************************************/
1202 : NS_IMETHODIMP
1203 66 : nsXPCComponents_ID::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
1204 : {
1205 66 : const uint32_t count = 2;
1206 66 : *aCount = count;
1207 : nsIID** array;
1208 66 : *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
1209 66 : if (!array)
1210 0 : return NS_ERROR_OUT_OF_MEMORY;
1211 :
1212 66 : uint32_t index = 0;
1213 : nsIID* clone;
1214 : #define PUSH_IID(id) \
1215 : clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ), \
1216 : sizeof(nsIID))); \
1217 : if (!clone) \
1218 : goto oom; \
1219 : array[index++] = clone;
1220 :
1221 66 : PUSH_IID(nsIXPCComponents_ID)
1222 66 : PUSH_IID(nsIXPCScriptable)
1223 : #undef PUSH_IID
1224 :
1225 66 : return NS_OK;
1226 : oom:
1227 0 : while (index)
1228 0 : free(array[--index]);
1229 0 : free(array);
1230 0 : *aArray = nullptr;
1231 0 : return NS_ERROR_OUT_OF_MEMORY;
1232 : }
1233 :
1234 : NS_IMETHODIMP
1235 67 : nsXPCComponents_ID::GetScriptableHelper(nsIXPCScriptable** retval)
1236 : {
1237 67 : *retval = nullptr;
1238 67 : return NS_OK;
1239 : }
1240 :
1241 : NS_IMETHODIMP
1242 0 : nsXPCComponents_ID::GetContractID(char * *aContractID)
1243 : {
1244 0 : *aContractID = nullptr;
1245 0 : return NS_ERROR_NOT_AVAILABLE;
1246 : }
1247 :
1248 : NS_IMETHODIMP
1249 0 : nsXPCComponents_ID::GetClassDescription(char * *aClassDescription)
1250 : {
1251 : static const char classDescription[] = "XPCComponents_ID";
1252 0 : *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
1253 0 : return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
1254 : }
1255 :
1256 : NS_IMETHODIMP
1257 0 : nsXPCComponents_ID::GetClassID(nsCID * *aClassID)
1258 : {
1259 0 : *aClassID = nullptr;
1260 0 : return NS_OK;
1261 : }
1262 :
1263 : NS_IMETHODIMP
1264 67 : nsXPCComponents_ID::GetFlags(uint32_t* aFlags)
1265 : {
1266 67 : *aFlags = 0;
1267 67 : return NS_OK;
1268 : }
1269 :
1270 : NS_IMETHODIMP
1271 0 : nsXPCComponents_ID::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
1272 : {
1273 0 : return NS_ERROR_NOT_AVAILABLE;
1274 : }
1275 :
1276 66 : nsXPCComponents_ID::nsXPCComponents_ID()
1277 : {
1278 66 : }
1279 :
1280 0 : nsXPCComponents_ID::~nsXPCComponents_ID()
1281 : {
1282 : // empty
1283 0 : }
1284 :
1285 1024 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_ID)
1286 1024 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_ID)
1287 958 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
1288 678 : NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
1289 544 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_ID)
1290 407 : NS_INTERFACE_MAP_END
1291 :
1292 1098 : NS_IMPL_ADDREF(nsXPCComponents_ID)
1293 764 : NS_IMPL_RELEASE(nsXPCComponents_ID)
1294 :
1295 : // The nsIXPCScriptable map declaration that will generate stubs for us...
1296 : #define XPC_MAP_CLASSNAME nsXPCComponents_ID
1297 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_ID"
1298 : #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_CALL | \
1299 : XPC_SCRIPTABLE_WANT_CONSTRUCT | \
1300 : XPC_SCRIPTABLE_WANT_HASINSTANCE | \
1301 : XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
1302 : #include "xpc_map_end.h" /* This will #undef the above */
1303 :
1304 :
1305 : NS_IMETHODIMP
1306 78 : nsXPCComponents_ID::Call(nsIXPConnectWrappedNative* wrapper, JSContext* cx, JSObject* objArg,
1307 : const CallArgs& args, bool* _retval)
1308 : {
1309 156 : RootedObject obj(cx, objArg);
1310 156 : return CallOrConstruct(wrapper, cx, obj, args, _retval);
1311 : }
1312 :
1313 : NS_IMETHODIMP
1314 0 : nsXPCComponents_ID::Construct(nsIXPConnectWrappedNative* wrapper, JSContext* cx, JSObject* objArg,
1315 : const CallArgs& args, bool* _retval)
1316 : {
1317 0 : RootedObject obj(cx, objArg);
1318 0 : return CallOrConstruct(wrapper, cx, obj, args, _retval);
1319 : }
1320 :
1321 : // static
1322 : nsresult
1323 78 : nsXPCComponents_ID::CallOrConstruct(nsIXPConnectWrappedNative* wrapper,
1324 : JSContext* cx, HandleObject obj,
1325 : const CallArgs& args, bool* _retval)
1326 : {
1327 : // make sure we have at least one arg
1328 :
1329 78 : if (args.length() < 1)
1330 0 : return ThrowAndFail(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx, _retval);
1331 :
1332 : // Do the security check if necessary
1333 :
1334 78 : if (NS_FAILED(nsXPConnect::SecurityManager()->CanCreateInstance(cx, nsJSID::GetCID()))) {
1335 : // the security manager vetoed. It should have set an exception.
1336 0 : *_retval = false;
1337 0 : return NS_OK;
1338 : }
1339 :
1340 : // convert the first argument into a string and see if it looks like an id
1341 :
1342 : JSString* jsstr;
1343 156 : JSAutoByteString bytes;
1344 : nsID id;
1345 :
1346 234 : if (!(jsstr = ToString(cx, args[0])) ||
1347 234 : !bytes.encodeLatin1(cx, jsstr) ||
1348 78 : !id.Parse(bytes.ptr())) {
1349 0 : return ThrowAndFail(NS_ERROR_XPC_BAD_ID_STRING, cx, _retval);
1350 : }
1351 :
1352 : // make the new object and return it.
1353 :
1354 78 : JSObject* newobj = xpc_NewIDObject(cx, obj, id);
1355 78 : if (!newobj)
1356 0 : return NS_ERROR_UNEXPECTED;
1357 :
1358 78 : args.rval().setObject(*newobj);
1359 78 : return NS_OK;
1360 : }
1361 :
1362 : NS_IMETHODIMP
1363 57 : nsXPCComponents_ID::HasInstance(nsIXPConnectWrappedNative* wrapper,
1364 : JSContext* cx, JSObject* obj,
1365 : HandleValue val, bool* bp, bool* _retval)
1366 : {
1367 57 : if (bp)
1368 57 : *bp = JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIJSID));
1369 57 : return NS_OK;
1370 : }
1371 :
1372 : /***************************************************************************/
1373 : // JavaScript Constructor for nsIXPCException objects (Components.Exception)
1374 :
1375 : class nsXPCComponents_Exception final :
1376 : public nsIXPCComponents_Exception,
1377 : public nsIXPCScriptable,
1378 : public nsIClassInfo
1379 : {
1380 : public:
1381 : // all the interface method declarations...
1382 : NS_DECL_ISUPPORTS
1383 : NS_DECL_NSIXPCCOMPONENTS_EXCEPTION
1384 : NS_DECL_NSIXPCSCRIPTABLE
1385 : NS_DECL_NSICLASSINFO
1386 :
1387 :
1388 : public:
1389 : nsXPCComponents_Exception();
1390 :
1391 : private:
1392 : virtual ~nsXPCComponents_Exception();
1393 : static nsresult CallOrConstruct(nsIXPConnectWrappedNative* wrapper,
1394 : JSContext* cx, HandleObject obj,
1395 : const CallArgs& args, bool* _retval);
1396 : };
1397 :
1398 : /***************************************************************************/
1399 : NS_IMETHODIMP
1400 0 : nsXPCComponents_Exception::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
1401 : {
1402 0 : const uint32_t count = 2;
1403 0 : *aCount = count;
1404 : nsIID** array;
1405 0 : *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
1406 0 : if (!array)
1407 0 : return NS_ERROR_OUT_OF_MEMORY;
1408 :
1409 0 : uint32_t index = 0;
1410 : nsIID* clone;
1411 : #define PUSH_IID(id) \
1412 : clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ), \
1413 : sizeof(nsIID))); \
1414 : if (!clone) \
1415 : goto oom; \
1416 : array[index++] = clone;
1417 :
1418 0 : PUSH_IID(nsIXPCComponents_Exception)
1419 0 : PUSH_IID(nsIXPCScriptable)
1420 : #undef PUSH_IID
1421 :
1422 0 : return NS_OK;
1423 : oom:
1424 0 : while (index)
1425 0 : free(array[--index]);
1426 0 : free(array);
1427 0 : *aArray = nullptr;
1428 0 : return NS_ERROR_OUT_OF_MEMORY;
1429 : }
1430 :
1431 : NS_IMETHODIMP
1432 0 : nsXPCComponents_Exception::GetScriptableHelper(nsIXPCScriptable** retval)
1433 : {
1434 0 : *retval = nullptr;
1435 0 : return NS_OK;
1436 : }
1437 :
1438 : NS_IMETHODIMP
1439 0 : nsXPCComponents_Exception::GetContractID(char * *aContractID)
1440 : {
1441 0 : *aContractID = nullptr;
1442 0 : return NS_ERROR_NOT_AVAILABLE;
1443 : }
1444 :
1445 : NS_IMETHODIMP
1446 0 : nsXPCComponents_Exception::GetClassDescription(char * *aClassDescription)
1447 : {
1448 : static const char classDescription[] = "XPCComponents_Exception";
1449 0 : *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
1450 0 : return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
1451 : }
1452 :
1453 : NS_IMETHODIMP
1454 0 : nsXPCComponents_Exception::GetClassID(nsCID * *aClassID)
1455 : {
1456 0 : *aClassID = nullptr;
1457 0 : return NS_OK;
1458 : }
1459 :
1460 : NS_IMETHODIMP
1461 0 : nsXPCComponents_Exception::GetFlags(uint32_t* aFlags)
1462 : {
1463 0 : *aFlags = 0;
1464 0 : return NS_OK;
1465 : }
1466 :
1467 : NS_IMETHODIMP
1468 0 : nsXPCComponents_Exception::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
1469 : {
1470 0 : return NS_ERROR_NOT_AVAILABLE;
1471 : }
1472 :
1473 0 : nsXPCComponents_Exception::nsXPCComponents_Exception()
1474 : {
1475 0 : }
1476 :
1477 0 : nsXPCComponents_Exception::~nsXPCComponents_Exception()
1478 : {
1479 : // empty
1480 0 : }
1481 :
1482 0 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Exception)
1483 0 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Exception)
1484 0 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
1485 0 : NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
1486 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Exception)
1487 0 : NS_INTERFACE_MAP_END
1488 :
1489 0 : NS_IMPL_ADDREF(nsXPCComponents_Exception)
1490 0 : NS_IMPL_RELEASE(nsXPCComponents_Exception)
1491 :
1492 : // The nsIXPCScriptable map declaration that will generate stubs for us...
1493 : #define XPC_MAP_CLASSNAME nsXPCComponents_Exception
1494 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Exception"
1495 : #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_CALL | \
1496 : XPC_SCRIPTABLE_WANT_CONSTRUCT | \
1497 : XPC_SCRIPTABLE_WANT_HASINSTANCE | \
1498 : XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
1499 : #include "xpc_map_end.h" /* This will #undef the above */
1500 :
1501 :
1502 : NS_IMETHODIMP
1503 0 : nsXPCComponents_Exception::Call(nsIXPConnectWrappedNative* wrapper, JSContext* cx, JSObject* objArg,
1504 : const CallArgs& args, bool* _retval)
1505 : {
1506 0 : RootedObject obj(cx, objArg);
1507 0 : return CallOrConstruct(wrapper, cx, obj, args, _retval);
1508 : }
1509 :
1510 : NS_IMETHODIMP
1511 0 : nsXPCComponents_Exception::Construct(nsIXPConnectWrappedNative* wrapper, JSContext* cx,
1512 : JSObject* objArg, const CallArgs& args, bool* _retval)
1513 : {
1514 0 : RootedObject obj(cx, objArg);
1515 0 : return CallOrConstruct(wrapper, cx, obj, args, _retval);
1516 : }
1517 :
1518 0 : struct MOZ_STACK_CLASS ExceptionArgParser
1519 : {
1520 0 : ExceptionArgParser(JSContext* context,
1521 : nsXPConnect* xpconnect)
1522 0 : : eMsg("exception")
1523 : , eResult(NS_ERROR_FAILURE)
1524 : , cx(context)
1525 0 : , xpc(xpconnect)
1526 0 : {}
1527 :
1528 : // Public exception parameter values. During construction, these are
1529 : // initialized to the appropriate defaults.
1530 : const char* eMsg;
1531 : nsresult eResult;
1532 : nsCOMPtr<nsIStackFrame> eStack;
1533 : nsCOMPtr<nsISupports> eData;
1534 :
1535 : // Parse the constructor arguments into the above |eFoo| parameter values.
1536 0 : bool parse(const CallArgs& args) {
1537 : /*
1538 : * The Components.Exception takes a series of arguments, all of them
1539 : * optional:
1540 : *
1541 : * Argument 0: Exception message (defaults to 'exception').
1542 : * Argument 1: Result code (defaults to NS_ERROR_FAILURE) _or_ options
1543 : * object (see below).
1544 : * Argument 2: Stack (defaults to the current stack, which we trigger
1545 : * by leaving this nullptr in the parser).
1546 : * Argument 3: Optional user data (defaults to nullptr).
1547 : *
1548 : * To dig our way out of this clunky API, we now support passing an
1549 : * options object as the second parameter (as opposed to a result code).
1550 : * If this is the case, all subsequent arguments are ignored, and the
1551 : * following properties are parsed out of the object (using the
1552 : * associated default if the property does not exist):
1553 : *
1554 : * result: Result code (see argument 1).
1555 : * stack: Call stack (see argument 2).
1556 : * data: User data (see argument 3).
1557 : */
1558 0 : if (args.length() > 0 && !parseMessage(args[0]))
1559 0 : return false;
1560 0 : if (args.length() > 1) {
1561 0 : if (args[1].isObject()) {
1562 0 : RootedObject obj(cx, &args[1].toObject());
1563 0 : return parseOptionsObject(obj);
1564 : }
1565 0 : if (!parseResult(args[1]))
1566 0 : return false;
1567 : }
1568 0 : if (args.length() > 2) {
1569 0 : if (!parseStack(args[2]))
1570 0 : return false;
1571 : }
1572 0 : if (args.length() > 3) {
1573 0 : if (!parseData(args[3]))
1574 0 : return false;
1575 : }
1576 0 : return true;
1577 : }
1578 :
1579 : protected:
1580 :
1581 : /*
1582 : * Parsing helpers.
1583 : */
1584 :
1585 0 : bool parseMessage(HandleValue v) {
1586 0 : JSString* str = ToString(cx, v);
1587 0 : if (!str)
1588 0 : return false;
1589 0 : eMsg = messageBytes.encodeLatin1(cx, str);
1590 0 : return !!eMsg;
1591 : }
1592 :
1593 0 : bool parseResult(HandleValue v) {
1594 0 : return JS::ToUint32(cx, v, (uint32_t*) &eResult);
1595 : }
1596 :
1597 0 : bool parseStack(HandleValue v) {
1598 0 : if (!v.isObject()) {
1599 : // eStack has already been initialized to null, which is what we want
1600 : // for any non-object values (including null).
1601 0 : return true;
1602 : }
1603 :
1604 0 : return NS_SUCCEEDED(xpc->WrapJS(cx, &v.toObject(),
1605 : NS_GET_IID(nsIStackFrame),
1606 : getter_AddRefs(eStack)));
1607 : }
1608 :
1609 0 : bool parseData(HandleValue v) {
1610 0 : if (!v.isObject()) {
1611 : // eData has already been initialized to null, which is what we want
1612 : // for any non-object values (including null).
1613 0 : return true;
1614 : }
1615 :
1616 0 : return NS_SUCCEEDED(xpc->WrapJS(cx, &v.toObject(),
1617 : NS_GET_IID(nsISupports),
1618 : getter_AddRefs(eData)));
1619 : }
1620 :
1621 0 : bool parseOptionsObject(HandleObject obj) {
1622 0 : RootedValue v(cx);
1623 :
1624 0 : if (!getOption(obj, "result", &v) ||
1625 0 : (!v.isUndefined() && !parseResult(v)))
1626 0 : return false;
1627 :
1628 0 : if (!getOption(obj, "stack", &v) ||
1629 0 : (!v.isUndefined() && !parseStack(v)))
1630 0 : return false;
1631 :
1632 0 : if (!getOption(obj, "data", &v) ||
1633 0 : (!v.isUndefined() && !parseData(v)))
1634 0 : return false;
1635 :
1636 0 : return true;
1637 : }
1638 :
1639 0 : bool getOption(HandleObject obj, const char* name, MutableHandleValue rv) {
1640 : // Look for the property.
1641 : bool found;
1642 0 : if (!JS_HasProperty(cx, obj, name, &found))
1643 0 : return false;
1644 :
1645 : // If it wasn't found, indicate with undefined.
1646 0 : if (!found) {
1647 0 : rv.setUndefined();
1648 0 : return true;
1649 : }
1650 :
1651 : // Get the property.
1652 0 : return JS_GetProperty(cx, obj, name, rv);
1653 : }
1654 :
1655 : /*
1656 : * Internal data members.
1657 : */
1658 :
1659 : // If there's a non-default exception string, hold onto the allocated bytes.
1660 : JSAutoByteString messageBytes;
1661 :
1662 : // Various bits and pieces that are helpful to have around.
1663 : JSContext* cx;
1664 : nsXPConnect* xpc;
1665 : };
1666 :
1667 : // static
1668 : nsresult
1669 0 : nsXPCComponents_Exception::CallOrConstruct(nsIXPConnectWrappedNative* wrapper,
1670 : JSContext* cx, HandleObject obj,
1671 : const CallArgs& args, bool* _retval)
1672 : {
1673 0 : nsXPConnect* xpc = nsXPConnect::XPConnect();
1674 :
1675 : // Do the security check if necessary
1676 :
1677 0 : if (NS_FAILED(nsXPConnect::SecurityManager()->CanCreateInstance(cx, Exception::GetCID()))) {
1678 : // the security manager vetoed. It should have set an exception.
1679 0 : *_retval = false;
1680 0 : return NS_OK;
1681 : }
1682 :
1683 : // Parse the arguments to the Exception constructor.
1684 0 : ExceptionArgParser parser(cx, xpc);
1685 0 : if (!parser.parse(args))
1686 0 : return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
1687 :
1688 0 : nsCOMPtr<nsIException> e = new Exception(nsCString(parser.eMsg),
1689 : parser.eResult,
1690 0 : EmptyCString(),
1691 : parser.eStack,
1692 0 : parser.eData);
1693 :
1694 0 : RootedObject newObj(cx);
1695 0 : if (NS_FAILED(xpc->WrapNative(cx, obj, e, NS_GET_IID(nsIXPCException), newObj.address())) || !newObj) {
1696 0 : return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval);
1697 : }
1698 :
1699 0 : args.rval().setObject(*newObj);
1700 0 : return NS_OK;
1701 : }
1702 :
1703 : NS_IMETHODIMP
1704 0 : nsXPCComponents_Exception::HasInstance(nsIXPConnectWrappedNative* wrapper,
1705 : JSContext * cx, JSObject * obj,
1706 : HandleValue val, bool* bp,
1707 : bool* _retval)
1708 : {
1709 : using namespace mozilla::dom;
1710 :
1711 0 : if (bp) {
1712 0 : *bp = (val.isObject() &&
1713 0 : IS_INSTANCE_OF(Exception, &val.toObject())) ||
1714 0 : JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIException));
1715 : }
1716 0 : return NS_OK;
1717 : }
1718 :
1719 : /***************************************************************************/
1720 : // This class is for the thing returned by "new Component.Constructor".
1721 :
1722 : // XXXjband we use this CID for security check, but security system can't see
1723 : // it since it has no registed factory. Security really kicks in when we try
1724 : // to build a wrapper around an instance.
1725 :
1726 : // {B4A95150-E25A-11d3-8F61-0010A4E73D9A}
1727 : #define NS_XPCCONSTRUCTOR_CID \
1728 : { 0xb4a95150, 0xe25a, 0x11d3, \
1729 : { 0x8f, 0x61, 0x0, 0x10, 0xa4, 0xe7, 0x3d, 0x9a } }
1730 :
1731 : class nsXPCConstructor :
1732 : public nsIXPCConstructor,
1733 : public nsIXPCScriptable,
1734 : public nsIClassInfo
1735 : {
1736 : public:
1737 10 : NS_DEFINE_STATIC_CID_ACCESSOR(NS_XPCCONSTRUCTOR_CID)
1738 : public:
1739 : // all the interface method declarations...
1740 : NS_DECL_ISUPPORTS
1741 : NS_DECL_NSIXPCCONSTRUCTOR
1742 : NS_DECL_NSIXPCSCRIPTABLE
1743 : NS_DECL_NSICLASSINFO
1744 :
1745 : public:
1746 : nsXPCConstructor() = delete;
1747 : nsXPCConstructor(nsIJSCID* aClassID,
1748 : nsIJSIID* aInterfaceID,
1749 : const char* aInitializer);
1750 :
1751 : private:
1752 : virtual ~nsXPCConstructor();
1753 : nsresult CallOrConstruct(nsIXPConnectWrappedNative* wrapper,
1754 : JSContext* cx, HandleObject obj,
1755 : const CallArgs& args, bool* _retval);
1756 : private:
1757 : RefPtr<nsIJSCID> mClassID;
1758 : RefPtr<nsIJSIID> mInterfaceID;
1759 : char* mInitializer;
1760 : };
1761 :
1762 : /***************************************************************************/
1763 : NS_IMETHODIMP
1764 10 : nsXPCConstructor::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
1765 : {
1766 10 : const uint32_t count = 2;
1767 10 : *aCount = count;
1768 : nsIID** array;
1769 10 : *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
1770 10 : if (!array)
1771 0 : return NS_ERROR_OUT_OF_MEMORY;
1772 :
1773 10 : uint32_t index = 0;
1774 : nsIID* clone;
1775 : #define PUSH_IID(id) \
1776 : clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ), \
1777 : sizeof(nsIID))); \
1778 : if (!clone) \
1779 : goto oom; \
1780 : array[index++] = clone;
1781 :
1782 10 : PUSH_IID(nsIXPCConstructor)
1783 10 : PUSH_IID(nsIXPCScriptable)
1784 : #undef PUSH_IID
1785 :
1786 10 : return NS_OK;
1787 : oom:
1788 0 : while (index)
1789 0 : free(array[--index]);
1790 0 : free(array);
1791 0 : *aArray = nullptr;
1792 0 : return NS_ERROR_OUT_OF_MEMORY;
1793 : }
1794 :
1795 : NS_IMETHODIMP
1796 12 : nsXPCConstructor::GetScriptableHelper(nsIXPCScriptable** retval)
1797 : {
1798 12 : *retval = nullptr;
1799 12 : return NS_OK;
1800 : }
1801 :
1802 : NS_IMETHODIMP
1803 0 : nsXPCConstructor::GetContractID(char * *aContractID)
1804 : {
1805 0 : *aContractID = nullptr;
1806 0 : return NS_ERROR_NOT_AVAILABLE;
1807 : }
1808 :
1809 : NS_IMETHODIMP
1810 0 : nsXPCConstructor::GetClassDescription(char * *aClassDescription)
1811 : {
1812 : static const char classDescription[] = "XPCConstructor";
1813 0 : *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
1814 0 : return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
1815 : }
1816 :
1817 : NS_IMETHODIMP
1818 0 : nsXPCConstructor::GetClassID(nsCID * *aClassID)
1819 : {
1820 0 : *aClassID = nullptr;
1821 0 : return NS_OK;
1822 : }
1823 :
1824 : NS_IMETHODIMP
1825 12 : nsXPCConstructor::GetFlags(uint32_t* aFlags)
1826 : {
1827 12 : *aFlags = 0;
1828 12 : return NS_OK;
1829 : }
1830 :
1831 : NS_IMETHODIMP
1832 0 : nsXPCConstructor::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
1833 : {
1834 0 : return NS_ERROR_NOT_AVAILABLE;
1835 : }
1836 :
1837 10 : nsXPCConstructor::nsXPCConstructor(nsIJSCID* aClassID,
1838 : nsIJSIID* aInterfaceID,
1839 10 : const char* aInitializer)
1840 : : mClassID(aClassID),
1841 10 : mInterfaceID(aInterfaceID)
1842 : {
1843 18 : mInitializer = aInitializer ?
1844 8 : (char*) nsMemory::Clone(aInitializer, strlen(aInitializer)+1) :
1845 : nullptr;
1846 10 : }
1847 :
1848 0 : nsXPCConstructor::~nsXPCConstructor()
1849 : {
1850 0 : if (mInitializer)
1851 0 : free(mInitializer);
1852 0 : }
1853 :
1854 : NS_IMETHODIMP
1855 0 : nsXPCConstructor::GetClassID(nsIJSCID * *aClassID)
1856 : {
1857 0 : RefPtr<nsIJSCID> rval = mClassID;
1858 0 : rval.forget(aClassID);
1859 0 : return NS_OK;
1860 : }
1861 :
1862 : NS_IMETHODIMP
1863 0 : nsXPCConstructor::GetInterfaceID(nsIJSIID * *aInterfaceID)
1864 : {
1865 0 : RefPtr<nsIJSIID> rval = mInterfaceID;
1866 0 : rval.forget(aInterfaceID);
1867 0 : return NS_OK;
1868 : }
1869 :
1870 : NS_IMETHODIMP
1871 0 : nsXPCConstructor::GetInitializer(char * *aInitializer)
1872 : {
1873 0 : XPC_STRING_GETTER_BODY(aInitializer, mInitializer);
1874 : }
1875 :
1876 175 : NS_INTERFACE_MAP_BEGIN(nsXPCConstructor)
1877 175 : NS_INTERFACE_MAP_ENTRY(nsIXPCConstructor)
1878 155 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
1879 88 : NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
1880 64 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCConstructor)
1881 50 : NS_INTERFACE_MAP_END
1882 :
1883 202 : NS_IMPL_ADDREF(nsXPCConstructor)
1884 154 : NS_IMPL_RELEASE(nsXPCConstructor)
1885 :
1886 : // The nsIXPCScriptable map declaration that will generate stubs for us...
1887 : #define XPC_MAP_CLASSNAME nsXPCConstructor
1888 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCConstructor"
1889 : #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_CALL | \
1890 : XPC_SCRIPTABLE_WANT_CONSTRUCT)
1891 : #include "xpc_map_end.h" /* This will #undef the above */
1892 :
1893 :
1894 : NS_IMETHODIMP
1895 2 : nsXPCConstructor::Call(nsIXPConnectWrappedNative* wrapper, JSContext* cx, JSObject* objArg,
1896 : const CallArgs& args, bool* _retval)
1897 : {
1898 4 : RootedObject obj(cx, objArg);
1899 4 : return CallOrConstruct(wrapper, cx, obj, args, _retval);
1900 :
1901 : }
1902 :
1903 : NS_IMETHODIMP
1904 27 : nsXPCConstructor::Construct(nsIXPConnectWrappedNative* wrapper, JSContext* cx, JSObject* objArg,
1905 : const CallArgs& args, bool* _retval)
1906 : {
1907 54 : RootedObject obj(cx, objArg);
1908 54 : return CallOrConstruct(wrapper, cx, obj, args, _retval);
1909 : }
1910 :
1911 : // static
1912 : nsresult
1913 29 : nsXPCConstructor::CallOrConstruct(nsIXPConnectWrappedNative* wrapper,JSContext* cx,
1914 : HandleObject obj, const CallArgs& args, bool* _retval)
1915 : {
1916 29 : nsXPConnect* xpc = nsXPConnect::XPConnect();
1917 :
1918 : // security check not required because we are going to call through the
1919 : // code which is reflected into JS which will do that for us later.
1920 :
1921 58 : RootedObject cidObj(cx);
1922 58 : RootedObject iidObj(cx);
1923 :
1924 116 : if (NS_FAILED(xpc->WrapNative(cx, obj, mClassID, NS_GET_IID(nsIJSCID), cidObj.address())) || !cidObj ||
1925 87 : NS_FAILED(xpc->WrapNative(cx, obj, mInterfaceID, NS_GET_IID(nsIJSIID), iidObj.address())) || !iidObj) {
1926 0 : return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval);
1927 : }
1928 :
1929 58 : JS::Rooted<JS::Value> arg(cx, ObjectValue(*iidObj));
1930 58 : RootedValue rval(cx);
1931 58 : if (!JS_CallFunctionName(cx, cidObj, "createInstance", JS::HandleValueArray(arg), &rval) ||
1932 29 : rval.isPrimitive()) {
1933 : // createInstance will have thrown an exception
1934 0 : *_retval = false;
1935 0 : return NS_OK;
1936 : }
1937 :
1938 29 : args.rval().set(rval);
1939 :
1940 : // call initializer method if supplied
1941 29 : if (mInitializer) {
1942 36 : RootedObject newObj(cx, &rval.toObject());
1943 : // first check existence of function property for better error reporting
1944 36 : RootedValue fun(cx);
1945 54 : if (!JS_GetProperty(cx, newObj, mInitializer, &fun) ||
1946 27 : fun.isPrimitive()) {
1947 0 : return ThrowAndFail(NS_ERROR_XPC_BAD_INITIALIZER_NAME, cx, _retval);
1948 : }
1949 :
1950 36 : RootedValue dummy(cx);
1951 27 : if (!JS_CallFunctionValue(cx, newObj, fun, args, &dummy)) {
1952 : // function should have thrown an exception
1953 18 : *_retval = false;
1954 18 : return NS_OK;
1955 : }
1956 : }
1957 :
1958 11 : return NS_OK;
1959 : }
1960 :
1961 : /*******************************************************/
1962 : // JavaScript Constructor for nsIXPCConstructor objects (Components.Constructor)
1963 :
1964 : class nsXPCComponents_Constructor final :
1965 : public nsIXPCComponents_Constructor,
1966 : public nsIXPCScriptable,
1967 : public nsIClassInfo
1968 : {
1969 : public:
1970 : // all the interface method declarations...
1971 : NS_DECL_ISUPPORTS
1972 : NS_DECL_NSIXPCCOMPONENTS_CONSTRUCTOR
1973 : NS_DECL_NSIXPCSCRIPTABLE
1974 : NS_DECL_NSICLASSINFO
1975 :
1976 : public:
1977 : nsXPCComponents_Constructor();
1978 :
1979 : private:
1980 : virtual ~nsXPCComponents_Constructor();
1981 : static nsresult CallOrConstruct(nsIXPConnectWrappedNative* wrapper,
1982 : JSContext* cx, HandleObject obj,
1983 : const CallArgs& args, bool* _retval);
1984 : };
1985 :
1986 : /***************************************************************************/
1987 : NS_IMETHODIMP
1988 9 : nsXPCComponents_Constructor::GetInterfaces(uint32_t* aCount, nsIID * **aArray)
1989 : {
1990 9 : const uint32_t count = 2;
1991 9 : *aCount = count;
1992 : nsIID** array;
1993 9 : *aArray = array = static_cast<nsIID**>(moz_xmalloc(count * sizeof(nsIID*)));
1994 9 : if (!array)
1995 0 : return NS_ERROR_OUT_OF_MEMORY;
1996 :
1997 9 : uint32_t index = 0;
1998 : nsIID* clone;
1999 : #define PUSH_IID(id) \
2000 : clone = static_cast<nsIID*>(nsMemory::Clone(&NS_GET_IID( id ), \
2001 : sizeof(nsIID))); \
2002 : if (!clone) \
2003 : goto oom; \
2004 : array[index++] = clone;
2005 :
2006 9 : PUSH_IID(nsIXPCComponents_Constructor)
2007 9 : PUSH_IID(nsIXPCScriptable)
2008 : #undef PUSH_IID
2009 :
2010 9 : return NS_OK;
2011 : oom:
2012 0 : while (index)
2013 0 : free(array[--index]);
2014 0 : free(array);
2015 0 : *aArray = nullptr;
2016 0 : return NS_ERROR_OUT_OF_MEMORY;
2017 : }
2018 :
2019 : NS_IMETHODIMP
2020 9 : nsXPCComponents_Constructor::GetScriptableHelper(nsIXPCScriptable** retval)
2021 : {
2022 9 : *retval = nullptr;
2023 9 : return NS_OK;
2024 : }
2025 :
2026 : NS_IMETHODIMP
2027 0 : nsXPCComponents_Constructor::GetContractID(char * *aContractID)
2028 : {
2029 0 : *aContractID = nullptr;
2030 0 : return NS_ERROR_NOT_AVAILABLE;
2031 : }
2032 :
2033 : NS_IMETHODIMP
2034 0 : nsXPCComponents_Constructor::GetClassDescription(char * *aClassDescription)
2035 : {
2036 : static const char classDescription[] = "XPCComponents_Constructor";
2037 0 : *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
2038 0 : return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
2039 : }
2040 :
2041 : NS_IMETHODIMP
2042 0 : nsXPCComponents_Constructor::GetClassID(nsCID * *aClassID)
2043 : {
2044 0 : *aClassID = nullptr;
2045 0 : return NS_OK;
2046 : }
2047 :
2048 : NS_IMETHODIMP
2049 9 : nsXPCComponents_Constructor::GetFlags(uint32_t* aFlags)
2050 : {
2051 9 : *aFlags = 0;
2052 9 : return NS_OK;
2053 : }
2054 :
2055 : NS_IMETHODIMP
2056 0 : nsXPCComponents_Constructor::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc)
2057 : {
2058 0 : return NS_ERROR_NOT_AVAILABLE;
2059 : }
2060 :
2061 9 : nsXPCComponents_Constructor::nsXPCComponents_Constructor()
2062 : {
2063 9 : }
2064 :
2065 0 : nsXPCComponents_Constructor::~nsXPCComponents_Constructor()
2066 : {
2067 : // empty
2068 0 : }
2069 :
2070 113 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Constructor)
2071 113 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Constructor)
2072 104 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
2073 63 : NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
2074 45 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Constructor)
2075 36 : NS_INTERFACE_MAP_END
2076 :
2077 136 : NS_IMPL_ADDREF(nsXPCComponents_Constructor)
2078 91 : NS_IMPL_RELEASE(nsXPCComponents_Constructor)
2079 :
2080 : // The nsIXPCScriptable map declaration that will generate stubs for us...
2081 : #define XPC_MAP_CLASSNAME nsXPCComponents_Constructor
2082 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Constructor"
2083 : #define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_CALL | \
2084 : XPC_SCRIPTABLE_WANT_CONSTRUCT | \
2085 : XPC_SCRIPTABLE_WANT_HASINSTANCE | \
2086 : XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE)
2087 : #include "xpc_map_end.h" /* This will #undef the above */
2088 :
2089 :
2090 : NS_IMETHODIMP
2091 10 : nsXPCComponents_Constructor::Call(nsIXPConnectWrappedNative* wrapper, JSContext* cx,
2092 : JSObject* objArg, const CallArgs& args, bool* _retval)
2093 : {
2094 20 : RootedObject obj(cx, objArg);
2095 20 : return CallOrConstruct(wrapper, cx, obj, args, _retval);
2096 : }
2097 :
2098 : NS_IMETHODIMP
2099 0 : nsXPCComponents_Constructor::Construct(nsIXPConnectWrappedNative* wrapper, JSContext* cx,
2100 : JSObject* objArg, const CallArgs& args, bool* _retval)
2101 : {
2102 0 : RootedObject obj(cx, objArg);
2103 0 : return CallOrConstruct(wrapper, cx, obj, args, _retval);
2104 : }
2105 :
2106 : // static
2107 : nsresult
2108 10 : nsXPCComponents_Constructor::CallOrConstruct(nsIXPConnectWrappedNative* wrapper,
2109 : JSContext* cx, HandleObject obj,
2110 : const CallArgs& args, bool* _retval)
2111 : {
2112 : // make sure we have at least one arg
2113 :
2114 10 : if (args.length() < 1)
2115 0 : return ThrowAndFail(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx, _retval);
2116 :
2117 : // get the various other object pointers we need
2118 :
2119 10 : nsXPConnect* xpc = nsXPConnect::XPConnect();
2120 10 : XPCWrappedNativeScope* scope = ObjectScope(obj);
2121 20 : nsCOMPtr<nsIXPCComponents> comp;
2122 :
2123 10 : if (!xpc || !scope || !(comp = do_QueryInterface(scope->GetComponents())))
2124 0 : return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
2125 :
2126 : // Do the security check if necessary
2127 :
2128 10 : if (NS_FAILED(nsXPConnect::SecurityManager()->CanCreateInstance(cx, nsXPCConstructor::GetCID()))) {
2129 : // the security manager vetoed. It should have set an exception.
2130 0 : *_retval = false;
2131 0 : return NS_OK;
2132 : }
2133 :
2134 : // initialization params for the Constructor object we will create
2135 20 : nsCOMPtr<nsIJSCID> cClassID;
2136 20 : nsCOMPtr<nsIJSIID> cInterfaceID;
2137 10 : const char* cInitializer = nullptr;
2138 20 : JSAutoByteString cInitializerBytes;
2139 :
2140 10 : if (args.length() >= 3) {
2141 : // args[2] is an initializer function or property name
2142 16 : RootedString str(cx, ToString(cx, args[2]));
2143 8 : if (!str || !(cInitializer = cInitializerBytes.encodeLatin1(cx, str)))
2144 0 : return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
2145 : }
2146 :
2147 10 : if (args.length() >= 2) {
2148 : // args[1] is an iid name string
2149 : // XXXjband support passing "Components.interfaces.foo"?
2150 :
2151 20 : nsCOMPtr<nsIXPCComponents_Interfaces> ifaces;
2152 20 : RootedObject ifacesObj(cx);
2153 :
2154 : // we do the lookup by asking the Components.interfaces object
2155 : // for the property with this name - i.e. we let its caching of these
2156 : // nsIJSIID objects work for us.
2157 :
2158 40 : if (NS_FAILED(comp->GetInterfaces(getter_AddRefs(ifaces))) ||
2159 10 : NS_FAILED(xpc->WrapNative(cx, obj, ifaces,
2160 : NS_GET_IID(nsIXPCComponents_Interfaces),
2161 40 : ifacesObj.address())) || !ifacesObj) {
2162 0 : return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
2163 : }
2164 :
2165 20 : RootedString str(cx, ToString(cx, args[1]));
2166 20 : RootedId id(cx);
2167 10 : if (!str || !JS_StringToId(cx, str, &id))
2168 0 : return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
2169 :
2170 20 : RootedValue val(cx);
2171 10 : if (!JS_GetPropertyById(cx, ifacesObj, id, &val) || val.isPrimitive())
2172 0 : return ThrowAndFail(NS_ERROR_XPC_BAD_IID, cx, _retval);
2173 :
2174 20 : nsCOMPtr<nsIXPConnectWrappedNative> wn;
2175 30 : if (NS_FAILED(xpc->GetWrappedNativeOfJSObject(cx, &val.toObject(),
2176 40 : getter_AddRefs(wn))) || !wn ||
2177 10 : !(cInterfaceID = do_QueryWrappedNative(wn))) {
2178 0 : return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
2179 : }
2180 : } else {
2181 0 : nsCOMPtr<nsIInterfaceInfo> info;
2182 0 : xpc->GetInfoForIID(&NS_GET_IID(nsISupports), getter_AddRefs(info));
2183 :
2184 0 : if (info) {
2185 0 : cInterfaceID = nsJSIID::NewID(info);
2186 : }
2187 0 : if (!cInterfaceID)
2188 0 : return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
2189 : }
2190 :
2191 : // a new scope to avoid warnings about shadowed names
2192 : {
2193 : // argv[0] is a contractid name string
2194 : // XXXjband support passing "Components.classes.foo"?
2195 :
2196 : // we do the lookup by asking the Components.classes object
2197 : // for the property with this name - i.e. we let its caching of these
2198 : // nsIJSCID objects work for us.
2199 :
2200 20 : nsCOMPtr<nsIXPCComponents_Classes> classes;
2201 20 : RootedObject classesObj(cx);
2202 :
2203 40 : if (NS_FAILED(comp->GetClasses(getter_AddRefs(classes))) ||
2204 10 : NS_FAILED(xpc->WrapNative(cx, obj, classes,
2205 : NS_GET_IID(nsIXPCComponents_Classes),
2206 40 : classesObj.address())) || !classesObj) {
2207 0 : return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
2208 : }
2209 :
2210 20 : RootedString str(cx, ToString(cx, args[0]));
2211 20 : RootedId id(cx);
2212 10 : if (!str || !JS_StringToId(cx, str, &id))
2213 0 : return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
2214 :
2215 20 : RootedValue val(cx);
2216 10 : if (!JS_GetPropertyById(cx, classesObj, id, &val) || val.isPrimitive())
2217 0 : return ThrowAndFail(NS_ERROR_XPC_BAD_CID, cx, _retval);
2218 :
2219 20 : nsCOMPtr<nsIXPConnectWrappedNative> wn;
2220 30 : if (NS_FAILED(xpc->GetWrappedNativeOfJSObject(cx, val.toObjectOrNull(),
2221 40 : getter_AddRefs(wn))) || !wn ||
2222 10 : !(cClassID = do_QueryWrappedNative(wn))) {
2223 0 : return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
2224 : }
2225 : }
2226 :
2227 30 : nsCOMPtr<nsIXPCConstructor> ctor = new nsXPCConstructor(cClassID, cInterfaceID, cInitializer);
2228 20 : RootedObject newObj(cx);
2229 :
2230 10 : if (NS_FAILED(xpc->WrapNative(cx, obj, ctor, NS_GET_IID(nsIXPCConstructor), newObj.address())) || !newObj) {
2231 0 : return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval);
2232 : }
2233 :
2234 10 : args.rval().setObject(*newObj);
2235 10 : return NS_OK;
2236 : }
2237 :
2238 : NS_IMETHODIMP
2239 0 : nsXPCComponents_Constructor::HasInstance(nsIXPConnectWrappedNative* wrapper,
2240 : JSContext * cx, JSObject * obj,
2241 : HandleValue val, bool* bp,
2242 : bool* _retval)
2243 : {
2244 0 : if (bp)
2245 0 : *bp = JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIXPCConstructor));
2246 0 : return NS_OK;
2247 : }
2248 :
2249 : class nsXPCComponents_Utils final :
2250 : public nsIXPCComponents_Utils,
2251 : public nsIXPCScriptable
2252 : {
2253 : public:
2254 : // all the interface method declarations...
2255 : NS_DECL_ISUPPORTS
2256 : NS_DECL_NSIXPCSCRIPTABLE
2257 : NS_DECL_NSIXPCCOMPONENTS_UTILS
2258 :
2259 : public:
2260 266 : nsXPCComponents_Utils() { }
2261 :
2262 : private:
2263 0 : virtual ~nsXPCComponents_Utils() { }
2264 : nsCOMPtr<nsIXPCComponents_utils_Sandbox> mSandbox;
2265 : };
2266 :
2267 5000 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Utils)
2268 5000 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Utils)
2269 4733 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
2270 1978 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Utils)
2271 1587 : NS_INTERFACE_MAP_END
2272 :
2273 6553 : NS_IMPL_ADDREF(nsXPCComponents_Utils)
2274 5485 : NS_IMPL_RELEASE(nsXPCComponents_Utils)
2275 :
2276 : // The nsIXPCScriptable map declaration that will generate stubs for us...
2277 : #define XPC_MAP_CLASSNAME nsXPCComponents_Utils
2278 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Utils"
2279 : #define XPC_MAP_FLAGS XPC_SCRIPTABLE_ALLOW_PROP_MODS_DURING_RESOLVE
2280 : #include "xpc_map_end.h" /* This will #undef the above */
2281 :
2282 : NS_IMETHODIMP
2283 16 : nsXPCComponents_Utils::GetSandbox(nsIXPCComponents_utils_Sandbox** aSandbox)
2284 : {
2285 16 : NS_ENSURE_ARG_POINTER(aSandbox);
2286 16 : if (!mSandbox)
2287 2 : mSandbox = NewSandboxConstructor();
2288 :
2289 32 : nsCOMPtr<nsIXPCComponents_utils_Sandbox> rval = mSandbox;
2290 16 : rval.forget(aSandbox);
2291 16 : return NS_OK;
2292 : }
2293 :
2294 : NS_IMETHODIMP
2295 0 : nsXPCComponents_Utils::ReportError(HandleValue error, JSContext* cx)
2296 : {
2297 : // This function shall never fail! Silently eat any failure conditions.
2298 :
2299 0 : nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
2300 0 : if (!console)
2301 0 : return NS_OK;
2302 :
2303 0 : nsGlobalWindow* globalWin = CurrentWindowOrNull(cx);
2304 0 : nsPIDOMWindowInner* win = globalWin ? globalWin->AsInner() : nullptr;
2305 0 : const uint64_t innerWindowID = win ? win->WindowID() : 0;
2306 :
2307 0 : RootedObject errorObj(cx, error.isObject() ? &error.toObject() : nullptr);
2308 0 : JSErrorReport* err = errorObj ? JS_ErrorFromException(cx, errorObj) : nullptr;
2309 :
2310 0 : nsCOMPtr<nsIScriptError> scripterr;
2311 :
2312 0 : if (errorObj) {
2313 : JS::RootedObject stackVal(cx,
2314 0 : FindExceptionStackForConsoleReport(win, error));
2315 0 : if (stackVal) {
2316 0 : scripterr = new nsScriptErrorWithStack(stackVal);
2317 : }
2318 : }
2319 :
2320 0 : nsString fileName;
2321 0 : int32_t lineNo = 0;
2322 :
2323 0 : if (!scripterr) {
2324 0 : nsCOMPtr<nsIStackFrame> frame = dom::GetCurrentJSStack();
2325 0 : if (frame) {
2326 0 : frame->GetFilename(cx, fileName);
2327 0 : frame->GetLineNumber(cx, &lineNo);
2328 0 : JS::Rooted<JS::Value> stack(cx);
2329 0 : nsresult rv = frame->GetNativeSavedFrame(&stack);
2330 0 : if (NS_SUCCEEDED(rv) && stack.isObject()) {
2331 0 : JS::Rooted<JSObject*> stackObj(cx, &stack.toObject());
2332 0 : scripterr = new nsScriptErrorWithStack(stackObj);
2333 : }
2334 : }
2335 : }
2336 :
2337 0 : if (!scripterr) {
2338 0 : scripterr = new nsScriptError();
2339 : }
2340 :
2341 0 : if (err) {
2342 : // It's a proper JS Error
2343 0 : nsAutoString fileUni;
2344 0 : CopyUTF8toUTF16(err->filename, fileUni);
2345 :
2346 0 : uint32_t column = err->tokenOffset();
2347 :
2348 0 : const char16_t* linebuf = err->linebuf();
2349 :
2350 0 : nsresult rv = scripterr->InitWithWindowID(
2351 0 : err->message() ? NS_ConvertUTF8toUTF16(err->message().c_str())
2352 0 : : EmptyString(),
2353 : fileUni,
2354 0 : linebuf ? nsDependentString(linebuf, err->linebufLength()) : EmptyString(),
2355 : err->lineno,
2356 0 : column, err->flags, "XPConnect JavaScript", innerWindowID);
2357 0 : NS_ENSURE_SUCCESS(rv, NS_OK);
2358 :
2359 0 : console->LogMessage(scripterr);
2360 0 : return NS_OK;
2361 : }
2362 :
2363 : // It's not a JS Error object, so we synthesize as best we're able.
2364 0 : RootedString msgstr(cx, ToString(cx, error));
2365 0 : if (!msgstr)
2366 0 : return NS_OK;
2367 :
2368 0 : nsAutoJSString msg;
2369 0 : if (!msg.init(cx, msgstr))
2370 0 : return NS_OK;
2371 :
2372 0 : nsresult rv = scripterr->InitWithWindowID(
2373 0 : msg, fileName, EmptyString(), lineNo, 0, 0,
2374 0 : "XPConnect JavaScript", innerWindowID);
2375 0 : NS_ENSURE_SUCCESS(rv, NS_OK);
2376 :
2377 0 : console->LogMessage(scripterr);
2378 0 : return NS_OK;
2379 : }
2380 :
2381 : NS_IMETHODIMP
2382 0 : nsXPCComponents_Utils::EvalInSandbox(const nsAString& source,
2383 : HandleValue sandboxVal,
2384 : HandleValue version,
2385 : const nsACString& filenameArg,
2386 : int32_t lineNumber,
2387 : JSContext* cx,
2388 : uint8_t optionalArgc,
2389 : MutableHandleValue retval)
2390 : {
2391 0 : RootedObject sandbox(cx);
2392 0 : if (!JS_ValueToObject(cx, sandboxVal, &sandbox) || !sandbox)
2393 0 : return NS_ERROR_INVALID_ARG;
2394 :
2395 : // Optional third argument: JS version, as a string.
2396 0 : JSVersion jsVersion = JSVERSION_DEFAULT;
2397 0 : if (optionalArgc >= 1) {
2398 0 : JSString* jsVersionStr = ToString(cx, version);
2399 0 : if (!jsVersionStr)
2400 0 : return NS_ERROR_INVALID_ARG;
2401 :
2402 0 : JSAutoByteString bytes(cx, jsVersionStr);
2403 0 : if (!bytes)
2404 0 : return NS_ERROR_INVALID_ARG;
2405 :
2406 0 : jsVersion = JS_StringToVersion(bytes.ptr());
2407 : // Explicitly check for "latest", which we support for sandboxes but
2408 : // isn't in the set of web-exposed version strings.
2409 0 : if (jsVersion == JSVERSION_UNKNOWN &&
2410 0 : !strcmp(bytes.ptr(), "latest"))
2411 : {
2412 0 : jsVersion = JSVERSION_LATEST;
2413 : }
2414 0 : if (jsVersion == JSVERSION_UNKNOWN)
2415 0 : return NS_ERROR_INVALID_ARG;
2416 : }
2417 :
2418 : // Optional fourth and fifth arguments: filename and line number.
2419 0 : int32_t lineNo = (optionalArgc >= 3) ? lineNumber : 1;
2420 0 : nsCString filename;
2421 0 : if (!filenameArg.IsVoid()) {
2422 0 : filename.Assign(filenameArg);
2423 : } else {
2424 : // Get the current source info from xpc.
2425 : nsresult rv;
2426 0 : nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv);
2427 0 : NS_ENSURE_SUCCESS(rv, rv);
2428 :
2429 0 : nsCOMPtr<nsIStackFrame> frame;
2430 0 : xpc->GetCurrentJSStack(getter_AddRefs(frame));
2431 0 : if (frame) {
2432 0 : nsString frameFile;
2433 0 : frame->GetFilename(cx, frameFile);
2434 0 : CopyUTF16toUTF8(frameFile, filename);
2435 0 : frame->GetLineNumber(cx, &lineNo);
2436 : }
2437 : }
2438 :
2439 0 : return xpc::EvalInSandbox(cx, sandbox, source, filename, lineNo,
2440 0 : jsVersion, retval);
2441 : }
2442 :
2443 : NS_IMETHODIMP
2444 0 : nsXPCComponents_Utils::GetSandboxAddonId(HandleValue sandboxVal,
2445 : JSContext* cx, MutableHandleValue rval)
2446 : {
2447 0 : if (!sandboxVal.isObject())
2448 0 : return NS_ERROR_INVALID_ARG;
2449 :
2450 0 : RootedObject sandbox(cx, &sandboxVal.toObject());
2451 0 : sandbox = js::CheckedUnwrap(sandbox);
2452 0 : if (!sandbox || !xpc::IsSandbox(sandbox))
2453 0 : return NS_ERROR_INVALID_ARG;
2454 :
2455 0 : return xpc::GetSandboxAddonId(cx, sandbox, rval);
2456 : }
2457 :
2458 : NS_IMETHODIMP
2459 0 : nsXPCComponents_Utils::GetSandboxMetadata(HandleValue sandboxVal,
2460 : JSContext* cx, MutableHandleValue rval)
2461 : {
2462 0 : if (!sandboxVal.isObject())
2463 0 : return NS_ERROR_INVALID_ARG;
2464 :
2465 0 : RootedObject sandbox(cx, &sandboxVal.toObject());
2466 0 : sandbox = js::CheckedUnwrap(sandbox);
2467 0 : if (!sandbox || !xpc::IsSandbox(sandbox))
2468 0 : return NS_ERROR_INVALID_ARG;
2469 :
2470 0 : return xpc::GetSandboxMetadata(cx, sandbox, rval);
2471 : }
2472 :
2473 : NS_IMETHODIMP
2474 0 : nsXPCComponents_Utils::SetSandboxMetadata(HandleValue sandboxVal,
2475 : HandleValue metadataVal,
2476 : JSContext* cx)
2477 : {
2478 0 : if (!sandboxVal.isObject())
2479 0 : return NS_ERROR_INVALID_ARG;
2480 :
2481 0 : RootedObject sandbox(cx, &sandboxVal.toObject());
2482 0 : sandbox = js::CheckedUnwrap(sandbox);
2483 0 : if (!sandbox || !xpc::IsSandbox(sandbox))
2484 0 : return NS_ERROR_INVALID_ARG;
2485 :
2486 0 : nsresult rv = xpc::SetSandboxMetadata(cx, sandbox, metadataVal);
2487 0 : NS_ENSURE_SUCCESS(rv, rv);
2488 :
2489 0 : return NS_OK;
2490 : }
2491 :
2492 : NS_IMETHODIMP
2493 998 : nsXPCComponents_Utils::Import(const nsACString& registryLocation,
2494 : HandleValue targetObj,
2495 : JSContext* cx,
2496 : uint8_t optionalArgc,
2497 : MutableHandleValue retval)
2498 : {
2499 : nsCOMPtr<xpcIJSModuleLoader> moduleloader =
2500 1996 : do_GetService(MOZJSCOMPONENTLOADER_CONTRACTID);
2501 998 : if (!moduleloader)
2502 0 : return NS_ERROR_FAILURE;
2503 :
2504 1996 : const nsCString& flatLocation = PromiseFlatCString(registryLocation);
2505 1996 : AUTO_PROFILER_LABEL_DYNAMIC("nsXPCComponents_Utils::Import", OTHER,
2506 : flatLocation.get());
2507 :
2508 998 : return moduleloader->Import(registryLocation, targetObj, cx, optionalArgc, retval);
2509 : }
2510 :
2511 : NS_IMETHODIMP
2512 0 : nsXPCComponents_Utils::IsModuleLoaded(const nsACString& registryLocation, bool* retval)
2513 : {
2514 : nsCOMPtr<xpcIJSModuleLoader> moduleloader =
2515 0 : do_GetService(MOZJSCOMPONENTLOADER_CONTRACTID);
2516 0 : if (!moduleloader)
2517 0 : return NS_ERROR_FAILURE;
2518 0 : return moduleloader->IsModuleLoaded(registryLocation, retval);
2519 : }
2520 :
2521 : NS_IMETHODIMP
2522 0 : nsXPCComponents_Utils::Unload(const nsACString & registryLocation)
2523 : {
2524 : nsCOMPtr<xpcIJSModuleLoader> moduleloader =
2525 0 : do_GetService(MOZJSCOMPONENTLOADER_CONTRACTID);
2526 0 : if (!moduleloader)
2527 0 : return NS_ERROR_FAILURE;
2528 0 : return moduleloader->Unload(registryLocation);
2529 : }
2530 :
2531 : NS_IMETHODIMP
2532 20 : nsXPCComponents_Utils::ImportGlobalProperties(HandleValue aPropertyList,
2533 : JSContext* cx)
2534 : {
2535 40 : RootedObject global(cx, CurrentGlobalOrNull(cx));
2536 20 : MOZ_ASSERT(global);
2537 :
2538 : // Don't allow doing this if the global is a Window
2539 : nsGlobalWindow* win;
2540 20 : if (NS_SUCCEEDED(UNWRAP_OBJECT(Window, &global, win))) {
2541 0 : return NS_ERROR_NOT_AVAILABLE;
2542 : }
2543 :
2544 20 : GlobalProperties options;
2545 20 : NS_ENSURE_TRUE(aPropertyList.isObject(), NS_ERROR_INVALID_ARG);
2546 :
2547 40 : RootedObject propertyList(cx, &aPropertyList.toObject());
2548 : bool isArray;
2549 20 : if (NS_WARN_IF(!JS_IsArrayObject(cx, propertyList, &isArray))) {
2550 0 : return NS_ERROR_FAILURE;
2551 : }
2552 20 : if (NS_WARN_IF(!isArray)) {
2553 0 : return NS_ERROR_INVALID_ARG;
2554 : }
2555 :
2556 80 : if (!options.Parse(cx, propertyList) ||
2557 60 : !options.DefineInXPCComponents(cx, global))
2558 : {
2559 0 : return NS_ERROR_FAILURE;
2560 : }
2561 :
2562 20 : return NS_OK;
2563 : }
2564 :
2565 : NS_IMETHODIMP
2566 0 : nsXPCComponents_Utils::GetWeakReference(HandleValue object, JSContext* cx,
2567 : xpcIJSWeakReference** _retval)
2568 : {
2569 0 : RefPtr<xpcJSWeakReference> ref = new xpcJSWeakReference();
2570 0 : nsresult rv = ref->Init(cx, object);
2571 0 : NS_ENSURE_SUCCESS(rv, rv);
2572 0 : ref.forget(_retval);
2573 0 : return NS_OK;
2574 : }
2575 :
2576 : NS_IMETHODIMP
2577 0 : nsXPCComponents_Utils::ForceGC()
2578 : {
2579 0 : JSContext* cx = XPCJSContext::Get()->Context();
2580 0 : PrepareForFullGC(cx);
2581 0 : GCForReason(cx, GC_NORMAL, gcreason::COMPONENT_UTILS);
2582 0 : return NS_OK;
2583 : }
2584 :
2585 : NS_IMETHODIMP
2586 0 : nsXPCComponents_Utils::ForceCC(nsICycleCollectorListener* listener)
2587 : {
2588 0 : nsJSContext::CycleCollectNow(listener);
2589 0 : return NS_OK;
2590 : }
2591 :
2592 : NS_IMETHODIMP
2593 0 : nsXPCComponents_Utils::FinishCC()
2594 : {
2595 0 : nsCycleCollector_finishAnyCurrentCollection();
2596 0 : return NS_OK;
2597 : }
2598 :
2599 : NS_IMETHODIMP
2600 0 : nsXPCComponents_Utils::CcSlice(int64_t budget)
2601 : {
2602 0 : nsJSContext::RunCycleCollectorWorkSlice(budget);
2603 0 : return NS_OK;
2604 : }
2605 :
2606 : NS_IMETHODIMP
2607 0 : nsXPCComponents_Utils::GetMaxCCSliceTimeSinceClear(int32_t* out)
2608 : {
2609 0 : *out = nsJSContext::GetMaxCCSliceTimeSinceClear();
2610 0 : return NS_OK;
2611 : }
2612 :
2613 : NS_IMETHODIMP
2614 0 : nsXPCComponents_Utils::ClearMaxCCTime()
2615 : {
2616 0 : nsJSContext::ClearMaxCCSliceTime();
2617 0 : return NS_OK;
2618 : }
2619 :
2620 : NS_IMETHODIMP
2621 0 : nsXPCComponents_Utils::ForceShrinkingGC()
2622 : {
2623 0 : JSContext* cx = dom::danger::GetJSContext();
2624 0 : PrepareForFullGC(cx);
2625 0 : GCForReason(cx, GC_SHRINK, gcreason::COMPONENT_UTILS);
2626 0 : return NS_OK;
2627 : }
2628 :
2629 0 : class PreciseGCRunnable : public Runnable
2630 : {
2631 : public:
2632 0 : PreciseGCRunnable(ScheduledGCCallback* aCallback, bool aShrinking)
2633 0 : : mozilla::Runnable("PreciseGCRunnable")
2634 : , mCallback(aCallback)
2635 0 : , mShrinking(aShrinking)
2636 : {
2637 0 : }
2638 :
2639 0 : NS_IMETHOD Run() override
2640 : {
2641 0 : nsJSContext::GarbageCollectNow(gcreason::COMPONENT_UTILS,
2642 : nsJSContext::NonIncrementalGC,
2643 0 : mShrinking ?
2644 : nsJSContext::ShrinkingGC :
2645 0 : nsJSContext::NonShrinkingGC);
2646 :
2647 0 : mCallback->Callback();
2648 0 : return NS_OK;
2649 : }
2650 :
2651 : private:
2652 : RefPtr<ScheduledGCCallback> mCallback;
2653 : bool mShrinking;
2654 : };
2655 :
2656 : NS_IMETHODIMP
2657 0 : nsXPCComponents_Utils::SchedulePreciseGC(ScheduledGCCallback* aCallback)
2658 : {
2659 0 : RefPtr<PreciseGCRunnable> event = new PreciseGCRunnable(aCallback, false);
2660 0 : return NS_DispatchToMainThread(event);
2661 : }
2662 :
2663 : NS_IMETHODIMP
2664 0 : nsXPCComponents_Utils::SchedulePreciseShrinkingGC(ScheduledGCCallback* aCallback)
2665 : {
2666 0 : RefPtr<PreciseGCRunnable> event = new PreciseGCRunnable(aCallback, true);
2667 0 : return NS_DispatchToMainThread(event);
2668 : }
2669 :
2670 : NS_IMETHODIMP
2671 0 : nsXPCComponents_Utils::UnlinkGhostWindows()
2672 : {
2673 : #ifdef DEBUG
2674 0 : nsWindowMemoryReporter::UnlinkGhostWindows();
2675 0 : return NS_OK;
2676 : #else
2677 : return NS_ERROR_NOT_IMPLEMENTED;
2678 : #endif
2679 : }
2680 :
2681 : NS_IMETHODIMP
2682 0 : nsXPCComponents_Utils::GetJSTestingFunctions(JSContext* cx,
2683 : MutableHandleValue retval)
2684 : {
2685 0 : JSObject* obj = js::GetTestingFunctions(cx);
2686 0 : if (!obj)
2687 0 : return NS_ERROR_XPC_JAVASCRIPT_ERROR;
2688 0 : retval.setObject(*obj);
2689 0 : return NS_OK;
2690 : }
2691 :
2692 : NS_IMETHODIMP
2693 0 : nsXPCComponents_Utils::CallFunctionWithAsyncStack(HandleValue function,
2694 : nsIStackFrame* stack,
2695 : const nsAString& asyncCause,
2696 : JSContext* cx,
2697 : MutableHandleValue retval)
2698 : {
2699 : nsresult rv;
2700 :
2701 0 : if (!stack || asyncCause.IsEmpty()) {
2702 0 : return NS_ERROR_INVALID_ARG;
2703 : }
2704 :
2705 0 : JS::Rooted<JS::Value> asyncStack(cx);
2706 0 : rv = stack->GetNativeSavedFrame(&asyncStack);
2707 0 : if (NS_FAILED(rv))
2708 0 : return rv;
2709 0 : if (!asyncStack.isObject()) {
2710 0 : JS_ReportErrorASCII(cx, "Must use a native JavaScript stack frame");
2711 0 : return NS_ERROR_INVALID_ARG;
2712 : }
2713 :
2714 0 : JS::Rooted<JSObject*> asyncStackObj(cx, &asyncStack.toObject());
2715 :
2716 0 : NS_ConvertUTF16toUTF8 utf8Cause(asyncCause);
2717 : JS::AutoSetAsyncStackForNewCalls sas(cx, asyncStackObj, utf8Cause.get(),
2718 0 : JS::AutoSetAsyncStackForNewCalls::AsyncCallKind::EXPLICIT);
2719 :
2720 0 : if (!JS_CallFunctionValue(cx, nullptr, function,
2721 0 : JS::HandleValueArray::empty(), retval))
2722 : {
2723 0 : return NS_ERROR_XPC_JAVASCRIPT_ERROR;
2724 : }
2725 :
2726 0 : return NS_OK;
2727 : }
2728 :
2729 : NS_IMETHODIMP
2730 0 : nsXPCComponents_Utils::GetGlobalForObject(HandleValue object,
2731 : JSContext* cx,
2732 : MutableHandleValue retval)
2733 : {
2734 : // First argument must be an object.
2735 0 : if (object.isPrimitive())
2736 0 : return NS_ERROR_XPC_BAD_CONVERT_JS;
2737 :
2738 : // Wrappers are parented to their the global in their home compartment. But
2739 : // when getting the global for a cross-compartment wrapper, we really want
2740 : // a wrapper for the foreign global. So we need to unwrap before getting the
2741 : // parent, enter the compartment for the duration of the call, and wrap the
2742 : // result.
2743 0 : Rooted<JSObject*> obj(cx, &object.toObject());
2744 0 : obj = js::UncheckedUnwrap(obj);
2745 : {
2746 0 : JSAutoCompartment ac(cx, obj);
2747 0 : obj = JS_GetGlobalForObject(cx, obj);
2748 : }
2749 :
2750 0 : if (!JS_WrapObject(cx, &obj))
2751 0 : return NS_ERROR_FAILURE;
2752 :
2753 : // Get the WindowProxy if necessary.
2754 0 : obj = js::ToWindowProxyIfWindow(obj);
2755 :
2756 0 : retval.setObject(*obj);
2757 0 : return NS_OK;
2758 : }
2759 :
2760 : NS_IMETHODIMP
2761 0 : nsXPCComponents_Utils::IsProxy(HandleValue vobj, JSContext* cx, bool* rval)
2762 : {
2763 0 : if (!vobj.isObject()) {
2764 0 : *rval = false;
2765 0 : return NS_OK;
2766 : }
2767 :
2768 0 : RootedObject obj(cx, &vobj.toObject());
2769 0 : obj = js::CheckedUnwrap(obj, /* stopAtWindowProxy = */ false);
2770 0 : NS_ENSURE_TRUE(obj, NS_ERROR_FAILURE);
2771 :
2772 0 : *rval = js::IsScriptedProxy(obj);
2773 0 : return NS_OK;
2774 : }
2775 :
2776 : NS_IMETHODIMP
2777 0 : nsXPCComponents_Utils::ExportFunction(HandleValue vfunction, HandleValue vscope,
2778 : HandleValue voptions, JSContext* cx,
2779 : MutableHandleValue rval)
2780 : {
2781 0 : if (!xpc::ExportFunction(cx, vfunction, vscope, voptions, rval))
2782 0 : return NS_ERROR_FAILURE;
2783 0 : return NS_OK;
2784 : }
2785 :
2786 : NS_IMETHODIMP
2787 0 : nsXPCComponents_Utils::CreateObjectIn(HandleValue vobj, HandleValue voptions,
2788 : JSContext* cx, MutableHandleValue rval)
2789 : {
2790 0 : RootedObject optionsObject(cx, voptions.isObject() ? &voptions.toObject()
2791 0 : : nullptr);
2792 0 : CreateObjectInOptions options(cx, optionsObject);
2793 0 : if (voptions.isObject() &&
2794 0 : !options.Parse())
2795 : {
2796 0 : return NS_ERROR_FAILURE;
2797 : }
2798 :
2799 0 : if (!xpc::CreateObjectIn(cx, vobj, options, rval))
2800 0 : return NS_ERROR_FAILURE;
2801 0 : return NS_OK;
2802 : }
2803 :
2804 : NS_IMETHODIMP
2805 0 : nsXPCComponents_Utils::MakeObjectPropsNormal(HandleValue vobj, JSContext* cx)
2806 : {
2807 0 : if (!cx)
2808 0 : return NS_ERROR_FAILURE;
2809 :
2810 : // first argument must be an object
2811 0 : if (vobj.isPrimitive())
2812 0 : return NS_ERROR_XPC_BAD_CONVERT_JS;
2813 :
2814 0 : RootedObject obj(cx, js::UncheckedUnwrap(&vobj.toObject()));
2815 0 : JSAutoCompartment ac(cx, obj);
2816 0 : Rooted<IdVector> ida(cx, IdVector(cx));
2817 0 : if (!JS_Enumerate(cx, obj, &ida))
2818 0 : return NS_ERROR_FAILURE;
2819 :
2820 0 : RootedId id(cx);
2821 0 : RootedValue v(cx);
2822 0 : for (size_t i = 0; i < ida.length(); ++i) {
2823 0 : id = ida[i];
2824 :
2825 0 : if (!JS_GetPropertyById(cx, obj, id, &v))
2826 0 : return NS_ERROR_FAILURE;
2827 :
2828 0 : if (v.isPrimitive())
2829 0 : continue;
2830 :
2831 0 : RootedObject propobj(cx, &v.toObject());
2832 : // TODO Deal with non-functions.
2833 0 : if (!js::IsWrapper(propobj) || !JS::IsCallable(propobj))
2834 0 : continue;
2835 :
2836 0 : FunctionForwarderOptions forwarderOptions;
2837 0 : if (!NewFunctionForwarder(cx, id, propobj, forwarderOptions, &v) ||
2838 0 : !JS_SetPropertyById(cx, obj, id, v))
2839 0 : return NS_ERROR_FAILURE;
2840 : }
2841 :
2842 0 : return NS_OK;
2843 : }
2844 :
2845 : NS_IMETHODIMP
2846 0 : nsXPCComponents_Utils::IsDeadWrapper(HandleValue obj, bool* out)
2847 : {
2848 0 : *out = false;
2849 0 : if (obj.isPrimitive())
2850 0 : return NS_ERROR_INVALID_ARG;
2851 :
2852 : // We should never have cross-compartment wrappers for dead wrappers.
2853 0 : MOZ_ASSERT_IF(js::IsCrossCompartmentWrapper(&obj.toObject()),
2854 : !JS_IsDeadWrapper(js::UncheckedUnwrap(&obj.toObject())));
2855 :
2856 0 : *out = JS_IsDeadWrapper(&obj.toObject());
2857 0 : return NS_OK;
2858 : }
2859 :
2860 : NS_IMETHODIMP
2861 0 : nsXPCComponents_Utils::IsCrossProcessWrapper(HandleValue obj, bool* out)
2862 : {
2863 0 : *out = false;
2864 0 : if (obj.isPrimitive())
2865 0 : return NS_ERROR_INVALID_ARG;
2866 :
2867 0 : *out = jsipc::IsWrappedCPOW(&obj.toObject());
2868 0 : return NS_OK;
2869 : }
2870 :
2871 : NS_IMETHODIMP
2872 0 : nsXPCComponents_Utils::GetCrossProcessWrapperTag(HandleValue obj, nsACString& out)
2873 : {
2874 0 : if (obj.isPrimitive() || !jsipc::IsWrappedCPOW(&obj.toObject()))
2875 0 : return NS_ERROR_INVALID_ARG;
2876 :
2877 0 : jsipc::GetWrappedCPOWTag(&obj.toObject(), out);
2878 0 : return NS_OK;
2879 : }
2880 :
2881 : NS_IMETHODIMP
2882 1 : nsXPCComponents_Utils::PermitCPOWsInScope(HandleValue obj)
2883 : {
2884 1 : if (!obj.isObject())
2885 0 : return NS_ERROR_INVALID_ARG;
2886 :
2887 1 : JSObject* scopeObj = js::UncheckedUnwrap(&obj.toObject());
2888 1 : CompartmentPrivate::Get(scopeObj)->allowCPOWs = true;
2889 1 : return NS_OK;
2890 : }
2891 :
2892 : NS_IMETHODIMP
2893 0 : nsXPCComponents_Utils::RecomputeWrappers(HandleValue vobj, JSContext* cx)
2894 : {
2895 : // Determine the compartment of the given object, if any.
2896 0 : JSCompartment* c = vobj.isObject()
2897 0 : ? js::GetObjectCompartment(js::UncheckedUnwrap(&vobj.toObject()))
2898 0 : : nullptr;
2899 :
2900 : // If no compartment was given, recompute all.
2901 0 : if (!c)
2902 0 : js::RecomputeWrappers(cx, js::AllCompartments(), js::AllCompartments());
2903 : // Otherwise, recompute wrappers for the given compartment.
2904 : else
2905 0 : js::RecomputeWrappers(cx, js::SingleCompartment(c), js::AllCompartments()) &&
2906 0 : js::RecomputeWrappers(cx, js::AllCompartments(), js::SingleCompartment(c));
2907 :
2908 0 : return NS_OK;
2909 : }
2910 :
2911 : NS_IMETHODIMP
2912 0 : nsXPCComponents_Utils::SetWantXrays(HandleValue vscope, JSContext* cx)
2913 : {
2914 0 : if (!vscope.isObject())
2915 0 : return NS_ERROR_INVALID_ARG;
2916 0 : JSObject* scopeObj = js::UncheckedUnwrap(&vscope.toObject());
2917 0 : JSCompartment* compartment = js::GetObjectCompartment(scopeObj);
2918 0 : CompartmentPrivate::Get(scopeObj)->wantXrays = true;
2919 0 : bool ok = js::RecomputeWrappers(cx, js::SingleCompartment(compartment),
2920 0 : js::AllCompartments());
2921 0 : NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);
2922 0 : return NS_OK;
2923 : }
2924 :
2925 : NS_IMETHODIMP
2926 0 : nsXPCComponents_Utils::ForcePermissiveCOWs(JSContext* cx)
2927 : {
2928 0 : xpc::CrashIfNotInAutomation();
2929 0 : CompartmentPrivate::Get(CurrentGlobalOrNull(cx))->forcePermissiveCOWs = true;
2930 0 : return NS_OK;
2931 : }
2932 :
2933 : NS_IMETHODIMP
2934 0 : nsXPCComponents_Utils::ForcePrivilegedComponentsForScope(HandleValue vscope,
2935 : JSContext* cx)
2936 : {
2937 0 : if (!vscope.isObject())
2938 0 : return NS_ERROR_INVALID_ARG;
2939 0 : xpc::CrashIfNotInAutomation();
2940 0 : JSObject* scopeObj = js::UncheckedUnwrap(&vscope.toObject());
2941 0 : XPCWrappedNativeScope* scope = ObjectScope(scopeObj);
2942 0 : scope->ForcePrivilegedComponents();
2943 0 : return NS_OK;
2944 : }
2945 :
2946 : NS_IMETHODIMP
2947 0 : nsXPCComponents_Utils::GetComponentsForScope(HandleValue vscope, JSContext* cx,
2948 : MutableHandleValue rval)
2949 : {
2950 0 : if (!vscope.isObject())
2951 0 : return NS_ERROR_INVALID_ARG;
2952 0 : JSObject* scopeObj = js::UncheckedUnwrap(&vscope.toObject());
2953 0 : XPCWrappedNativeScope* scope = ObjectScope(scopeObj);
2954 0 : RootedObject components(cx);
2955 0 : if (!scope->GetComponentsJSObject(&components))
2956 0 : return NS_ERROR_FAILURE;
2957 0 : if (!JS_WrapObject(cx, &components))
2958 0 : return NS_ERROR_FAILURE;
2959 0 : rval.setObject(*components);
2960 0 : return NS_OK;
2961 : }
2962 :
2963 : NS_IMETHODIMP
2964 0 : nsXPCComponents_Utils::Dispatch(HandleValue runnableArg, HandleValue scope,
2965 : JSContext* cx)
2966 : {
2967 0 : RootedValue runnable(cx, runnableArg);
2968 : // Enter the given compartment, if any, and rewrap runnable.
2969 0 : Maybe<JSAutoCompartment> ac;
2970 0 : if (scope.isObject()) {
2971 0 : JSObject* scopeObj = js::UncheckedUnwrap(&scope.toObject());
2972 0 : if (!scopeObj)
2973 0 : return NS_ERROR_FAILURE;
2974 0 : ac.emplace(cx, scopeObj);
2975 0 : if (!JS_WrapValue(cx, &runnable))
2976 0 : return NS_ERROR_FAILURE;
2977 : }
2978 :
2979 : // Get an XPCWrappedJS for |runnable|.
2980 0 : if (!runnable.isObject())
2981 0 : return NS_ERROR_INVALID_ARG;
2982 :
2983 0 : nsCOMPtr<nsIRunnable> run;
2984 0 : nsresult rv = nsXPConnect::XPConnect()->WrapJS(cx, &runnable.toObject(),
2985 : NS_GET_IID(nsIRunnable),
2986 0 : getter_AddRefs(run));
2987 0 : NS_ENSURE_SUCCESS(rv, rv);
2988 0 : MOZ_ASSERT(run);
2989 :
2990 : // Dispatch.
2991 0 : return NS_DispatchToMainThread(run);
2992 : }
2993 :
2994 : #define GENERATE_JSCONTEXTOPTION_GETTER_SETTER(_attr, _getter, _setter) \
2995 : NS_IMETHODIMP \
2996 : nsXPCComponents_Utils::Get## _attr(JSContext* cx, bool* aValue) \
2997 : { \
2998 : *aValue = ContextOptionsRef(cx)._getter(); \
2999 : return NS_OK; \
3000 : } \
3001 : NS_IMETHODIMP \
3002 : nsXPCComponents_Utils::Set## _attr(JSContext* cx, bool aValue) \
3003 : { \
3004 : ContextOptionsRef(cx)._setter(aValue); \
3005 : return NS_OK; \
3006 : }
3007 :
3008 0 : GENERATE_JSCONTEXTOPTION_GETTER_SETTER(Strict, extraWarnings, setExtraWarnings)
3009 0 : GENERATE_JSCONTEXTOPTION_GETTER_SETTER(Werror, werror, setWerror)
3010 0 : GENERATE_JSCONTEXTOPTION_GETTER_SETTER(Strict_mode, strictMode, setStrictMode)
3011 0 : GENERATE_JSCONTEXTOPTION_GETTER_SETTER(Ion, ion, setIon)
3012 :
3013 : #undef GENERATE_JSCONTEXTOPTION_GETTER_SETTER
3014 :
3015 : NS_IMETHODIMP
3016 0 : nsXPCComponents_Utils::SetGCZeal(int32_t aValue, JSContext* cx)
3017 : {
3018 : #ifdef JS_GC_ZEAL
3019 0 : JS_SetGCZeal(cx, uint8_t(aValue), JS_DEFAULT_ZEAL_FREQ);
3020 : #endif
3021 0 : return NS_OK;
3022 : }
3023 :
3024 : NS_IMETHODIMP
3025 0 : nsXPCComponents_Utils::GetIsInAutomation(bool* aResult)
3026 : {
3027 0 : NS_ENSURE_ARG_POINTER(aResult);
3028 :
3029 0 : *aResult = xpc::IsInAutomation();
3030 0 : return NS_OK;
3031 : }
3032 :
3033 : NS_IMETHODIMP
3034 0 : nsXPCComponents_Utils::CrashIfNotInAutomation()
3035 : {
3036 0 : xpc::CrashIfNotInAutomation();
3037 0 : return NS_OK;
3038 : }
3039 :
3040 : NS_IMETHODIMP
3041 0 : nsXPCComponents_Utils::NukeSandbox(HandleValue obj, JSContext* cx)
3042 : {
3043 0 : AUTO_PROFILER_LABEL("nsXPCComponents_Utils::NukeSandbox", JS);
3044 0 : NS_ENSURE_TRUE(obj.isObject(), NS_ERROR_INVALID_ARG);
3045 0 : JSObject* wrapper = &obj.toObject();
3046 0 : NS_ENSURE_TRUE(IsWrapper(wrapper), NS_ERROR_INVALID_ARG);
3047 0 : RootedObject sb(cx, UncheckedUnwrap(wrapper));
3048 0 : NS_ENSURE_TRUE(IsSandbox(sb), NS_ERROR_INVALID_ARG);
3049 :
3050 0 : xpc::NukeAllWrappersForCompartment(cx, GetObjectCompartment(sb));
3051 :
3052 0 : return NS_OK;
3053 : }
3054 :
3055 : NS_IMETHODIMP
3056 0 : nsXPCComponents_Utils::BlockScriptForGlobal(HandleValue globalArg,
3057 : JSContext* cx)
3058 : {
3059 0 : NS_ENSURE_TRUE(globalArg.isObject(), NS_ERROR_INVALID_ARG);
3060 0 : RootedObject global(cx, UncheckedUnwrap(&globalArg.toObject(),
3061 0 : /* stopAtWindowProxy = */ false));
3062 0 : NS_ENSURE_TRUE(JS_IsGlobalObject(global), NS_ERROR_INVALID_ARG);
3063 0 : if (nsContentUtils::IsSystemPrincipal(xpc::GetObjectPrincipal(global))) {
3064 0 : JS_ReportErrorASCII(cx, "Script may not be disabled for system globals");
3065 0 : return NS_ERROR_FAILURE;
3066 : }
3067 0 : Scriptability::Get(global).Block();
3068 0 : return NS_OK;
3069 : }
3070 :
3071 : NS_IMETHODIMP
3072 0 : nsXPCComponents_Utils::UnblockScriptForGlobal(HandleValue globalArg,
3073 : JSContext* cx)
3074 : {
3075 0 : NS_ENSURE_TRUE(globalArg.isObject(), NS_ERROR_INVALID_ARG);
3076 0 : RootedObject global(cx, UncheckedUnwrap(&globalArg.toObject(),
3077 0 : /* stopAtWindowProxy = */ false));
3078 0 : NS_ENSURE_TRUE(JS_IsGlobalObject(global), NS_ERROR_INVALID_ARG);
3079 0 : if (nsContentUtils::IsSystemPrincipal(xpc::GetObjectPrincipal(global))) {
3080 0 : JS_ReportErrorASCII(cx, "Script may not be disabled for system globals");
3081 0 : return NS_ERROR_FAILURE;
3082 : }
3083 0 : Scriptability::Get(global).Unblock();
3084 0 : return NS_OK;
3085 : }
3086 :
3087 : NS_IMETHODIMP
3088 0 : nsXPCComponents_Utils::IsXrayWrapper(HandleValue obj, bool* aRetval)
3089 : {
3090 0 : *aRetval =
3091 0 : obj.isObject() && xpc::WrapperFactory::IsXrayWrapper(&obj.toObject());
3092 0 : return NS_OK;
3093 : }
3094 :
3095 : NS_IMETHODIMP
3096 0 : nsXPCComponents_Utils::WaiveXrays(HandleValue aVal, JSContext* aCx, MutableHandleValue aRetval)
3097 : {
3098 0 : RootedValue value(aCx, aVal);
3099 0 : if (!xpc::WrapperFactory::WaiveXrayAndWrap(aCx, &value))
3100 0 : return NS_ERROR_FAILURE;
3101 0 : aRetval.set(value);
3102 0 : return NS_OK;
3103 : }
3104 :
3105 : NS_IMETHODIMP
3106 0 : nsXPCComponents_Utils::UnwaiveXrays(HandleValue aVal, JSContext* aCx, MutableHandleValue aRetval)
3107 : {
3108 0 : if (!aVal.isObject()) {
3109 0 : aRetval.set(aVal);
3110 0 : return NS_OK;
3111 : }
3112 :
3113 0 : RootedObject obj(aCx, js::UncheckedUnwrap(&aVal.toObject()));
3114 0 : if (!JS_WrapObject(aCx, &obj))
3115 0 : return NS_ERROR_FAILURE;
3116 0 : aRetval.setObject(*obj);
3117 0 : return NS_OK;
3118 : }
3119 :
3120 : NS_IMETHODIMP
3121 0 : nsXPCComponents_Utils::GetClassName(HandleValue aObj, bool aUnwrap, JSContext* aCx, char** aRv)
3122 : {
3123 0 : if (!aObj.isObject())
3124 0 : return NS_ERROR_INVALID_ARG;
3125 0 : RootedObject obj(aCx, &aObj.toObject());
3126 0 : if (aUnwrap)
3127 0 : obj = js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false);
3128 0 : *aRv = NS_strdup(js::GetObjectClass(obj)->name);
3129 0 : NS_ENSURE_TRUE(*aRv, NS_ERROR_OUT_OF_MEMORY);
3130 0 : return NS_OK;
3131 : }
3132 :
3133 : NS_IMETHODIMP
3134 0 : nsXPCComponents_Utils::GetDOMClassInfo(const nsAString& aClassName,
3135 : nsIClassInfo** aClassInfo)
3136 : {
3137 0 : *aClassInfo = nullptr;
3138 0 : return NS_ERROR_NOT_AVAILABLE;
3139 : }
3140 :
3141 : NS_IMETHODIMP
3142 0 : nsXPCComponents_Utils::GetIncumbentGlobal(HandleValue aCallback,
3143 : JSContext* aCx, MutableHandleValue aOut)
3144 : {
3145 0 : nsCOMPtr<nsIGlobalObject> global = mozilla::dom::GetIncumbentGlobal();
3146 0 : RootedValue globalVal(aCx);
3147 :
3148 0 : if (!global) {
3149 0 : globalVal = NullValue();
3150 : } else {
3151 : // Note: We rely on the wrap call for outerization.
3152 0 : globalVal = ObjectValue(*global->GetGlobalJSObject());
3153 0 : if (!JS_WrapValue(aCx, &globalVal))
3154 0 : return NS_ERROR_FAILURE;
3155 : }
3156 :
3157 : // Invoke the callback, if passed.
3158 0 : if (aCallback.isObject()) {
3159 0 : RootedValue ignored(aCx);
3160 0 : if (!JS_CallFunctionValue(aCx, nullptr, aCallback, JS::HandleValueArray(globalVal), &ignored))
3161 0 : return NS_ERROR_FAILURE;
3162 : }
3163 :
3164 0 : aOut.set(globalVal);
3165 0 : return NS_OK;
3166 : }
3167 :
3168 : /*
3169 : * Below is a bunch of awkward junk to allow JS test code to trigger the
3170 : * creation of an XPCWrappedJS, such that it ends up in the map. We need to
3171 : * hand the caller some sort of reference to hold onto (to prevent the
3172 : * refcount from dropping to zero as soon as the function returns), but trying
3173 : * to return a bonafide XPCWrappedJS to script causes all sorts of trouble. So
3174 : * we create a benign holder class instead, which acts as an opaque reference
3175 : * that script can use to keep the XPCWrappedJS alive and in the map.
3176 : */
3177 :
3178 : class WrappedJSHolder : public nsISupports
3179 : {
3180 : NS_DECL_ISUPPORTS
3181 0 : WrappedJSHolder() {}
3182 :
3183 : RefPtr<nsXPCWrappedJS> mWrappedJS;
3184 :
3185 : private:
3186 0 : virtual ~WrappedJSHolder() {}
3187 : };
3188 0 : NS_IMPL_ISUPPORTS0(WrappedJSHolder);
3189 :
3190 : NS_IMETHODIMP
3191 0 : nsXPCComponents_Utils::GenerateXPCWrappedJS(HandleValue aObj, HandleValue aScope,
3192 : JSContext* aCx, nsISupports** aOut)
3193 : {
3194 0 : if (!aObj.isObject())
3195 0 : return NS_ERROR_INVALID_ARG;
3196 0 : RootedObject obj(aCx, &aObj.toObject());
3197 0 : RootedObject scope(aCx, aScope.isObject() ? js::UncheckedUnwrap(&aScope.toObject())
3198 0 : : CurrentGlobalOrNull(aCx));
3199 0 : JSAutoCompartment ac(aCx, scope);
3200 0 : if (!JS_WrapObject(aCx, &obj))
3201 0 : return NS_ERROR_FAILURE;
3202 :
3203 0 : RefPtr<WrappedJSHolder> holder = new WrappedJSHolder();
3204 0 : nsresult rv = nsXPCWrappedJS::GetNewOrUsed(obj, NS_GET_IID(nsISupports),
3205 0 : getter_AddRefs(holder->mWrappedJS));
3206 0 : holder.forget(aOut);
3207 0 : return rv;
3208 : }
3209 :
3210 : NS_IMETHODIMP
3211 0 : nsXPCComponents_Utils::GetWatchdogTimestamp(const nsAString& aCategory, PRTime* aOut)
3212 : {
3213 : WatchdogTimestampCategory category;
3214 0 : if (aCategory.EqualsLiteral("ContextStateChange"))
3215 0 : category = TimestampContextStateChange;
3216 0 : else if (aCategory.EqualsLiteral("WatchdogWakeup"))
3217 0 : category = TimestampWatchdogWakeup;
3218 0 : else if (aCategory.EqualsLiteral("WatchdogHibernateStart"))
3219 0 : category = TimestampWatchdogHibernateStart;
3220 0 : else if (aCategory.EqualsLiteral("WatchdogHibernateStop"))
3221 0 : category = TimestampWatchdogHibernateStop;
3222 : else
3223 0 : return NS_ERROR_INVALID_ARG;
3224 0 : *aOut = XPCJSContext::Get()->GetWatchdogTimestamp(category);
3225 0 : return NS_OK;
3226 : }
3227 :
3228 : NS_IMETHODIMP
3229 0 : nsXPCComponents_Utils::GetJSEngineTelemetryValue(JSContext* cx, MutableHandleValue rval)
3230 : {
3231 0 : RootedObject obj(cx, JS_NewPlainObject(cx));
3232 0 : if (!obj)
3233 0 : return NS_ERROR_OUT_OF_MEMORY;
3234 :
3235 0 : unsigned attrs = JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT;
3236 :
3237 0 : size_t i = JS_SetProtoCalled(cx);
3238 0 : RootedValue v(cx, DoubleValue(i));
3239 0 : if (!JS_DefineProperty(cx, obj, "setProto", v, attrs))
3240 0 : return NS_ERROR_OUT_OF_MEMORY;
3241 :
3242 0 : i = JS_GetCustomIteratorCount(cx);
3243 0 : v.setDouble(i);
3244 0 : if (!JS_DefineProperty(cx, obj, "customIter", v, attrs))
3245 0 : return NS_ERROR_OUT_OF_MEMORY;
3246 :
3247 0 : rval.setObject(*obj);
3248 0 : return NS_OK;
3249 : }
3250 :
3251 : bool
3252 4 : xpc::CloneInto(JSContext* aCx, HandleValue aValue, HandleValue aScope,
3253 : HandleValue aOptions, MutableHandleValue aCloned)
3254 : {
3255 4 : if (!aScope.isObject())
3256 0 : return false;
3257 :
3258 8 : RootedObject scope(aCx, &aScope.toObject());
3259 4 : scope = js::CheckedUnwrap(scope);
3260 4 : if(!scope) {
3261 0 : JS_ReportErrorASCII(aCx, "Permission denied to clone object into scope");
3262 0 : return false;
3263 : }
3264 :
3265 4 : if (!aOptions.isUndefined() && !aOptions.isObject()) {
3266 0 : JS_ReportErrorASCII(aCx, "Invalid argument");
3267 0 : return false;
3268 : }
3269 :
3270 8 : RootedObject optionsObject(aCx, aOptions.isObject() ? &aOptions.toObject()
3271 8 : : nullptr);
3272 8 : StackScopedCloneOptions options(aCx, optionsObject);
3273 4 : if (aOptions.isObject() && !options.Parse())
3274 0 : return false;
3275 :
3276 : {
3277 8 : JSAutoCompartment ac(aCx, scope);
3278 4 : aCloned.set(aValue);
3279 4 : if (!StackScopedClone(aCx, options, aCloned))
3280 0 : return false;
3281 : }
3282 :
3283 4 : return JS_WrapValue(aCx, aCloned);
3284 : }
3285 :
3286 : NS_IMETHODIMP
3287 4 : nsXPCComponents_Utils::CloneInto(HandleValue aValue, HandleValue aScope,
3288 : HandleValue aOptions, JSContext* aCx,
3289 : MutableHandleValue aCloned)
3290 : {
3291 4 : return xpc::CloneInto(aCx, aValue, aScope, aOptions, aCloned) ?
3292 4 : NS_OK : NS_ERROR_FAILURE;
3293 : }
3294 :
3295 : NS_IMETHODIMP
3296 0 : nsXPCComponents_Utils::GetWebIDLCallerPrincipal(nsIPrincipal** aResult)
3297 : {
3298 : // This API may only be when the Entry Settings Object corresponds to a
3299 : // JS-implemented WebIDL call. In all other cases, the value will be null,
3300 : // and we throw.
3301 0 : nsCOMPtr<nsIPrincipal> callerPrin = mozilla::dom::GetWebIDLCallerPrincipal();
3302 0 : if (!callerPrin)
3303 0 : return NS_ERROR_NOT_AVAILABLE;
3304 0 : callerPrin.forget(aResult);
3305 0 : return NS_OK;
3306 : }
3307 :
3308 : NS_IMETHODIMP
3309 0 : nsXPCComponents_Utils::GetObjectPrincipal(HandleValue val, JSContext* cx,
3310 : nsIPrincipal** result)
3311 : {
3312 0 : if (!val.isObject())
3313 0 : return NS_ERROR_INVALID_ARG;
3314 0 : RootedObject obj(cx, &val.toObject());
3315 0 : obj = js::CheckedUnwrap(obj);
3316 0 : MOZ_ASSERT(obj);
3317 :
3318 0 : nsCOMPtr<nsIPrincipal> prin = nsContentUtils::ObjectPrincipal(obj);
3319 0 : prin.forget(result);
3320 0 : return NS_OK;
3321 : }
3322 :
3323 : NS_IMETHODIMP
3324 0 : nsXPCComponents_Utils::GetCompartmentLocation(HandleValue val,
3325 : JSContext* cx,
3326 : nsACString& result)
3327 : {
3328 0 : if (!val.isObject())
3329 0 : return NS_ERROR_INVALID_ARG;
3330 0 : RootedObject obj(cx, &val.toObject());
3331 0 : obj = js::CheckedUnwrap(obj);
3332 0 : MOZ_ASSERT(obj);
3333 :
3334 0 : result = xpc::CompartmentPrivate::Get(obj)->GetLocation();
3335 0 : return NS_OK;
3336 : }
3337 :
3338 : NS_IMETHODIMP
3339 0 : nsXPCComponents_Utils::SetAddonInterposition(const nsACString& addonIdStr,
3340 : nsIAddonInterposition* interposition,
3341 : JSContext* cx)
3342 : {
3343 0 : JSAddonId* addonId = xpc::NewAddonId(cx, addonIdStr);
3344 0 : if (!addonId)
3345 0 : return NS_ERROR_FAILURE;
3346 0 : if (!XPCWrappedNativeScope::SetAddonInterposition(cx, addonId, interposition))
3347 0 : return NS_ERROR_FAILURE;
3348 :
3349 0 : return NS_OK;
3350 : }
3351 :
3352 : NS_IMETHODIMP
3353 0 : nsXPCComponents_Utils::SetAddonCallInterposition(HandleValue target,
3354 : JSContext* cx)
3355 : {
3356 0 : NS_ENSURE_TRUE(target.isObject(), NS_ERROR_INVALID_ARG);
3357 0 : RootedObject targetObj(cx, &target.toObject());
3358 0 : targetObj = js::CheckedUnwrap(targetObj);
3359 0 : NS_ENSURE_TRUE(targetObj, NS_ERROR_INVALID_ARG);
3360 0 : XPCWrappedNativeScope* xpcScope = ObjectScope(targetObj);
3361 0 : NS_ENSURE_TRUE(xpcScope, NS_ERROR_INVALID_ARG);
3362 :
3363 0 : xpcScope->SetAddonCallInterposition();
3364 0 : return NS_OK;
3365 : }
3366 :
3367 : NS_IMETHODIMP
3368 0 : nsXPCComponents_Utils::AllowCPOWsInAddon(const nsACString& addonIdStr,
3369 : bool allow,
3370 : JSContext* cx)
3371 : {
3372 0 : JSAddonId* addonId = xpc::NewAddonId(cx, addonIdStr);
3373 0 : if (!addonId)
3374 0 : return NS_ERROR_FAILURE;
3375 0 : if (!XPCWrappedNativeScope::AllowCPOWsInAddon(cx, addonId, allow))
3376 0 : return NS_ERROR_FAILURE;
3377 :
3378 0 : return NS_OK;
3379 : }
3380 :
3381 : NS_IMETHODIMP
3382 16 : nsXPCComponents_Utils::Now(double* aRetval)
3383 : {
3384 16 : TimeStamp start = TimeStamp::ProcessCreation();
3385 16 : *aRetval = (TimeStamp::Now() - start).ToMilliseconds();
3386 16 : return NS_OK;
3387 : }
3388 :
3389 : /***************************************************************************/
3390 : /***************************************************************************/
3391 : /***************************************************************************/
3392 :
3393 :
3394 279 : nsXPCComponentsBase::nsXPCComponentsBase(XPCWrappedNativeScope* aScope)
3395 279 : : mScope(aScope)
3396 : {
3397 279 : MOZ_ASSERT(aScope, "aScope must not be null");
3398 279 : }
3399 :
3400 279 : nsXPCComponents::nsXPCComponents(XPCWrappedNativeScope* aScope)
3401 279 : : nsXPCComponentsBase(aScope)
3402 : {
3403 279 : }
3404 :
3405 0 : nsXPCComponentsBase::~nsXPCComponentsBase()
3406 : {
3407 0 : }
3408 :
3409 0 : nsXPCComponents::~nsXPCComponents()
3410 : {
3411 0 : }
3412 :
3413 : void
3414 0 : nsXPCComponentsBase::ClearMembers()
3415 : {
3416 0 : mInterfaces = nullptr;
3417 0 : mInterfacesByID = nullptr;
3418 0 : mResults = nullptr;
3419 0 : }
3420 :
3421 : void
3422 0 : nsXPCComponents::ClearMembers()
3423 : {
3424 0 : mClasses = nullptr;
3425 0 : mClassesByID = nullptr;
3426 0 : mID = nullptr;
3427 0 : mException = nullptr;
3428 0 : mConstructor = nullptr;
3429 0 : mUtils = nullptr;
3430 :
3431 0 : nsXPCComponentsBase::ClearMembers();
3432 0 : }
3433 :
3434 : /*******************************************/
3435 : #define XPC_IMPL_GET_OBJ_METHOD(_class, _n) \
3436 : NS_IMETHODIMP _class::Get##_n(nsIXPCComponents_##_n * *a##_n) { \
3437 : NS_ENSURE_ARG_POINTER(a##_n); \
3438 : if (!m##_n) \
3439 : m##_n = new nsXPCComponents_##_n(); \
3440 : RefPtr<nsXPCComponents_##_n> ret = m##_n; \
3441 : ret.forget(a##_n); \
3442 : return NS_OK; \
3443 : }
3444 :
3445 701 : XPC_IMPL_GET_OBJ_METHOD(nsXPCComponentsBase, Interfaces)
3446 0 : XPC_IMPL_GET_OBJ_METHOD(nsXPCComponentsBase, InterfacesByID)
3447 495 : XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, Classes)
3448 0 : XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, ClassesByID)
3449 275 : XPC_IMPL_GET_OBJ_METHOD(nsXPCComponentsBase, Results)
3450 201 : XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, ID)
3451 0 : XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, Exception)
3452 18 : XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, Constructor)
3453 651 : XPC_IMPL_GET_OBJ_METHOD(nsXPCComponents, Utils)
3454 :
3455 : #undef XPC_IMPL_GET_OBJ_METHOD
3456 : /*******************************************/
3457 :
3458 : NS_IMETHODIMP
3459 2 : nsXPCComponentsBase::IsSuccessCode(nsresult result, bool* out)
3460 : {
3461 2 : *out = NS_SUCCEEDED(result);
3462 2 : return NS_OK;
3463 : }
3464 :
3465 : NS_IMETHODIMP
3466 25 : nsXPCComponents::GetStack(nsIStackFrame * *aStack)
3467 : {
3468 : nsresult rv;
3469 25 : nsXPConnect* xpc = nsXPConnect::XPConnect();
3470 25 : rv = xpc->GetCurrentJSStack(aStack);
3471 25 : return rv;
3472 : }
3473 :
3474 : NS_IMETHODIMP
3475 31 : nsXPCComponents::GetManager(nsIComponentManager * *aManager)
3476 : {
3477 31 : MOZ_ASSERT(aManager, "bad param");
3478 31 : return NS_GetComponentManager(aManager);
3479 : }
3480 :
3481 : NS_IMETHODIMP
3482 0 : nsXPCComponents::GetReturnCode(JSContext* aCx, MutableHandleValue aOut)
3483 : {
3484 0 : nsresult res = XPCJSContext::Get()->GetPendingResult();
3485 0 : aOut.setNumber(static_cast<uint32_t>(res));
3486 0 : return NS_OK;
3487 : }
3488 :
3489 : NS_IMETHODIMP
3490 0 : nsXPCComponents::SetReturnCode(JSContext* aCx, HandleValue aCode)
3491 : {
3492 : nsresult rv;
3493 0 : if (!ToUint32(aCx, aCode, (uint32_t*)&rv))
3494 0 : return NS_ERROR_FAILURE;
3495 0 : XPCJSContext::Get()->SetPendingResult(rv);
3496 0 : return NS_OK;
3497 : }
3498 :
3499 : // static
3500 0 : NS_IMETHODIMP nsXPCComponents::ReportError(HandleValue error, JSContext* cx)
3501 : {
3502 0 : NS_WARNING("Components.reportError deprecated, use Components.utils.reportError");
3503 :
3504 0 : nsCOMPtr<nsIXPCComponents_Utils> utils;
3505 0 : nsresult rv = GetUtils(getter_AddRefs(utils));
3506 0 : if (NS_FAILED(rv))
3507 0 : return rv;
3508 :
3509 0 : return utils->ReportError(error, cx);
3510 : }
3511 :
3512 : /**********************************************/
3513 :
3514 : class ComponentsSH : public nsIXPCScriptable
3515 : {
3516 : public:
3517 : explicit constexpr ComponentsSH(unsigned dummy)
3518 : {
3519 : }
3520 :
3521 : // We don't actually inherit any ref counting infrastructure, but we don't
3522 : // need an nsAutoRefCnt member, so the _INHERITED macro is a hack to avoid
3523 : // having one.
3524 : NS_DECL_ISUPPORTS_INHERITED
3525 : NS_DECL_NSIXPCSCRIPTABLE
3526 279 : static nsresult Get(nsIXPCScriptable** helper)
3527 : {
3528 279 : *helper = &singleton;
3529 279 : return NS_OK;
3530 : }
3531 :
3532 : private:
3533 : static ComponentsSH singleton;
3534 : };
3535 :
3536 : ComponentsSH ComponentsSH::singleton(0);
3537 :
3538 : // Singleton refcounting.
3539 13428 : NS_IMETHODIMP_(MozExternalRefCountType) ComponentsSH::AddRef(void) { return 1; }
3540 13149 : NS_IMETHODIMP_(MozExternalRefCountType) ComponentsSH::Release(void) { return 1; }
3541 :
3542 6993 : NS_INTERFACE_MAP_BEGIN(ComponentsSH)
3543 6993 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
3544 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
3545 0 : NS_INTERFACE_MAP_END
3546 :
3547 : #define NSXPCCOMPONENTSBASE_CID \
3548 : { 0xc62998e5, 0x95f1, 0x4058, \
3549 : { 0xa5, 0x09, 0xec, 0x21, 0x66, 0x18, 0x92, 0xb9 } }
3550 :
3551 : #define NSXPCCOMPONENTS_CID \
3552 : { 0x3649f405, 0xf0ec, 0x4c28, \
3553 : { 0xae, 0xb0, 0xaf, 0x9a, 0x51, 0xe4, 0x4c, 0x81 } }
3554 :
3555 3 : NS_IMPL_CLASSINFO(nsXPCComponentsBase, &ComponentsSH::Get, nsIClassInfo::DOM_OBJECT, NSXPCCOMPONENTSBASE_CID)
3556 5002 : NS_IMPL_ISUPPORTS_CI(nsXPCComponentsBase, nsIXPCComponentsBase)
3557 :
3558 3 : NS_IMPL_CLASSINFO(nsXPCComponents, &ComponentsSH::Get, nsIClassInfo::DOM_OBJECT, NSXPCCOMPONENTS_CID)
3559 : // Below is more or less what NS_IMPL_ISUPPORTS_CI_INHERITED1 would look like
3560 : // if it existed.
3561 1943 : NS_IMPL_ADDREF_INHERITED(nsXPCComponents, nsXPCComponentsBase)
3562 837 : NS_IMPL_RELEASE_INHERITED(nsXPCComponents, nsXPCComponentsBase)
3563 3059 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents)
3564 3059 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents)
3565 2501 : NS_IMPL_QUERY_CLASSINFO(nsXPCComponents)
3566 2222 : NS_INTERFACE_MAP_END_INHERITING(nsXPCComponentsBase)
3567 3 : NS_IMPL_CI_INTERFACE_GETTER(nsXPCComponents, nsIXPCComponents)
3568 :
3569 : // The nsIXPCScriptable map declaration that will generate stubs for us
3570 : #define XPC_MAP_CLASSNAME ComponentsSH
3571 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents"
3572 : #define XPC_MAP_FLAGS XPC_SCRIPTABLE_WANT_PRECREATE
3573 : #include "xpc_map_end.h" /* This will #undef the above */
3574 :
3575 : NS_IMETHODIMP
3576 281 : ComponentsSH::PreCreate(nsISupports* nativeObj, JSContext* cx, JSObject* globalObj, JSObject** parentObj)
3577 : {
3578 281 : nsXPCComponentsBase* self = static_cast<nsXPCComponentsBase*>(nativeObj);
3579 : // this should never happen
3580 281 : if (!self->GetScope()) {
3581 0 : NS_WARNING("mScope must not be null when nsXPCComponents::PreCreate is called");
3582 0 : return NS_ERROR_FAILURE;
3583 : }
3584 281 : *parentObj = self->GetScope()->GetGlobalJSObject();
3585 281 : return NS_OK;
3586 : }
|