1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sw=4 et tw=78:
3 : *
4 : * ***** BEGIN LICENSE BLOCK *****
5 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 : *
7 : * The contents of this file are subject to the Mozilla Public License Version
8 : * 1.1 (the "License"); you may not use this file except in compliance with
9 : * the License. You may obtain a copy of the License at
10 : * http://www.mozilla.org/MPL/
11 : *
12 : * Software distributed under the License is distributed on an "AS IS" basis,
13 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 : * for the specific language governing rights and limitations under the
15 : * License.
16 : *
17 : * The Original Code is Mozilla Communicator client code, released
18 : * March 31, 1998.
19 : *
20 : * The Initial Developer of the Original Code is
21 : * Netscape Communications Corporation.
22 : * Portions created by the Initial Developer are Copyright (C) 1998
23 : * the Initial Developer. All Rights Reserved.
24 : *
25 : * Contributor(s):
26 : * John Bandhauer <jband@netscape.com> (original author)
27 : * Pierre Phaneuf <pp@ludusdesign.com>
28 : *
29 : * Alternatively, the contents of this file may be used under the terms of
30 : * either of the GNU General Public License Version 2 or later (the "GPL"),
31 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
32 : * in which case the provisions of the GPL or the LGPL are applicable instead
33 : * of those above. If you wish to allow use of your version of this file only
34 : * under the terms of either the GPL or the LGPL, and not to allow others to
35 : * use your version of this file under the terms of the MPL, indicate your
36 : * decision by deleting the provisions above and replace them with the notice
37 : * and other provisions required by the GPL or the LGPL. If you do not delete
38 : * the provisions above, a recipient may use your version of this file under
39 : * the terms of any one of the MPL, the GPL or the LGPL.
40 : *
41 : * ***** END LICENSE BLOCK ***** */
42 :
43 : /* The "Components" xpcom objects for JavaScript. */
44 :
45 : #include "mozilla/unused.h"
46 :
47 : #include "xpcprivate.h"
48 : #include "nsReadableUtils.h"
49 : #include "xpcIJSModuleLoader.h"
50 : #include "nsIScriptObjectPrincipal.h"
51 : #include "nsIDOMWindow.h"
52 : #include "XPCJSWeakReference.h"
53 : #include "XPCWrapper.h"
54 : #include "jsproxy.h"
55 : #include "WrapperFactory.h"
56 : #include "XrayWrapper.h"
57 : #include "nsNullPrincipal.h"
58 : #include "nsJSUtils.h"
59 : #include "mozJSComponentLoader.h"
60 : #include "nsContentUtils.h"
61 : #include "jsgc.h"
62 : #include "jsfriendapi.h"
63 :
64 : using namespace mozilla;
65 : using namespace js;
66 : /***************************************************************************/
67 : // stuff used by all
68 :
69 0 : static nsresult ThrowAndFail(unsigned errNum, JSContext* cx, bool* retval)
70 : {
71 0 : XPCThrower::Throw(errNum, cx);
72 0 : *retval = false;
73 0 : return NS_OK;
74 : }
75 :
76 : static JSBool
77 2628 : JSValIsInterfaceOfType(JSContext *cx, jsval v, REFNSIID iid)
78 : {
79 5256 : nsCOMPtr<nsIXPConnect> xpc;
80 5256 : nsCOMPtr<nsIXPConnectWrappedNative> wn;
81 5256 : nsCOMPtr<nsISupports> sup;
82 : nsISupports* iface;
83 18396 : if (!JSVAL_IS_PRIMITIVE(v) &&
84 2628 : nsnull != (xpc = nsXPConnect::GetXPConnect()) &&
85 7884 : NS_SUCCEEDED(xpc->GetWrappedNativeOfJSObject(cx, JSVAL_TO_OBJECT(v),
86 2628 : getter_AddRefs(wn))) && wn &&
87 2628 : NS_SUCCEEDED(wn->Native()->QueryInterface(iid, (void**)&iface)) && iface) {
88 2628 : NS_RELEASE(iface);
89 2628 : return true;
90 : }
91 0 : return false;
92 : }
93 :
94 46803 : char* xpc_CloneAllAccess()
95 : {
96 : static const char allAccess[] = "AllAccess";
97 46803 : return (char*)nsMemory::Clone(allAccess, sizeof(allAccess));
98 : }
99 :
100 0 : char * xpc_CheckAccessList(const PRUnichar* wideName, const char* list[])
101 : {
102 0 : nsCAutoString asciiName;
103 0 : CopyUTF16toUTF8(nsDependentString(wideName), asciiName);
104 :
105 0 : for (const char** p = list; *p; p++)
106 0 : if (!strcmp(*p, asciiName.get()))
107 0 : return xpc_CloneAllAccess();
108 :
109 0 : return nsnull;
110 : }
111 :
112 : /***************************************************************************/
113 : /***************************************************************************/
114 : /***************************************************************************/
115 :
116 :
117 :
118 : class nsXPCComponents_Interfaces :
119 : public nsIXPCComponents_Interfaces,
120 : public nsIXPCScriptable,
121 : public nsIClassInfo,
122 : public nsISecurityCheckedComponent
123 : {
124 : public:
125 : // all the interface method declarations...
126 : NS_DECL_ISUPPORTS
127 : NS_DECL_NSIXPCCOMPONENTS_INTERFACES
128 : NS_DECL_NSIXPCSCRIPTABLE
129 : NS_DECL_NSICLASSINFO
130 : NS_DECL_NSISECURITYCHECKEDCOMPONENT
131 :
132 : public:
133 : nsXPCComponents_Interfaces();
134 : virtual ~nsXPCComponents_Interfaces();
135 :
136 : private:
137 : nsCOMPtr<nsIInterfaceInfoManager> mManager;
138 : };
139 :
140 : /* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
141 : out nsIIDPtr array); */
142 : NS_IMETHODIMP
143 12967 : nsXPCComponents_Interfaces::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
144 : {
145 12967 : const PRUint32 count = 3;
146 12967 : *aCount = count;
147 : nsIID **array;
148 12967 : *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*)));
149 12967 : if (!array)
150 0 : return NS_ERROR_OUT_OF_MEMORY;
151 :
152 12967 : PRUint32 index = 0;
153 : nsIID* clone;
154 : #define PUSH_IID(id) \
155 : clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ), \
156 : sizeof(nsIID))); \
157 : if (!clone) \
158 : goto oom; \
159 : array[index++] = clone;
160 :
161 12967 : PUSH_IID(nsIXPCComponents_Interfaces)
162 12967 : PUSH_IID(nsIXPCScriptable)
163 12967 : PUSH_IID(nsISecurityCheckedComponent)
164 : #undef PUSH_IID
165 :
166 12967 : return NS_OK;
167 : oom:
168 0 : while (index)
169 0 : nsMemory::Free(array[--index]);
170 0 : nsMemory::Free(array);
171 0 : *aArray = nsnull;
172 0 : return NS_ERROR_OUT_OF_MEMORY;
173 : }
174 :
175 : /* nsISupports getHelperForLanguage (in PRUint32 language); */
176 : NS_IMETHODIMP
177 12967 : nsXPCComponents_Interfaces::GetHelperForLanguage(PRUint32 language,
178 : nsISupports **retval)
179 : {
180 12967 : *retval = nsnull;
181 12967 : return NS_OK;
182 : }
183 :
184 : /* readonly attribute string contractID; */
185 : NS_IMETHODIMP
186 0 : nsXPCComponents_Interfaces::GetContractID(char * *aContractID)
187 : {
188 0 : *aContractID = nsnull;
189 0 : return NS_ERROR_NOT_AVAILABLE;
190 : }
191 :
192 : /* readonly attribute string classDescription; */
193 : NS_IMETHODIMP
194 1 : nsXPCComponents_Interfaces::GetClassDescription(char * *aClassDescription)
195 : {
196 : static const char classDescription[] = "XPCComponents_Interfaces";
197 1 : *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
198 1 : return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
199 : }
200 :
201 : /* readonly attribute nsCIDPtr classID; */
202 : NS_IMETHODIMP
203 0 : nsXPCComponents_Interfaces::GetClassID(nsCID * *aClassID)
204 : {
205 0 : *aClassID = nsnull;
206 0 : return NS_OK;
207 : }
208 :
209 : /* readonly attribute PRUint32 implementationLanguage; */
210 : NS_IMETHODIMP
211 0 : nsXPCComponents_Interfaces::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
212 : {
213 0 : *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
214 0 : return NS_OK;
215 : }
216 :
217 : /* readonly attribute PRUint32 flags; */
218 : NS_IMETHODIMP
219 25325 : nsXPCComponents_Interfaces::GetFlags(PRUint32 *aFlags)
220 : {
221 25325 : *aFlags = nsIClassInfo::THREADSAFE;
222 25325 : return NS_OK;
223 : }
224 :
225 : /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
226 : NS_IMETHODIMP
227 0 : nsXPCComponents_Interfaces::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
228 : {
229 0 : return NS_ERROR_NOT_AVAILABLE;
230 : }
231 :
232 12686 : nsXPCComponents_Interfaces::nsXPCComponents_Interfaces() :
233 12686 : mManager(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID))
234 : {
235 12686 : }
236 :
237 25336 : nsXPCComponents_Interfaces::~nsXPCComponents_Interfaces()
238 : {
239 : // empty
240 50672 : }
241 :
242 :
243 295680 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Interfaces)
244 295680 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Interfaces)
245 276206 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
246 237305 : NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
247 211369 : NS_INTERFACE_MAP_ENTRY(nsISecurityCheckedComponent)
248 199011 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Interfaces)
249 127080 : NS_INTERFACE_MAP_END_THREADSAFE
250 :
251 279148 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents_Interfaces)
252 279109 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents_Interfaces)
253 :
254 : // The nsIXPCScriptable map declaration that will generate stubs for us...
255 : #define XPC_MAP_CLASSNAME nsXPCComponents_Interfaces
256 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Interfaces"
257 : #define XPC_MAP_WANT_NEWRESOLVE
258 : #define XPC_MAP_WANT_NEWENUMERATE
259 : #define XPC_MAP_FLAGS nsIXPCScriptable::DONT_ENUM_STATIC_PROPS |\
260 : nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
261 : #include "xpc_map_end.h" /* This will #undef the above */
262 :
263 :
264 : /* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 enum_op, in JSValPtr statep, out JSID idp); */
265 : NS_IMETHODIMP
266 0 : nsXPCComponents_Interfaces::NewEnumerate(nsIXPConnectWrappedNative *wrapper,
267 : JSContext * cx, JSObject * obj,
268 : PRUint32 enum_op, jsval * statep,
269 : jsid * idp, bool *_retval)
270 : {
271 : nsIEnumerator* e;
272 :
273 0 : switch (enum_op) {
274 : case JSENUMERATE_INIT:
275 : case JSENUMERATE_INIT_ALL:
276 : {
277 0 : if (!mManager ||
278 0 : NS_FAILED(mManager->EnumerateInterfaces(&e)) || !e ||
279 0 : NS_FAILED(e->First()))
280 :
281 : {
282 0 : *statep = JSVAL_NULL;
283 0 : return NS_ERROR_UNEXPECTED;
284 : }
285 :
286 0 : *statep = PRIVATE_TO_JSVAL(e);
287 0 : if (idp)
288 0 : *idp = INT_TO_JSID(0); // indicate that we don't know the count
289 0 : return NS_OK;
290 : }
291 : case JSENUMERATE_NEXT:
292 : {
293 0 : nsCOMPtr<nsISupports> isup;
294 :
295 0 : e = (nsIEnumerator*) JSVAL_TO_PRIVATE(*statep);
296 :
297 0 : while (1) {
298 0 : if (NS_ENUMERATOR_FALSE == e->IsDone() &&
299 0 : NS_SUCCEEDED(e->CurrentItem(getter_AddRefs(isup))) && isup) {
300 0 : e->Next();
301 0 : nsCOMPtr<nsIInterfaceInfo> iface(do_QueryInterface(isup));
302 0 : if (iface) {
303 : JSString* idstr;
304 : const char* name;
305 : bool scriptable;
306 :
307 0 : if (NS_SUCCEEDED(iface->IsScriptable(&scriptable)) &&
308 0 : !scriptable) {
309 0 : continue;
310 : }
311 :
312 0 : if (NS_SUCCEEDED(iface->GetNameShared(&name)) && name &&
313 0 : nsnull != (idstr = JS_NewStringCopyZ(cx, name)) &&
314 0 : JS_ValueToId(cx, STRING_TO_JSVAL(idstr), idp)) {
315 0 : return NS_OK;
316 : }
317 : }
318 : }
319 : // else...
320 : break;
321 : }
322 : // FALL THROUGH
323 : }
324 :
325 : case JSENUMERATE_DESTROY:
326 : default:
327 0 : e = (nsIEnumerator*) JSVAL_TO_PRIVATE(*statep);
328 0 : NS_IF_RELEASE(e);
329 0 : *statep = JSVAL_NULL;
330 0 : return NS_OK;
331 : }
332 : }
333 :
334 : /* bool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, in PRUint32 flags, out JSObjectPtr objp); */
335 : NS_IMETHODIMP
336 92930 : nsXPCComponents_Interfaces::NewResolve(nsIXPConnectWrappedNative *wrapper,
337 : JSContext * cx, JSObject * obj,
338 : jsid id, PRUint32 flags,
339 : JSObject * *objp, bool *_retval)
340 : {
341 185860 : JSAutoByteString name;
342 371720 : if (mManager &&
343 185860 : JSID_IS_STRING(id) &&
344 92930 : name.encode(cx, JSID_TO_STRING(id)) &&
345 92930 : name.ptr()[0] != '{') { // we only allow interfaces by name here
346 185860 : nsCOMPtr<nsIInterfaceInfo> info;
347 92930 : mManager->GetInfoForName(name.ptr(), getter_AddRefs(info));
348 92930 : if (!info)
349 1594 : return NS_OK;
350 :
351 : nsCOMPtr<nsIJSIID> nsid =
352 275602 : dont_AddRef(static_cast<nsIJSIID*>(nsJSIID::NewID(info)));
353 :
354 91336 : if (nsid) {
355 182672 : nsCOMPtr<nsIXPConnect> xpc;
356 91336 : wrapper->GetXPConnect(getter_AddRefs(xpc));
357 91336 : if (xpc) {
358 182672 : nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
359 91336 : if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
360 : static_cast<nsIJSIID*>(nsid),
361 : NS_GET_IID(nsIJSIID),
362 : getter_AddRefs(holder)))) {
363 : JSObject* idobj;
364 91336 : if (holder && NS_SUCCEEDED(holder->GetJSObject(&idobj))) {
365 91336 : *objp = obj;
366 : *_retval = JS_DefinePropertyById(cx, obj, id,
367 91336 : OBJECT_TO_JSVAL(idobj),
368 : nsnull, nsnull,
369 : JSPROP_ENUMERATE |
370 : JSPROP_READONLY |
371 91336 : JSPROP_PERMANENT);
372 : }
373 : }
374 : }
375 : }
376 : }
377 91336 : return NS_OK;
378 : }
379 :
380 : /* string canCreateWrapper (in nsIIDPtr iid); */
381 : NS_IMETHODIMP
382 12358 : nsXPCComponents_Interfaces::CanCreateWrapper(const nsIID * iid, char **_retval)
383 : {
384 : // We let anyone do this...
385 12358 : *_retval = xpc_CloneAllAccess();
386 12358 : return NS_OK;
387 : }
388 :
389 : /* string canCallMethod (in nsIIDPtr iid, in wstring methodName); */
390 : NS_IMETHODIMP
391 0 : nsXPCComponents_Interfaces::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
392 : {
393 : // If you have to ask, then the answer is NO
394 0 : *_retval = nsnull;
395 0 : return NS_OK;
396 : }
397 :
398 : /* string canGetProperty (in nsIIDPtr iid, in wstring propertyName); */
399 : NS_IMETHODIMP
400 0 : nsXPCComponents_Interfaces::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
401 : {
402 : // If you have to ask, then the answer is NO
403 0 : *_retval = nsnull;
404 0 : return NS_OK;
405 : }
406 :
407 : /* string canSetProperty (in nsIIDPtr iid, in wstring propertyName); */
408 : NS_IMETHODIMP
409 0 : nsXPCComponents_Interfaces::CanSetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
410 : {
411 : // If you have to ask, then the answer is NO
412 0 : *_retval = nsnull;
413 0 : return NS_OK;
414 : }
415 :
416 : /***************************************************************************/
417 : /***************************************************************************/
418 : /***************************************************************************/
419 :
420 : class nsXPCComponents_InterfacesByID :
421 : public nsIXPCComponents_InterfacesByID,
422 : public nsIXPCScriptable,
423 : public nsIClassInfo,
424 : public nsISecurityCheckedComponent
425 : {
426 : public:
427 : // all the interface method declarations...
428 : NS_DECL_ISUPPORTS
429 : NS_DECL_NSIXPCCOMPONENTS_INTERFACESBYID
430 : NS_DECL_NSIXPCSCRIPTABLE
431 : NS_DECL_NSICLASSINFO
432 : NS_DECL_NSISECURITYCHECKEDCOMPONENT
433 :
434 : public:
435 : nsXPCComponents_InterfacesByID();
436 : virtual ~nsXPCComponents_InterfacesByID();
437 :
438 : private:
439 : nsCOMPtr<nsIInterfaceInfoManager> mManager;
440 : };
441 :
442 : /***************************************************************************/
443 : /* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
444 : out nsIIDPtr array); */
445 : NS_IMETHODIMP
446 1 : nsXPCComponents_InterfacesByID::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
447 : {
448 1 : const PRUint32 count = 3;
449 1 : *aCount = count;
450 : nsIID **array;
451 1 : *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*)));
452 1 : if (!array)
453 0 : return NS_ERROR_OUT_OF_MEMORY;
454 :
455 1 : PRUint32 index = 0;
456 : nsIID* clone;
457 : #define PUSH_IID(id) \
458 : clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ), \
459 : sizeof(nsIID))); \
460 : if (!clone) \
461 : goto oom; \
462 : array[index++] = clone;
463 :
464 1 : PUSH_IID(nsIXPCComponents_InterfacesByID)
465 1 : PUSH_IID(nsIXPCScriptable)
466 1 : PUSH_IID(nsISecurityCheckedComponent)
467 : #undef PUSH_IID
468 :
469 1 : return NS_OK;
470 : oom:
471 0 : while (index)
472 0 : nsMemory::Free(array[--index]);
473 0 : nsMemory::Free(array);
474 0 : *aArray = nsnull;
475 0 : return NS_ERROR_OUT_OF_MEMORY;
476 : }
477 :
478 : /* nsISupports getHelperForLanguage (in PRUint32 language); */
479 : NS_IMETHODIMP
480 1 : nsXPCComponents_InterfacesByID::GetHelperForLanguage(PRUint32 language,
481 : nsISupports **retval)
482 : {
483 1 : *retval = nsnull;
484 1 : return NS_OK;
485 : }
486 :
487 : /* readonly attribute string contractID; */
488 : NS_IMETHODIMP
489 0 : nsXPCComponents_InterfacesByID::GetContractID(char * *aContractID)
490 : {
491 0 : *aContractID = nsnull;
492 0 : return NS_ERROR_NOT_AVAILABLE;
493 : }
494 :
495 : /* readonly attribute string classDescription; */
496 : NS_IMETHODIMP
497 1 : nsXPCComponents_InterfacesByID::GetClassDescription(char * *aClassDescription)
498 : {
499 : static const char classDescription[] = "XPCComponents_InterfacesByID";
500 1 : *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
501 1 : return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
502 : }
503 :
504 : /* readonly attribute nsCIDPtr classID; */
505 : NS_IMETHODIMP
506 0 : nsXPCComponents_InterfacesByID::GetClassID(nsCID * *aClassID)
507 : {
508 0 : *aClassID = nsnull;
509 0 : return NS_OK;
510 : }
511 :
512 : /* readonly attribute PRUint32 implementationLanguage; */
513 : NS_IMETHODIMP
514 0 : nsXPCComponents_InterfacesByID::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
515 : {
516 0 : *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
517 0 : return NS_OK;
518 : }
519 :
520 : /* readonly attribute PRUint32 flags; */
521 : NS_IMETHODIMP
522 1 : nsXPCComponents_InterfacesByID::GetFlags(PRUint32 *aFlags)
523 : {
524 1 : *aFlags = nsIClassInfo::THREADSAFE;
525 1 : return NS_OK;
526 : }
527 :
528 : /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
529 : NS_IMETHODIMP
530 0 : nsXPCComponents_InterfacesByID::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
531 : {
532 0 : return NS_ERROR_NOT_AVAILABLE;
533 : }
534 :
535 1 : nsXPCComponents_InterfacesByID::nsXPCComponents_InterfacesByID() :
536 1 : mManager(do_GetService(NS_INTERFACEINFOMANAGER_SERVICE_CONTRACTID))
537 : {
538 1 : }
539 :
540 2 : nsXPCComponents_InterfacesByID::~nsXPCComponents_InterfacesByID()
541 : {
542 : // empty
543 4 : }
544 :
545 20 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_InterfacesByID)
546 20 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_InterfacesByID)
547 19 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
548 16 : NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
549 12 : NS_INTERFACE_MAP_ENTRY(nsISecurityCheckedComponent)
550 12 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_InterfacesByID)
551 8 : NS_INTERFACE_MAP_END_THREADSAFE
552 :
553 16 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents_InterfacesByID)
554 16 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents_InterfacesByID)
555 :
556 : // The nsIXPCScriptable map declaration that will generate stubs for us...
557 : #define XPC_MAP_CLASSNAME nsXPCComponents_InterfacesByID
558 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_InterfacesByID"
559 : #define XPC_MAP_WANT_NEWRESOLVE
560 : #define XPC_MAP_WANT_NEWENUMERATE
561 : #define XPC_MAP_FLAGS nsIXPCScriptable::DONT_ENUM_STATIC_PROPS |\
562 : nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
563 : #include "xpc_map_end.h" /* This will #undef the above */
564 :
565 : /* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 enum_op, in JSValPtr statep, out JSID idp); */
566 : NS_IMETHODIMP
567 0 : nsXPCComponents_InterfacesByID::NewEnumerate(nsIXPConnectWrappedNative *wrapper,
568 : JSContext * cx, JSObject * obj,
569 : PRUint32 enum_op, jsval * statep,
570 : jsid * idp, bool *_retval)
571 : {
572 : nsIEnumerator* e;
573 :
574 0 : switch (enum_op) {
575 : case JSENUMERATE_INIT:
576 : case JSENUMERATE_INIT_ALL:
577 : {
578 0 : if (!mManager ||
579 0 : NS_FAILED(mManager->EnumerateInterfaces(&e)) || !e ||
580 0 : NS_FAILED(e->First()))
581 :
582 : {
583 0 : *statep = JSVAL_NULL;
584 0 : return NS_ERROR_UNEXPECTED;
585 : }
586 :
587 0 : *statep = PRIVATE_TO_JSVAL(e);
588 0 : if (idp)
589 0 : *idp = INT_TO_JSID(0); // indicate that we don't know the count
590 0 : return NS_OK;
591 : }
592 : case JSENUMERATE_NEXT:
593 : {
594 0 : nsCOMPtr<nsISupports> isup;
595 :
596 0 : e = (nsIEnumerator*) JSVAL_TO_PRIVATE(*statep);
597 :
598 0 : while (1) {
599 0 : if (NS_ENUMERATOR_FALSE == e->IsDone() &&
600 0 : NS_SUCCEEDED(e->CurrentItem(getter_AddRefs(isup))) && isup) {
601 0 : e->Next();
602 0 : nsCOMPtr<nsIInterfaceInfo> iface(do_QueryInterface(isup));
603 0 : if (iface) {
604 : nsIID const *iid;
605 : char idstr[NSID_LENGTH];
606 : JSString* jsstr;
607 : bool scriptable;
608 :
609 0 : if (NS_SUCCEEDED(iface->IsScriptable(&scriptable)) &&
610 0 : !scriptable) {
611 0 : continue;
612 : }
613 :
614 0 : if (NS_SUCCEEDED(iface->GetIIDShared(&iid))) {
615 0 : iid->ToProvidedString(idstr);
616 0 : jsstr = JS_NewStringCopyZ(cx, idstr);
617 0 : if (jsstr &&
618 0 : JS_ValueToId(cx, STRING_TO_JSVAL(jsstr), idp)) {
619 0 : return NS_OK;
620 : }
621 : }
622 : }
623 : }
624 : // else...
625 : break;
626 : }
627 : // FALL THROUGH
628 : }
629 :
630 : case JSENUMERATE_DESTROY:
631 : default:
632 0 : e = (nsIEnumerator*) JSVAL_TO_PRIVATE(*statep);
633 0 : NS_IF_RELEASE(e);
634 0 : *statep = JSVAL_NULL;
635 0 : return NS_OK;
636 : }
637 : }
638 :
639 : /* bool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, in PRUint32 flags, out JSObjectPtr objp); */
640 : NS_IMETHODIMP
641 2 : nsXPCComponents_InterfacesByID::NewResolve(nsIXPConnectWrappedNative *wrapper,
642 : JSContext * cx, JSObject * obj,
643 : jsid id, PRUint32 flags,
644 : JSObject * *objp, bool *_retval)
645 : {
646 2 : const jschar* name = nsnull;
647 :
648 6 : if (mManager &&
649 4 : JSID_IS_STRING(id) &&
650 2 : 38 == JS_GetStringLength(JSID_TO_STRING(id)) &&
651 0 : nsnull != (name = JS_GetInternedStringChars(JSID_TO_STRING(id)))) {
652 : nsID iid;
653 0 : if (!iid.Parse(NS_ConvertUTF16toUTF8(name).get()))
654 0 : return NS_OK;
655 :
656 0 : nsCOMPtr<nsIInterfaceInfo> info;
657 0 : mManager->GetInfoForIID(&iid, getter_AddRefs(info));
658 0 : if (!info)
659 0 : return NS_OK;
660 :
661 : nsCOMPtr<nsIJSIID> nsid =
662 0 : dont_AddRef(static_cast<nsIJSIID*>(nsJSIID::NewID(info)));
663 :
664 0 : if (!nsid)
665 0 : return NS_ERROR_OUT_OF_MEMORY;
666 :
667 0 : nsCOMPtr<nsIXPConnect> xpc;
668 0 : wrapper->GetXPConnect(getter_AddRefs(xpc));
669 0 : if (xpc) {
670 0 : nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
671 0 : if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
672 : static_cast<nsIJSIID*>(nsid),
673 : NS_GET_IID(nsIJSIID),
674 : getter_AddRefs(holder)))) {
675 : JSObject* idobj;
676 0 : if (holder && NS_SUCCEEDED(holder->GetJSObject(&idobj))) {
677 0 : *objp = obj;
678 : *_retval =
679 : JS_DefinePropertyById(cx, obj, id,
680 0 : OBJECT_TO_JSVAL(idobj),
681 : nsnull, nsnull,
682 : JSPROP_ENUMERATE |
683 : JSPROP_READONLY |
684 0 : JSPROP_PERMANENT);
685 : }
686 : }
687 : }
688 : }
689 2 : return NS_OK;
690 : }
691 :
692 : /* string canCreateWrapper (in nsIIDPtr iid); */
693 : NS_IMETHODIMP
694 0 : nsXPCComponents_InterfacesByID::CanCreateWrapper(const nsIID * iid, char **_retval)
695 : {
696 : // We let anyone do this...
697 0 : *_retval = xpc_CloneAllAccess();
698 0 : return NS_OK;
699 : }
700 :
701 : /* string canCallMethod (in nsIIDPtr iid, in wstring methodName); */
702 : NS_IMETHODIMP
703 0 : nsXPCComponents_InterfacesByID::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
704 : {
705 : // If you have to ask, then the answer is NO
706 0 : *_retval = nsnull;
707 0 : return NS_OK;
708 : }
709 :
710 : /* string canGetProperty (in nsIIDPtr iid, in wstring propertyName); */
711 : NS_IMETHODIMP
712 0 : nsXPCComponents_InterfacesByID::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
713 : {
714 : // If you have to ask, then the answer is NO
715 0 : *_retval = nsnull;
716 0 : return NS_OK;
717 : }
718 :
719 : /* string canSetProperty (in nsIIDPtr iid, in wstring propertyName); */
720 : NS_IMETHODIMP
721 0 : nsXPCComponents_InterfacesByID::CanSetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
722 : {
723 : // If you have to ask, then the answer is NO
724 0 : *_retval = nsnull;
725 0 : return NS_OK;
726 : }
727 :
728 : /***************************************************************************/
729 : /***************************************************************************/
730 : /***************************************************************************/
731 :
732 :
733 :
734 : class nsXPCComponents_Classes :
735 : public nsIXPCComponents_Classes,
736 : public nsIXPCScriptable,
737 : public nsIClassInfo
738 : {
739 : public:
740 : // all the interface method declarations...
741 : NS_DECL_ISUPPORTS
742 : NS_DECL_NSIXPCCOMPONENTS_CLASSES
743 : NS_DECL_NSIXPCSCRIPTABLE
744 : NS_DECL_NSICLASSINFO
745 :
746 : public:
747 : nsXPCComponents_Classes();
748 : virtual ~nsXPCComponents_Classes();
749 : };
750 :
751 : /***************************************************************************/
752 : /* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
753 : out nsIIDPtr array); */
754 : NS_IMETHODIMP
755 12878 : nsXPCComponents_Classes::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
756 : {
757 12878 : const PRUint32 count = 2;
758 12878 : *aCount = count;
759 : nsIID **array;
760 12878 : *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*)));
761 12878 : if (!array)
762 0 : return NS_ERROR_OUT_OF_MEMORY;
763 :
764 12878 : PRUint32 index = 0;
765 : nsIID* clone;
766 : #define PUSH_IID(id) \
767 : clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ), \
768 : sizeof(nsIID))); \
769 : if (!clone) \
770 : goto oom; \
771 : array[index++] = clone;
772 :
773 12878 : PUSH_IID(nsIXPCComponents_Classes)
774 12878 : PUSH_IID(nsIXPCScriptable)
775 : #undef PUSH_IID
776 :
777 12878 : return NS_OK;
778 : oom:
779 0 : while (index)
780 0 : nsMemory::Free(array[--index]);
781 0 : nsMemory::Free(array);
782 0 : *aArray = nsnull;
783 0 : return NS_ERROR_OUT_OF_MEMORY;
784 : }
785 :
786 : /* nsISupports getHelperForLanguage (in PRUint32 language); */
787 : NS_IMETHODIMP
788 12878 : nsXPCComponents_Classes::GetHelperForLanguage(PRUint32 language,
789 : nsISupports **retval)
790 : {
791 12878 : *retval = nsnull;
792 12878 : return NS_OK;
793 : }
794 :
795 : /* readonly attribute string contractID; */
796 : NS_IMETHODIMP
797 0 : nsXPCComponents_Classes::GetContractID(char * *aContractID)
798 : {
799 0 : *aContractID = nsnull;
800 0 : return NS_ERROR_NOT_AVAILABLE;
801 : }
802 :
803 : /* readonly attribute string classDescription; */
804 : NS_IMETHODIMP
805 1 : nsXPCComponents_Classes::GetClassDescription(char * *aClassDescription)
806 : {
807 : static const char classDescription[] = "XPCComponents_Classes";
808 1 : *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
809 1 : return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
810 : }
811 :
812 : /* readonly attribute nsCIDPtr classID; */
813 : NS_IMETHODIMP
814 0 : nsXPCComponents_Classes::GetClassID(nsCID * *aClassID)
815 : {
816 0 : *aClassID = nsnull;
817 0 : return NS_OK;
818 : }
819 :
820 : /* readonly attribute PRUint32 implementationLanguage; */
821 : NS_IMETHODIMP
822 0 : nsXPCComponents_Classes::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
823 : {
824 0 : *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
825 0 : return NS_OK;
826 : }
827 :
828 : /* readonly attribute PRUint32 flags; */
829 : NS_IMETHODIMP
830 25076 : nsXPCComponents_Classes::GetFlags(PRUint32 *aFlags)
831 : {
832 25076 : *aFlags = nsIClassInfo::THREADSAFE;
833 25076 : return NS_OK;
834 : }
835 :
836 : /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
837 : NS_IMETHODIMP
838 0 : nsXPCComponents_Classes::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
839 : {
840 0 : return NS_ERROR_NOT_AVAILABLE;
841 : }
842 :
843 12598 : nsXPCComponents_Classes::nsXPCComponents_Classes()
844 : {
845 12598 : }
846 :
847 25162 : nsXPCComponents_Classes::~nsXPCComponents_Classes()
848 : {
849 : // empty
850 50324 : }
851 :
852 243273 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Classes)
853 243273 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Classes)
854 224074 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
855 185440 : NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
856 159682 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Classes)
857 113220 : NS_INTERFACE_MAP_END_THREADSAFE
858 :
859 214866 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents_Classes)
860 214831 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents_Classes)
861 :
862 : // The nsIXPCScriptable map declaration that will generate stubs for us...
863 : #define XPC_MAP_CLASSNAME nsXPCComponents_Classes
864 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Classes"
865 : #define XPC_MAP_WANT_NEWRESOLVE
866 : #define XPC_MAP_WANT_NEWENUMERATE
867 : #define XPC_MAP_FLAGS nsIXPCScriptable::DONT_ENUM_STATIC_PROPS |\
868 : nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
869 : #include "xpc_map_end.h" /* This will #undef the above */
870 :
871 :
872 : /* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 enum_op, in JSValPtr statep, out JSID idp); */
873 : NS_IMETHODIMP
874 0 : nsXPCComponents_Classes::NewEnumerate(nsIXPConnectWrappedNative *wrapper,
875 : JSContext * cx, JSObject * obj,
876 : PRUint32 enum_op, jsval * statep,
877 : jsid * idp, bool *_retval)
878 : {
879 : nsISimpleEnumerator* e;
880 :
881 0 : switch (enum_op) {
882 : case JSENUMERATE_INIT:
883 : case JSENUMERATE_INIT_ALL:
884 : {
885 0 : nsCOMPtr<nsIComponentRegistrar> compMgr;
886 0 : if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || !compMgr ||
887 0 : NS_FAILED(compMgr->EnumerateContractIDs(&e)) || !e ) {
888 0 : *statep = JSVAL_NULL;
889 0 : return NS_ERROR_UNEXPECTED;
890 : }
891 :
892 0 : *statep = PRIVATE_TO_JSVAL(e);
893 0 : if (idp)
894 0 : *idp = INT_TO_JSID(0); // indicate that we don't know the count
895 0 : return NS_OK;
896 : }
897 : case JSENUMERATE_NEXT:
898 : {
899 0 : nsCOMPtr<nsISupports> isup;
900 : bool hasMore;
901 0 : e = (nsISimpleEnumerator*) JSVAL_TO_PRIVATE(*statep);
902 :
903 0 : if (NS_SUCCEEDED(e->HasMoreElements(&hasMore)) && hasMore &&
904 0 : NS_SUCCEEDED(e->GetNext(getter_AddRefs(isup))) && isup) {
905 0 : nsCOMPtr<nsISupportsCString> holder(do_QueryInterface(isup));
906 0 : if (holder) {
907 0 : nsCAutoString name;
908 0 : if (NS_SUCCEEDED(holder->GetData(name))) {
909 0 : JSString* idstr = JS_NewStringCopyN(cx, name.get(), name.Length());
910 0 : if (idstr &&
911 0 : JS_ValueToId(cx, STRING_TO_JSVAL(idstr), idp)) {
912 0 : return NS_OK;
913 : }
914 : }
915 : }
916 : }
917 : // else... FALL THROUGH
918 : }
919 :
920 : case JSENUMERATE_DESTROY:
921 : default:
922 0 : e = (nsISimpleEnumerator*) JSVAL_TO_PRIVATE(*statep);
923 0 : NS_IF_RELEASE(e);
924 0 : *statep = JSVAL_NULL;
925 0 : return NS_OK;
926 : }
927 : }
928 :
929 : /* bool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, in PRUint32 flags, out JSObjectPtr objp); */
930 : NS_IMETHODIMP
931 44142 : nsXPCComponents_Classes::NewResolve(nsIXPConnectWrappedNative *wrapper,
932 : JSContext * cx, JSObject * obj,
933 : jsid id, PRUint32 flags,
934 : JSObject * *objp, bool *_retval)
935 :
936 : {
937 88284 : JSAutoByteString name;
938 :
939 132426 : if (JSID_IS_STRING(id) &&
940 44142 : name.encode(cx, JSID_TO_STRING(id)) &&
941 44142 : name.ptr()[0] != '{') { // we only allow contractids here
942 : nsCOMPtr<nsIJSCID> nsid =
943 88284 : dont_AddRef(static_cast<nsIJSCID*>(nsJSCID::NewID(name.ptr())));
944 44142 : if (nsid) {
945 85116 : nsCOMPtr<nsIXPConnect> xpc;
946 42558 : wrapper->GetXPConnect(getter_AddRefs(xpc));
947 42558 : if (xpc) {
948 85116 : nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
949 42558 : if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
950 : static_cast<nsIJSCID*>(nsid),
951 : NS_GET_IID(nsIJSCID),
952 : getter_AddRefs(holder)))) {
953 : JSObject* idobj;
954 42558 : if (holder && NS_SUCCEEDED(holder->GetJSObject(&idobj))) {
955 42558 : *objp = obj;
956 : *_retval = JS_DefinePropertyById(cx, obj, id,
957 42558 : OBJECT_TO_JSVAL(idobj),
958 : nsnull, nsnull,
959 : JSPROP_ENUMERATE |
960 : JSPROP_READONLY |
961 42558 : JSPROP_PERMANENT);
962 : }
963 : }
964 : }
965 : }
966 : }
967 44142 : return NS_OK;
968 : }
969 :
970 : /***************************************************************************/
971 : /***************************************************************************/
972 : /***************************************************************************/
973 :
974 : class nsXPCComponents_ClassesByID :
975 : public nsIXPCComponents_ClassesByID,
976 : public nsIXPCScriptable,
977 : public nsIClassInfo
978 : {
979 : public:
980 : // all the interface method declarations...
981 : NS_DECL_ISUPPORTS
982 : NS_DECL_NSIXPCCOMPONENTS_CLASSESBYID
983 : NS_DECL_NSIXPCSCRIPTABLE
984 : NS_DECL_NSICLASSINFO
985 :
986 : public:
987 : nsXPCComponents_ClassesByID();
988 : virtual ~nsXPCComponents_ClassesByID();
989 : };
990 :
991 : /***************************************************************************/
992 : /* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
993 : out nsIIDPtr array); */
994 : NS_IMETHODIMP
995 4 : nsXPCComponents_ClassesByID::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
996 : {
997 4 : const PRUint32 count = 2;
998 4 : *aCount = count;
999 : nsIID **array;
1000 4 : *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*)));
1001 4 : if (!array)
1002 0 : return NS_ERROR_OUT_OF_MEMORY;
1003 :
1004 4 : PRUint32 index = 0;
1005 : nsIID* clone;
1006 : #define PUSH_IID(id) \
1007 : clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ), \
1008 : sizeof(nsIID))); \
1009 : if (!clone) \
1010 : goto oom; \
1011 : array[index++] = clone;
1012 :
1013 4 : PUSH_IID(nsIXPCComponents_ClassesByID)
1014 4 : PUSH_IID(nsIXPCScriptable)
1015 : #undef PUSH_IID
1016 :
1017 4 : return NS_OK;
1018 : oom:
1019 0 : while (index)
1020 0 : nsMemory::Free(array[--index]);
1021 0 : nsMemory::Free(array);
1022 0 : *aArray = nsnull;
1023 0 : return NS_ERROR_OUT_OF_MEMORY;
1024 : }
1025 :
1026 : /* nsISupports getHelperForLanguage (in PRUint32 language); */
1027 : NS_IMETHODIMP
1028 4 : nsXPCComponents_ClassesByID::GetHelperForLanguage(PRUint32 language,
1029 : nsISupports **retval)
1030 : {
1031 4 : *retval = nsnull;
1032 4 : return NS_OK;
1033 : }
1034 :
1035 : /* readonly attribute string contractID; */
1036 : NS_IMETHODIMP
1037 0 : nsXPCComponents_ClassesByID::GetContractID(char * *aContractID)
1038 : {
1039 0 : *aContractID = nsnull;
1040 0 : return NS_ERROR_NOT_AVAILABLE;
1041 : }
1042 :
1043 : /* readonly attribute string classDescription; */
1044 : NS_IMETHODIMP
1045 1 : nsXPCComponents_ClassesByID::GetClassDescription(char * *aClassDescription)
1046 : {
1047 : static const char classDescription[] = "XPCComponents_ClassesByID";
1048 1 : *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
1049 1 : return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
1050 : }
1051 :
1052 : /* readonly attribute nsCIDPtr classID; */
1053 : NS_IMETHODIMP
1054 0 : nsXPCComponents_ClassesByID::GetClassID(nsCID * *aClassID)
1055 : {
1056 0 : *aClassID = nsnull;
1057 0 : return NS_OK;
1058 : }
1059 :
1060 : /* readonly attribute PRUint32 implementationLanguage; */
1061 : NS_IMETHODIMP
1062 0 : nsXPCComponents_ClassesByID::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
1063 : {
1064 0 : *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
1065 0 : return NS_OK;
1066 : }
1067 :
1068 : /* readonly attribute PRUint32 flags; */
1069 : NS_IMETHODIMP
1070 4 : nsXPCComponents_ClassesByID::GetFlags(PRUint32 *aFlags)
1071 : {
1072 4 : *aFlags = nsIClassInfo::THREADSAFE;
1073 4 : return NS_OK;
1074 : }
1075 :
1076 : /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
1077 : NS_IMETHODIMP
1078 0 : nsXPCComponents_ClassesByID::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
1079 : {
1080 0 : return NS_ERROR_NOT_AVAILABLE;
1081 : }
1082 :
1083 4 : nsXPCComponents_ClassesByID::nsXPCComponents_ClassesByID()
1084 : {
1085 4 : }
1086 :
1087 8 : nsXPCComponents_ClassesByID::~nsXPCComponents_ClassesByID()
1088 : {
1089 : // empty
1090 16 : }
1091 :
1092 58 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_ClassesByID)
1093 58 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_ClassesByID)
1094 54 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
1095 42 : NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
1096 32 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_ClassesByID)
1097 24 : NS_INTERFACE_MAP_END_THREADSAFE
1098 :
1099 51 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents_ClassesByID)
1100 51 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents_ClassesByID)
1101 :
1102 : // The nsIXPCScriptable map declaration that will generate stubs for us...
1103 : #define XPC_MAP_CLASSNAME nsXPCComponents_ClassesByID
1104 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_ClassesByID"
1105 : #define XPC_MAP_WANT_NEWRESOLVE
1106 : #define XPC_MAP_WANT_NEWENUMERATE
1107 : #define XPC_MAP_FLAGS nsIXPCScriptable::DONT_ENUM_STATIC_PROPS |\
1108 : nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
1109 : #include "xpc_map_end.h" /* This will #undef the above */
1110 :
1111 : /* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 enum_op, in JSValPtr statep, out JSID idp); */
1112 : NS_IMETHODIMP
1113 0 : nsXPCComponents_ClassesByID::NewEnumerate(nsIXPConnectWrappedNative *wrapper,
1114 : JSContext * cx, JSObject * obj,
1115 : PRUint32 enum_op, jsval * statep,
1116 : jsid * idp, bool *_retval)
1117 : {
1118 : nsISimpleEnumerator* e;
1119 :
1120 0 : switch (enum_op) {
1121 : case JSENUMERATE_INIT:
1122 : case JSENUMERATE_INIT_ALL:
1123 : {
1124 0 : nsCOMPtr<nsIComponentRegistrar> compMgr;
1125 0 : if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || !compMgr ||
1126 0 : NS_FAILED(compMgr->EnumerateCIDs(&e)) || !e ) {
1127 0 : *statep = JSVAL_NULL;
1128 0 : return NS_ERROR_UNEXPECTED;
1129 : }
1130 :
1131 0 : *statep = PRIVATE_TO_JSVAL(e);
1132 0 : if (idp)
1133 0 : *idp = INT_TO_JSID(0); // indicate that we don't know the count
1134 0 : return NS_OK;
1135 : }
1136 : case JSENUMERATE_NEXT:
1137 : {
1138 0 : nsCOMPtr<nsISupports> isup;
1139 : bool hasMore;
1140 0 : e = (nsISimpleEnumerator*) JSVAL_TO_PRIVATE(*statep);
1141 :
1142 0 : if (NS_SUCCEEDED(e->HasMoreElements(&hasMore)) && hasMore &&
1143 0 : NS_SUCCEEDED(e->GetNext(getter_AddRefs(isup))) && isup) {
1144 0 : nsCOMPtr<nsISupportsID> holder(do_QueryInterface(isup));
1145 0 : if (holder) {
1146 : char* name;
1147 0 : if (NS_SUCCEEDED(holder->ToString(&name)) && name) {
1148 0 : JSString* idstr = JS_NewStringCopyZ(cx, name);
1149 0 : nsMemory::Free(name);
1150 0 : if (idstr &&
1151 0 : JS_ValueToId(cx, STRING_TO_JSVAL(idstr), idp)) {
1152 0 : return NS_OK;
1153 : }
1154 : }
1155 : }
1156 : }
1157 : // else... FALL THROUGH
1158 : }
1159 :
1160 : case JSENUMERATE_DESTROY:
1161 : default:
1162 0 : e = (nsISimpleEnumerator*) JSVAL_TO_PRIVATE(*statep);
1163 0 : NS_IF_RELEASE(e);
1164 0 : *statep = JSVAL_NULL;
1165 0 : return NS_OK;
1166 : }
1167 : }
1168 :
1169 : static bool
1170 3 : IsRegisteredCLSID(const char* str)
1171 : {
1172 : bool registered;
1173 : nsID id;
1174 :
1175 3 : if (!id.Parse(str))
1176 0 : return false;
1177 :
1178 6 : nsCOMPtr<nsIComponentRegistrar> compMgr;
1179 6 : if (NS_FAILED(NS_GetComponentRegistrar(getter_AddRefs(compMgr))) || !compMgr ||
1180 3 : NS_FAILED(compMgr->IsCIDRegistered(id, ®istered)))
1181 0 : return false;
1182 :
1183 3 : return registered;
1184 : }
1185 :
1186 : /* bool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, in PRUint32 flags, out JSObjectPtr objp); */
1187 : NS_IMETHODIMP
1188 5 : nsXPCComponents_ClassesByID::NewResolve(nsIXPConnectWrappedNative *wrapper,
1189 : JSContext * cx, JSObject * obj,
1190 : jsid id, PRUint32 flags,
1191 : JSObject * *objp, bool *_retval)
1192 : {
1193 10 : JSAutoByteString name;
1194 :
1195 18 : if (JSID_IS_STRING(id) &&
1196 5 : name.encode(cx, JSID_TO_STRING(id)) &&
1197 5 : name.ptr()[0] == '{' &&
1198 3 : IsRegisteredCLSID(name.ptr())) { // we only allow canonical CLSIDs here
1199 : nsCOMPtr<nsIJSCID> nsid =
1200 4 : dont_AddRef(static_cast<nsIJSCID*>(nsJSCID::NewID(name.ptr())));
1201 2 : if (nsid) {
1202 4 : nsCOMPtr<nsIXPConnect> xpc;
1203 2 : wrapper->GetXPConnect(getter_AddRefs(xpc));
1204 2 : if (xpc) {
1205 4 : nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
1206 2 : if (NS_SUCCEEDED(xpc->WrapNative(cx, obj,
1207 : static_cast<nsIJSCID*>(nsid),
1208 : NS_GET_IID(nsIJSCID),
1209 : getter_AddRefs(holder)))) {
1210 : JSObject* idobj;
1211 2 : if (holder && NS_SUCCEEDED(holder->GetJSObject(&idobj))) {
1212 2 : *objp = obj;
1213 : *_retval = JS_DefinePropertyById(cx, obj, id,
1214 2 : OBJECT_TO_JSVAL(idobj),
1215 : nsnull, nsnull,
1216 : JSPROP_ENUMERATE |
1217 : JSPROP_READONLY |
1218 2 : JSPROP_PERMANENT);
1219 : }
1220 : }
1221 : }
1222 : }
1223 : }
1224 5 : return NS_OK;
1225 : }
1226 :
1227 :
1228 : /***************************************************************************/
1229 :
1230 : // Currently the possible results do not change at runtime, so they are only
1231 : // cached once (unlike ContractIDs, CLSIDs, and IIDs)
1232 :
1233 : class nsXPCComponents_Results :
1234 : public nsIXPCComponents_Results,
1235 : public nsIXPCScriptable,
1236 : public nsIClassInfo
1237 : {
1238 : public:
1239 : // all the interface method declarations...
1240 : NS_DECL_ISUPPORTS
1241 : NS_DECL_NSIXPCCOMPONENTS_RESULTS
1242 : NS_DECL_NSIXPCSCRIPTABLE
1243 : NS_DECL_NSICLASSINFO
1244 :
1245 : public:
1246 : nsXPCComponents_Results();
1247 : virtual ~nsXPCComponents_Results();
1248 : };
1249 :
1250 : /***************************************************************************/
1251 : /* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
1252 : out nsIIDPtr array); */
1253 : NS_IMETHODIMP
1254 9796 : nsXPCComponents_Results::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
1255 : {
1256 9796 : const PRUint32 count = 2;
1257 9796 : *aCount = count;
1258 : nsIID **array;
1259 9796 : *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*)));
1260 9796 : if (!array)
1261 0 : return NS_ERROR_OUT_OF_MEMORY;
1262 :
1263 9796 : PRUint32 index = 0;
1264 : nsIID* clone;
1265 : #define PUSH_IID(id) \
1266 : clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ), \
1267 : sizeof(nsIID))); \
1268 : if (!clone) \
1269 : goto oom; \
1270 : array[index++] = clone;
1271 :
1272 9796 : PUSH_IID(nsIXPCComponents_Results)
1273 9796 : PUSH_IID(nsIXPCScriptable)
1274 : #undef PUSH_IID
1275 :
1276 9796 : return NS_OK;
1277 : oom:
1278 0 : while (index)
1279 0 : nsMemory::Free(array[--index]);
1280 0 : nsMemory::Free(array);
1281 0 : *aArray = nsnull;
1282 0 : return NS_ERROR_OUT_OF_MEMORY;
1283 : }
1284 :
1285 : /* nsISupports getHelperForLanguage (in PRUint32 language); */
1286 : NS_IMETHODIMP
1287 9796 : nsXPCComponents_Results::GetHelperForLanguage(PRUint32 language,
1288 : nsISupports **retval)
1289 : {
1290 9796 : *retval = nsnull;
1291 9796 : return NS_OK;
1292 : }
1293 :
1294 : /* readonly attribute string contractID; */
1295 : NS_IMETHODIMP
1296 0 : nsXPCComponents_Results::GetContractID(char * *aContractID)
1297 : {
1298 0 : *aContractID = nsnull;
1299 0 : return NS_ERROR_NOT_AVAILABLE;
1300 : }
1301 :
1302 : /* readonly attribute string classDescription; */
1303 : NS_IMETHODIMP
1304 1 : nsXPCComponents_Results::GetClassDescription(char * *aClassDescription)
1305 : {
1306 : static const char classDescription[] = "XPCComponents_Results";
1307 1 : *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
1308 1 : return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
1309 : }
1310 :
1311 : /* readonly attribute nsCIDPtr classID; */
1312 : NS_IMETHODIMP
1313 0 : nsXPCComponents_Results::GetClassID(nsCID * *aClassID)
1314 : {
1315 0 : *aClassID = nsnull;
1316 0 : return NS_OK;
1317 : }
1318 :
1319 : /* readonly attribute PRUint32 implementationLanguage; */
1320 : NS_IMETHODIMP
1321 0 : nsXPCComponents_Results::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
1322 : {
1323 0 : *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
1324 0 : return NS_OK;
1325 : }
1326 :
1327 : /* readonly attribute PRUint32 flags; */
1328 : NS_IMETHODIMP
1329 18403 : nsXPCComponents_Results::GetFlags(PRUint32 *aFlags)
1330 : {
1331 18403 : *aFlags = nsIClassInfo::THREADSAFE;
1332 18403 : return NS_OK;
1333 : }
1334 :
1335 : /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
1336 : NS_IMETHODIMP
1337 0 : nsXPCComponents_Results::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
1338 : {
1339 0 : return NS_ERROR_NOT_AVAILABLE;
1340 : }
1341 :
1342 9794 : nsXPCComponents_Results::nsXPCComponents_Results()
1343 : {
1344 9794 : }
1345 :
1346 19568 : nsXPCComponents_Results::~nsXPCComponents_Results()
1347 : {
1348 : // empty
1349 39136 : }
1350 :
1351 139315 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Results)
1352 139315 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Results)
1353 129152 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
1354 99764 : NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
1355 80170 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Results)
1356 64668 : NS_INTERFACE_MAP_END_THREADSAFE
1357 :
1358 119532 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents_Results)
1359 119512 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents_Results)
1360 :
1361 : // The nsIXPCScriptable map declaration that will generate stubs for us...
1362 : #define XPC_MAP_CLASSNAME nsXPCComponents_Results
1363 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Results"
1364 : #define XPC_MAP_WANT_NEWRESOLVE
1365 : #define XPC_MAP_WANT_NEWENUMERATE
1366 : #define XPC_MAP_FLAGS nsIXPCScriptable::DONT_ENUM_STATIC_PROPS |\
1367 : nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
1368 : #include "xpc_map_end.h" /* This will #undef the above */
1369 :
1370 : /* bool newEnumerate (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 enum_op, in JSValPtr statep, out JSID idp); */
1371 : NS_IMETHODIMP
1372 0 : nsXPCComponents_Results::NewEnumerate(nsIXPConnectWrappedNative *wrapper,
1373 : JSContext * cx, JSObject * obj,
1374 : PRUint32 enum_op, jsval * statep,
1375 : jsid * idp, bool *_retval)
1376 : {
1377 : void** iter;
1378 :
1379 0 : switch (enum_op) {
1380 : case JSENUMERATE_INIT:
1381 : case JSENUMERATE_INIT_ALL:
1382 : {
1383 0 : if (idp)
1384 0 : *idp = INT_TO_JSID(nsXPCException::GetNSResultCount());
1385 :
1386 0 : void** space = (void**) new char[sizeof(void*)];
1387 0 : *space = nsnull;
1388 0 : *statep = PRIVATE_TO_JSVAL(space);
1389 0 : return NS_OK;
1390 : }
1391 : case JSENUMERATE_NEXT:
1392 : {
1393 : const char* name;
1394 0 : iter = (void**) JSVAL_TO_PRIVATE(*statep);
1395 0 : if (nsXPCException::IterateNSResults(nsnull, &name, nsnull, iter)) {
1396 0 : JSString* idstr = JS_NewStringCopyZ(cx, name);
1397 0 : if (idstr && JS_ValueToId(cx, STRING_TO_JSVAL(idstr), idp))
1398 0 : return NS_OK;
1399 : }
1400 : // else... FALL THROUGH
1401 : }
1402 :
1403 : case JSENUMERATE_DESTROY:
1404 : default:
1405 0 : iter = (void**) JSVAL_TO_PRIVATE(*statep);
1406 0 : delete [] (char*) iter;
1407 0 : *statep = JSVAL_NULL;
1408 0 : return NS_OK;
1409 : }
1410 : }
1411 :
1412 :
1413 : /* bool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, in PRUint32 flags, out JSObjectPtr objp); */
1414 : NS_IMETHODIMP
1415 5763 : nsXPCComponents_Results::NewResolve(nsIXPConnectWrappedNative *wrapper,
1416 : JSContext * cx, JSObject * obj,
1417 : jsid id, PRUint32 flags,
1418 : JSObject * *objp, bool *_retval)
1419 : {
1420 11526 : JSAutoByteString name;
1421 :
1422 5763 : if (JSID_IS_STRING(id) && name.encode(cx, JSID_TO_STRING(id))) {
1423 : const char* rv_name;
1424 5763 : void* iter = nsnull;
1425 : nsresult rv;
1426 933606 : while (nsXPCException::IterateNSResults(&rv, &rv_name, nsnull, &iter)) {
1427 922080 : if (!strcmp(name.ptr(), rv_name)) {
1428 : jsval val;
1429 :
1430 5761 : *objp = obj;
1431 11522 : if (!JS_NewNumberValue(cx, (double)rv, &val) ||
1432 : !JS_DefinePropertyById(cx, obj, id, val,
1433 : nsnull, nsnull,
1434 : JSPROP_ENUMERATE |
1435 : JSPROP_READONLY |
1436 5761 : JSPROP_PERMANENT)) {
1437 0 : return NS_ERROR_UNEXPECTED;
1438 : }
1439 : }
1440 : }
1441 : }
1442 5763 : return NS_OK;
1443 : }
1444 :
1445 : /***************************************************************************/
1446 : // JavaScript Constructor for nsIJSID objects (Components.ID)
1447 :
1448 : class nsXPCComponents_ID :
1449 : public nsIXPCComponents_ID,
1450 : public nsIXPCScriptable,
1451 : public nsIClassInfo
1452 : {
1453 : public:
1454 : // all the interface method declarations...
1455 : NS_DECL_ISUPPORTS
1456 : NS_DECL_NSIXPCCOMPONENTS_ID
1457 : NS_DECL_NSIXPCSCRIPTABLE
1458 : NS_DECL_NSICLASSINFO
1459 :
1460 :
1461 : public:
1462 : nsXPCComponents_ID();
1463 : virtual ~nsXPCComponents_ID();
1464 :
1465 : private:
1466 : static nsresult CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
1467 : JSContext * cx, JSObject * obj,
1468 : PRUint32 argc, jsval * argv,
1469 : jsval * vp, bool *_retval);
1470 : };
1471 :
1472 : /***************************************************************************/
1473 : /* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
1474 : out nsIIDPtr array); */
1475 : NS_IMETHODIMP
1476 3525 : nsXPCComponents_ID::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
1477 : {
1478 3525 : const PRUint32 count = 2;
1479 3525 : *aCount = count;
1480 : nsIID **array;
1481 3525 : *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*)));
1482 3525 : if (!array)
1483 0 : return NS_ERROR_OUT_OF_MEMORY;
1484 :
1485 3525 : PRUint32 index = 0;
1486 : nsIID* clone;
1487 : #define PUSH_IID(id) \
1488 : clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ), \
1489 : sizeof(nsIID))); \
1490 : if (!clone) \
1491 : goto oom; \
1492 : array[index++] = clone;
1493 :
1494 3525 : PUSH_IID(nsIXPCComponents_ID)
1495 3525 : PUSH_IID(nsIXPCScriptable)
1496 : #undef PUSH_IID
1497 :
1498 3525 : return NS_OK;
1499 : oom:
1500 0 : while (index)
1501 0 : nsMemory::Free(array[--index]);
1502 0 : nsMemory::Free(array);
1503 0 : *aArray = nsnull;
1504 0 : return NS_ERROR_OUT_OF_MEMORY;
1505 : }
1506 :
1507 : /* nsISupports getHelperForLanguage (in PRUint32 language); */
1508 : NS_IMETHODIMP
1509 3525 : nsXPCComponents_ID::GetHelperForLanguage(PRUint32 language,
1510 : nsISupports **retval)
1511 : {
1512 3525 : *retval = nsnull;
1513 3525 : return NS_OK;
1514 : }
1515 :
1516 : /* readonly attribute string contractID; */
1517 : NS_IMETHODIMP
1518 0 : nsXPCComponents_ID::GetContractID(char * *aContractID)
1519 : {
1520 0 : *aContractID = nsnull;
1521 0 : return NS_ERROR_NOT_AVAILABLE;
1522 : }
1523 :
1524 : /* readonly attribute string classDescription; */
1525 : NS_IMETHODIMP
1526 0 : nsXPCComponents_ID::GetClassDescription(char * *aClassDescription)
1527 : {
1528 : static const char classDescription[] = "XPCComponents_ID";
1529 0 : *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
1530 0 : return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
1531 : }
1532 :
1533 : /* readonly attribute nsCIDPtr classID; */
1534 : NS_IMETHODIMP
1535 0 : nsXPCComponents_ID::GetClassID(nsCID * *aClassID)
1536 : {
1537 0 : *aClassID = nsnull;
1538 0 : return NS_OK;
1539 : }
1540 :
1541 : /* readonly attribute PRUint32 implementationLanguage; */
1542 : NS_IMETHODIMP
1543 0 : nsXPCComponents_ID::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
1544 : {
1545 0 : *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
1546 0 : return NS_OK;
1547 : }
1548 :
1549 : /* readonly attribute PRUint32 flags; */
1550 : NS_IMETHODIMP
1551 6126 : nsXPCComponents_ID::GetFlags(PRUint32 *aFlags)
1552 : {
1553 6126 : *aFlags = nsIClassInfo::THREADSAFE;
1554 6126 : return NS_OK;
1555 : }
1556 :
1557 : /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
1558 : NS_IMETHODIMP
1559 0 : nsXPCComponents_ID::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
1560 : {
1561 0 : return NS_ERROR_NOT_AVAILABLE;
1562 : }
1563 :
1564 3458 : nsXPCComponents_ID::nsXPCComponents_ID()
1565 : {
1566 3458 : }
1567 :
1568 6912 : nsXPCComponents_ID::~nsXPCComponents_ID()
1569 : {
1570 : // empty
1571 13824 : }
1572 :
1573 49621 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_ID)
1574 49621 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_ID)
1575 46096 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
1576 35521 : NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
1577 28471 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_ID)
1578 22586 : NS_INTERFACE_MAP_END_THREADSAFE
1579 :
1580 43428 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents_ID)
1581 43426 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents_ID)
1582 :
1583 : // The nsIXPCScriptable map declaration that will generate stubs for us...
1584 : #define XPC_MAP_CLASSNAME nsXPCComponents_ID
1585 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_ID"
1586 : #define XPC_MAP_WANT_CALL
1587 : #define XPC_MAP_WANT_CONSTRUCT
1588 : #define XPC_MAP_WANT_HASINSTANCE
1589 : #define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
1590 : #include "xpc_map_end.h" /* This will #undef the above */
1591 :
1592 :
1593 : /* bool call (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); */
1594 : NS_IMETHODIMP
1595 3257 : nsXPCComponents_ID::Call(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, PRUint32 argc, jsval * argv, jsval * vp, bool *_retval)
1596 : {
1597 3257 : return CallOrConstruct(wrapper, cx, obj, argc, argv, vp, _retval);
1598 :
1599 : }
1600 :
1601 : /* bool construct (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); */
1602 : NS_IMETHODIMP
1603 0 : nsXPCComponents_ID::Construct(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, PRUint32 argc, jsval * argv, jsval * vp, bool *_retval)
1604 : {
1605 0 : return CallOrConstruct(wrapper, cx, obj, argc, argv, vp, _retval);
1606 : }
1607 :
1608 : // static
1609 : nsresult
1610 3257 : nsXPCComponents_ID::CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
1611 : JSContext * cx, JSObject * obj,
1612 : PRUint32 argc, jsval * argv,
1613 : jsval * vp, bool *_retval)
1614 : {
1615 : // make sure we have at least one arg
1616 :
1617 3257 : if (!argc)
1618 0 : return ThrowAndFail(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx, _retval);
1619 :
1620 6514 : XPCCallContext ccx(JS_CALLER, cx);
1621 3257 : if (!ccx.IsValid())
1622 0 : return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
1623 :
1624 3257 : XPCContext* xpcc = ccx.GetXPCContext();
1625 :
1626 : // Do the security check if necessary
1627 :
1628 : nsIXPCSecurityManager* sm =
1629 3257 : xpcc->GetAppropriateSecurityManager(nsIXPCSecurityManager::HOOK_CREATE_INSTANCE);
1630 3257 : if (sm && NS_FAILED(sm->CanCreateInstance(cx, nsJSID::GetCID()))) {
1631 : // the security manager vetoed. It should have set an exception.
1632 0 : *_retval = false;
1633 0 : return NS_OK;
1634 : }
1635 :
1636 : // convert the first argument into a string and see if it looks like an id
1637 :
1638 : JSString* jsstr;
1639 6514 : JSAutoByteString bytes;
1640 : nsID id;
1641 :
1642 9771 : if (!(jsstr = JS_ValueToString(cx, argv[0])) ||
1643 3257 : !bytes.encode(cx, jsstr) ||
1644 3257 : !id.Parse(bytes.ptr())) {
1645 0 : return ThrowAndFail(NS_ERROR_XPC_BAD_ID_STRING, cx, _retval);
1646 : }
1647 :
1648 : // make the new object and return it.
1649 :
1650 3257 : JSObject* newobj = xpc_NewIDObject(cx, obj, id);
1651 :
1652 3257 : if (vp)
1653 3257 : *vp = OBJECT_TO_JSVAL(newobj);
1654 :
1655 3257 : return NS_OK;
1656 : }
1657 :
1658 : /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
1659 : NS_IMETHODIMP
1660 2628 : nsXPCComponents_ID::HasInstance(nsIXPConnectWrappedNative *wrapper,
1661 : JSContext * cx, JSObject * obj,
1662 : const jsval &val, bool *bp, bool *_retval)
1663 : {
1664 2628 : if (bp)
1665 2628 : *bp = JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIJSID));
1666 2628 : return NS_OK;
1667 : }
1668 :
1669 : /***************************************************************************/
1670 : // JavaScript Constructor for nsIXPCException objects (Components.Exception)
1671 :
1672 : class nsXPCComponents_Exception :
1673 : public nsIXPCComponents_Exception,
1674 : public nsIXPCScriptable,
1675 : public nsIClassInfo
1676 : {
1677 : public:
1678 : // all the interface method declarations...
1679 : NS_DECL_ISUPPORTS
1680 : NS_DECL_NSIXPCCOMPONENTS_EXCEPTION
1681 : NS_DECL_NSIXPCSCRIPTABLE
1682 : NS_DECL_NSICLASSINFO
1683 :
1684 :
1685 : public:
1686 : nsXPCComponents_Exception();
1687 : virtual ~nsXPCComponents_Exception();
1688 :
1689 : private:
1690 : static nsresult CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
1691 : JSContext * cx, JSObject * obj,
1692 : PRUint32 argc, jsval * argv,
1693 : jsval * vp, bool *_retval);
1694 : };
1695 :
1696 : /***************************************************************************/
1697 : /* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
1698 : out nsIIDPtr array); */
1699 : NS_IMETHODIMP
1700 372 : nsXPCComponents_Exception::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
1701 : {
1702 372 : const PRUint32 count = 2;
1703 372 : *aCount = count;
1704 : nsIID **array;
1705 372 : *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*)));
1706 372 : if (!array)
1707 0 : return NS_ERROR_OUT_OF_MEMORY;
1708 :
1709 372 : PRUint32 index = 0;
1710 : nsIID* clone;
1711 : #define PUSH_IID(id) \
1712 : clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ), \
1713 : sizeof(nsIID))); \
1714 : if (!clone) \
1715 : goto oom; \
1716 : array[index++] = clone;
1717 :
1718 372 : PUSH_IID(nsIXPCComponents_Exception)
1719 372 : PUSH_IID(nsIXPCScriptable)
1720 : #undef PUSH_IID
1721 :
1722 372 : return NS_OK;
1723 : oom:
1724 0 : while (index)
1725 0 : nsMemory::Free(array[--index]);
1726 0 : nsMemory::Free(array);
1727 0 : *aArray = nsnull;
1728 0 : return NS_ERROR_OUT_OF_MEMORY;
1729 : }
1730 :
1731 : /* nsISupports getHelperForLanguage (in PRUint32 language); */
1732 : NS_IMETHODIMP
1733 372 : nsXPCComponents_Exception::GetHelperForLanguage(PRUint32 language,
1734 : nsISupports **retval)
1735 : {
1736 372 : *retval = nsnull;
1737 372 : return NS_OK;
1738 : }
1739 :
1740 : /* readonly attribute string contractID; */
1741 : NS_IMETHODIMP
1742 0 : nsXPCComponents_Exception::GetContractID(char * *aContractID)
1743 : {
1744 0 : *aContractID = nsnull;
1745 0 : return NS_ERROR_NOT_AVAILABLE;
1746 : }
1747 :
1748 : /* readonly attribute string classDescription; */
1749 : NS_IMETHODIMP
1750 0 : nsXPCComponents_Exception::GetClassDescription(char * *aClassDescription)
1751 : {
1752 : static const char classDescription[] = "XPCComponents_Exception";
1753 0 : *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
1754 0 : return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
1755 : }
1756 :
1757 : /* readonly attribute nsCIDPtr classID; */
1758 : NS_IMETHODIMP
1759 0 : nsXPCComponents_Exception::GetClassID(nsCID * *aClassID)
1760 : {
1761 0 : *aClassID = nsnull;
1762 0 : return NS_OK;
1763 : }
1764 :
1765 : /* readonly attribute PRUint32 implementationLanguage; */
1766 : NS_IMETHODIMP
1767 0 : nsXPCComponents_Exception::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
1768 : {
1769 0 : *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
1770 0 : return NS_OK;
1771 : }
1772 :
1773 : /* readonly attribute PRUint32 flags; */
1774 : NS_IMETHODIMP
1775 734 : nsXPCComponents_Exception::GetFlags(PRUint32 *aFlags)
1776 : {
1777 734 : *aFlags = nsIClassInfo::THREADSAFE;
1778 734 : return NS_OK;
1779 : }
1780 :
1781 : /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
1782 : NS_IMETHODIMP
1783 0 : nsXPCComponents_Exception::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
1784 : {
1785 0 : return NS_ERROR_NOT_AVAILABLE;
1786 : }
1787 :
1788 361 : nsXPCComponents_Exception::nsXPCComponents_Exception()
1789 : {
1790 361 : }
1791 :
1792 722 : nsXPCComponents_Exception::~nsXPCComponents_Exception()
1793 : {
1794 : // empty
1795 1444 : }
1796 :
1797 4974 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Exception)
1798 4974 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Exception)
1799 4602 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
1800 3486 : NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
1801 2742 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Exception)
1802 2296 : NS_INTERFACE_MAP_END_THREADSAFE
1803 :
1804 4229 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents_Exception)
1805 4229 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents_Exception)
1806 :
1807 : // The nsIXPCScriptable map declaration that will generate stubs for us...
1808 : #define XPC_MAP_CLASSNAME nsXPCComponents_Exception
1809 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Exception"
1810 : #define XPC_MAP_WANT_CALL
1811 : #define XPC_MAP_WANT_CONSTRUCT
1812 : #define XPC_MAP_WANT_HASINSTANCE
1813 : #define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
1814 : #include "xpc_map_end.h" /* This will #undef the above */
1815 :
1816 :
1817 : /* bool call (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); */
1818 : NS_IMETHODIMP
1819 96 : nsXPCComponents_Exception::Call(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, PRUint32 argc, jsval * argv, jsval * vp, bool *_retval)
1820 : {
1821 96 : return CallOrConstruct(wrapper, cx, obj, argc, argv, vp, _retval);
1822 :
1823 : }
1824 :
1825 : /* bool construct (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); */
1826 : NS_IMETHODIMP
1827 12 : nsXPCComponents_Exception::Construct(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, PRUint32 argc, jsval * argv, jsval * vp, bool *_retval)
1828 : {
1829 12 : return CallOrConstruct(wrapper, cx, obj, argc, argv, vp, _retval);
1830 : }
1831 :
1832 : // static
1833 : nsresult
1834 108 : nsXPCComponents_Exception::CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
1835 : JSContext * cx, JSObject * obj,
1836 : PRUint32 argc, jsval * argv,
1837 : jsval * vp, bool *_retval)
1838 : {
1839 216 : XPCCallContext ccx(JS_CALLER, cx);
1840 108 : if (!ccx.IsValid())
1841 0 : return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
1842 :
1843 108 : nsXPConnect* xpc = ccx.GetXPConnect();
1844 108 : XPCContext* xpcc = ccx.GetXPCContext();
1845 :
1846 : // Do the security check if necessary
1847 :
1848 : nsIXPCSecurityManager* sm =
1849 108 : xpcc->GetAppropriateSecurityManager(nsIXPCSecurityManager::HOOK_CREATE_INSTANCE);
1850 108 : if (sm && NS_FAILED(sm->CanCreateInstance(cx, nsXPCException::GetCID()))) {
1851 : // the security manager vetoed. It should have set an exception.
1852 0 : *_retval = false;
1853 0 : return NS_OK;
1854 : }
1855 :
1856 : // initialization params for the exception object we will create
1857 108 : const char* eMsg = "exception";
1858 216 : JSAutoByteString eMsgBytes;
1859 108 : nsresult eResult = NS_ERROR_FAILURE;
1860 216 : nsCOMPtr<nsIStackFrame> eStack;
1861 216 : nsCOMPtr<nsISupports> eData;
1862 :
1863 : // all params are optional - grab any passed in
1864 108 : switch (argc) {
1865 : default: // more than 4 - ignore extra
1866 : // ...fall through...
1867 : case 4: // argv[3] is object for eData
1868 3 : if (JSVAL_IS_NULL(argv[3])) {
1869 : // do nothing, leave eData as null
1870 : } else {
1871 0 : if (JSVAL_IS_PRIMITIVE(argv[3]) ||
1872 0 : NS_FAILED(xpc->WrapJS(cx, JSVAL_TO_OBJECT(argv[3]),
1873 : NS_GET_IID(nsISupports),
1874 : (void**)getter_AddRefs(eData))))
1875 0 : return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
1876 : }
1877 : // ...fall through...
1878 : case 3: // argv[2] is object for eStack
1879 10 : if (JSVAL_IS_NULL(argv[2])) {
1880 : // do nothing, leave eStack as null
1881 : } else {
1882 40 : if (JSVAL_IS_PRIMITIVE(argv[2]) ||
1883 30 : NS_FAILED(xpc->WrapJS(cx, JSVAL_TO_OBJECT(argv[2]),
1884 : NS_GET_IID(nsIStackFrame),
1885 : (void**)getter_AddRefs(eStack))))
1886 0 : return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
1887 : }
1888 : // fall through...
1889 : case 2: // argv[1] is nsresult for eResult
1890 108 : if (!JS_ValueToECMAInt32(cx, argv[1], (int32_t*) &eResult))
1891 0 : return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
1892 : // ...fall through...
1893 : case 1: // argv[0] is string for eMsg
1894 : {
1895 108 : JSString* str = JS_ValueToString(cx, argv[0]);
1896 108 : if (!str || !(eMsg = eMsgBytes.encode(cx, str)))
1897 0 : return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
1898 : }
1899 : // ...fall through...
1900 : case 0: // this case required so that 'default' does not include zero.
1901 : ; // -- do nothing --
1902 : }
1903 :
1904 216 : nsCOMPtr<nsIException> e;
1905 108 : nsXPCException::NewException(eMsg, eResult, eStack, eData, getter_AddRefs(e));
1906 108 : if (!e)
1907 0 : return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
1908 :
1909 216 : nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
1910 108 : JSObject* newObj = nsnull;
1911 :
1912 432 : if (NS_FAILED(xpc->WrapNative(cx, obj, e, NS_GET_IID(nsIXPCException),
1913 108 : getter_AddRefs(holder))) || !holder ||
1914 216 : NS_FAILED(holder->GetJSObject(&newObj)) || !newObj) {
1915 0 : return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval);
1916 : }
1917 :
1918 108 : if (vp)
1919 108 : *vp = OBJECT_TO_JSVAL(newObj);
1920 :
1921 108 : return NS_OK;
1922 : }
1923 :
1924 : /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
1925 : NS_IMETHODIMP
1926 0 : nsXPCComponents_Exception::HasInstance(nsIXPConnectWrappedNative *wrapper,
1927 : JSContext * cx, JSObject * obj,
1928 : const jsval &val, bool *bp,
1929 : bool *_retval)
1930 : {
1931 0 : if (bp)
1932 0 : *bp = JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIException));
1933 0 : return NS_OK;
1934 : }
1935 :
1936 : /***************************************************************************/
1937 : // This class is for the thing returned by "new Component.Constructor".
1938 :
1939 : // XXXjband we use this CID for security check, but security system can't see
1940 : // it since it has no registed factory. Security really kicks in when we try
1941 : // to build a wrapper around an instance.
1942 :
1943 : // {B4A95150-E25A-11d3-8F61-0010A4E73D9A}
1944 : #define NS_XPCCONSTRUCTOR_CID \
1945 : { 0xb4a95150, 0xe25a, 0x11d3, \
1946 : { 0x8f, 0x61, 0x0, 0x10, 0xa4, 0xe7, 0x3d, 0x9a } }
1947 :
1948 : class nsXPCConstructor :
1949 : public nsIXPCConstructor,
1950 : public nsIXPCScriptable,
1951 : public nsIClassInfo
1952 : {
1953 : public:
1954 4556 : NS_DEFINE_STATIC_CID_ACCESSOR(NS_XPCCONSTRUCTOR_CID)
1955 : public:
1956 : // all the interface method declarations...
1957 : NS_DECL_ISUPPORTS
1958 : NS_DECL_NSIXPCCONSTRUCTOR
1959 : NS_DECL_NSIXPCSCRIPTABLE
1960 : NS_DECL_NSICLASSINFO
1961 :
1962 : public:
1963 : nsXPCConstructor(); // not implemented
1964 : nsXPCConstructor(nsIJSCID* aClassID,
1965 : nsIJSIID* aInterfaceID,
1966 : const char* aInitializer);
1967 : virtual ~nsXPCConstructor();
1968 :
1969 : private:
1970 : nsresult CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
1971 : JSContext * cx, JSObject * obj,
1972 : PRUint32 argc, jsval * argv,
1973 : jsval * vp, bool *_retval);
1974 : private:
1975 : nsIJSCID* mClassID;
1976 : nsIJSIID* mInterfaceID;
1977 : char* mInitializer;
1978 : };
1979 :
1980 : /***************************************************************************/
1981 : /* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
1982 : out nsIIDPtr array); */
1983 : NS_IMETHODIMP
1984 4556 : nsXPCConstructor::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
1985 : {
1986 4556 : const PRUint32 count = 2;
1987 4556 : *aCount = count;
1988 : nsIID **array;
1989 4556 : *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*)));
1990 4556 : if (!array)
1991 0 : return NS_ERROR_OUT_OF_MEMORY;
1992 :
1993 4556 : PRUint32 index = 0;
1994 : nsIID* clone;
1995 : #define PUSH_IID(id) \
1996 : clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ), \
1997 : sizeof(nsIID))); \
1998 : if (!clone) \
1999 : goto oom; \
2000 : array[index++] = clone;
2001 :
2002 4556 : PUSH_IID(nsIXPCConstructor)
2003 4556 : PUSH_IID(nsIXPCScriptable)
2004 : #undef PUSH_IID
2005 :
2006 4556 : return NS_OK;
2007 : oom:
2008 0 : while (index)
2009 0 : nsMemory::Free(array[--index]);
2010 0 : nsMemory::Free(array);
2011 0 : *aArray = nsnull;
2012 0 : return NS_ERROR_OUT_OF_MEMORY;
2013 : }
2014 :
2015 : /* nsISupports getHelperForLanguage (in PRUint32 language); */
2016 : NS_IMETHODIMP
2017 4556 : nsXPCConstructor::GetHelperForLanguage(PRUint32 language,
2018 : nsISupports **retval)
2019 : {
2020 4556 : *retval = nsnull;
2021 4556 : return NS_OK;
2022 : }
2023 :
2024 : /* readonly attribute string contractID; */
2025 : NS_IMETHODIMP
2026 0 : nsXPCConstructor::GetContractID(char * *aContractID)
2027 : {
2028 0 : *aContractID = nsnull;
2029 0 : return NS_ERROR_NOT_AVAILABLE;
2030 : }
2031 :
2032 : /* readonly attribute string classDescription; */
2033 : NS_IMETHODIMP
2034 0 : nsXPCConstructor::GetClassDescription(char * *aClassDescription)
2035 : {
2036 : static const char classDescription[] = "XPCConstructor";
2037 0 : *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
2038 0 : return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
2039 : }
2040 :
2041 : /* readonly attribute nsCIDPtr classID; */
2042 : NS_IMETHODIMP
2043 0 : nsXPCConstructor::GetClassID(nsCID * *aClassID)
2044 : {
2045 0 : *aClassID = nsnull;
2046 0 : return NS_OK;
2047 : }
2048 :
2049 : /* readonly attribute PRUint32 implementationLanguage; */
2050 : NS_IMETHODIMP
2051 0 : nsXPCConstructor::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
2052 : {
2053 0 : *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
2054 0 : return NS_OK;
2055 : }
2056 :
2057 : /* readonly attribute PRUint32 flags; */
2058 : NS_IMETHODIMP
2059 4556 : nsXPCConstructor::GetFlags(PRUint32 *aFlags)
2060 : {
2061 4556 : *aFlags = nsIClassInfo::THREADSAFE;
2062 4556 : return NS_OK;
2063 : }
2064 :
2065 : /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
2066 : NS_IMETHODIMP
2067 0 : nsXPCConstructor::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
2068 : {
2069 0 : return NS_ERROR_NOT_AVAILABLE;
2070 : }
2071 :
2072 4556 : nsXPCConstructor::nsXPCConstructor(nsIJSCID* aClassID,
2073 : nsIJSIID* aInterfaceID,
2074 4556 : const char* aInitializer)
2075 : {
2076 4556 : NS_IF_ADDREF(mClassID = aClassID);
2077 4556 : NS_IF_ADDREF(mInterfaceID = aInterfaceID);
2078 : mInitializer = aInitializer ?
2079 3494 : (char*) nsMemory::Clone(aInitializer, strlen(aInitializer)+1) :
2080 8050 : nsnull;
2081 4556 : }
2082 :
2083 9112 : nsXPCConstructor::~nsXPCConstructor()
2084 : {
2085 4556 : NS_IF_RELEASE(mClassID);
2086 4556 : NS_IF_RELEASE(mInterfaceID);
2087 4556 : if (mInitializer)
2088 3494 : nsMemory::Free(mInitializer);
2089 18224 : }
2090 :
2091 : /* readonly attribute nsIJSCID classID; */
2092 : NS_IMETHODIMP
2093 0 : nsXPCConstructor::GetClassID(nsIJSCID * *aClassID)
2094 : {
2095 0 : NS_IF_ADDREF(*aClassID = mClassID);
2096 0 : return NS_OK;
2097 : }
2098 :
2099 : /* readonly attribute nsIJSIID interfaceID; */
2100 : NS_IMETHODIMP
2101 0 : nsXPCConstructor::GetInterfaceID(nsIJSIID * *aInterfaceID)
2102 : {
2103 0 : NS_IF_ADDREF(*aInterfaceID = mInterfaceID);
2104 0 : return NS_OK;
2105 : }
2106 :
2107 : /* readonly attribute string initializer; */
2108 : NS_IMETHODIMP
2109 0 : nsXPCConstructor::GetInitializer(char * *aInitializer)
2110 : {
2111 0 : XPC_STRING_GETTER_BODY(aInitializer, mInitializer);
2112 : }
2113 :
2114 59228 : NS_INTERFACE_MAP_BEGIN(nsXPCConstructor)
2115 59228 : NS_INTERFACE_MAP_ENTRY(nsIXPCConstructor)
2116 50116 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
2117 36448 : NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
2118 27336 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCConstructor)
2119 22780 : NS_INTERFACE_MAP_END_THREADSAFE
2120 :
2121 50116 : NS_IMPL_THREADSAFE_ADDREF(nsXPCConstructor)
2122 50116 : NS_IMPL_THREADSAFE_RELEASE(nsXPCConstructor)
2123 :
2124 : // The nsIXPCScriptable map declaration that will generate stubs for us...
2125 : #define XPC_MAP_CLASSNAME nsXPCConstructor
2126 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCConstructor"
2127 : #define XPC_MAP_WANT_CALL
2128 : #define XPC_MAP_WANT_CONSTRUCT
2129 : #define XPC_MAP_FLAGS 0
2130 : #include "xpc_map_end.h" /* This will #undef the above */
2131 :
2132 :
2133 : /* bool call (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); */
2134 : NS_IMETHODIMP
2135 29 : nsXPCConstructor::Call(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, PRUint32 argc, jsval * argv, jsval * vp, bool *_retval)
2136 : {
2137 29 : return CallOrConstruct(wrapper, cx, obj, argc, argv, vp, _retval);
2138 :
2139 : }
2140 :
2141 : /* bool construct (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); */
2142 : NS_IMETHODIMP
2143 47121 : nsXPCConstructor::Construct(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, PRUint32 argc, jsval * argv, jsval * vp, bool *_retval)
2144 : {
2145 47121 : return CallOrConstruct(wrapper, cx, obj, argc, argv, vp, _retval);
2146 : }
2147 :
2148 : // static
2149 : nsresult
2150 47150 : nsXPCConstructor::CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
2151 : JSContext * cx, JSObject * obj,
2152 : PRUint32 argc, jsval * argv,
2153 : jsval * vp, bool *_retval)
2154 : {
2155 94300 : XPCCallContext ccx(JS_CALLER, cx);
2156 47150 : if (!ccx.IsValid())
2157 0 : return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
2158 :
2159 47150 : nsXPConnect* xpc = ccx.GetXPConnect();
2160 :
2161 : // security check not required because we are going to call through the
2162 : // code which is reflected into JS which will do that for us later.
2163 :
2164 94300 : nsCOMPtr<nsIXPConnectJSObjectHolder> cidHolder;
2165 94300 : nsCOMPtr<nsIXPConnectJSObjectHolder> iidHolder;
2166 : JSObject* cidObj;
2167 : JSObject* iidObj;
2168 :
2169 471500 : if (NS_FAILED(xpc->WrapNative(cx, obj, mClassID, NS_GET_IID(nsIJSCID),
2170 47150 : getter_AddRefs(cidHolder))) || !cidHolder ||
2171 94300 : NS_FAILED(cidHolder->GetJSObject(&cidObj)) || !cidObj ||
2172 141450 : NS_FAILED(xpc->WrapNative(cx, obj, mInterfaceID, NS_GET_IID(nsIJSIID),
2173 47150 : getter_AddRefs(iidHolder))) || !iidHolder ||
2174 94300 : NS_FAILED(iidHolder->GetJSObject(&iidObj)) || !iidObj) {
2175 0 : return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval);
2176 : }
2177 :
2178 47150 : jsval ctorArgs[1] = {OBJECT_TO_JSVAL(iidObj)};
2179 : jsval val;
2180 :
2181 94300 : if (!JS_CallFunctionName(cx, cidObj, "createInstance", 1, ctorArgs, &val) ||
2182 47150 : JSVAL_IS_PRIMITIVE(val)) {
2183 : // createInstance will have thrown an exception
2184 0 : *_retval = false;
2185 0 : return NS_OK;
2186 : }
2187 :
2188 : // root the result
2189 47150 : if (vp)
2190 47150 : *vp = val;
2191 :
2192 : // call initializer method if supplied
2193 47150 : if (mInitializer) {
2194 27182 : JSObject* newObj = JSVAL_TO_OBJECT(val);
2195 : jsval fun;
2196 : jsval ignored;
2197 :
2198 : // first check existence of function property for better error reporting
2199 54364 : if (!JS_GetProperty(cx, newObj, mInitializer, &fun) ||
2200 27182 : JSVAL_IS_PRIMITIVE(fun)) {
2201 0 : return ThrowAndFail(NS_ERROR_XPC_BAD_INITIALIZER_NAME, cx, _retval);
2202 : }
2203 :
2204 27182 : if (!JS_CallFunctionValue(cx, newObj, fun, argc, argv, &ignored)) {
2205 : // function should have thrown an exception
2206 28 : *_retval = false;
2207 28 : return NS_OK;
2208 : }
2209 : }
2210 :
2211 47122 : return NS_OK;
2212 : }
2213 :
2214 : /*******************************************************/
2215 : // JavaScript Constructor for nsIXPCConstructor objects (Components.Constructor)
2216 :
2217 : class nsXPCComponents_Constructor :
2218 : public nsIXPCComponents_Constructor,
2219 : public nsIXPCScriptable,
2220 : public nsIClassInfo
2221 : {
2222 : public:
2223 : // all the interface method declarations...
2224 : NS_DECL_ISUPPORTS
2225 : NS_DECL_NSIXPCCOMPONENTS_CONSTRUCTOR
2226 : NS_DECL_NSIXPCSCRIPTABLE
2227 : NS_DECL_NSICLASSINFO
2228 :
2229 : public:
2230 : nsXPCComponents_Constructor();
2231 : virtual ~nsXPCComponents_Constructor();
2232 :
2233 : private:
2234 : static nsresult CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
2235 : JSContext * cx, JSObject * obj,
2236 : PRUint32 argc, jsval * argv,
2237 : jsval * vp, bool *_retval);
2238 : };
2239 :
2240 : /***************************************************************************/
2241 : /* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
2242 : out nsIIDPtr array); */
2243 : NS_IMETHODIMP
2244 1078 : nsXPCComponents_Constructor::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
2245 : {
2246 1078 : const PRUint32 count = 2;
2247 1078 : *aCount = count;
2248 : nsIID **array;
2249 1078 : *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*)));
2250 1078 : if (!array)
2251 0 : return NS_ERROR_OUT_OF_MEMORY;
2252 :
2253 1078 : PRUint32 index = 0;
2254 : nsIID* clone;
2255 : #define PUSH_IID(id) \
2256 : clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ), \
2257 : sizeof(nsIID))); \
2258 : if (!clone) \
2259 : goto oom; \
2260 : array[index++] = clone;
2261 :
2262 1078 : PUSH_IID(nsIXPCComponents_Constructor)
2263 1078 : PUSH_IID(nsIXPCScriptable)
2264 : #undef PUSH_IID
2265 :
2266 1078 : return NS_OK;
2267 : oom:
2268 0 : while (index)
2269 0 : nsMemory::Free(array[--index]);
2270 0 : nsMemory::Free(array);
2271 0 : *aArray = nsnull;
2272 0 : return NS_ERROR_OUT_OF_MEMORY;
2273 : }
2274 :
2275 : /* nsISupports getHelperForLanguage (in PRUint32 language); */
2276 : NS_IMETHODIMP
2277 1078 : nsXPCComponents_Constructor::GetHelperForLanguage(PRUint32 language,
2278 : nsISupports **retval)
2279 : {
2280 1078 : *retval = nsnull;
2281 1078 : return NS_OK;
2282 : }
2283 :
2284 : /* readonly attribute string contractID; */
2285 : NS_IMETHODIMP
2286 0 : nsXPCComponents_Constructor::GetContractID(char * *aContractID)
2287 : {
2288 0 : *aContractID = nsnull;
2289 0 : return NS_ERROR_NOT_AVAILABLE;
2290 : }
2291 :
2292 : /* readonly attribute string classDescription; */
2293 : NS_IMETHODIMP
2294 0 : nsXPCComponents_Constructor::GetClassDescription(char * *aClassDescription)
2295 : {
2296 : static const char classDescription[] = "XPCComponents_Constructor";
2297 0 : *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
2298 0 : return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
2299 : }
2300 :
2301 : /* readonly attribute nsCIDPtr classID; */
2302 : NS_IMETHODIMP
2303 0 : nsXPCComponents_Constructor::GetClassID(nsCID * *aClassID)
2304 : {
2305 0 : *aClassID = nsnull;
2306 0 : return NS_OK;
2307 : }
2308 :
2309 : /* readonly attribute PRUint32 implementationLanguage; */
2310 : NS_IMETHODIMP
2311 0 : nsXPCComponents_Constructor::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
2312 : {
2313 0 : *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
2314 0 : return NS_OK;
2315 : }
2316 :
2317 : /* readonly attribute PRUint32 flags; */
2318 : NS_IMETHODIMP
2319 1542 : nsXPCComponents_Constructor::GetFlags(PRUint32 *aFlags)
2320 : {
2321 1542 : *aFlags = nsIClassInfo::THREADSAFE;
2322 1542 : return NS_OK;
2323 : }
2324 :
2325 : /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
2326 : NS_IMETHODIMP
2327 0 : nsXPCComponents_Constructor::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
2328 : {
2329 0 : return NS_ERROR_NOT_AVAILABLE;
2330 : }
2331 :
2332 1074 : nsXPCComponents_Constructor::nsXPCComponents_Constructor()
2333 : {
2334 1074 : }
2335 :
2336 2148 : nsXPCComponents_Constructor::~nsXPCComponents_Constructor()
2337 : {
2338 : // empty
2339 4296 : }
2340 :
2341 15178 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Constructor)
2342 15178 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Constructor)
2343 13749 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
2344 10515 : NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
2345 8359 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Constructor)
2346 6743 : NS_INTERFACE_MAP_END_THREADSAFE
2347 :
2348 13281 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents_Constructor)
2349 13281 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents_Constructor)
2350 :
2351 : // The nsIXPCScriptable map declaration that will generate stubs for us...
2352 : #define XPC_MAP_CLASSNAME nsXPCComponents_Constructor
2353 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Constructor"
2354 : #define XPC_MAP_WANT_CALL
2355 : #define XPC_MAP_WANT_CONSTRUCT
2356 : #define XPC_MAP_WANT_HASINSTANCE
2357 : #define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
2358 : #include "xpc_map_end.h" /* This will #undef the above */
2359 :
2360 :
2361 : /* bool call (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); */
2362 : NS_IMETHODIMP
2363 4378 : nsXPCComponents_Constructor::Call(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, PRUint32 argc, jsval * argv, jsval * vp, bool *_retval)
2364 : {
2365 4378 : return CallOrConstruct(wrapper, cx, obj, argc, argv, vp, _retval);
2366 : }
2367 :
2368 : /* bool construct (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in PRUint32 argc, in JSValPtr argv, in JSValPtr vp); */
2369 : NS_IMETHODIMP
2370 178 : nsXPCComponents_Constructor::Construct(nsIXPConnectWrappedNative *wrapper, JSContext * cx, JSObject * obj, PRUint32 argc, jsval * argv, jsval * vp, bool *_retval)
2371 : {
2372 178 : return CallOrConstruct(wrapper, cx, obj, argc, argv, vp, _retval);
2373 : }
2374 :
2375 : // static
2376 : nsresult
2377 4556 : nsXPCComponents_Constructor::CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
2378 : JSContext * cx, JSObject * obj,
2379 : PRUint32 argc, jsval * argv,
2380 : jsval * vp, bool *_retval)
2381 : {
2382 : // make sure we have at least one arg
2383 :
2384 4556 : if (!argc)
2385 0 : return ThrowAndFail(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx, _retval);
2386 :
2387 : // get the various other object pointers we need
2388 :
2389 9112 : XPCCallContext ccx(JS_CALLER, cx);
2390 4556 : if (!ccx.IsValid())
2391 0 : return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
2392 :
2393 4556 : nsXPConnect* xpc = ccx.GetXPConnect();
2394 4556 : XPCContext* xpcc = ccx.GetXPCContext();
2395 : XPCWrappedNativeScope* scope =
2396 4556 : XPCWrappedNativeScope::FindInJSObjectScope(ccx, obj);
2397 : nsXPCComponents* comp;
2398 :
2399 4556 : if (!xpc || !xpcc || !scope || !(comp = scope->GetComponents()))
2400 0 : return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
2401 :
2402 : // Do the security check if necessary
2403 :
2404 : nsIXPCSecurityManager* sm =
2405 4556 : xpcc->GetAppropriateSecurityManager(nsIXPCSecurityManager::HOOK_CREATE_INSTANCE);
2406 4556 : if (sm && NS_FAILED(sm->CanCreateInstance(cx, nsXPCConstructor::GetCID()))) {
2407 : // the security manager vetoed. It should have set an exception.
2408 0 : *_retval = false;
2409 0 : return NS_OK;
2410 : }
2411 :
2412 : // initialization params for the Constructor object we will create
2413 9112 : nsCOMPtr<nsIJSCID> cClassID;
2414 9112 : nsCOMPtr<nsIJSIID> cInterfaceID;
2415 4556 : const char* cInitializer = nsnull;
2416 9112 : JSAutoByteString cInitializerBytes;
2417 :
2418 4556 : if (argc >= 3) {
2419 : // argv[2] is an initializer function or property name
2420 3494 : JSString* str = JS_ValueToString(cx, argv[2]);
2421 3494 : if (!str || !(cInitializer = cInitializerBytes.encode(cx, str)))
2422 0 : return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
2423 : }
2424 :
2425 4556 : if (argc >= 2) {
2426 : // argv[1] is an iid name string
2427 : // XXXjband support passing "Components.interfaces.foo"?
2428 :
2429 9112 : nsCOMPtr<nsIXPCComponents_Interfaces> ifaces;
2430 9112 : nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
2431 4556 : JSObject* ifacesObj = nsnull;
2432 :
2433 : // we do the lookup by asking the Components.interfaces object
2434 : // for the property with this name - i.e. we let its caching of these
2435 : // nsIJSIID objects work for us.
2436 :
2437 31892 : if (NS_FAILED(comp->GetInterfaces(getter_AddRefs(ifaces))) ||
2438 13668 : NS_FAILED(xpc->WrapNative(cx, obj, ifaces,
2439 : NS_GET_IID(nsIXPCComponents_Interfaces),
2440 4556 : getter_AddRefs(holder))) || !holder ||
2441 9112 : NS_FAILED(holder->GetJSObject(&ifacesObj)) || !ifacesObj) {
2442 0 : return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
2443 : }
2444 :
2445 4556 : JSString* str = JS_ValueToString(cx, argv[1]);
2446 : jsid id;
2447 4556 : if (!str || !JS_ValueToId(cx, STRING_TO_JSVAL(str), &id))
2448 0 : return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
2449 :
2450 : jsval val;
2451 4556 : if (!JS_GetPropertyById(cx, ifacesObj, id, &val) || JSVAL_IS_PRIMITIVE(val))
2452 0 : return ThrowAndFail(NS_ERROR_XPC_BAD_IID, cx, _retval);
2453 :
2454 9112 : nsCOMPtr<nsIXPConnectWrappedNative> wn;
2455 13668 : if (NS_FAILED(xpc->GetWrappedNativeOfJSObject(cx, JSVAL_TO_OBJECT(val),
2456 4556 : getter_AddRefs(wn))) || !wn ||
2457 4556 : !(cInterfaceID = do_QueryWrappedNative(wn))) {
2458 0 : return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
2459 : }
2460 : } else {
2461 0 : nsCOMPtr<nsIInterfaceInfo> info;
2462 0 : xpc->GetInfoForIID(&NS_GET_IID(nsISupports), getter_AddRefs(info));
2463 :
2464 0 : if (info) {
2465 : cInterfaceID =
2466 0 : dont_AddRef(static_cast<nsIJSIID*>(nsJSIID::NewID(info)));
2467 : }
2468 0 : if (!cInterfaceID)
2469 0 : return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
2470 : }
2471 :
2472 : // a new scope to avoid warnings about shadowed names
2473 : {
2474 : // argv[0] is a contractid name string
2475 : // XXXjband support passing "Components.classes.foo"?
2476 :
2477 : // we do the lookup by asking the Components.classes object
2478 : // for the property with this name - i.e. we let its caching of these
2479 : // nsIJSCID objects work for us.
2480 :
2481 9112 : nsCOMPtr<nsIXPCComponents_Classes> classes;
2482 9112 : nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
2483 4556 : JSObject* classesObj = nsnull;
2484 :
2485 31892 : if (NS_FAILED(comp->GetClasses(getter_AddRefs(classes))) ||
2486 13668 : NS_FAILED(xpc->WrapNative(cx, obj, classes,
2487 : NS_GET_IID(nsIXPCComponents_Classes),
2488 4556 : getter_AddRefs(holder))) || !holder ||
2489 9112 : NS_FAILED(holder->GetJSObject(&classesObj)) || !classesObj) {
2490 0 : return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
2491 : }
2492 :
2493 4556 : JSString* str = JS_ValueToString(cx, argv[0]);
2494 : jsid id;
2495 4556 : if (!str || !JS_ValueToId(cx, STRING_TO_JSVAL(str), &id))
2496 0 : return ThrowAndFail(NS_ERROR_XPC_BAD_CONVERT_JS, cx, _retval);
2497 :
2498 : jsval val;
2499 4556 : if (!JS_GetPropertyById(cx, classesObj, id, &val) || JSVAL_IS_PRIMITIVE(val))
2500 0 : return ThrowAndFail(NS_ERROR_XPC_BAD_CID, cx, _retval);
2501 :
2502 9112 : nsCOMPtr<nsIXPConnectWrappedNative> wn;
2503 13668 : if (NS_FAILED(xpc->GetWrappedNativeOfJSObject(cx, JSVAL_TO_OBJECT(val),
2504 4556 : getter_AddRefs(wn))) || !wn ||
2505 4556 : !(cClassID = do_QueryWrappedNative(wn))) {
2506 0 : return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
2507 : }
2508 : }
2509 :
2510 : nsCOMPtr<nsIXPCConstructor> ctor =
2511 : static_cast<nsIXPCConstructor*>
2512 13668 : (new nsXPCConstructor(cClassID, cInterfaceID, cInitializer));
2513 4556 : if (!ctor)
2514 0 : return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
2515 :
2516 9112 : nsCOMPtr<nsIXPConnectJSObjectHolder> holder2;
2517 4556 : JSObject* newObj = nsnull;
2518 :
2519 18224 : if (NS_FAILED(xpc->WrapNative(cx, obj, ctor, NS_GET_IID(nsIXPCConstructor),
2520 4556 : getter_AddRefs(holder2))) || !holder2 ||
2521 9112 : NS_FAILED(holder2->GetJSObject(&newObj)) || !newObj) {
2522 0 : return ThrowAndFail(NS_ERROR_XPC_CANT_CREATE_WN, cx, _retval);
2523 : }
2524 :
2525 4556 : if (vp)
2526 4556 : *vp = OBJECT_TO_JSVAL(newObj);
2527 :
2528 4556 : return NS_OK;
2529 : }
2530 :
2531 : /* bool hasInstance (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval val, out bool bp); */
2532 : NS_IMETHODIMP
2533 0 : nsXPCComponents_Constructor::HasInstance(nsIXPConnectWrappedNative *wrapper,
2534 : JSContext * cx, JSObject * obj,
2535 : const jsval &val, bool *bp,
2536 : bool *_retval)
2537 : {
2538 0 : if (bp)
2539 0 : *bp = JSValIsInterfaceOfType(cx, val, NS_GET_IID(nsIXPCConstructor));
2540 0 : return NS_OK;
2541 : }
2542 :
2543 : /***************************************************************************/
2544 : // Javascript constructor for the sandbox object
2545 : class nsXPCComponents_utils_Sandbox : public nsIXPCComponents_utils_Sandbox,
2546 : public nsIXPCScriptable
2547 : {
2548 : public:
2549 : // Aren't macros nice?
2550 : NS_DECL_ISUPPORTS
2551 : NS_DECL_NSIXPCCOMPONENTS_UTILS_SANDBOX
2552 : NS_DECL_NSIXPCSCRIPTABLE
2553 :
2554 : public:
2555 : nsXPCComponents_utils_Sandbox();
2556 : virtual ~nsXPCComponents_utils_Sandbox();
2557 :
2558 : private:
2559 : static nsresult CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
2560 : JSContext * cx, JSObject * obj,
2561 : PRUint32 argc, jsval * argv,
2562 : jsval * vp, bool *_retval);
2563 : };
2564 :
2565 : class nsXPCComponents_Utils :
2566 : public nsIXPCComponents_Utils,
2567 : public nsIXPCScriptable,
2568 : public nsISecurityCheckedComponent
2569 : {
2570 : public:
2571 : // all the interface method declarations...
2572 : NS_DECL_ISUPPORTS
2573 : NS_DECL_NSIXPCSCRIPTABLE
2574 : NS_DECL_NSISECURITYCHECKEDCOMPONENT
2575 : NS_DECL_NSIXPCCOMPONENTS_UTILS
2576 :
2577 : public:
2578 11477 : nsXPCComponents_Utils() { }
2579 45872 : virtual ~nsXPCComponents_Utils() { }
2580 :
2581 : private:
2582 : nsCOMPtr<nsIXPCComponents_utils_Sandbox> mSandbox;
2583 : };
2584 :
2585 193935 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_Utils)
2586 193935 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_Utils)
2587 181427 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
2588 145886 : NS_INTERFACE_MAP_ENTRY(nsISecurityCheckedComponent)
2589 134801 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_Utils)
2590 91603 : NS_INTERFACE_MAP_END_THREADSAFE
2591 :
2592 168854 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents_Utils)
2593 168843 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents_Utils)
2594 :
2595 : // The nsIXPCScriptable map declaration that will generate stubs for us...
2596 : #define XPC_MAP_CLASSNAME nsXPCComponents_Utils
2597 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_Utils"
2598 : #define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
2599 : #include "xpc_map_end.h" /* This will #undef the above */
2600 :
2601 : NS_IMETHODIMP
2602 574 : nsXPCComponents_Utils::GetSandbox(nsIXPCComponents_utils_Sandbox **aSandbox)
2603 : {
2604 574 : NS_ENSURE_ARG_POINTER(aSandbox);
2605 783 : if (!mSandbox && !(mSandbox = new nsXPCComponents_utils_Sandbox())) {
2606 0 : *aSandbox = nsnull;
2607 0 : return NS_ERROR_OUT_OF_MEMORY;
2608 : }
2609 574 : NS_ADDREF(*aSandbox = mSandbox);
2610 574 : return NS_OK;
2611 : }
2612 :
2613 : /* void lookupMethod (); */
2614 : NS_IMETHODIMP
2615 0 : nsXPCComponents_Utils::LookupMethod(const JS::Value& object,
2616 : const JS::Value& name,
2617 : JSContext *cx,
2618 : JS::Value *retval)
2619 : {
2620 0 : JSAutoRequest ar(cx);
2621 :
2622 : // first param must be a JSObject
2623 0 : if (JSVAL_IS_PRIMITIVE(object))
2624 0 : return NS_ERROR_XPC_BAD_CONVERT_JS;
2625 :
2626 0 : JSObject* obj = JSVAL_TO_OBJECT(object);
2627 0 : while (obj && !js::IsWrapper(obj) && !IS_WRAPPER_CLASS(js::GetObjectClass(obj)))
2628 0 : obj = JS_GetPrototype(obj);
2629 :
2630 0 : if (!obj)
2631 0 : return NS_ERROR_XPC_BAD_CONVERT_JS;
2632 :
2633 : JSObject* unwrappedObject;
2634 0 : nsresult rv = nsXPConnect::GetXPConnect()->GetJSObjectOfWrapper(cx, obj, &unwrappedObject);
2635 0 : if (NS_FAILED(rv))
2636 0 : return rv;
2637 :
2638 0 : unwrappedObject = JS_ObjectToInnerObject(cx, unwrappedObject);
2639 0 : if (!unwrappedObject)
2640 0 : return NS_ERROR_XPC_BAD_CONVERT_JS;
2641 :
2642 : // second param must be a string
2643 0 : if (!JSVAL_IS_STRING(name))
2644 0 : return NS_ERROR_XPC_BAD_CONVERT_JS;
2645 :
2646 : // Make sure the name that we use for looking up the method/property is
2647 : // atomized.
2648 : jsid name_id;
2649 : JS::Value dummy;
2650 0 : if (!JS_ValueToId(cx, name, &name_id) ||
2651 0 : !JS_IdToValue(cx, name_id, &dummy))
2652 0 : return NS_ERROR_XPC_BAD_CONVERT_JS;
2653 :
2654 : // this will do verification and the method lookup for us
2655 : // Note that if |obj| is an XPCNativeWrapper this will all still work.
2656 : // We'll hand back the same method that we'd hand back for the underlying
2657 : // XPCWrappedNative. This means no deep wrapping, unfortunately, but we
2658 : // can't keep track of both the underlying function and the
2659 : // XPCNativeWrapper at once in a single parent slot...
2660 0 : XPCCallContext inner_cc(JS_CALLER, cx, unwrappedObject, nsnull, name_id);
2661 :
2662 : // was our jsobject really a wrapped native at all?
2663 0 : XPCWrappedNative* wrapper = inner_cc.GetWrapper();
2664 0 : if (!wrapper || !wrapper->IsValid())
2665 0 : return NS_ERROR_XPC_BAD_CONVERT_JS;
2666 :
2667 : // did we find a method/attribute by that name?
2668 0 : XPCNativeMember* member = inner_cc.GetMember();
2669 0 : if (!member || member->IsConstant())
2670 0 : return NS_ERROR_XPC_BAD_CONVERT_JS;
2671 :
2672 : // it would a be a big surprise if there is a member without an interface :)
2673 0 : XPCNativeInterface* iface = inner_cc.GetInterface();
2674 0 : if (!iface)
2675 0 : return NS_ERROR_XPC_BAD_CONVERT_JS;
2676 :
2677 : jsval funval;
2678 :
2679 : // get (and perhaps lazily create) the member's cloned function
2680 0 : if (!member->NewFunctionObject(inner_cc, iface, obj, &funval))
2681 0 : return NS_ERROR_XPC_BAD_CONVERT_JS;
2682 :
2683 0 : NS_ASSERTION(JS_ValueToFunction(inner_cc, funval),
2684 : "Function is not a function");
2685 :
2686 : // Stick the function in the return value. This roots it.
2687 0 : *retval = funval;
2688 0 : return NS_OK;
2689 : }
2690 :
2691 : /* void reportError (); */
2692 : NS_IMETHODIMP
2693 45 : nsXPCComponents_Utils::ReportError(const JS::Value &error, JSContext *cx)
2694 : {
2695 : // This function shall never fail! Silently eat any failure conditions.
2696 :
2697 90 : nsCOMPtr<nsIConsoleService> console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
2698 :
2699 90 : nsCOMPtr<nsIScriptError> scripterr(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID));
2700 :
2701 45 : if (!scripterr || !console)
2702 0 : return NS_OK;
2703 :
2704 90 : JSAutoRequest ar(cx);
2705 :
2706 45 : const PRUint64 innerWindowID = nsJSUtils::GetCurrentlyRunningCodeInnerWindowID(cx);
2707 :
2708 45 : JSErrorReport *err = JS_ErrorFromException(cx, error);
2709 45 : if (err) {
2710 : // It's a proper JS Error
2711 0 : nsAutoString fileUni;
2712 0 : CopyUTF8toUTF16(err->filename, fileUni);
2713 :
2714 0 : PRUint32 column = err->uctokenptr - err->uclinebuf;
2715 :
2716 0 : nsresult rv = scripterr->InitWithWindowID(
2717 : static_cast<const PRUnichar*>(err->ucmessage), fileUni.get(),
2718 : static_cast<const PRUnichar*>(err->uclinebuf), err->lineno,
2719 0 : column, err->flags, "XPConnect JavaScript", innerWindowID);
2720 0 : NS_ENSURE_SUCCESS(rv, NS_OK);
2721 :
2722 0 : console->LogMessage(scripterr);
2723 0 : return NS_OK;
2724 : }
2725 :
2726 : // It's not a JS Error object, so we synthesize as best we're able.
2727 45 : JSString *msgstr = JS_ValueToString(cx, error);
2728 45 : if (!msgstr) {
2729 0 : return NS_OK;
2730 : }
2731 :
2732 90 : nsCOMPtr<nsIStackFrame> frame;
2733 45 : nsXPConnect *xpc = nsXPConnect::GetXPConnect();
2734 45 : if (xpc)
2735 45 : xpc->GetCurrentJSStack(getter_AddRefs(frame));
2736 :
2737 90 : nsXPIDLCString fileName;
2738 45 : PRInt32 lineNo = 0;
2739 45 : if (frame) {
2740 45 : frame->GetFilename(getter_Copies(fileName));
2741 45 : frame->GetLineNumber(&lineNo);
2742 : }
2743 :
2744 45 : const jschar *msgchars = JS_GetStringCharsZ(cx, msgstr);
2745 45 : if (!msgchars)
2746 0 : return NS_OK;
2747 :
2748 45 : nsresult rv = scripterr->InitWithWindowID(
2749 : reinterpret_cast<const PRUnichar *>(msgchars),
2750 45 : NS_ConvertUTF8toUTF16(fileName).get(),
2751 45 : nsnull, lineNo, 0, 0, "XPConnect JavaScript", innerWindowID);
2752 45 : NS_ENSURE_SUCCESS(rv, NS_OK);
2753 :
2754 45 : console->LogMessage(scripterr);
2755 45 : return NS_OK;
2756 : }
2757 :
2758 : #include "nsIScriptSecurityManager.h"
2759 : #include "nsIURI.h"
2760 : #include "nsNetUtil.h"
2761 : const char kScriptSecurityManagerContractID[] = NS_SCRIPTSECURITYMANAGER_CONTRACTID;
2762 :
2763 30535 : NS_IMPL_THREADSAFE_ISUPPORTS1(PrincipalHolder, nsIScriptObjectPrincipal)
2764 :
2765 : nsIPrincipal *
2766 4413 : PrincipalHolder::GetPrincipal()
2767 : {
2768 4413 : return mHoldee;
2769 : }
2770 :
2771 : static JSBool
2772 26 : SandboxDump(JSContext *cx, unsigned argc, jsval *vp)
2773 : {
2774 : JSString *str;
2775 26 : if (!argc)
2776 0 : return true;
2777 :
2778 26 : str = JS_ValueToString(cx, JS_ARGV(cx, vp)[0]);
2779 26 : if (!str)
2780 0 : return false;
2781 :
2782 : size_t length;
2783 26 : const jschar *chars = JS_GetStringCharsZAndLength(cx, str, &length);
2784 26 : if (!chars)
2785 0 : return false;
2786 :
2787 52 : nsDependentString wstr(chars, length);
2788 26 : char *cstr = ToNewUTF8String(wstr);
2789 26 : if (!cstr)
2790 0 : return false;
2791 :
2792 : #if defined(XP_MACOSX)
2793 : // Be nice and convert all \r to \n.
2794 : char *c = cstr, *cEnd = cstr + strlen(cstr);
2795 : while (c < cEnd) {
2796 : if (*c == '\r')
2797 : *c = '\n';
2798 : c++;
2799 : }
2800 : #endif
2801 :
2802 26 : fputs(cstr, stdout);
2803 26 : fflush(stdout);
2804 26 : NS_Free(cstr);
2805 26 : JS_SET_RVAL(cx, vp, JSVAL_TRUE);
2806 26 : return true;
2807 : }
2808 :
2809 : static JSBool
2810 0 : SandboxDebug(JSContext *cx, unsigned argc, jsval *vp)
2811 : {
2812 : #ifdef DEBUG
2813 0 : return SandboxDump(cx, argc, vp);
2814 : #else
2815 : return true;
2816 : #endif
2817 : }
2818 :
2819 : static JSBool
2820 2206 : SandboxImport(JSContext *cx, unsigned argc, jsval *vp)
2821 : {
2822 2206 : JSObject *thisobj = JS_THIS_OBJECT(cx, vp);
2823 2206 : if (!thisobj)
2824 0 : return false;
2825 :
2826 2206 : jsval *argv = JS_ARGV(cx, vp);
2827 2206 : if (argc < 1 || JSVAL_IS_PRIMITIVE(argv[0])) {
2828 0 : XPCThrower::Throw(NS_ERROR_INVALID_ARG, cx);
2829 0 : return false;
2830 : }
2831 :
2832 : JSString *funname;
2833 2206 : if (argc > 1) {
2834 : // Use the second parameter as the function name.
2835 282 : funname = JS_ValueToString(cx, argv[1]);
2836 282 : if (!funname)
2837 0 : return false;
2838 282 : argv[1] = STRING_TO_JSVAL(funname);
2839 : } else {
2840 : // NB: funobj must only be used to get the JSFunction out.
2841 1924 : JSObject *funobj = JSVAL_TO_OBJECT(argv[0]);
2842 1924 : if (js::IsProxy(funobj)) {
2843 1924 : funobj = XPCWrapper::UnsafeUnwrapSecurityWrapper(funobj);
2844 : }
2845 :
2846 3848 : JSAutoEnterCompartment ac;
2847 1924 : if (!ac.enter(cx, funobj)) {
2848 0 : return false;
2849 : }
2850 :
2851 1924 : JSFunction *fun = JS_ValueToFunction(cx, OBJECT_TO_JSVAL(funobj));
2852 1924 : if (!fun) {
2853 0 : XPCThrower::Throw(NS_ERROR_INVALID_ARG, cx);
2854 0 : return false;
2855 : }
2856 :
2857 : // Use the actual function name as the name.
2858 1924 : funname = JS_GetFunctionId(fun);
2859 1924 : if (!funname) {
2860 0 : XPCThrower::Throw(NS_ERROR_INVALID_ARG, cx);
2861 0 : return false;
2862 : }
2863 : }
2864 :
2865 : jsid id;
2866 2206 : if (!JS_ValueToId(cx, STRING_TO_JSVAL(funname), &id))
2867 0 : return false;
2868 :
2869 2206 : JS_SET_RVAL(cx, vp, JSVAL_VOID);
2870 2206 : return JS_SetPropertyById(cx, thisobj, id, &argv[0]);
2871 : }
2872 :
2873 : static JSBool
2874 0 : sandbox_enumerate(JSContext *cx, JSObject *obj)
2875 : {
2876 0 : return JS_EnumerateStandardClasses(cx, obj);
2877 : }
2878 :
2879 : static JSBool
2880 6708 : sandbox_resolve(JSContext *cx, JSObject *obj, jsid id)
2881 : {
2882 : JSBool resolved;
2883 6708 : return JS_ResolveStandardClass(cx, obj, id, &resolved);
2884 : }
2885 :
2886 : static void
2887 574 : sandbox_finalize(JSContext *cx, JSObject *obj)
2888 : {
2889 : nsIScriptObjectPrincipal *sop =
2890 574 : (nsIScriptObjectPrincipal *)xpc_GetJSPrivate(obj);
2891 574 : NS_IF_RELEASE(sop);
2892 574 : }
2893 :
2894 : static JSBool
2895 127 : sandbox_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
2896 : {
2897 127 : if (type == JSTYPE_OBJECT) {
2898 0 : *vp = OBJECT_TO_JSVAL(obj);
2899 0 : return true;
2900 : }
2901 :
2902 127 : return JS_ConvertStub(cx, obj, type, vp);
2903 : }
2904 :
2905 : static JSClass SandboxClass = {
2906 : "Sandbox",
2907 : XPCONNECT_GLOBAL_FLAGS,
2908 : JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
2909 : sandbox_enumerate, sandbox_resolve, sandbox_convert, sandbox_finalize,
2910 : NULL, NULL, NULL, NULL, TraceXPCGlobal
2911 : };
2912 :
2913 : static JSFunctionSpec SandboxFunctions[] = {
2914 : {"dump", SandboxDump, 1,0},
2915 : {"debug", SandboxDebug, 1,0},
2916 : {"importFunction", SandboxImport, 1,0},
2917 : {nsnull,nsnull,0,0}
2918 : };
2919 :
2920 : /***************************************************************************/
2921 209 : nsXPCComponents_utils_Sandbox::nsXPCComponents_utils_Sandbox()
2922 : {
2923 209 : }
2924 :
2925 418 : nsXPCComponents_utils_Sandbox::~nsXPCComponents_utils_Sandbox()
2926 : {
2927 836 : }
2928 :
2929 5358 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents_utils_Sandbox)
2930 5358 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents_utils_Sandbox)
2931 4668 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
2932 3225 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents_utils_Sandbox)
2933 2651 : NS_INTERFACE_MAP_END_THREADSAFE
2934 :
2935 3971 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents_utils_Sandbox)
2936 3971 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents_utils_Sandbox)
2937 :
2938 : // We use the nsIXPScriptable macros to generate lots of stuff for us.
2939 : #define XPC_MAP_CLASSNAME nsXPCComponents_utils_Sandbox
2940 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents_utils_Sandbox"
2941 : #define XPC_MAP_WANT_CALL
2942 : #define XPC_MAP_WANT_CONSTRUCT
2943 : #define XPC_MAP_FLAGS 0
2944 : #include "xpc_map_end.h" /* This #undef's the above. */
2945 :
2946 : static bool
2947 1086 : WrapForSandbox(JSContext *cx, bool wantXrays, jsval *vp)
2948 : {
2949 : return wantXrays
2950 1086 : ? JS_WrapValue(cx, vp)
2951 2172 : : xpc::WrapperFactory::WaiveXrayAndWrap(cx, vp);
2952 : }
2953 :
2954 : // Needed to distinguish multiple compartments with the same origin from each
2955 : // other. The only thing we need out of identity objects are unique addresses.
2956 : class Identity : public nsISupports
2957 574 : {
2958 : NS_DECL_ISUPPORTS
2959 : };
2960 :
2961 5166 : NS_IMPL_ISUPPORTS0(Identity)
2962 :
2963 : nsresult
2964 574 : xpc_CreateSandboxObject(JSContext * cx, jsval * vp, nsISupports *prinOrSop, JSObject *proto,
2965 : bool wantXrays, const nsACString &sandboxName, nsISupports *identityPtr)
2966 : {
2967 : // Create the sandbox global object
2968 : nsresult rv;
2969 1148 : nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv));
2970 574 : if (NS_FAILED(rv))
2971 0 : return NS_ERROR_XPC_UNEXPECTED;
2972 :
2973 1148 : nsCOMPtr<nsIScriptObjectPrincipal> sop(do_QueryInterface(prinOrSop));
2974 :
2975 574 : if (!sop) {
2976 604 : nsCOMPtr<nsIPrincipal> principal(do_QueryInterface(prinOrSop));
2977 :
2978 302 : if (!principal) {
2979 0 : principal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
2980 0 : NS_ASSERTION(NS_FAILED(rv) || principal,
2981 : "Bad return from do_CreateInstance");
2982 :
2983 0 : if (!principal || NS_FAILED(rv)) {
2984 0 : if (NS_SUCCEEDED(rv)) {
2985 0 : rv = NS_ERROR_FAILURE;
2986 : }
2987 :
2988 0 : return rv;
2989 : }
2990 : }
2991 :
2992 604 : sop = new PrincipalHolder(principal);
2993 302 : if (!sop)
2994 0 : return NS_ERROR_OUT_OF_MEMORY;
2995 : }
2996 :
2997 574 : nsIPrincipal *principal = sop->GetPrincipal();
2998 :
2999 : JSCompartment *compartment;
3000 : JSObject *sandbox;
3001 :
3002 1148 : nsRefPtr<Identity> identity;
3003 574 : if (!identityPtr) {
3004 574 : identity = new Identity();
3005 574 : identityPtr = identity;
3006 : }
3007 :
3008 : rv = xpc_CreateGlobalObject(cx, &SandboxClass, principal, identityPtr,
3009 574 : wantXrays, &sandbox, &compartment);
3010 574 : NS_ENSURE_SUCCESS(rv, rv);
3011 :
3012 1148 : JS::AutoObjectRooter tvr(cx, sandbox);
3013 :
3014 : {
3015 1148 : JSAutoEnterCompartment ac;
3016 574 : if (!ac.enter(cx, sandbox))
3017 0 : return NS_ERROR_XPC_UNEXPECTED;
3018 :
3019 574 : if (proto) {
3020 0 : bool ok = JS_WrapObject(cx, &proto);
3021 0 : if (!ok)
3022 0 : return NS_ERROR_XPC_UNEXPECTED;
3023 :
3024 0 : if (xpc::WrapperFactory::IsXrayWrapper(proto) && !wantXrays) {
3025 0 : jsval v = OBJECT_TO_JSVAL(proto);
3026 0 : if (!xpc::WrapperFactory::WaiveXrayAndWrap(cx, &v))
3027 0 : return NS_ERROR_FAILURE;
3028 0 : proto = JSVAL_TO_OBJECT(v);
3029 : }
3030 :
3031 0 : ok = JS_SetPrototype(cx, sandbox, proto);
3032 0 : if (!ok)
3033 0 : return NS_ERROR_XPC_UNEXPECTED;
3034 : }
3035 :
3036 : // Pass on ownership of sop to |sandbox|.
3037 574 : JS_SetPrivate(sandbox, sop.forget().get());
3038 :
3039 574 : rv = xpc->InitClasses(cx, sandbox);
3040 1148 : if (NS_SUCCEEDED(rv) &&
3041 574 : !JS_DefineFunctions(cx, sandbox, SandboxFunctions)) {
3042 0 : rv = NS_ERROR_FAILURE;
3043 : }
3044 574 : if (NS_FAILED(rv))
3045 0 : return NS_ERROR_XPC_UNEXPECTED;
3046 : }
3047 :
3048 574 : if (vp) {
3049 574 : *vp = OBJECT_TO_JSVAL(sandbox);
3050 574 : if (!WrapForSandbox(cx, wantXrays, vp)) {
3051 0 : return NS_ERROR_UNEXPECTED;
3052 : }
3053 : }
3054 :
3055 : xpc::CompartmentPrivate *compartmentPrivate =
3056 574 : static_cast<xpc::CompartmentPrivate*>(JS_GetCompartmentPrivate(compartment));
3057 574 : compartmentPrivate->location = sandboxName;
3058 :
3059 574 : return NS_OK;
3060 : }
3061 :
3062 : /* bool call(in nsIXPConnectWrappedNative wrapper,
3063 : in JSContextPtr cx,
3064 : in JSObjectPtr obj,
3065 : in PRUint32 argc,
3066 : in JSValPtr argv,
3067 : in JSValPtr vp);
3068 : */
3069 : NS_IMETHODIMP
3070 320 : nsXPCComponents_utils_Sandbox::Call(nsIXPConnectWrappedNative *wrapper,
3071 : JSContext * cx,
3072 : JSObject * obj,
3073 : PRUint32 argc,
3074 : jsval * argv,
3075 : jsval * vp,
3076 : bool *_retval)
3077 : {
3078 320 : return CallOrConstruct(wrapper, cx, obj, argc, argv, vp, _retval);
3079 : }
3080 :
3081 : /* bool construct(in nsIXPConnectWrappedNative wrapper,
3082 : in JSContextPtr cx,
3083 : in JSObjectPtr obj,
3084 : in PRUint32 argc,
3085 : in JSValPtr argv,
3086 : in JSValPtr vp);
3087 : */
3088 : NS_IMETHODIMP
3089 254 : nsXPCComponents_utils_Sandbox::Construct(nsIXPConnectWrappedNative *wrapper,
3090 : JSContext * cx,
3091 : JSObject * obj,
3092 : PRUint32 argc,
3093 : jsval * argv,
3094 : jsval * vp,
3095 : bool *_retval)
3096 : {
3097 254 : return CallOrConstruct(wrapper, cx, obj, argc, argv, vp, _retval);
3098 : }
3099 :
3100 : // static
3101 : nsresult
3102 574 : nsXPCComponents_utils_Sandbox::CallOrConstruct(nsIXPConnectWrappedNative *wrapper,
3103 : JSContext * cx, JSObject * obj,
3104 : PRUint32 argc, jsval * argv,
3105 : jsval * vp, bool *_retval)
3106 : {
3107 574 : if (argc < 1)
3108 0 : return ThrowAndFail(NS_ERROR_XPC_NOT_ENOUGH_ARGS, cx, _retval);
3109 :
3110 : nsresult rv;
3111 :
3112 : // Make sure to set up principals on the sandbox before initing classes
3113 1148 : nsCOMPtr<nsIScriptObjectPrincipal> sop;
3114 1148 : nsCOMPtr<nsIPrincipal> principal;
3115 574 : nsISupports *prinOrSop = nsnull;
3116 574 : nsISupports *identity = nsnull;
3117 574 : if (JSVAL_IS_STRING(argv[0])) {
3118 10 : JSString *codebaseStr = JSVAL_TO_STRING(argv[0]);
3119 : size_t codebaseLength;
3120 : const jschar *codebaseChars = JS_GetStringCharsAndLength(cx, codebaseStr,
3121 10 : &codebaseLength);
3122 10 : if (!codebaseChars) {
3123 0 : return ThrowAndFail(NS_ERROR_FAILURE, cx, _retval);
3124 : }
3125 :
3126 20 : nsAutoString codebase(codebaseChars, codebaseLength);
3127 20 : nsCOMPtr<nsIURI> uri;
3128 10 : rv = NS_NewURI(getter_AddRefs(uri), codebase);
3129 10 : if (NS_FAILED(rv)) {
3130 0 : return ThrowAndFail(rv, cx, _retval);
3131 : }
3132 :
3133 : nsCOMPtr<nsIScriptSecurityManager> secman =
3134 20 : do_GetService(kScriptSecurityManagerContractID);
3135 60 : if (!secman ||
3136 40 : NS_FAILED(rv = secman->GetCodebasePrincipal(uri,
3137 : getter_AddRefs(principal))) ||
3138 10 : !principal) {
3139 0 : if (NS_SUCCEEDED(rv))
3140 0 : rv = NS_ERROR_FAILURE;
3141 0 : return ThrowAndFail(rv, cx, _retval);
3142 : }
3143 :
3144 20 : prinOrSop = principal;
3145 : } else {
3146 564 : if (!JSVAL_IS_PRIMITIVE(argv[0])) {
3147 1128 : nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID()));
3148 564 : if (!xpc)
3149 0 : return NS_ERROR_XPC_UNEXPECTED;
3150 1692 : nsCOMPtr<nsIXPConnectWrappedNative> wrapper;
3151 564 : xpc->GetWrappedNativeOfJSObject(cx, JSVAL_TO_OBJECT(argv[0]),
3152 564 : getter_AddRefs(wrapper));
3153 :
3154 564 : if (wrapper) {
3155 564 : sop = do_QueryWrappedNative(wrapper);
3156 564 : if (sop) {
3157 272 : prinOrSop = sop;
3158 : } else {
3159 292 : principal = do_QueryWrappedNative(wrapper);
3160 292 : prinOrSop = principal;
3161 : }
3162 : }
3163 : }
3164 :
3165 564 : if (!prinOrSop)
3166 0 : return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
3167 : }
3168 :
3169 574 : JSObject *proto = nsnull;
3170 574 : bool wantXrays = true;
3171 1148 : nsCString sandboxName;
3172 :
3173 574 : if (argc > 1) {
3174 253 : if (!JSVAL_IS_OBJECT(argv[1]))
3175 0 : return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
3176 :
3177 253 : JSObject *optionsObject = JSVAL_TO_OBJECT(argv[1]);
3178 : jsval option;
3179 :
3180 : JSBool found;
3181 253 : if (!JS_HasProperty(cx, optionsObject, "sandboxPrototype", &found))
3182 0 : return NS_ERROR_INVALID_ARG;
3183 :
3184 253 : if (found) {
3185 0 : if (!JS_GetProperty(cx, optionsObject, "sandboxPrototype", &option) ||
3186 0 : !JSVAL_IS_OBJECT(option)) {
3187 0 : return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
3188 : }
3189 :
3190 0 : proto = JSVAL_TO_OBJECT(option);
3191 : }
3192 :
3193 253 : if (!JS_HasProperty(cx, optionsObject, "wantXrays", &found))
3194 0 : return NS_ERROR_INVALID_ARG;
3195 :
3196 253 : if (found) {
3197 0 : if (!JS_GetProperty(cx, optionsObject, "wantXrays", &option) ||
3198 0 : !JSVAL_IS_BOOLEAN(option)) {
3199 0 : return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
3200 : }
3201 :
3202 0 : wantXrays = JSVAL_TO_BOOLEAN(option);
3203 : }
3204 :
3205 253 : if (!JS_HasProperty(cx, optionsObject, "sandboxName", &found))
3206 0 : return NS_ERROR_INVALID_ARG;
3207 :
3208 253 : if (found) {
3209 506 : if (!JS_GetProperty(cx, optionsObject, "sandboxName", &option) ||
3210 253 : !JSVAL_IS_STRING(option)) {
3211 0 : return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
3212 : }
3213 :
3214 253 : char *tmp = JS_EncodeString(cx, JSVAL_TO_STRING(option));
3215 253 : if (!tmp) {
3216 0 : return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
3217 : }
3218 :
3219 253 : sandboxName.Adopt(tmp, strlen(tmp));
3220 : }
3221 :
3222 : // see Bug 677294:
3223 253 : if (!JS_HasProperty(cx, optionsObject, "sameGroupAs", &found))
3224 0 : return NS_ERROR_INVALID_ARG;
3225 :
3226 253 : if (found) {
3227 0 : if (!JS_GetProperty(cx, optionsObject, "sameGroupAs", &option) ||
3228 0 : JSVAL_IS_PRIMITIVE(option))
3229 0 : return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
3230 :
3231 0 : JSObject* unwrapped = UnwrapObject(JSVAL_TO_OBJECT(option));
3232 0 : JSObject* global = GetGlobalForObjectCrossCompartment(unwrapped);
3233 0 : if (GetObjectJSClass(unwrapped) != &SandboxClass &&
3234 0 : GetObjectJSClass(global) != &SandboxClass)
3235 0 : return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
3236 :
3237 : void* privateValue =
3238 0 : JS_GetCompartmentPrivate(GetObjectCompartment(unwrapped));
3239 : xpc::CompartmentPrivate *compartmentPrivate =
3240 0 : static_cast<xpc::CompartmentPrivate*>(privateValue);
3241 :
3242 0 : if (!compartmentPrivate || !compartmentPrivate->key)
3243 0 : return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
3244 :
3245 0 : identity = compartmentPrivate->key->GetPtr();
3246 : }
3247 : }
3248 :
3249 : // If there is no options object given, or no sandboxName property
3250 : // specified, use the caller's filename as sandboxName.
3251 574 : if (sandboxName.IsEmpty()) {
3252 321 : nsXPConnect* xpc = nsXPConnect::GetXPConnect();
3253 :
3254 321 : if (!xpc)
3255 0 : return ThrowAndFail(NS_ERROR_XPC_UNEXPECTED, cx, _retval);
3256 :
3257 : // Get the xpconnect native call context.
3258 321 : nsAXPCNativeCallContext *cc = nsnull;
3259 321 : xpc->GetCurrentNativeCallContext(&cc);
3260 :
3261 321 : if (!cc)
3262 0 : return ThrowAndFail(NS_ERROR_INVALID_ARG, cx, _retval);
3263 :
3264 : // Get the current source info from xpc.
3265 642 : nsCOMPtr<nsIStackFrame> frame;
3266 321 : xpc->GetCurrentJSStack(getter_AddRefs(frame));
3267 :
3268 321 : if (frame)
3269 321 : frame->GetFilename(getter_Copies(sandboxName));
3270 : }
3271 :
3272 574 : rv = xpc_CreateSandboxObject(cx, vp, prinOrSop, proto, wantXrays, sandboxName, identity);
3273 :
3274 574 : if (NS_FAILED(rv)) {
3275 0 : return ThrowAndFail(rv, cx, _retval);
3276 : }
3277 :
3278 574 : *_retval = true;
3279 :
3280 574 : return rv;
3281 : }
3282 :
3283 : class ContextHolder : public nsISupports
3284 : {
3285 : public:
3286 : ContextHolder(JSContext *aOuterCx, JSObject *aSandbox);
3287 : virtual ~ContextHolder();
3288 :
3289 3356 : JSContext * GetJSContext()
3290 : {
3291 3356 : return mJSContext;
3292 : }
3293 :
3294 : NS_DECL_ISUPPORTS
3295 :
3296 : private:
3297 : static JSBool ContextHolderOperationCallback(JSContext *cx);
3298 :
3299 : JSContext* mJSContext;
3300 : JSContext* mOrigCx;
3301 : };
3302 :
3303 1186 : NS_IMPL_ISUPPORTS0(ContextHolder)
3304 :
3305 591 : ContextHolder::ContextHolder(JSContext *aOuterCx, JSObject *aSandbox)
3306 591 : : mJSContext(JS_NewContext(JS_GetRuntime(aOuterCx), 1024)),
3307 1182 : mOrigCx(aOuterCx)
3308 : {
3309 591 : if (mJSContext) {
3310 1182 : JSAutoRequest ar(mJSContext);
3311 : JS_SetOptions(mJSContext,
3312 591 : JS_GetOptions(mJSContext) |
3313 : JSOPTION_DONT_REPORT_UNCAUGHT |
3314 591 : JSOPTION_PRIVATE_IS_NSISUPPORTS);
3315 591 : JS_SetGlobalObject(mJSContext, aSandbox);
3316 591 : JS_SetContextPrivate(mJSContext, this);
3317 591 : JS_SetOperationCallback(mJSContext, ContextHolderOperationCallback);
3318 : }
3319 591 : }
3320 :
3321 1182 : ContextHolder::~ContextHolder()
3322 : {
3323 591 : if (mJSContext)
3324 591 : JS_DestroyContextNoGC(mJSContext);
3325 2364 : }
3326 :
3327 : JSBool
3328 3 : ContextHolder::ContextHolderOperationCallback(JSContext *cx)
3329 : {
3330 : ContextHolder* thisObject =
3331 3 : static_cast<ContextHolder*>(JS_GetContextPrivate(cx));
3332 3 : NS_ASSERTION(thisObject, "How did that happen?");
3333 :
3334 3 : JSContext *origCx = thisObject->mOrigCx;
3335 3 : JSOperationCallback callback = JS_GetOperationCallback(origCx);
3336 3 : JSBool ok = true;
3337 3 : if (callback)
3338 0 : ok = callback(origCx);
3339 3 : return ok;
3340 : }
3341 :
3342 : /***************************************************************************/
3343 :
3344 : /* void evalInSandbox(in AString source, in nativeobj sandbox); */
3345 : NS_IMETHODIMP
3346 591 : nsXPCComponents_Utils::EvalInSandbox(const nsAString& source,
3347 : const JS::Value& sandboxVal,
3348 : const JS::Value& version,
3349 : const JS::Value& filenameVal,
3350 : PRInt32 lineNumber,
3351 : JSContext *cx,
3352 : PRUint8 optionalArgc,
3353 : JS::Value *retval)
3354 : {
3355 : JSObject *sandbox;
3356 591 : if (!JS_ValueToObject(cx, sandboxVal, &sandbox) || !sandbox)
3357 0 : return NS_ERROR_INVALID_ARG;
3358 :
3359 : // Optional third argument: JS version, as a string.
3360 591 : JSVersion jsVersion = JSVERSION_DEFAULT;
3361 591 : if (optionalArgc >= 1) {
3362 243 : JSString *jsVersionStr = JS_ValueToString(cx, version);
3363 243 : if (!jsVersionStr)
3364 0 : return NS_ERROR_INVALID_ARG;
3365 :
3366 486 : JSAutoByteString bytes(cx, jsVersionStr);
3367 243 : if (!bytes)
3368 0 : return NS_ERROR_INVALID_ARG;
3369 :
3370 243 : jsVersion = JS_StringToVersion(bytes.ptr());
3371 243 : if (jsVersion == JSVERSION_UNKNOWN)
3372 0 : return NS_ERROR_INVALID_ARG;
3373 : }
3374 :
3375 : // Optional fourth and fifth arguments: filename and line number.
3376 1182 : nsXPIDLCString filename;
3377 591 : PRInt32 lineNo = (optionalArgc >= 3) ? lineNumber : 0;
3378 591 : if (optionalArgc >= 2) {
3379 0 : JSString *filenameStr = JS_ValueToString(cx, filenameVal);
3380 0 : if (!filenameStr)
3381 0 : return NS_ERROR_INVALID_ARG;
3382 :
3383 0 : JSAutoByteString filenameBytes;
3384 0 : if (!filenameBytes.encode(cx, filenameStr))
3385 0 : return NS_ERROR_INVALID_ARG;
3386 0 : filename = filenameBytes.ptr();
3387 : } else {
3388 : // Get the current source info from xpc.
3389 : nsresult rv;
3390 1182 : nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID(), &rv);
3391 591 : NS_ENSURE_SUCCESS(rv, rv);
3392 :
3393 1773 : nsCOMPtr<nsIStackFrame> frame;
3394 591 : xpc->GetCurrentJSStack(getter_AddRefs(frame));
3395 591 : if (frame) {
3396 591 : frame->GetFilename(getter_Copies(filename));
3397 591 : frame->GetLineNumber(&lineNo);
3398 : }
3399 : }
3400 :
3401 : return xpc_EvalInSandbox(cx, sandbox, source, filename.get(), lineNo,
3402 591 : jsVersion, false, retval);
3403 : }
3404 :
3405 : nsresult
3406 591 : xpc_EvalInSandbox(JSContext *cx, JSObject *sandbox, const nsAString& source,
3407 : const char *filename, PRInt32 lineNo,
3408 : JSVersion jsVersion, bool returnStringOnly, jsval *rval)
3409 : {
3410 591 : JS_AbortIfWrongThread(JS_GetRuntime(cx));
3411 :
3412 : #ifdef DEBUG
3413 : // NB: The "unsafe" unwrap here is OK because we must be called from chrome.
3414 : {
3415 591 : nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
3416 591 : if (ssm) {
3417 : JSStackFrame *fp;
3418 : nsIPrincipal *subjectPrincipal =
3419 591 : ssm->GetCxSubjectPrincipalAndFrame(cx, &fp);
3420 : bool system;
3421 591 : ssm->IsSystemPrincipal(subjectPrincipal, &system);
3422 591 : if (fp && !system) {
3423 0 : ssm->IsCapabilityEnabled("UniversalXPConnect", &system);
3424 0 : NS_ASSERTION(system, "Bad caller!");
3425 : }
3426 : }
3427 : }
3428 : #endif
3429 :
3430 591 : sandbox = XPCWrapper::UnsafeUnwrapSecurityWrapper(sandbox);
3431 591 : if (!sandbox || js::GetObjectJSClass(sandbox) != &SandboxClass) {
3432 0 : return NS_ERROR_INVALID_ARG;
3433 : }
3434 :
3435 : nsIScriptObjectPrincipal *sop =
3436 591 : (nsIScriptObjectPrincipal*)xpc_GetJSPrivate(sandbox);
3437 591 : NS_ASSERTION(sop, "Invalid sandbox passed");
3438 1182 : nsCOMPtr<nsIPrincipal> prin = sop->GetPrincipal();
3439 :
3440 591 : if (!prin) {
3441 0 : return NS_ERROR_FAILURE;
3442 : }
3443 :
3444 1182 : nsCAutoString filenameBuf;
3445 591 : if (!filename) {
3446 : // Default to the spec of the principal.
3447 0 : nsJSPrincipals::get(prin)->GetScriptLocation(filenameBuf);
3448 0 : filename = filenameBuf.get();
3449 0 : lineNo = 1;
3450 : }
3451 :
3452 : JSObject *callingScope;
3453 : {
3454 1182 : JSAutoRequest req(cx);
3455 :
3456 591 : callingScope = JS_GetGlobalForScopeChain(cx);
3457 591 : if (!callingScope) {
3458 0 : return NS_ERROR_FAILURE;
3459 : }
3460 : }
3461 :
3462 1182 : nsRefPtr<ContextHolder> sandcx = new ContextHolder(cx, sandbox);
3463 591 : if (!sandcx || !sandcx->GetJSContext()) {
3464 0 : JS_ReportError(cx, "Can't prepare context for evalInSandbox");
3465 0 : return NS_ERROR_OUT_OF_MEMORY;
3466 : }
3467 :
3468 591 : if (jsVersion != JSVERSION_DEFAULT)
3469 243 : JS_SetVersion(sandcx->GetJSContext(), jsVersion);
3470 :
3471 591 : XPCPerThreadData *data = XPCPerThreadData::GetData(cx);
3472 591 : XPCJSContextStack *stack = nsnull;
3473 591 : if (data && (stack = data->GetJSContextStack())) {
3474 591 : if (!stack->Push(sandcx->GetJSContext())) {
3475 : JS_ReportError(cx,
3476 0 : "Unable to initialize XPConnect with the sandbox context");
3477 0 : return NS_ERROR_FAILURE;
3478 : }
3479 : }
3480 :
3481 591 : nsresult rv = NS_OK;
3482 :
3483 : {
3484 1182 : JSAutoRequest req(sandcx->GetJSContext());
3485 1182 : JSAutoEnterCompartment ac;
3486 :
3487 591 : if (!ac.enter(sandcx->GetJSContext(), sandbox)) {
3488 0 : if (stack)
3489 0 : unused << stack->Pop();
3490 0 : return NS_ERROR_FAILURE;
3491 : }
3492 :
3493 : jsval v;
3494 591 : JSString *str = nsnull;
3495 : JSBool ok =
3496 : JS_EvaluateUCScriptForPrincipals(sandcx->GetJSContext(), sandbox,
3497 591 : nsJSPrincipals::get(prin),
3498 : reinterpret_cast<const jschar *>
3499 1182 : (PromiseFlatString(source).get()),
3500 : source.Length(), filename, lineNo,
3501 1182 : &v);
3502 591 : if (ok && returnStringOnly && !(JSVAL_IS_VOID(v))) {
3503 0 : ok = !!(str = JS_ValueToString(sandcx->GetJSContext(), v));
3504 : }
3505 :
3506 591 : if (!ok) {
3507 : // The sandbox threw an exception, convert it to a string (if
3508 : // asked) or convert it to a SJOW.
3509 :
3510 : jsval exn;
3511 79 : if (JS_GetPendingException(sandcx->GetJSContext(), &exn)) {
3512 79 : JS_ClearPendingException(sandcx->GetJSContext());
3513 :
3514 79 : if (returnStringOnly) {
3515 : // The caller asked for strings only, convert the
3516 : // exception into a string.
3517 0 : str = JS_ValueToString(sandcx->GetJSContext(), exn);
3518 :
3519 0 : if (str) {
3520 : // We converted the exception to a string. Use that
3521 : // as the value exception.
3522 0 : exn = STRING_TO_JSVAL(str);
3523 0 : if (JS_WrapValue(cx, &exn)) {
3524 0 : JS_SetPendingException(cx, exn);
3525 : } else {
3526 0 : JS_ClearPendingException(cx);
3527 0 : rv = NS_ERROR_FAILURE;
3528 : }
3529 : } else {
3530 0 : JS_ClearPendingException(cx);
3531 0 : rv = NS_ERROR_FAILURE;
3532 : }
3533 : } else {
3534 79 : if (JS_WrapValue(cx, &exn)) {
3535 79 : JS_SetPendingException(cx, exn);
3536 : }
3537 : }
3538 :
3539 :
3540 : // Clear str so we don't confuse callers.
3541 79 : str = nsnull;
3542 : } else {
3543 0 : rv = NS_ERROR_OUT_OF_MEMORY;
3544 : }
3545 : } else {
3546 : // Convert the result into something safe for our caller.
3547 1024 : JSAutoRequest req(cx);
3548 1024 : JSAutoEnterCompartment ac;
3549 512 : if (str) {
3550 0 : v = STRING_TO_JSVAL(str);
3551 : }
3552 :
3553 : xpc::CompartmentPrivate *sandboxdata =
3554 : static_cast<xpc::CompartmentPrivate *>
3555 512 : (JS_GetCompartmentPrivate(js::GetObjectCompartment(sandbox)));
3556 1024 : if (!ac.enter(cx, callingScope) ||
3557 512 : !WrapForSandbox(cx, sandboxdata->wantXrays, &v)) {
3558 0 : rv = NS_ERROR_FAILURE;
3559 : }
3560 :
3561 512 : if (NS_SUCCEEDED(rv)) {
3562 512 : *rval = v;
3563 : }
3564 : }
3565 : }
3566 :
3567 591 : if (stack)
3568 591 : unused << stack->Pop();
3569 :
3570 591 : return rv;
3571 : }
3572 :
3573 : /* JSObject import (in AUTF8String registryLocation,
3574 : * [optional] in JSObject targetObj);
3575 : */
3576 : NS_IMETHODIMP
3577 45915 : nsXPCComponents_Utils::Import(const nsACString& registryLocation,
3578 : const JS::Value& targetObj,
3579 : JSContext* cx,
3580 : PRUint8 optionalArgc,
3581 : JS::Value* retval)
3582 : {
3583 : nsCOMPtr<xpcIJSModuleLoader> moduleloader =
3584 91830 : do_GetService(MOZJSCOMPONENTLOADER_CONTRACTID);
3585 45915 : if (!moduleloader)
3586 0 : return NS_ERROR_FAILURE;
3587 45915 : return moduleloader->Import(registryLocation, targetObj, cx, optionalArgc, retval);
3588 : }
3589 :
3590 : /* unload (in AUTF8String registryLocation);
3591 : */
3592 : NS_IMETHODIMP
3593 1236 : nsXPCComponents_Utils::Unload(const nsACString & registryLocation)
3594 : {
3595 : nsCOMPtr<xpcIJSModuleLoader> moduleloader =
3596 2472 : do_GetService(MOZJSCOMPONENTLOADER_CONTRACTID);
3597 1236 : if (!moduleloader)
3598 0 : return NS_ERROR_FAILURE;
3599 1236 : return moduleloader->Unload(registryLocation);
3600 : }
3601 :
3602 : /* xpcIJSWeakReference getWeakReference (); */
3603 : NS_IMETHODIMP
3604 3505 : nsXPCComponents_Utils::GetWeakReference(const JS::Value &object, JSContext *cx,
3605 : xpcIJSWeakReference **_retval)
3606 : {
3607 7010 : nsRefPtr<xpcJSWeakReference> ref = new xpcJSWeakReference();
3608 3505 : nsresult rv = ref->Init(cx, object);
3609 3505 : NS_ENSURE_SUCCESS(rv, rv);
3610 3505 : ref.forget(_retval);
3611 3505 : return NS_OK;
3612 : }
3613 :
3614 : /* void forceGC (); */
3615 : NS_IMETHODIMP
3616 7 : nsXPCComponents_Utils::ForceGC(JSContext *cx)
3617 : {
3618 7 : js::GCForReason(cx, js::gcreason::COMPONENT_UTILS);
3619 7 : return NS_OK;
3620 : }
3621 :
3622 : /* void forceShrinkingGC (); */
3623 : NS_IMETHODIMP
3624 0 : nsXPCComponents_Utils::ForceShrinkingGC(JSContext *cx)
3625 : {
3626 0 : js::ShrinkingGC(cx, js::gcreason::COMPONENT_UTILS);
3627 0 : return NS_OK;
3628 : }
3629 :
3630 : class PreciseGCRunnable : public nsRunnable
3631 0 : {
3632 : public:
3633 0 : PreciseGCRunnable(JSContext *aCx, ScheduledGCCallback* aCallback, bool aShrinking)
3634 0 : : mCallback(aCallback), mCx(aCx), mShrinking(aShrinking) {}
3635 :
3636 0 : NS_IMETHOD Run()
3637 : {
3638 0 : nsCOMPtr<nsIJSRuntimeService> runtimeSvc = do_GetService("@mozilla.org/js/xpc/RuntimeService;1");
3639 0 : NS_ENSURE_STATE(runtimeSvc);
3640 :
3641 0 : JSRuntime* rt = nsnull;
3642 0 : runtimeSvc->GetRuntime(&rt);
3643 0 : NS_ENSURE_STATE(rt);
3644 :
3645 : JSContext *cx;
3646 0 : JSContext *iter = nsnull;
3647 0 : while ((cx = JS_ContextIterator(rt, &iter)) != NULL) {
3648 0 : if (JS_IsRunning(cx)) {
3649 0 : return NS_DispatchToMainThread(this);
3650 : }
3651 : }
3652 :
3653 0 : if (mShrinking)
3654 0 : js::ShrinkingGC(mCx, js::gcreason::COMPONENT_UTILS);
3655 : else
3656 0 : js::GCForReason(mCx, js::gcreason::COMPONENT_UTILS);
3657 :
3658 0 : mCallback->Callback();
3659 0 : return NS_OK;
3660 : }
3661 :
3662 : private:
3663 : nsRefPtr<ScheduledGCCallback> mCallback;
3664 : JSContext *mCx;
3665 : bool mShrinking;
3666 : };
3667 :
3668 : /* [inline_jscontext] void schedulePreciseGC(in ScheduledGCCallback callback); */
3669 : NS_IMETHODIMP
3670 0 : nsXPCComponents_Utils::SchedulePreciseGC(ScheduledGCCallback* aCallback, JSContext* aCx)
3671 : {
3672 0 : nsRefPtr<PreciseGCRunnable> event = new PreciseGCRunnable(aCx, aCallback, false);
3673 0 : return NS_DispatchToMainThread(event);
3674 : }
3675 :
3676 : /* [inline_jscontext] void schedulePreciseShrinkingGC(in ScheduledGCCallback callback); */
3677 : NS_IMETHODIMP
3678 0 : nsXPCComponents_Utils::SchedulePreciseShrinkingGC(ScheduledGCCallback* aCallback, JSContext* aCx)
3679 : {
3680 0 : nsRefPtr<PreciseGCRunnable> event = new PreciseGCRunnable(aCx, aCallback, true);
3681 0 : return NS_DispatchToMainThread(event);
3682 : }
3683 :
3684 : /* [implicit_jscontext] jsval nondeterministicGetWeakMapKeys(in jsval aMap); */
3685 : NS_IMETHODIMP
3686 0 : nsXPCComponents_Utils::NondeterministicGetWeakMapKeys(const jsval &aMap,
3687 : JSContext *aCx,
3688 : jsval *aKeys)
3689 : {
3690 0 : if (!JSVAL_IS_OBJECT(aMap)) {
3691 0 : *aKeys = JSVAL_VOID;
3692 0 : return NS_OK;
3693 : }
3694 : JSObject *objRet;
3695 0 : if (!JS_NondeterministicGetWeakMapKeys(aCx, JSVAL_TO_OBJECT(aMap), &objRet))
3696 0 : return NS_ERROR_OUT_OF_MEMORY;
3697 0 : *aKeys = objRet ? OBJECT_TO_JSVAL(objRet) : JSVAL_VOID;
3698 0 : return NS_OK;
3699 : }
3700 :
3701 : /* void getDebugObject(); */
3702 : NS_IMETHODIMP
3703 0 : nsXPCComponents_Utils::GetJSTestingFunctions(JSContext *cx,
3704 : JS::Value *retval)
3705 : {
3706 0 : JSObject *obj = js::GetTestingFunctions(cx);
3707 0 : if (!obj)
3708 0 : return NS_ERROR_XPC_JAVASCRIPT_ERROR;
3709 0 : *retval = OBJECT_TO_JSVAL(obj);
3710 0 : return NS_OK;
3711 : }
3712 :
3713 : /* void getGlobalForObject(); */
3714 : NS_IMETHODIMP
3715 176 : nsXPCComponents_Utils::GetGlobalForObject(const JS::Value& object,
3716 : JSContext *cx,
3717 : JS::Value *retval)
3718 : {
3719 : // First argument must be an object.
3720 176 : if (JSVAL_IS_PRIMITIVE(object))
3721 0 : return NS_ERROR_XPC_BAD_CONVERT_JS;
3722 :
3723 176 : JSObject *obj = JS_GetGlobalForObject(cx, JSVAL_TO_OBJECT(object));
3724 176 : *retval = OBJECT_TO_JSVAL(obj);
3725 :
3726 : // Outerize if necessary.
3727 176 : if (JSObjectOp outerize = js::GetObjectClass(obj)->ext.outerObject)
3728 0 : *retval = OBJECT_TO_JSVAL(outerize(cx, obj));
3729 :
3730 176 : return NS_OK;
3731 : }
3732 :
3733 : /* jsval createObjectIn(in jsval vobj); */
3734 : NS_IMETHODIMP
3735 0 : nsXPCComponents_Utils::CreateObjectIn(const jsval &vobj, JSContext *cx, jsval *rval)
3736 : {
3737 0 : if (!cx)
3738 0 : return NS_ERROR_FAILURE;
3739 :
3740 : // first argument must be an object
3741 0 : if (JSVAL_IS_PRIMITIVE(vobj))
3742 0 : return NS_ERROR_XPC_BAD_CONVERT_JS;
3743 :
3744 0 : JSObject *scope = js::UnwrapObject(JSVAL_TO_OBJECT(vobj));
3745 : JSObject *obj;
3746 : {
3747 0 : JSAutoEnterCompartment ac;
3748 0 : if (!ac.enter(cx, scope))
3749 0 : return NS_ERROR_FAILURE;
3750 :
3751 0 : obj = JS_NewObject(cx, nsnull, nsnull, scope);
3752 0 : if (!obj)
3753 0 : return NS_ERROR_FAILURE;
3754 : }
3755 :
3756 0 : if (!JS_WrapObject(cx, &obj))
3757 0 : return NS_ERROR_FAILURE;
3758 0 : *rval = OBJECT_TO_JSVAL(obj);
3759 0 : return NS_OK;
3760 : }
3761 :
3762 : JSBool
3763 0 : FunctionWrapper(JSContext *cx, unsigned argc, jsval *vp)
3764 : {
3765 0 : jsval v = js::GetFunctionNativeReserved(JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)), 0);
3766 0 : NS_ASSERTION(JSVAL_IS_OBJECT(v), "weird function");
3767 :
3768 0 : JSObject *obj = JS_THIS_OBJECT(cx, vp);
3769 0 : if (!obj) {
3770 0 : return JS_FALSE;
3771 : }
3772 0 : return JS_CallFunctionValue(cx, obj, v, argc, JS_ARGV(cx, vp), vp);
3773 : }
3774 :
3775 : JSBool
3776 0 : WrapCallable(JSContext *cx, JSObject *obj, jsid id, JSObject *propobj, jsval *vp)
3777 : {
3778 : JSFunction *fun = js::NewFunctionByIdWithReserved(cx, FunctionWrapper, 0, 0,
3779 0 : JS_GetGlobalForObject(cx, obj), id);
3780 0 : if (!fun)
3781 0 : return false;
3782 :
3783 0 : JSObject *funobj = JS_GetFunctionObject(fun);
3784 0 : js::SetFunctionNativeReserved(funobj, 0, OBJECT_TO_JSVAL(propobj));
3785 0 : *vp = OBJECT_TO_JSVAL(funobj);
3786 0 : return true;
3787 : }
3788 :
3789 : /* void makeObjectPropsNormal(jsval vobj); */
3790 : NS_IMETHODIMP
3791 0 : nsXPCComponents_Utils::MakeObjectPropsNormal(const jsval &vobj, JSContext *cx)
3792 : {
3793 0 : if (!cx)
3794 0 : return NS_ERROR_FAILURE;
3795 :
3796 : // first argument must be an object
3797 0 : if (JSVAL_IS_PRIMITIVE(vobj))
3798 0 : return NS_ERROR_XPC_BAD_CONVERT_JS;
3799 :
3800 0 : JSObject *obj = js::UnwrapObject(JSVAL_TO_OBJECT(vobj));
3801 :
3802 0 : JSAutoEnterCompartment ac;
3803 0 : if (!ac.enter(cx, obj))
3804 0 : return NS_ERROR_FAILURE;
3805 :
3806 0 : JS::AutoIdArray ida(cx, JS_Enumerate(cx, obj));
3807 0 : if (!ida)
3808 0 : return NS_ERROR_FAILURE;
3809 :
3810 0 : for (size_t i = 0; i < ida.length(); ++i) {
3811 0 : jsid id = ida[i];
3812 : jsval v;
3813 :
3814 0 : if (!JS_GetPropertyById(cx, obj, id, &v))
3815 0 : return NS_ERROR_FAILURE;
3816 :
3817 0 : if (JSVAL_IS_PRIMITIVE(v))
3818 0 : continue;
3819 :
3820 0 : JSObject *propobj = JSVAL_TO_OBJECT(v);
3821 : // TODO Deal with non-functions.
3822 0 : if (!js::IsWrapper(propobj) || !JS_ObjectIsCallable(cx, propobj))
3823 0 : continue;
3824 :
3825 0 : if (!WrapCallable(cx, obj, id, propobj, &v) ||
3826 0 : !JS_SetPropertyById(cx, obj, id, &v))
3827 0 : return NS_ERROR_FAILURE;
3828 : }
3829 :
3830 0 : return NS_OK;
3831 : }
3832 :
3833 : /* string canCreateWrapper (in nsIIDPtr iid); */
3834 : NS_IMETHODIMP
3835 11085 : nsXPCComponents_Utils::CanCreateWrapper(const nsIID * iid, char **_retval)
3836 : {
3837 : // We let anyone do this...
3838 11085 : *_retval = xpc_CloneAllAccess();
3839 11085 : return NS_OK;
3840 : }
3841 :
3842 : /* string canCallMethod (in nsIIDPtr iid, in wstring methodName); */
3843 : NS_IMETHODIMP
3844 0 : nsXPCComponents_Utils::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
3845 : {
3846 : static const char* allowed[] = { "lookupMethod", "evalInSandbox", nsnull };
3847 0 : *_retval = xpc_CheckAccessList(methodName, allowed);
3848 0 : return NS_OK;
3849 : }
3850 :
3851 : /* string canGetProperty (in nsIIDPtr iid, in wstring propertyName); */
3852 : NS_IMETHODIMP
3853 0 : nsXPCComponents_Utils::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
3854 : {
3855 0 : *_retval = nsnull;
3856 0 : return NS_OK;
3857 : }
3858 :
3859 : /* string canSetProperty (in nsIIDPtr iid, in wstring propertyName); */
3860 : NS_IMETHODIMP
3861 0 : nsXPCComponents_Utils::CanSetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
3862 : {
3863 : // If you have to ask, then the answer is NO
3864 0 : *_retval = nsnull;
3865 0 : return NS_OK;
3866 : }
3867 :
3868 : nsresult
3869 0 : GetBoolOption(JSContext* cx, uint32_t aOption, bool* aValue)
3870 : {
3871 0 : *aValue = !!(JS_GetOptions(cx) & aOption);
3872 0 : return NS_OK;
3873 : }
3874 :
3875 : nsresult
3876 0 : SetBoolOption(JSContext* cx, uint32_t aOption, bool aValue)
3877 : {
3878 0 : uint32_t options = JS_GetOptions(cx);
3879 0 : if (aValue) {
3880 0 : options |= aOption;
3881 : } else {
3882 0 : options &= ~aOption;
3883 : }
3884 0 : JS_SetOptions(cx, options & JSALLOPTION_MASK);
3885 0 : return NS_OK;
3886 : }
3887 :
3888 : #define GENERATE_JSOPTION_GETTER_SETTER(_attr, _flag) \
3889 : NS_IMETHODIMP \
3890 : nsXPCComponents_Utils::Get## _attr(JSContext* cx, bool* aValue) \
3891 : { \
3892 : return GetBoolOption(cx, _flag, aValue); \
3893 : } \
3894 : NS_IMETHODIMP \
3895 : nsXPCComponents_Utils::Set## _attr(JSContext* cx, bool aValue) \
3896 : { \
3897 : return SetBoolOption(cx, _flag, aValue); \
3898 : }
3899 :
3900 0 : GENERATE_JSOPTION_GETTER_SETTER(Strict, JSOPTION_STRICT)
3901 0 : GENERATE_JSOPTION_GETTER_SETTER(Werror, JSOPTION_WERROR)
3902 0 : GENERATE_JSOPTION_GETTER_SETTER(Atline, JSOPTION_ATLINE)
3903 0 : GENERATE_JSOPTION_GETTER_SETTER(Xml, JSOPTION_XML)
3904 0 : GENERATE_JSOPTION_GETTER_SETTER(Relimit, JSOPTION_RELIMIT)
3905 0 : GENERATE_JSOPTION_GETTER_SETTER(Methodjit, JSOPTION_METHODJIT)
3906 0 : GENERATE_JSOPTION_GETTER_SETTER(Methodjit_always, JSOPTION_METHODJIT_ALWAYS)
3907 :
3908 : #undef GENERATE_JSOPTION_GETTER_SETTER
3909 :
3910 : NS_IMETHODIMP
3911 0 : nsXPCComponents_Utils::SetGCZeal(PRInt32 aValue, JSContext* cx)
3912 : {
3913 : #ifdef JS_GC_ZEAL
3914 0 : JS_SetGCZeal(cx, PRUint8(aValue), JS_DEFAULT_ZEAL_FREQ, false);
3915 : #endif
3916 0 : return NS_OK;
3917 : }
3918 :
3919 : /***************************************************************************/
3920 : /***************************************************************************/
3921 : /***************************************************************************/
3922 :
3923 : // XXXjband We ought to cache the wrapper in the object's slots rather than
3924 : // re-wrapping on demand
3925 :
3926 220799 : NS_INTERFACE_MAP_BEGIN(nsXPCComponents)
3927 220799 : NS_INTERFACE_MAP_ENTRY(nsIXPCComponents)
3928 183403 : NS_INTERFACE_MAP_ENTRY(nsIXPCScriptable)
3929 136975 : NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
3930 106021 : NS_INTERFACE_MAP_ENTRY(nsISecurityCheckedComponent)
3931 102553 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIXPCComponents)
3932 87073 : NS_INTERFACE_MAP_END_THREADSAFE
3933 :
3934 195628 : NS_IMPL_THREADSAFE_ADDREF(nsXPCComponents)
3935 195564 : NS_IMPL_THREADSAFE_RELEASE(nsXPCComponents)
3936 :
3937 : /* void getInterfaces (out PRUint32 count, [array, size_is (count), retval]
3938 : out nsIIDPtr array); */
3939 : NS_IMETHODIMP
3940 15475 : nsXPCComponents::GetInterfaces(PRUint32 *aCount, nsIID * **aArray)
3941 : {
3942 15475 : const PRUint32 count = 3;
3943 15475 : *aCount = count;
3944 : nsIID **array;
3945 15475 : *aArray = array = static_cast<nsIID**>(nsMemory::Alloc(count * sizeof(nsIID*)));
3946 15475 : if (!array)
3947 0 : return NS_ERROR_OUT_OF_MEMORY;
3948 :
3949 15475 : PRUint32 index = 0;
3950 : nsIID* clone;
3951 : #define PUSH_IID(id) \
3952 : clone = static_cast<nsIID *>(nsMemory::Clone(&NS_GET_IID( id ), \
3953 : sizeof(nsIID))); \
3954 : if (!clone) \
3955 : goto oom; \
3956 : array[index++] = clone;
3957 :
3958 15475 : PUSH_IID(nsIXPCComponents)
3959 15475 : PUSH_IID(nsIXPCScriptable)
3960 15475 : PUSH_IID(nsISecurityCheckedComponent)
3961 : #undef PUSH_IID
3962 :
3963 15475 : return NS_OK;
3964 : oom:
3965 0 : while (index)
3966 0 : nsMemory::Free(array[--index]);
3967 0 : nsMemory::Free(array);
3968 0 : *aArray = nsnull;
3969 0 : return NS_ERROR_OUT_OF_MEMORY;
3970 : }
3971 :
3972 : /* nsISupports getHelperForLanguage (in PRUint32 language); */
3973 : NS_IMETHODIMP
3974 15476 : nsXPCComponents::GetHelperForLanguage(PRUint32 language,
3975 : nsISupports **retval)
3976 : {
3977 15476 : *retval = nsnull;
3978 15476 : return NS_OK;
3979 : }
3980 :
3981 : /* readonly attribute string contractID; */
3982 : NS_IMETHODIMP
3983 0 : nsXPCComponents::GetContractID(char * *aContractID)
3984 : {
3985 0 : *aContractID = nsnull;
3986 0 : return NS_ERROR_NOT_AVAILABLE;
3987 : }
3988 :
3989 : /* readonly attribute string classDescription; */
3990 : NS_IMETHODIMP
3991 1 : nsXPCComponents::GetClassDescription(char * *aClassDescription)
3992 : {
3993 : static const char classDescription[] = "XPCComponents";
3994 1 : *aClassDescription = (char*)nsMemory::Clone(classDescription, sizeof(classDescription));
3995 1 : return *aClassDescription ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
3996 : }
3997 :
3998 : /* readonly attribute nsCIDPtr classID; */
3999 : NS_IMETHODIMP
4000 0 : nsXPCComponents::GetClassID(nsCID * *aClassID)
4001 : {
4002 0 : *aClassID = nsnull;
4003 0 : return NS_OK;
4004 : }
4005 :
4006 : /* readonly attribute PRUint32 implementationLanguage; */
4007 : NS_IMETHODIMP
4008 0 : nsXPCComponents::GetImplementationLanguage(PRUint32 *aImplementationLanguage)
4009 : {
4010 0 : *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
4011 0 : return NS_OK;
4012 : }
4013 :
4014 : /* readonly attribute PRUint32 flags; */
4015 : NS_IMETHODIMP
4016 18944 : nsXPCComponents::GetFlags(PRUint32 *aFlags)
4017 : {
4018 18944 : *aFlags = nsIClassInfo::THREADSAFE;
4019 18944 : return NS_OK;
4020 : }
4021 :
4022 : /* [notxpcom] readonly attribute nsCID classIDNoAlloc; */
4023 : NS_IMETHODIMP
4024 0 : nsXPCComponents::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
4025 : {
4026 0 : return NS_ERROR_NOT_AVAILABLE;
4027 : }
4028 :
4029 15475 : nsXPCComponents::nsXPCComponents()
4030 : : mInterfaces(nsnull),
4031 : mInterfacesByID(nsnull),
4032 : mClasses(nsnull),
4033 : mClassesByID(nsnull),
4034 : mResults(nsnull),
4035 : mID(nsnull),
4036 : mException(nsnull),
4037 : mConstructor(nsnull),
4038 15475 : mUtils(nsnull)
4039 : {
4040 15475 : }
4041 :
4042 30894 : nsXPCComponents::~nsXPCComponents()
4043 : {
4044 15447 : ClearMembers();
4045 61788 : }
4046 :
4047 : void
4048 15471 : nsXPCComponents::ClearMembers()
4049 : {
4050 15471 : NS_IF_RELEASE(mInterfaces);
4051 15471 : NS_IF_RELEASE(mInterfacesByID);
4052 15471 : NS_IF_RELEASE(mClasses);
4053 15471 : NS_IF_RELEASE(mClassesByID);
4054 15471 : NS_IF_RELEASE(mResults);
4055 15471 : NS_IF_RELEASE(mID);
4056 15471 : NS_IF_RELEASE(mException);
4057 15471 : NS_IF_RELEASE(mConstructor);
4058 15471 : NS_IF_RELEASE(mUtils);
4059 15471 : }
4060 :
4061 : /*******************************************/
4062 : #define XPC_IMPL_GET_OBJ_METHOD(_n) \
4063 : NS_IMETHODIMP nsXPCComponents::Get##_n(nsIXPCComponents_##_n * *a##_n) { \
4064 : NS_ENSURE_ARG_POINTER(a##_n); \
4065 : if (!m##_n) { \
4066 : if (!(m##_n = new nsXPCComponents_##_n())) { \
4067 : *a##_n = nsnull; \
4068 : return NS_ERROR_OUT_OF_MEMORY; \
4069 : } \
4070 : NS_ADDREF(m##_n); \
4071 : } \
4072 : NS_ADDREF(m##_n); \
4073 : *a##_n = m##_n; \
4074 : return NS_OK; \
4075 : }
4076 :
4077 84614 : XPC_IMPL_GET_OBJ_METHOD(Interfaces)
4078 2 : XPC_IMPL_GET_OBJ_METHOD(InterfacesByID)
4079 59057 : XPC_IMPL_GET_OBJ_METHOD(Classes)
4080 9 : XPC_IMPL_GET_OBJ_METHOD(ClassesByID)
4081 25293 : XPC_IMPL_GET_OBJ_METHOD(Results)
4082 9343 : XPC_IMPL_GET_OBJ_METHOD(ID)
4083 807 : XPC_IMPL_GET_OBJ_METHOD(Exception)
4084 2690 : XPC_IMPL_GET_OBJ_METHOD(Constructor)
4085 54675 : XPC_IMPL_GET_OBJ_METHOD(Utils)
4086 :
4087 : #undef XPC_IMPL_GET_OBJ_METHOD
4088 : /*******************************************/
4089 :
4090 : NS_IMETHODIMP
4091 8269 : nsXPCComponents::IsSuccessCode(nsresult result, bool *out)
4092 : {
4093 8269 : *out = NS_SUCCEEDED(result);
4094 8269 : return NS_OK;
4095 : }
4096 :
4097 : NS_IMETHODIMP
4098 155853 : nsXPCComponents::GetStack(nsIStackFrame * *aStack)
4099 : {
4100 : nsresult rv;
4101 155853 : nsXPConnect* xpc = nsXPConnect::GetXPConnect();
4102 155853 : if (!xpc)
4103 0 : return NS_ERROR_FAILURE;
4104 155853 : rv = xpc->GetCurrentJSStack(aStack);
4105 155853 : return rv;
4106 : }
4107 :
4108 : NS_IMETHODIMP
4109 3824 : nsXPCComponents::GetManager(nsIComponentManager * *aManager)
4110 : {
4111 3824 : NS_ASSERTION(aManager, "bad param");
4112 3824 : return NS_GetComponentManager(aManager);
4113 : }
4114 :
4115 : /**********************************************/
4116 :
4117 : // The nsIXPCScriptable map declaration that will generate stubs for us...
4118 : #define XPC_MAP_CLASSNAME nsXPCComponents
4119 : #define XPC_MAP_QUOTED_CLASSNAME "nsXPCComponents"
4120 : #define XPC_MAP_WANT_NEWRESOLVE
4121 : #define XPC_MAP_WANT_GETPROPERTY
4122 : #define XPC_MAP_WANT_SETPROPERTY
4123 : #define XPC_MAP_FLAGS nsIXPCScriptable::ALLOW_PROP_MODS_DURING_RESOLVE
4124 : #include "xpc_map_end.h" /* This will #undef the above */
4125 :
4126 : /* bool newResolve (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, in PRUint32 flags, out JSObjectPtr objp); */
4127 : NS_IMETHODIMP
4128 161341 : nsXPCComponents::NewResolve(nsIXPConnectWrappedNative *wrapper,
4129 : JSContext * cx, JSObject * obj,
4130 : jsid id, PRUint32 flags,
4131 : JSObject * *objp, bool *_retval)
4132 : {
4133 161341 : XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance();
4134 161341 : if (!rt)
4135 0 : return NS_ERROR_FAILURE;
4136 :
4137 161341 : unsigned attrs = 0;
4138 :
4139 161341 : if (id == rt->GetStringID(XPCJSRuntime::IDX_LAST_RESULT))
4140 2 : attrs = JSPROP_READONLY;
4141 161339 : else if (id != rt->GetStringID(XPCJSRuntime::IDX_RETURN_CODE))
4142 161339 : return NS_OK;
4143 :
4144 2 : *objp = obj;
4145 : *_retval = JS_DefinePropertyById(cx, obj, id, JSVAL_VOID, nsnull, nsnull,
4146 : JSPROP_ENUMERATE | JSPROP_PERMANENT |
4147 2 : attrs);
4148 2 : return NS_OK;
4149 : }
4150 :
4151 : /* bool getProperty (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsval id, in JSValPtr vp); */
4152 : NS_IMETHODIMP
4153 2 : nsXPCComponents::GetProperty(nsIXPConnectWrappedNative *wrapper,
4154 : JSContext * cx, JSObject * obj,
4155 : jsid id, jsval * vp, bool *_retval)
4156 : {
4157 2 : XPCContext* xpcc = XPCContext::GetXPCContext(cx);
4158 2 : if (!xpcc)
4159 0 : return NS_ERROR_FAILURE;
4160 :
4161 2 : bool doResult = false;
4162 : nsresult res;
4163 2 : XPCJSRuntime* rt = xpcc->GetRuntime();
4164 2 : if (id == rt->GetStringID(XPCJSRuntime::IDX_LAST_RESULT)) {
4165 2 : res = xpcc->GetLastResult();
4166 2 : doResult = true;
4167 0 : } else if (id == rt->GetStringID(XPCJSRuntime::IDX_RETURN_CODE)) {
4168 0 : res = xpcc->GetPendingResult();
4169 0 : doResult = true;
4170 : }
4171 :
4172 2 : nsresult rv = NS_OK;
4173 2 : if (doResult) {
4174 2 : if (!JS_NewNumberValue(cx, (double) res, vp))
4175 0 : return NS_ERROR_OUT_OF_MEMORY;
4176 2 : rv = NS_SUCCESS_I_DID_SOMETHING;
4177 : }
4178 :
4179 2 : return rv;
4180 : }
4181 :
4182 : /* bool setProperty (in nsIXPConnectWrappedNative wrapper, in JSContextPtr cx, in JSObjectPtr obj, in jsid id, in JSValPtr vp); */
4183 : NS_IMETHODIMP
4184 0 : nsXPCComponents::SetProperty(nsIXPConnectWrappedNative *wrapper,
4185 : JSContext * cx, JSObject * obj, jsid id,
4186 : jsval * vp, bool *_retval)
4187 : {
4188 0 : XPCContext* xpcc = XPCContext::GetXPCContext(cx);
4189 0 : if (!xpcc)
4190 0 : return NS_ERROR_FAILURE;
4191 :
4192 0 : XPCJSRuntime* rt = xpcc->GetRuntime();
4193 0 : if (!rt)
4194 0 : return NS_ERROR_FAILURE;
4195 :
4196 0 : if (id == rt->GetStringID(XPCJSRuntime::IDX_RETURN_CODE)) {
4197 : nsresult rv;
4198 0 : if (JS_ValueToECMAUint32(cx, *vp, (uint32_t*)&rv)) {
4199 0 : xpcc->SetPendingResult(rv);
4200 0 : xpcc->SetLastResult(rv);
4201 0 : return NS_SUCCESS_I_DID_SOMETHING;
4202 : }
4203 0 : return NS_ERROR_FAILURE;
4204 : }
4205 :
4206 0 : return NS_ERROR_XPC_CANT_MODIFY_PROP_ON_WN;
4207 : }
4208 :
4209 : // static
4210 : JSBool
4211 15475 : nsXPCComponents::AttachNewComponentsObject(XPCCallContext& ccx,
4212 : XPCWrappedNativeScope* aScope,
4213 : JSObject* aGlobal)
4214 : {
4215 15475 : if (!aGlobal)
4216 0 : return false;
4217 :
4218 15475 : nsXPCComponents* components = new nsXPCComponents();
4219 15475 : if (!components)
4220 0 : return false;
4221 :
4222 30950 : nsCOMPtr<nsIXPCComponents> cholder(components);
4223 :
4224 30950 : AutoMarkingNativeInterfacePtr iface(ccx);
4225 15475 : iface = XPCNativeInterface::GetNewOrUsed(ccx, &NS_GET_IID(nsIXPCComponents));
4226 :
4227 15475 : if (!iface)
4228 0 : return false;
4229 :
4230 30950 : nsCOMPtr<XPCWrappedNative> wrapper;
4231 30950 : xpcObjectHelper helper(cholder);
4232 15475 : XPCWrappedNative::GetNewOrUsed(ccx, helper, aScope, iface, getter_AddRefs(wrapper));
4233 15475 : if (!wrapper)
4234 0 : return false;
4235 :
4236 15475 : aScope->SetComponents(components);
4237 :
4238 15475 : jsid id = ccx.GetRuntime()->GetStringID(XPCJSRuntime::IDX_COMPONENTS);
4239 : JSObject* obj;
4240 :
4241 15475 : return NS_SUCCEEDED(wrapper->GetJSObject(&obj)) &&
4242 15475 : obj && JS_DefinePropertyById(ccx, aGlobal, id, OBJECT_TO_JSVAL(obj),
4243 : nsnull, nsnull,
4244 30950 : JSPROP_PERMANENT | JSPROP_READONLY);
4245 : }
4246 :
4247 : /* void lookupMethod (); */
4248 : NS_IMETHODIMP
4249 0 : nsXPCComponents::LookupMethod(const JS::Value& object,
4250 : const JS::Value& name,
4251 : JSContext *cx,
4252 : JS::Value *retval)
4253 : {
4254 0 : NS_WARNING("Components.lookupMethod deprecated, use Components.utils.lookupMethod");
4255 :
4256 0 : nsCOMPtr<nsIXPCComponents_Utils> utils;
4257 0 : nsresult rv = GetUtils(getter_AddRefs(utils));
4258 0 : if (NS_FAILED(rv))
4259 0 : return rv;
4260 :
4261 0 : return utils->LookupMethod(object, name, cx, retval);
4262 : }
4263 :
4264 : /* void reportError (); */
4265 0 : NS_IMETHODIMP nsXPCComponents::ReportError(const JS::Value &error, JSContext *cx)
4266 : {
4267 0 : NS_WARNING("Components.reportError deprecated, use Components.utils.reportError");
4268 :
4269 0 : nsCOMPtr<nsIXPCComponents_Utils> utils;
4270 0 : nsresult rv = GetUtils(getter_AddRefs(utils));
4271 0 : if (NS_FAILED(rv))
4272 0 : return rv;
4273 :
4274 0 : return utils->ReportError(error, cx);
4275 : }
4276 :
4277 : /* string canCreateWrapper (in nsIIDPtr iid); */
4278 : NS_IMETHODIMP
4279 3468 : nsXPCComponents::CanCreateWrapper(const nsIID * iid, char **_retval)
4280 : {
4281 : // We let anyone do this...
4282 3468 : *_retval = xpc_CloneAllAccess();
4283 3468 : return NS_OK;
4284 : }
4285 :
4286 : /* string canCallMethod (in nsIIDPtr iid, in wstring methodName); */
4287 : NS_IMETHODIMP
4288 0 : nsXPCComponents::CanCallMethod(const nsIID * iid, const PRUnichar *methodName, char **_retval)
4289 : {
4290 : static const char* allowed[] = { "isSuccessCode", "lookupMethod", nsnull };
4291 0 : *_retval = xpc_CheckAccessList(methodName, allowed);
4292 0 : return NS_OK;
4293 : }
4294 :
4295 : /* string canGetProperty (in nsIIDPtr iid, in wstring propertyName); */
4296 : NS_IMETHODIMP
4297 0 : nsXPCComponents::CanGetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
4298 : {
4299 : static const char* allowed[] = { "interfaces", "interfacesByID", "results", nsnull};
4300 0 : *_retval = xpc_CheckAccessList(propertyName, allowed);
4301 0 : return NS_OK;
4302 : }
4303 :
4304 : /* string canSetProperty (in nsIIDPtr iid, in wstring propertyName); */
4305 : NS_IMETHODIMP
4306 0 : nsXPCComponents::CanSetProperty(const nsIID * iid, const PRUnichar *propertyName, char **_retval)
4307 : {
4308 : // If you have to ask, then the answer is NO
4309 0 : *_retval = nsnull;
4310 0 : return NS_OK;
4311 : }
|