Line data Source code
1 : /* THIS FILE IS AUTOGENERATED FROM WebAuthentication.webidl BY Codegen.py - DO NOT EDIT */
2 :
3 : #include "AtomList.h"
4 : #include "CredentialManagementBinding.h"
5 : #include "WebAuthenticationBinding.h"
6 : #include "WrapperFactory.h"
7 : #include "jsapi.h"
8 : #include "jsfriendapi.h"
9 : #include "mozilla/OwningNonNull.h"
10 : #include "mozilla/Preferences.h"
11 : #include "mozilla/dom/AuthenticatorAssertionResponse.h"
12 : #include "mozilla/dom/AuthenticatorAttestationResponse.h"
13 : #include "mozilla/dom/AuthenticatorResponse.h"
14 : #include "mozilla/dom/BindingUtils.h"
15 : #include "mozilla/dom/DOMJSClass.h"
16 : #include "mozilla/dom/NonRefcountedDOMObject.h"
17 : #include "mozilla/dom/PrimitiveConversions.h"
18 : #include "mozilla/dom/PublicKeyCredential.h"
19 : #include "mozilla/dom/ScriptSettings.h"
20 : #include "mozilla/dom/SimpleGlobalObject.h"
21 : #include "mozilla/dom/TypedArray.h"
22 : #include "mozilla/dom/UnionConversions.h"
23 : #include "mozilla/dom/XrayExpandoClass.h"
24 :
25 : namespace mozilla {
26 : namespace dom {
27 :
28 : namespace AttachmentValues {
29 : extern const EnumEntry strings[3] = {
30 : {"platform", 8},
31 : {"cross-platform", 14},
32 : { nullptr, 0 }
33 : };
34 : } // namespace AttachmentValues
35 :
36 : bool
37 0 : ToJSValue(JSContext* aCx, Attachment aArgument, JS::MutableHandle<JS::Value> aValue)
38 : {
39 0 : MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(AttachmentValues::strings));
40 : JSString* resultStr =
41 0 : JS_NewStringCopyN(aCx, AttachmentValues::strings[uint32_t(aArgument)].value,
42 0 : AttachmentValues::strings[uint32_t(aArgument)].length);
43 0 : if (!resultStr) {
44 0 : return false;
45 : }
46 0 : aValue.setString(resultStr);
47 0 : return true;
48 : }
49 :
50 :
51 : namespace PublicKeyCredentialTypeValues {
52 : extern const EnumEntry strings[2] = {
53 : {"public-key", 10},
54 : { nullptr, 0 }
55 : };
56 : } // namespace PublicKeyCredentialTypeValues
57 :
58 : bool
59 0 : ToJSValue(JSContext* aCx, PublicKeyCredentialType aArgument, JS::MutableHandle<JS::Value> aValue)
60 : {
61 0 : MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(PublicKeyCredentialTypeValues::strings));
62 : JSString* resultStr =
63 0 : JS_NewStringCopyN(aCx, PublicKeyCredentialTypeValues::strings[uint32_t(aArgument)].value,
64 0 : PublicKeyCredentialTypeValues::strings[uint32_t(aArgument)].length);
65 0 : if (!resultStr) {
66 0 : return false;
67 : }
68 0 : aValue.setString(resultStr);
69 0 : return true;
70 : }
71 :
72 :
73 : namespace WebAuthnTransportValues {
74 : extern const EnumEntry strings[4] = {
75 : {"usb", 3},
76 : {"nfc", 3},
77 : {"ble", 3},
78 : { nullptr, 0 }
79 : };
80 : } // namespace WebAuthnTransportValues
81 :
82 : bool
83 0 : ToJSValue(JSContext* aCx, WebAuthnTransport aArgument, JS::MutableHandle<JS::Value> aValue)
84 : {
85 0 : MOZ_ASSERT(uint32_t(aArgument) < ArrayLength(WebAuthnTransportValues::strings));
86 : JSString* resultStr =
87 0 : JS_NewStringCopyN(aCx, WebAuthnTransportValues::strings[uint32_t(aArgument)].value,
88 0 : WebAuthnTransportValues::strings[uint32_t(aArgument)].length);
89 0 : if (!resultStr) {
90 0 : return false;
91 : }
92 0 : aValue.setString(resultStr);
93 0 : return true;
94 : }
95 :
96 :
97 :
98 0 : AuthenticatorSelectionCriteria::AuthenticatorSelectionCriteria()
99 : {
100 : // Safe to pass a null context if we pass a null value
101 0 : Init(nullptr, JS::NullHandleValue);
102 0 : }
103 :
104 :
105 :
106 : bool
107 0 : AuthenticatorSelectionCriteria::InitIds(JSContext* cx, AuthenticatorSelectionCriteriaAtoms* atomsCache)
108 : {
109 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
110 :
111 : // Initialize these in reverse order so that any failure leaves the first one
112 : // uninitialized.
113 0 : if (!atomsCache->requireResidentKey_id.init(cx, "requireResidentKey") ||
114 0 : !atomsCache->attachment_id.init(cx, "attachment")) {
115 0 : return false;
116 : }
117 0 : return true;
118 : }
119 :
120 : bool
121 0 : AuthenticatorSelectionCriteria::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
122 : {
123 : // Passing a null JSContext is OK only if we're initing from null,
124 : // Since in that case we will not have to do any property gets
125 : // Also evaluate isNullOrUndefined in order to avoid false-positive
126 : // checkers by static analysis tools
127 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
128 0 : AuthenticatorSelectionCriteriaAtoms* atomsCache = nullptr;
129 0 : if (cx) {
130 0 : atomsCache = GetAtomCache<AuthenticatorSelectionCriteriaAtoms>(cx);
131 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
132 0 : return false;
133 : }
134 : }
135 :
136 0 : if (!IsConvertibleToDictionary(val)) {
137 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
138 : }
139 :
140 0 : bool isNull = val.isNullOrUndefined();
141 : // We only need these if !isNull, in which case we have |cx|.
142 0 : Maybe<JS::Rooted<JSObject *> > object;
143 0 : Maybe<JS::Rooted<JS::Value> > temp;
144 0 : if (!isNull) {
145 0 : MOZ_ASSERT(cx);
146 0 : object.emplace(cx, &val.toObject());
147 0 : temp.emplace(cx);
148 : }
149 0 : if (!isNull) {
150 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->attachment_id, temp.ptr())) {
151 0 : return false;
152 : }
153 : }
154 0 : if (!isNull && !temp->isUndefined()) {
155 0 : mAttachment.Construct();
156 : {
157 : int index;
158 0 : if (!FindEnumStringIndex<true>(cx, temp.ref(), AttachmentValues::strings, "Attachment", "'attachment' member of AuthenticatorSelectionCriteria", &index)) {
159 0 : return false;
160 : }
161 0 : MOZ_ASSERT(index >= 0);
162 0 : (mAttachment.Value()) = static_cast<Attachment>(index);
163 : }
164 0 : mIsAnyMemberPresent = true;
165 : }
166 :
167 0 : if (!isNull) {
168 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->requireResidentKey_id, temp.ptr())) {
169 0 : return false;
170 : }
171 : }
172 0 : if (!isNull && !temp->isUndefined()) {
173 0 : if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &mRequireResidentKey)) {
174 0 : return false;
175 : }
176 : } else {
177 0 : mRequireResidentKey = false;
178 : }
179 0 : mIsAnyMemberPresent = true;
180 0 : return true;
181 : }
182 :
183 : bool
184 0 : AuthenticatorSelectionCriteria::Init(const nsAString& aJSON)
185 : {
186 0 : AutoJSAPI jsapi;
187 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
188 0 : if (!cleanGlobal) {
189 0 : return false;
190 : }
191 0 : if (!jsapi.Init(cleanGlobal)) {
192 0 : return false;
193 : }
194 0 : JSContext* cx = jsapi.cx();
195 0 : JS::Rooted<JS::Value> json(cx);
196 0 : bool ok = ParseJSON(cx, aJSON, &json);
197 0 : NS_ENSURE_TRUE(ok, false);
198 0 : return Init(cx, json);
199 : }
200 :
201 : bool
202 0 : AuthenticatorSelectionCriteria::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
203 : {
204 0 : AuthenticatorSelectionCriteriaAtoms* atomsCache = GetAtomCache<AuthenticatorSelectionCriteriaAtoms>(cx);
205 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
206 0 : return false;
207 : }
208 :
209 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
210 0 : if (!obj) {
211 0 : return false;
212 : }
213 0 : rval.set(JS::ObjectValue(*obj));
214 :
215 0 : if (mAttachment.WasPassed()) {
216 : do {
217 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
218 0 : JS::Rooted<JS::Value> temp(cx);
219 0 : Attachment const & currentValue = mAttachment.InternalValue();
220 0 : if (!ToJSValue(cx, currentValue, &temp)) {
221 0 : return false;
222 : }
223 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->attachment_id, temp, JSPROP_ENUMERATE)) {
224 0 : return false;
225 : }
226 0 : break;
227 : } while(0);
228 : }
229 :
230 : do {
231 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
232 0 : JS::Rooted<JS::Value> temp(cx);
233 0 : bool const & currentValue = mRequireResidentKey;
234 0 : temp.setBoolean(currentValue);
235 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->requireResidentKey_id, temp, JSPROP_ENUMERATE)) {
236 0 : return false;
237 : }
238 0 : break;
239 : } while(0);
240 :
241 0 : return true;
242 : }
243 :
244 : bool
245 0 : AuthenticatorSelectionCriteria::ToJSON(nsAString& aJSON) const
246 : {
247 0 : AutoJSAPI jsapi;
248 0 : jsapi.Init();
249 0 : JSContext *cx = jsapi.cx();
250 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
251 : // because we'll only be creating objects, in ways that have no
252 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
253 : // which likewise guarantees no side-effects for the sorts of
254 : // things we will pass it.
255 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
256 0 : JS::Rooted<JS::Value> val(cx);
257 0 : if (!ToObjectInternal(cx, &val)) {
258 0 : return false;
259 : }
260 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
261 0 : return StringifyToJSON(cx, obj, aJSON);
262 : }
263 :
264 : void
265 0 : AuthenticatorSelectionCriteria::TraceDictionary(JSTracer* trc)
266 : {
267 0 : }
268 :
269 : AuthenticatorSelectionCriteria&
270 0 : AuthenticatorSelectionCriteria::operator=(const AuthenticatorSelectionCriteria& aOther)
271 : {
272 0 : mAttachment.Reset();
273 0 : if (aOther.mAttachment.WasPassed()) {
274 0 : mAttachment.Construct(aOther.mAttachment.Value());
275 : }
276 0 : mRequireResidentKey = aOther.mRequireResidentKey;
277 0 : return *this;
278 : }
279 :
280 : namespace binding_detail {
281 : } // namespace binding_detail
282 :
283 :
284 : bool
285 0 : BooleanOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
286 : {
287 0 : switch (mType) {
288 : case eUninitialized: {
289 0 : return false;
290 : break;
291 : }
292 : case eBoolean: {
293 0 : rval.setBoolean(mValue.mBoolean.Value());
294 0 : return true;
295 : break;
296 : }
297 : case eString: {
298 0 : if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
299 0 : return false;
300 : }
301 0 : return true;
302 : break;
303 : }
304 : default: {
305 0 : return false;
306 : break;
307 : }
308 : }
309 :
310 : return false;
311 : }
312 :
313 :
314 : bool&
315 0 : OwningBooleanOrString::RawSetAsBoolean()
316 : {
317 0 : if (mType == eBoolean) {
318 0 : return mValue.mBoolean.Value();
319 : }
320 0 : MOZ_ASSERT(mType == eUninitialized);
321 0 : mType = eBoolean;
322 0 : return mValue.mBoolean.SetValue();
323 : }
324 :
325 : bool&
326 0 : OwningBooleanOrString::SetAsBoolean()
327 : {
328 0 : if (mType == eBoolean) {
329 0 : return mValue.mBoolean.Value();
330 : }
331 0 : Uninit();
332 0 : mType = eBoolean;
333 0 : return mValue.mBoolean.SetValue();
334 : }
335 :
336 : bool
337 0 : OwningBooleanOrString::TrySetToBoolean(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
338 : {
339 0 : tryNext = false;
340 : { // scope for memberSlot
341 0 : bool& memberSlot = RawSetAsBoolean();
342 0 : if (!ValueToPrimitive<bool, eDefault>(cx, value, &memberSlot)) {
343 0 : return false;
344 : }
345 : }
346 0 : return true;
347 : }
348 :
349 : void
350 0 : OwningBooleanOrString::DestroyBoolean()
351 : {
352 0 : MOZ_ASSERT(IsBoolean(), "Wrong type!");
353 0 : mValue.mBoolean.Destroy();
354 0 : mType = eUninitialized;
355 0 : }
356 :
357 :
358 :
359 :
360 : nsString&
361 0 : OwningBooleanOrString::RawSetAsString()
362 : {
363 0 : if (mType == eString) {
364 0 : return mValue.mString.Value();
365 : }
366 0 : MOZ_ASSERT(mType == eUninitialized);
367 0 : mType = eString;
368 0 : return mValue.mString.SetValue();
369 : }
370 :
371 : nsString&
372 0 : OwningBooleanOrString::SetAsString()
373 : {
374 0 : if (mType == eString) {
375 0 : return mValue.mString.Value();
376 : }
377 0 : Uninit();
378 0 : mType = eString;
379 0 : return mValue.mString.SetValue();
380 : }
381 :
382 : bool
383 0 : OwningBooleanOrString::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
384 : {
385 0 : tryNext = false;
386 : { // scope for memberSlot
387 0 : nsString& memberSlot = RawSetAsString();
388 0 : if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
389 0 : return false;
390 : }
391 : }
392 0 : return true;
393 : }
394 :
395 :
396 : void
397 0 : OwningBooleanOrString::DestroyString()
398 : {
399 0 : MOZ_ASSERT(IsString(), "Wrong type!");
400 0 : mValue.mString.Destroy();
401 0 : mType = eUninitialized;
402 0 : }
403 :
404 :
405 :
406 :
407 : void
408 0 : OwningBooleanOrString::Uninit()
409 : {
410 0 : switch (mType) {
411 : case eUninitialized: {
412 0 : break;
413 : }
414 : case eBoolean: {
415 0 : DestroyBoolean();
416 0 : break;
417 : }
418 : case eString: {
419 0 : DestroyString();
420 0 : break;
421 : }
422 : }
423 0 : }
424 :
425 : bool
426 0 : OwningBooleanOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
427 : {
428 0 : switch (mType) {
429 : case eUninitialized: {
430 0 : return false;
431 : break;
432 : }
433 : case eBoolean: {
434 0 : rval.setBoolean(mValue.mBoolean.Value());
435 0 : return true;
436 : break;
437 : }
438 : case eString: {
439 0 : if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
440 0 : return false;
441 : }
442 0 : return true;
443 : break;
444 : }
445 : default: {
446 0 : return false;
447 : break;
448 : }
449 : }
450 :
451 : return false;
452 : }
453 :
454 : void
455 0 : OwningBooleanOrString::TraceUnion(JSTracer* trc)
456 : {
457 0 : }
458 :
459 : OwningBooleanOrString&
460 0 : OwningBooleanOrString::operator=(const OwningBooleanOrString& aOther)
461 : {
462 0 : switch (aOther.mType) {
463 : case eUninitialized: {
464 0 : MOZ_ASSERT(mType == eUninitialized,
465 : "We need to destroy ourselves?");
466 0 : break;
467 : }
468 : case eBoolean: {
469 0 : SetAsBoolean() = aOther.GetAsBoolean();
470 0 : break;
471 : }
472 : case eString: {
473 0 : SetAsString() = aOther.GetAsString();
474 0 : break;
475 : }
476 : }
477 0 : return *this;
478 : }
479 :
480 :
481 :
482 0 : CollectedClientData::CollectedClientData()
483 : {
484 : // Safe to pass a null context if we pass a null value
485 0 : Init(nullptr, JS::NullHandleValue);
486 0 : }
487 :
488 :
489 :
490 : bool
491 0 : CollectedClientData::InitIds(JSContext* cx, CollectedClientDataAtoms* atomsCache)
492 : {
493 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
494 :
495 : // Initialize these in reverse order so that any failure leaves the first one
496 : // uninitialized.
497 0 : if (!atomsCache->tokenBinding_id.init(cx, "tokenBinding") ||
498 0 : !atomsCache->origin_id.init(cx, "origin") ||
499 0 : !atomsCache->hashAlg_id.init(cx, "hashAlg") ||
500 0 : !atomsCache->challenge_id.init(cx, "challenge")) {
501 0 : return false;
502 : }
503 0 : return true;
504 : }
505 :
506 : bool
507 0 : CollectedClientData::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
508 : {
509 : // Passing a null JSContext is OK only if we're initing from null,
510 : // Since in that case we will not have to do any property gets
511 : // Also evaluate isNullOrUndefined in order to avoid false-positive
512 : // checkers by static analysis tools
513 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
514 0 : CollectedClientDataAtoms* atomsCache = nullptr;
515 0 : if (cx) {
516 0 : atomsCache = GetAtomCache<CollectedClientDataAtoms>(cx);
517 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
518 0 : return false;
519 : }
520 : }
521 :
522 0 : if (!IsConvertibleToDictionary(val)) {
523 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
524 : }
525 :
526 0 : bool isNull = val.isNullOrUndefined();
527 : // We only need these if !isNull, in which case we have |cx|.
528 0 : Maybe<JS::Rooted<JSObject *> > object;
529 0 : Maybe<JS::Rooted<JS::Value> > temp;
530 0 : if (!isNull) {
531 0 : MOZ_ASSERT(cx);
532 0 : object.emplace(cx, &val.toObject());
533 0 : temp.emplace(cx);
534 : }
535 0 : if (!isNull) {
536 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->challenge_id, temp.ptr())) {
537 0 : return false;
538 : }
539 : }
540 0 : if (!isNull && !temp->isUndefined()) {
541 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mChallenge)) {
542 0 : return false;
543 : }
544 0 : mIsAnyMemberPresent = true;
545 0 : } else if (cx) {
546 : // Don't error out if we have no cx. In that
547 : // situation the caller is default-constructing us and we'll
548 : // just assume they know what they're doing.
549 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
550 0 : "'challenge' member of CollectedClientData");
551 : }
552 :
553 0 : if (!isNull) {
554 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->hashAlg_id, temp.ptr())) {
555 0 : return false;
556 : }
557 : }
558 0 : if (!isNull && !temp->isUndefined()) {
559 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mHashAlg)) {
560 0 : return false;
561 : }
562 0 : mIsAnyMemberPresent = true;
563 0 : } else if (cx) {
564 : // Don't error out if we have no cx. In that
565 : // situation the caller is default-constructing us and we'll
566 : // just assume they know what they're doing.
567 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
568 0 : "'hashAlg' member of CollectedClientData");
569 : }
570 :
571 0 : if (!isNull) {
572 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->origin_id, temp.ptr())) {
573 0 : return false;
574 : }
575 : }
576 0 : if (!isNull && !temp->isUndefined()) {
577 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mOrigin)) {
578 0 : return false;
579 : }
580 0 : mIsAnyMemberPresent = true;
581 0 : } else if (cx) {
582 : // Don't error out if we have no cx. In that
583 : // situation the caller is default-constructing us and we'll
584 : // just assume they know what they're doing.
585 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
586 0 : "'origin' member of CollectedClientData");
587 : }
588 :
589 0 : if (!isNull) {
590 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->tokenBinding_id, temp.ptr())) {
591 0 : return false;
592 : }
593 : }
594 0 : if (!isNull && !temp->isUndefined()) {
595 0 : mTokenBinding.Construct();
596 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mTokenBinding.Value()))) {
597 0 : return false;
598 : }
599 0 : mIsAnyMemberPresent = true;
600 : }
601 0 : return true;
602 : }
603 :
604 : bool
605 0 : CollectedClientData::Init(const nsAString& aJSON)
606 : {
607 0 : AutoJSAPI jsapi;
608 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
609 0 : if (!cleanGlobal) {
610 0 : return false;
611 : }
612 0 : if (!jsapi.Init(cleanGlobal)) {
613 0 : return false;
614 : }
615 0 : JSContext* cx = jsapi.cx();
616 0 : JS::Rooted<JS::Value> json(cx);
617 0 : bool ok = ParseJSON(cx, aJSON, &json);
618 0 : NS_ENSURE_TRUE(ok, false);
619 0 : return Init(cx, json);
620 : }
621 :
622 : bool
623 0 : CollectedClientData::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
624 : {
625 0 : CollectedClientDataAtoms* atomsCache = GetAtomCache<CollectedClientDataAtoms>(cx);
626 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
627 0 : return false;
628 : }
629 :
630 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
631 0 : if (!obj) {
632 0 : return false;
633 : }
634 0 : rval.set(JS::ObjectValue(*obj));
635 :
636 : do {
637 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
638 0 : JS::Rooted<JS::Value> temp(cx);
639 0 : nsString const & currentValue = mChallenge;
640 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
641 0 : return false;
642 : }
643 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->challenge_id, temp, JSPROP_ENUMERATE)) {
644 0 : return false;
645 : }
646 0 : break;
647 : } while(0);
648 :
649 : do {
650 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
651 0 : JS::Rooted<JS::Value> temp(cx);
652 0 : nsString const & currentValue = mHashAlg;
653 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
654 0 : return false;
655 : }
656 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->hashAlg_id, temp, JSPROP_ENUMERATE)) {
657 0 : return false;
658 : }
659 0 : break;
660 : } while(0);
661 :
662 : do {
663 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
664 0 : JS::Rooted<JS::Value> temp(cx);
665 0 : nsString const & currentValue = mOrigin;
666 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
667 0 : return false;
668 : }
669 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->origin_id, temp, JSPROP_ENUMERATE)) {
670 0 : return false;
671 : }
672 0 : break;
673 : } while(0);
674 :
675 0 : if (mTokenBinding.WasPassed()) {
676 : do {
677 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
678 0 : JS::Rooted<JS::Value> temp(cx);
679 0 : nsString const & currentValue = mTokenBinding.InternalValue();
680 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
681 0 : return false;
682 : }
683 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->tokenBinding_id, temp, JSPROP_ENUMERATE)) {
684 0 : return false;
685 : }
686 0 : break;
687 : } while(0);
688 : }
689 :
690 0 : return true;
691 : }
692 :
693 : bool
694 0 : CollectedClientData::ToJSON(nsAString& aJSON) const
695 : {
696 0 : AutoJSAPI jsapi;
697 0 : jsapi.Init();
698 0 : JSContext *cx = jsapi.cx();
699 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
700 : // because we'll only be creating objects, in ways that have no
701 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
702 : // which likewise guarantees no side-effects for the sorts of
703 : // things we will pass it.
704 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
705 0 : JS::Rooted<JS::Value> val(cx);
706 0 : if (!ToObjectInternal(cx, &val)) {
707 0 : return false;
708 : }
709 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
710 0 : return StringifyToJSON(cx, obj, aJSON);
711 : }
712 :
713 : void
714 0 : CollectedClientData::TraceDictionary(JSTracer* trc)
715 : {
716 0 : }
717 :
718 : CollectedClientData&
719 0 : CollectedClientData::operator=(const CollectedClientData& aOther)
720 : {
721 0 : mChallenge = aOther.mChallenge;
722 0 : mHashAlg = aOther.mHashAlg;
723 0 : mOrigin = aOther.mOrigin;
724 0 : mTokenBinding.Reset();
725 0 : if (aOther.mTokenBinding.WasPassed()) {
726 0 : mTokenBinding.Construct(aOther.mTokenBinding.Value());
727 : }
728 0 : return *this;
729 : }
730 :
731 : namespace binding_detail {
732 : } // namespace binding_detail
733 :
734 :
735 :
736 0 : PublicKeyCredentialDescriptor::PublicKeyCredentialDescriptor()
737 : {
738 : // Safe to pass a null context if we pass a null value
739 0 : Init(nullptr, JS::NullHandleValue);
740 0 : }
741 :
742 :
743 : bool
744 0 : PublicKeyCredentialDescriptor::InitIds(JSContext* cx, PublicKeyCredentialDescriptorAtoms* atomsCache)
745 : {
746 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
747 :
748 : // Initialize these in reverse order so that any failure leaves the first one
749 : // uninitialized.
750 0 : if (!atomsCache->type_id.init(cx, "type") ||
751 0 : !atomsCache->transports_id.init(cx, "transports") ||
752 0 : !atomsCache->id_id.init(cx, "id")) {
753 0 : return false;
754 : }
755 0 : return true;
756 : }
757 :
758 : bool
759 0 : PublicKeyCredentialDescriptor::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
760 : {
761 : // Passing a null JSContext is OK only if we're initing from null,
762 : // Since in that case we will not have to do any property gets
763 : // Also evaluate isNullOrUndefined in order to avoid false-positive
764 : // checkers by static analysis tools
765 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
766 0 : PublicKeyCredentialDescriptorAtoms* atomsCache = nullptr;
767 0 : if (cx) {
768 0 : atomsCache = GetAtomCache<PublicKeyCredentialDescriptorAtoms>(cx);
769 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
770 0 : return false;
771 : }
772 : }
773 :
774 0 : if (!IsConvertibleToDictionary(val)) {
775 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
776 : }
777 :
778 0 : bool isNull = val.isNullOrUndefined();
779 : // We only need these if !isNull, in which case we have |cx|.
780 0 : Maybe<JS::Rooted<JSObject *> > object;
781 0 : Maybe<JS::Rooted<JS::Value> > temp;
782 0 : if (!isNull) {
783 0 : MOZ_ASSERT(cx);
784 0 : object.emplace(cx, &val.toObject());
785 0 : temp.emplace(cx);
786 : }
787 0 : if (!isNull) {
788 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->id_id, temp.ptr())) {
789 0 : return false;
790 : }
791 : }
792 0 : if (!isNull && !temp->isUndefined()) {
793 : {
794 0 : bool done = false, failed = false, tryNext;
795 0 : if (temp.ref().isObject()) {
796 0 : done = (failed = !mId.TrySetToArrayBufferView(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext ||
797 0 : (failed = !mId.TrySetToArrayBuffer(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext;
798 :
799 : }
800 0 : if (failed) {
801 0 : return false;
802 : }
803 0 : if (!done) {
804 0 : ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'id' member of PublicKeyCredentialDescriptor", "ArrayBufferView, ArrayBuffer");
805 0 : return false;
806 : }
807 : }
808 0 : mIsAnyMemberPresent = true;
809 0 : } else if (cx) {
810 : // Don't error out if we have no cx. In that
811 : // situation the caller is default-constructing us and we'll
812 : // just assume they know what they're doing.
813 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
814 0 : "'id' member of PublicKeyCredentialDescriptor");
815 : }
816 :
817 0 : if (!isNull) {
818 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->transports_id, temp.ptr())) {
819 0 : return false;
820 : }
821 : }
822 0 : if (!isNull && !temp->isUndefined()) {
823 0 : mTransports.Construct();
824 0 : if (temp.ref().isObject()) {
825 0 : JS::ForOfIterator iter(cx);
826 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
827 0 : return false;
828 : }
829 0 : if (!iter.valueIsIterable()) {
830 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'transports' member of PublicKeyCredentialDescriptor");
831 0 : return false;
832 : }
833 0 : Sequence<WebAuthnTransport> &arr = (mTransports.Value());
834 0 : JS::Rooted<JS::Value> temp(cx);
835 : while (true) {
836 : bool done;
837 0 : if (!iter.next(&temp, &done)) {
838 0 : return false;
839 : }
840 0 : if (done) {
841 0 : break;
842 : }
843 0 : WebAuthnTransport* slotPtr = arr.AppendElement(mozilla::fallible);
844 0 : if (!slotPtr) {
845 0 : JS_ReportOutOfMemory(cx);
846 0 : return false;
847 : }
848 0 : WebAuthnTransport& slot = *slotPtr;
849 : {
850 : int index;
851 0 : if (!FindEnumStringIndex<true>(cx, temp, WebAuthnTransportValues::strings, "WebAuthnTransport", "Element of 'transports' member of PublicKeyCredentialDescriptor", &index)) {
852 0 : return false;
853 : }
854 0 : MOZ_ASSERT(index >= 0);
855 0 : slot = static_cast<WebAuthnTransport>(index);
856 : }
857 0 : }
858 : } else {
859 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'transports' member of PublicKeyCredentialDescriptor");
860 0 : return false;
861 : }
862 0 : mIsAnyMemberPresent = true;
863 : }
864 :
865 0 : if (!isNull) {
866 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->type_id, temp.ptr())) {
867 0 : return false;
868 : }
869 : }
870 0 : if (!isNull && !temp->isUndefined()) {
871 : {
872 : int index;
873 0 : if (!FindEnumStringIndex<true>(cx, temp.ref(), PublicKeyCredentialTypeValues::strings, "PublicKeyCredentialType", "'type' member of PublicKeyCredentialDescriptor", &index)) {
874 0 : return false;
875 : }
876 0 : MOZ_ASSERT(index >= 0);
877 0 : mType = static_cast<PublicKeyCredentialType>(index);
878 : }
879 0 : mIsAnyMemberPresent = true;
880 0 : } else if (cx) {
881 : // Don't error out if we have no cx. In that
882 : // situation the caller is default-constructing us and we'll
883 : // just assume they know what they're doing.
884 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
885 0 : "'type' member of PublicKeyCredentialDescriptor");
886 : }
887 0 : return true;
888 : }
889 :
890 : bool
891 0 : PublicKeyCredentialDescriptor::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
892 : {
893 0 : PublicKeyCredentialDescriptorAtoms* atomsCache = GetAtomCache<PublicKeyCredentialDescriptorAtoms>(cx);
894 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
895 0 : return false;
896 : }
897 :
898 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
899 0 : if (!obj) {
900 0 : return false;
901 : }
902 0 : rval.set(JS::ObjectValue(*obj));
903 :
904 : do {
905 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
906 0 : JS::Rooted<JS::Value> temp(cx);
907 0 : OwningArrayBufferViewOrArrayBuffer const & currentValue = mId;
908 0 : if (!currentValue.ToJSVal(cx, obj, &temp)) {
909 0 : return false;
910 : }
911 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->id_id, temp, JSPROP_ENUMERATE)) {
912 0 : return false;
913 : }
914 0 : break;
915 : } while(0);
916 :
917 0 : if (mTransports.WasPassed()) {
918 : do {
919 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
920 0 : JS::Rooted<JS::Value> temp(cx);
921 0 : Sequence<WebAuthnTransport> const & currentValue = mTransports.InternalValue();
922 :
923 0 : uint32_t length = currentValue.Length();
924 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
925 0 : if (!returnArray) {
926 0 : return false;
927 : }
928 : // Scope for 'tmp'
929 : {
930 0 : JS::Rooted<JS::Value> tmp(cx);
931 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
932 : // Control block to let us common up the JS_DefineElement calls when there
933 : // are different ways to succeed at wrapping the object.
934 : do {
935 0 : if (!ToJSValue(cx, currentValue[sequenceIdx0], &tmp)) {
936 0 : return false;
937 : }
938 0 : break;
939 : } while (0);
940 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
941 : JSPROP_ENUMERATE)) {
942 0 : return false;
943 : }
944 : }
945 : }
946 0 : temp.setObject(*returnArray);
947 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->transports_id, temp, JSPROP_ENUMERATE)) {
948 0 : return false;
949 : }
950 0 : break;
951 : } while(0);
952 : }
953 :
954 : do {
955 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
956 0 : JS::Rooted<JS::Value> temp(cx);
957 0 : PublicKeyCredentialType const & currentValue = mType;
958 0 : if (!ToJSValue(cx, currentValue, &temp)) {
959 0 : return false;
960 : }
961 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->type_id, temp, JSPROP_ENUMERATE)) {
962 0 : return false;
963 : }
964 0 : break;
965 : } while(0);
966 :
967 0 : return true;
968 : }
969 :
970 : void
971 0 : PublicKeyCredentialDescriptor::TraceDictionary(JSTracer* trc)
972 : {
973 0 : mId.TraceUnion(trc);
974 0 : }
975 :
976 : namespace binding_detail {
977 : } // namespace binding_detail
978 :
979 :
980 :
981 0 : PublicKeyCredentialEntity::PublicKeyCredentialEntity()
982 : {
983 : // Safe to pass a null context if we pass a null value
984 0 : Init(nullptr, JS::NullHandleValue);
985 0 : }
986 :
987 :
988 :
989 : bool
990 0 : PublicKeyCredentialEntity::InitIds(JSContext* cx, PublicKeyCredentialEntityAtoms* atomsCache)
991 : {
992 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
993 :
994 : // Initialize these in reverse order so that any failure leaves the first one
995 : // uninitialized.
996 0 : if (!atomsCache->name_id.init(cx, "name") ||
997 0 : !atomsCache->id_id.init(cx, "id") ||
998 0 : !atomsCache->icon_id.init(cx, "icon")) {
999 0 : return false;
1000 : }
1001 0 : return true;
1002 : }
1003 :
1004 : bool
1005 0 : PublicKeyCredentialEntity::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1006 : {
1007 : // Passing a null JSContext is OK only if we're initing from null,
1008 : // Since in that case we will not have to do any property gets
1009 : // Also evaluate isNullOrUndefined in order to avoid false-positive
1010 : // checkers by static analysis tools
1011 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1012 0 : PublicKeyCredentialEntityAtoms* atomsCache = nullptr;
1013 0 : if (cx) {
1014 0 : atomsCache = GetAtomCache<PublicKeyCredentialEntityAtoms>(cx);
1015 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1016 0 : return false;
1017 : }
1018 : }
1019 :
1020 0 : if (!IsConvertibleToDictionary(val)) {
1021 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
1022 : }
1023 :
1024 0 : bool isNull = val.isNullOrUndefined();
1025 : // We only need these if !isNull, in which case we have |cx|.
1026 0 : Maybe<JS::Rooted<JSObject *> > object;
1027 0 : Maybe<JS::Rooted<JS::Value> > temp;
1028 0 : if (!isNull) {
1029 0 : MOZ_ASSERT(cx);
1030 0 : object.emplace(cx, &val.toObject());
1031 0 : temp.emplace(cx);
1032 : }
1033 0 : if (!isNull) {
1034 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->icon_id, temp.ptr())) {
1035 0 : return false;
1036 : }
1037 : }
1038 0 : if (!isNull && !temp->isUndefined()) {
1039 0 : mIcon.Construct();
1040 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mIcon.Value()))) {
1041 0 : return false;
1042 : }
1043 0 : NormalizeUSVString((mIcon.Value()));
1044 0 : mIsAnyMemberPresent = true;
1045 : }
1046 :
1047 0 : if (!isNull) {
1048 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->id_id, temp.ptr())) {
1049 0 : return false;
1050 : }
1051 : }
1052 0 : if (!isNull && !temp->isUndefined()) {
1053 0 : mId.Construct();
1054 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mId.Value()))) {
1055 0 : return false;
1056 : }
1057 0 : mIsAnyMemberPresent = true;
1058 : }
1059 :
1060 0 : if (!isNull) {
1061 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->name_id, temp.ptr())) {
1062 0 : return false;
1063 : }
1064 : }
1065 0 : if (!isNull && !temp->isUndefined()) {
1066 0 : mName.Construct();
1067 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mName.Value()))) {
1068 0 : return false;
1069 : }
1070 0 : mIsAnyMemberPresent = true;
1071 : }
1072 0 : return true;
1073 : }
1074 :
1075 : bool
1076 0 : PublicKeyCredentialEntity::Init(const nsAString& aJSON)
1077 : {
1078 0 : AutoJSAPI jsapi;
1079 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
1080 0 : if (!cleanGlobal) {
1081 0 : return false;
1082 : }
1083 0 : if (!jsapi.Init(cleanGlobal)) {
1084 0 : return false;
1085 : }
1086 0 : JSContext* cx = jsapi.cx();
1087 0 : JS::Rooted<JS::Value> json(cx);
1088 0 : bool ok = ParseJSON(cx, aJSON, &json);
1089 0 : NS_ENSURE_TRUE(ok, false);
1090 0 : return Init(cx, json);
1091 : }
1092 :
1093 : bool
1094 0 : PublicKeyCredentialEntity::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1095 : {
1096 0 : PublicKeyCredentialEntityAtoms* atomsCache = GetAtomCache<PublicKeyCredentialEntityAtoms>(cx);
1097 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1098 0 : return false;
1099 : }
1100 :
1101 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
1102 0 : if (!obj) {
1103 0 : return false;
1104 : }
1105 0 : rval.set(JS::ObjectValue(*obj));
1106 :
1107 0 : if (mIcon.WasPassed()) {
1108 : do {
1109 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1110 0 : JS::Rooted<JS::Value> temp(cx);
1111 0 : nsString const & currentValue = mIcon.InternalValue();
1112 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1113 0 : return false;
1114 : }
1115 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->icon_id, temp, JSPROP_ENUMERATE)) {
1116 0 : return false;
1117 : }
1118 0 : break;
1119 : } while(0);
1120 : }
1121 :
1122 0 : if (mId.WasPassed()) {
1123 : do {
1124 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1125 0 : JS::Rooted<JS::Value> temp(cx);
1126 0 : nsString const & currentValue = mId.InternalValue();
1127 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1128 0 : return false;
1129 : }
1130 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->id_id, temp, JSPROP_ENUMERATE)) {
1131 0 : return false;
1132 : }
1133 0 : break;
1134 : } while(0);
1135 : }
1136 :
1137 0 : if (mName.WasPassed()) {
1138 : do {
1139 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1140 0 : JS::Rooted<JS::Value> temp(cx);
1141 0 : nsString const & currentValue = mName.InternalValue();
1142 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1143 0 : return false;
1144 : }
1145 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->name_id, temp, JSPROP_ENUMERATE)) {
1146 0 : return false;
1147 : }
1148 0 : break;
1149 : } while(0);
1150 : }
1151 :
1152 0 : return true;
1153 : }
1154 :
1155 : bool
1156 0 : PublicKeyCredentialEntity::ToJSON(nsAString& aJSON) const
1157 : {
1158 0 : AutoJSAPI jsapi;
1159 0 : jsapi.Init();
1160 0 : JSContext *cx = jsapi.cx();
1161 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
1162 : // because we'll only be creating objects, in ways that have no
1163 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
1164 : // which likewise guarantees no side-effects for the sorts of
1165 : // things we will pass it.
1166 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
1167 0 : JS::Rooted<JS::Value> val(cx);
1168 0 : if (!ToObjectInternal(cx, &val)) {
1169 0 : return false;
1170 : }
1171 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
1172 0 : return StringifyToJSON(cx, obj, aJSON);
1173 : }
1174 :
1175 : void
1176 0 : PublicKeyCredentialEntity::TraceDictionary(JSTracer* trc)
1177 : {
1178 0 : }
1179 :
1180 : PublicKeyCredentialEntity&
1181 0 : PublicKeyCredentialEntity::operator=(const PublicKeyCredentialEntity& aOther)
1182 : {
1183 0 : mIcon.Reset();
1184 0 : if (aOther.mIcon.WasPassed()) {
1185 0 : mIcon.Construct(aOther.mIcon.Value());
1186 : }
1187 0 : mId.Reset();
1188 0 : if (aOther.mId.WasPassed()) {
1189 0 : mId.Construct(aOther.mId.Value());
1190 : }
1191 0 : mName.Reset();
1192 0 : if (aOther.mName.WasPassed()) {
1193 0 : mName.Construct(aOther.mName.Value());
1194 : }
1195 0 : return *this;
1196 : }
1197 :
1198 : namespace binding_detail {
1199 : } // namespace binding_detail
1200 :
1201 :
1202 :
1203 0 : PublicKeyCredentialParameters::PublicKeyCredentialParameters()
1204 : {
1205 : // Safe to pass a null context if we pass a null value
1206 0 : Init(nullptr, JS::NullHandleValue);
1207 0 : }
1208 :
1209 :
1210 :
1211 : bool
1212 0 : PublicKeyCredentialParameters::InitIds(JSContext* cx, PublicKeyCredentialParametersAtoms* atomsCache)
1213 : {
1214 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1215 :
1216 : // Initialize these in reverse order so that any failure leaves the first one
1217 : // uninitialized.
1218 0 : if (!atomsCache->type_id.init(cx, "type") ||
1219 0 : !atomsCache->algorithm_id.init(cx, "algorithm")) {
1220 0 : return false;
1221 : }
1222 0 : return true;
1223 : }
1224 :
1225 : bool
1226 0 : PublicKeyCredentialParameters::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1227 : {
1228 : // Passing a null JSContext is OK only if we're initing from null,
1229 : // Since in that case we will not have to do any property gets
1230 : // Also evaluate isNullOrUndefined in order to avoid false-positive
1231 : // checkers by static analysis tools
1232 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1233 0 : PublicKeyCredentialParametersAtoms* atomsCache = nullptr;
1234 0 : if (cx) {
1235 0 : atomsCache = GetAtomCache<PublicKeyCredentialParametersAtoms>(cx);
1236 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1237 0 : return false;
1238 : }
1239 : }
1240 :
1241 0 : if (!IsConvertibleToDictionary(val)) {
1242 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
1243 : }
1244 :
1245 0 : bool isNull = val.isNullOrUndefined();
1246 : // We only need these if !isNull, in which case we have |cx|.
1247 0 : Maybe<JS::Rooted<JSObject *> > object;
1248 0 : Maybe<JS::Rooted<JS::Value> > temp;
1249 0 : if (!isNull) {
1250 0 : MOZ_ASSERT(cx);
1251 0 : object.emplace(cx, &val.toObject());
1252 0 : temp.emplace(cx);
1253 : }
1254 0 : if (!isNull) {
1255 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->algorithm_id, temp.ptr())) {
1256 0 : return false;
1257 : }
1258 : }
1259 0 : if (!isNull && !temp->isUndefined()) {
1260 : {
1261 0 : bool done = false, failed = false, tryNext;
1262 : do {
1263 0 : if (temp.ref().isBoolean()) {
1264 0 : done = (failed = !mAlgorithm.TrySetToBoolean(cx, temp.ref(), tryNext)) || !tryNext;
1265 0 : break;
1266 : }
1267 0 : done = (failed = !mAlgorithm.TrySetToString(cx, temp.ref(), tryNext)) || !tryNext;
1268 0 : break;
1269 : } while (0);
1270 0 : if (failed) {
1271 0 : return false;
1272 : }
1273 0 : if (!done) {
1274 0 : ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'algorithm' member of PublicKeyCredentialParameters", "");
1275 0 : return false;
1276 : }
1277 : }
1278 0 : mIsAnyMemberPresent = true;
1279 0 : } else if (cx) {
1280 : // Don't error out if we have no cx. In that
1281 : // situation the caller is default-constructing us and we'll
1282 : // just assume they know what they're doing.
1283 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
1284 0 : "'algorithm' member of PublicKeyCredentialParameters");
1285 : }
1286 :
1287 0 : if (!isNull) {
1288 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->type_id, temp.ptr())) {
1289 0 : return false;
1290 : }
1291 : }
1292 0 : if (!isNull && !temp->isUndefined()) {
1293 : {
1294 : int index;
1295 0 : if (!FindEnumStringIndex<true>(cx, temp.ref(), PublicKeyCredentialTypeValues::strings, "PublicKeyCredentialType", "'type' member of PublicKeyCredentialParameters", &index)) {
1296 0 : return false;
1297 : }
1298 0 : MOZ_ASSERT(index >= 0);
1299 0 : mType = static_cast<PublicKeyCredentialType>(index);
1300 : }
1301 0 : mIsAnyMemberPresent = true;
1302 0 : } else if (cx) {
1303 : // Don't error out if we have no cx. In that
1304 : // situation the caller is default-constructing us and we'll
1305 : // just assume they know what they're doing.
1306 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
1307 0 : "'type' member of PublicKeyCredentialParameters");
1308 : }
1309 0 : return true;
1310 : }
1311 :
1312 : bool
1313 0 : PublicKeyCredentialParameters::Init(const nsAString& aJSON)
1314 : {
1315 0 : AutoJSAPI jsapi;
1316 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
1317 0 : if (!cleanGlobal) {
1318 0 : return false;
1319 : }
1320 0 : if (!jsapi.Init(cleanGlobal)) {
1321 0 : return false;
1322 : }
1323 0 : JSContext* cx = jsapi.cx();
1324 0 : JS::Rooted<JS::Value> json(cx);
1325 0 : bool ok = ParseJSON(cx, aJSON, &json);
1326 0 : NS_ENSURE_TRUE(ok, false);
1327 0 : return Init(cx, json);
1328 : }
1329 :
1330 : bool
1331 0 : PublicKeyCredentialParameters::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1332 : {
1333 0 : PublicKeyCredentialParametersAtoms* atomsCache = GetAtomCache<PublicKeyCredentialParametersAtoms>(cx);
1334 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1335 0 : return false;
1336 : }
1337 :
1338 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
1339 0 : if (!obj) {
1340 0 : return false;
1341 : }
1342 0 : rval.set(JS::ObjectValue(*obj));
1343 :
1344 : do {
1345 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1346 0 : JS::Rooted<JS::Value> temp(cx);
1347 0 : OwningBooleanOrString const & currentValue = mAlgorithm;
1348 0 : if (!currentValue.ToJSVal(cx, obj, &temp)) {
1349 0 : return false;
1350 : }
1351 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->algorithm_id, temp, JSPROP_ENUMERATE)) {
1352 0 : return false;
1353 : }
1354 0 : break;
1355 : } while(0);
1356 :
1357 : do {
1358 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1359 0 : JS::Rooted<JS::Value> temp(cx);
1360 0 : PublicKeyCredentialType const & currentValue = mType;
1361 0 : if (!ToJSValue(cx, currentValue, &temp)) {
1362 0 : return false;
1363 : }
1364 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->type_id, temp, JSPROP_ENUMERATE)) {
1365 0 : return false;
1366 : }
1367 0 : break;
1368 : } while(0);
1369 :
1370 0 : return true;
1371 : }
1372 :
1373 : bool
1374 0 : PublicKeyCredentialParameters::ToJSON(nsAString& aJSON) const
1375 : {
1376 0 : AutoJSAPI jsapi;
1377 0 : jsapi.Init();
1378 0 : JSContext *cx = jsapi.cx();
1379 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
1380 : // because we'll only be creating objects, in ways that have no
1381 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
1382 : // which likewise guarantees no side-effects for the sorts of
1383 : // things we will pass it.
1384 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
1385 0 : JS::Rooted<JS::Value> val(cx);
1386 0 : if (!ToObjectInternal(cx, &val)) {
1387 0 : return false;
1388 : }
1389 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
1390 0 : return StringifyToJSON(cx, obj, aJSON);
1391 : }
1392 :
1393 : void
1394 0 : PublicKeyCredentialParameters::TraceDictionary(JSTracer* trc)
1395 : {
1396 0 : }
1397 :
1398 : PublicKeyCredentialParameters&
1399 0 : PublicKeyCredentialParameters::operator=(const PublicKeyCredentialParameters& aOther)
1400 : {
1401 0 : mAlgorithm = aOther.mAlgorithm;
1402 0 : mType = aOther.mType;
1403 0 : return *this;
1404 : }
1405 :
1406 : namespace binding_detail {
1407 : } // namespace binding_detail
1408 :
1409 :
1410 :
1411 0 : PublicKeyCredentialRequestOptions::PublicKeyCredentialRequestOptions()
1412 : {
1413 : // Safe to pass a null context if we pass a null value
1414 0 : Init(nullptr, JS::NullHandleValue);
1415 0 : }
1416 :
1417 :
1418 : bool
1419 0 : PublicKeyCredentialRequestOptions::InitIds(JSContext* cx, PublicKeyCredentialRequestOptionsAtoms* atomsCache)
1420 : {
1421 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1422 :
1423 : // Initialize these in reverse order so that any failure leaves the first one
1424 : // uninitialized.
1425 0 : if (!atomsCache->timeout_id.init(cx, "timeout") ||
1426 0 : !atomsCache->rpId_id.init(cx, "rpId") ||
1427 0 : !atomsCache->challenge_id.init(cx, "challenge") ||
1428 0 : !atomsCache->allowList_id.init(cx, "allowList")) {
1429 0 : return false;
1430 : }
1431 0 : return true;
1432 : }
1433 :
1434 : bool
1435 0 : PublicKeyCredentialRequestOptions::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1436 : {
1437 : // Passing a null JSContext is OK only if we're initing from null,
1438 : // Since in that case we will not have to do any property gets
1439 : // Also evaluate isNullOrUndefined in order to avoid false-positive
1440 : // checkers by static analysis tools
1441 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1442 0 : PublicKeyCredentialRequestOptionsAtoms* atomsCache = nullptr;
1443 0 : if (cx) {
1444 0 : atomsCache = GetAtomCache<PublicKeyCredentialRequestOptionsAtoms>(cx);
1445 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1446 0 : return false;
1447 : }
1448 : }
1449 :
1450 0 : if (!IsConvertibleToDictionary(val)) {
1451 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
1452 : }
1453 :
1454 0 : bool isNull = val.isNullOrUndefined();
1455 : // We only need these if !isNull, in which case we have |cx|.
1456 0 : Maybe<JS::Rooted<JSObject *> > object;
1457 0 : Maybe<JS::Rooted<JS::Value> > temp;
1458 0 : if (!isNull) {
1459 0 : MOZ_ASSERT(cx);
1460 0 : object.emplace(cx, &val.toObject());
1461 0 : temp.emplace(cx);
1462 : }
1463 0 : if (!isNull) {
1464 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->allowList_id, temp.ptr())) {
1465 0 : return false;
1466 : }
1467 : }
1468 0 : if (!isNull && !temp->isUndefined()) {
1469 0 : if (temp.ref().isObject()) {
1470 0 : JS::ForOfIterator iter(cx);
1471 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
1472 0 : return false;
1473 : }
1474 0 : if (!iter.valueIsIterable()) {
1475 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'allowList' member of PublicKeyCredentialRequestOptions");
1476 0 : return false;
1477 : }
1478 0 : Sequence<PublicKeyCredentialDescriptor> &arr = mAllowList;
1479 0 : JS::Rooted<JS::Value> temp(cx);
1480 : while (true) {
1481 : bool done;
1482 0 : if (!iter.next(&temp, &done)) {
1483 0 : return false;
1484 : }
1485 0 : if (done) {
1486 0 : break;
1487 : }
1488 0 : PublicKeyCredentialDescriptor* slotPtr = arr.AppendElement(mozilla::fallible);
1489 0 : if (!slotPtr) {
1490 0 : JS_ReportOutOfMemory(cx);
1491 0 : return false;
1492 : }
1493 0 : PublicKeyCredentialDescriptor& slot = *slotPtr;
1494 0 : if (!slot.Init(cx, temp, "Element of 'allowList' member of PublicKeyCredentialRequestOptions", passedToJSImpl)) {
1495 0 : return false;
1496 : }
1497 0 : }
1498 : } else {
1499 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'allowList' member of PublicKeyCredentialRequestOptions");
1500 0 : return false;
1501 : }
1502 : } else {
1503 : /* Array is already empty; nothing to do */
1504 : }
1505 0 : mIsAnyMemberPresent = true;
1506 :
1507 0 : if (!isNull) {
1508 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->challenge_id, temp.ptr())) {
1509 0 : return false;
1510 : }
1511 : }
1512 0 : if (!isNull && !temp->isUndefined()) {
1513 : {
1514 0 : bool done = false, failed = false, tryNext;
1515 0 : if (temp.ref().isObject()) {
1516 0 : done = (failed = !mChallenge.TrySetToArrayBufferView(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext ||
1517 0 : (failed = !mChallenge.TrySetToArrayBuffer(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext;
1518 :
1519 : }
1520 0 : if (failed) {
1521 0 : return false;
1522 : }
1523 0 : if (!done) {
1524 0 : ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'challenge' member of PublicKeyCredentialRequestOptions", "ArrayBufferView, ArrayBuffer");
1525 0 : return false;
1526 : }
1527 : }
1528 0 : mIsAnyMemberPresent = true;
1529 0 : } else if (cx) {
1530 : // Don't error out if we have no cx. In that
1531 : // situation the caller is default-constructing us and we'll
1532 : // just assume they know what they're doing.
1533 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
1534 0 : "'challenge' member of PublicKeyCredentialRequestOptions");
1535 : }
1536 :
1537 0 : if (!isNull) {
1538 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->rpId_id, temp.ptr())) {
1539 0 : return false;
1540 : }
1541 : }
1542 0 : if (!isNull && !temp->isUndefined()) {
1543 0 : mRpId.Construct();
1544 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mRpId.Value()))) {
1545 0 : return false;
1546 : }
1547 0 : NormalizeUSVString((mRpId.Value()));
1548 0 : mIsAnyMemberPresent = true;
1549 : }
1550 :
1551 0 : if (!isNull) {
1552 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->timeout_id, temp.ptr())) {
1553 0 : return false;
1554 : }
1555 : }
1556 0 : if (!isNull && !temp->isUndefined()) {
1557 0 : mTimeout.Construct();
1558 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mTimeout.Value()))) {
1559 0 : return false;
1560 : }
1561 0 : mIsAnyMemberPresent = true;
1562 : }
1563 0 : return true;
1564 : }
1565 :
1566 : bool
1567 0 : PublicKeyCredentialRequestOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1568 : {
1569 0 : PublicKeyCredentialRequestOptionsAtoms* atomsCache = GetAtomCache<PublicKeyCredentialRequestOptionsAtoms>(cx);
1570 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1571 0 : return false;
1572 : }
1573 :
1574 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
1575 0 : if (!obj) {
1576 0 : return false;
1577 : }
1578 0 : rval.set(JS::ObjectValue(*obj));
1579 :
1580 : do {
1581 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1582 0 : JS::Rooted<JS::Value> temp(cx);
1583 0 : Sequence<PublicKeyCredentialDescriptor> const & currentValue = mAllowList;
1584 :
1585 0 : uint32_t length = currentValue.Length();
1586 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
1587 0 : if (!returnArray) {
1588 0 : return false;
1589 : }
1590 : // Scope for 'tmp'
1591 : {
1592 0 : JS::Rooted<JS::Value> tmp(cx);
1593 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
1594 : // Control block to let us common up the JS_DefineElement calls when there
1595 : // are different ways to succeed at wrapping the object.
1596 : do {
1597 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
1598 0 : return false;
1599 : }
1600 0 : break;
1601 : } while (0);
1602 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
1603 : JSPROP_ENUMERATE)) {
1604 0 : return false;
1605 : }
1606 : }
1607 : }
1608 0 : temp.setObject(*returnArray);
1609 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->allowList_id, temp, JSPROP_ENUMERATE)) {
1610 0 : return false;
1611 : }
1612 0 : break;
1613 : } while(0);
1614 :
1615 : do {
1616 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1617 0 : JS::Rooted<JS::Value> temp(cx);
1618 0 : OwningArrayBufferViewOrArrayBuffer const & currentValue = mChallenge;
1619 0 : if (!currentValue.ToJSVal(cx, obj, &temp)) {
1620 0 : return false;
1621 : }
1622 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->challenge_id, temp, JSPROP_ENUMERATE)) {
1623 0 : return false;
1624 : }
1625 0 : break;
1626 : } while(0);
1627 :
1628 0 : if (mRpId.WasPassed()) {
1629 : do {
1630 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1631 0 : JS::Rooted<JS::Value> temp(cx);
1632 0 : nsString const & currentValue = mRpId.InternalValue();
1633 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1634 0 : return false;
1635 : }
1636 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->rpId_id, temp, JSPROP_ENUMERATE)) {
1637 0 : return false;
1638 : }
1639 0 : break;
1640 : } while(0);
1641 : }
1642 :
1643 0 : if (mTimeout.WasPassed()) {
1644 : do {
1645 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1646 0 : JS::Rooted<JS::Value> temp(cx);
1647 0 : uint32_t const & currentValue = mTimeout.InternalValue();
1648 0 : temp.setNumber(currentValue);
1649 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->timeout_id, temp, JSPROP_ENUMERATE)) {
1650 0 : return false;
1651 : }
1652 0 : break;
1653 : } while(0);
1654 : }
1655 :
1656 0 : return true;
1657 : }
1658 :
1659 : void
1660 0 : PublicKeyCredentialRequestOptions::TraceDictionary(JSTracer* trc)
1661 : {
1662 0 : DoTraceSequence(trc, mAllowList);
1663 :
1664 0 : mChallenge.TraceUnion(trc);
1665 0 : }
1666 :
1667 : namespace binding_detail {
1668 : } // namespace binding_detail
1669 :
1670 :
1671 :
1672 0 : PublicKeyCredentialUserEntity::PublicKeyCredentialUserEntity()
1673 0 : : PublicKeyCredentialEntity(FastDictionaryInitializer())
1674 : {
1675 : // Safe to pass a null context if we pass a null value
1676 0 : Init(nullptr, JS::NullHandleValue);
1677 0 : }
1678 :
1679 :
1680 :
1681 : bool
1682 0 : PublicKeyCredentialUserEntity::InitIds(JSContext* cx, PublicKeyCredentialUserEntityAtoms* atomsCache)
1683 : {
1684 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1685 :
1686 : // Initialize these in reverse order so that any failure leaves the first one
1687 : // uninitialized.
1688 0 : if (!atomsCache->displayName_id.init(cx, "displayName")) {
1689 0 : return false;
1690 : }
1691 0 : return true;
1692 : }
1693 :
1694 : bool
1695 0 : PublicKeyCredentialUserEntity::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1696 : {
1697 : // Passing a null JSContext is OK only if we're initing from null,
1698 : // Since in that case we will not have to do any property gets
1699 : // Also evaluate isNullOrUndefined in order to avoid false-positive
1700 : // checkers by static analysis tools
1701 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1702 0 : PublicKeyCredentialUserEntityAtoms* atomsCache = nullptr;
1703 0 : if (cx) {
1704 0 : atomsCache = GetAtomCache<PublicKeyCredentialUserEntityAtoms>(cx);
1705 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1706 0 : return false;
1707 : }
1708 : }
1709 :
1710 : // Per spec, we init the parent's members first
1711 0 : if (!PublicKeyCredentialEntity::Init(cx, val)) {
1712 0 : return false;
1713 : }
1714 :
1715 0 : bool isNull = val.isNullOrUndefined();
1716 : // We only need these if !isNull, in which case we have |cx|.
1717 0 : Maybe<JS::Rooted<JSObject *> > object;
1718 0 : Maybe<JS::Rooted<JS::Value> > temp;
1719 0 : if (!isNull) {
1720 0 : MOZ_ASSERT(cx);
1721 0 : object.emplace(cx, &val.toObject());
1722 0 : temp.emplace(cx);
1723 : }
1724 0 : if (!isNull) {
1725 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->displayName_id, temp.ptr())) {
1726 0 : return false;
1727 : }
1728 : }
1729 0 : if (!isNull && !temp->isUndefined()) {
1730 0 : mDisplayName.Construct();
1731 0 : if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mDisplayName.Value()))) {
1732 0 : return false;
1733 : }
1734 0 : mIsAnyMemberPresent = true;
1735 : }
1736 0 : return true;
1737 : }
1738 :
1739 : bool
1740 0 : PublicKeyCredentialUserEntity::Init(const nsAString& aJSON)
1741 : {
1742 0 : AutoJSAPI jsapi;
1743 0 : JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
1744 0 : if (!cleanGlobal) {
1745 0 : return false;
1746 : }
1747 0 : if (!jsapi.Init(cleanGlobal)) {
1748 0 : return false;
1749 : }
1750 0 : JSContext* cx = jsapi.cx();
1751 0 : JS::Rooted<JS::Value> json(cx);
1752 0 : bool ok = ParseJSON(cx, aJSON, &json);
1753 0 : NS_ENSURE_TRUE(ok, false);
1754 0 : return Init(cx, json);
1755 : }
1756 :
1757 : bool
1758 0 : PublicKeyCredentialUserEntity::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1759 : {
1760 0 : PublicKeyCredentialUserEntityAtoms* atomsCache = GetAtomCache<PublicKeyCredentialUserEntityAtoms>(cx);
1761 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1762 0 : return false;
1763 : }
1764 :
1765 : // Per spec, we define the parent's members first
1766 0 : if (!PublicKeyCredentialEntity::ToObjectInternal(cx, rval)) {
1767 0 : return false;
1768 : }
1769 0 : JS::Rooted<JSObject*> obj(cx, &rval.toObject());
1770 :
1771 0 : if (mDisplayName.WasPassed()) {
1772 : do {
1773 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1774 0 : JS::Rooted<JS::Value> temp(cx);
1775 0 : nsString const & currentValue = mDisplayName.InternalValue();
1776 0 : if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
1777 0 : return false;
1778 : }
1779 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->displayName_id, temp, JSPROP_ENUMERATE)) {
1780 0 : return false;
1781 : }
1782 0 : break;
1783 : } while(0);
1784 : }
1785 :
1786 0 : return true;
1787 : }
1788 :
1789 : bool
1790 0 : PublicKeyCredentialUserEntity::ToJSON(nsAString& aJSON) const
1791 : {
1792 0 : AutoJSAPI jsapi;
1793 0 : jsapi.Init();
1794 0 : JSContext *cx = jsapi.cx();
1795 : // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
1796 : // because we'll only be creating objects, in ways that have no
1797 : // side-effects, followed by a call to JS::ToJSONMaybeSafely,
1798 : // which likewise guarantees no side-effects for the sorts of
1799 : // things we will pass it.
1800 0 : JSAutoCompartment ac(cx, binding_detail::UnprivilegedJunkScopeOrWorkerGlobal());
1801 0 : JS::Rooted<JS::Value> val(cx);
1802 0 : if (!ToObjectInternal(cx, &val)) {
1803 0 : return false;
1804 : }
1805 0 : JS::Rooted<JSObject*> obj(cx, &val.toObject());
1806 0 : return StringifyToJSON(cx, obj, aJSON);
1807 : }
1808 :
1809 : void
1810 0 : PublicKeyCredentialUserEntity::TraceDictionary(JSTracer* trc)
1811 : {
1812 0 : PublicKeyCredentialEntity::TraceDictionary(trc);
1813 0 : }
1814 :
1815 : PublicKeyCredentialUserEntity&
1816 0 : PublicKeyCredentialUserEntity::operator=(const PublicKeyCredentialUserEntity& aOther)
1817 : {
1818 0 : PublicKeyCredentialEntity::operator=(aOther);
1819 0 : mDisplayName.Reset();
1820 0 : if (aOther.mDisplayName.WasPassed()) {
1821 0 : mDisplayName.Construct(aOther.mDisplayName.Value());
1822 : }
1823 0 : return *this;
1824 : }
1825 :
1826 : namespace binding_detail {
1827 : } // namespace binding_detail
1828 :
1829 :
1830 :
1831 0 : MakeCredentialOptions::MakeCredentialOptions()
1832 0 : : mAuthenticatorSelection(FastDictionaryInitializer()),
1833 0 : mRp(FastDictionaryInitializer()),
1834 0 : mUser(FastDictionaryInitializer())
1835 : {
1836 : // Safe to pass a null context if we pass a null value
1837 0 : Init(nullptr, JS::NullHandleValue);
1838 0 : }
1839 :
1840 :
1841 : bool
1842 0 : MakeCredentialOptions::InitIds(JSContext* cx, MakeCredentialOptionsAtoms* atomsCache)
1843 : {
1844 0 : MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1845 :
1846 : // Initialize these in reverse order so that any failure leaves the first one
1847 : // uninitialized.
1848 0 : if (!atomsCache->user_id.init(cx, "user") ||
1849 0 : !atomsCache->timeout_id.init(cx, "timeout") ||
1850 0 : !atomsCache->rp_id.init(cx, "rp") ||
1851 0 : !atomsCache->parameters_id.init(cx, "parameters") ||
1852 0 : !atomsCache->excludeList_id.init(cx, "excludeList") ||
1853 0 : !atomsCache->challenge_id.init(cx, "challenge") ||
1854 0 : !atomsCache->authenticatorSelection_id.init(cx, "authenticatorSelection")) {
1855 0 : return false;
1856 : }
1857 0 : return true;
1858 : }
1859 :
1860 : bool
1861 0 : MakeCredentialOptions::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1862 : {
1863 : // Passing a null JSContext is OK only if we're initing from null,
1864 : // Since in that case we will not have to do any property gets
1865 : // Also evaluate isNullOrUndefined in order to avoid false-positive
1866 : // checkers by static analysis tools
1867 0 : MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1868 0 : MakeCredentialOptionsAtoms* atomsCache = nullptr;
1869 0 : if (cx) {
1870 0 : atomsCache = GetAtomCache<MakeCredentialOptionsAtoms>(cx);
1871 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1872 0 : return false;
1873 : }
1874 : }
1875 :
1876 0 : if (!IsConvertibleToDictionary(val)) {
1877 0 : return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
1878 : }
1879 :
1880 0 : bool isNull = val.isNullOrUndefined();
1881 : // We only need these if !isNull, in which case we have |cx|.
1882 0 : Maybe<JS::Rooted<JSObject *> > object;
1883 0 : Maybe<JS::Rooted<JS::Value> > temp;
1884 0 : if (!isNull) {
1885 0 : MOZ_ASSERT(cx);
1886 0 : object.emplace(cx, &val.toObject());
1887 0 : temp.emplace(cx);
1888 : }
1889 0 : if (!isNull) {
1890 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->authenticatorSelection_id, temp.ptr())) {
1891 0 : return false;
1892 : }
1893 : }
1894 0 : if (!mAuthenticatorSelection.Init(cx, (!isNull && !temp->isUndefined()) ? temp.ref() : JS::NullHandleValue, "'authenticatorSelection' member of MakeCredentialOptions", passedToJSImpl)) {
1895 0 : return false;
1896 : }
1897 0 : mIsAnyMemberPresent = true;
1898 :
1899 0 : if (!isNull) {
1900 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->challenge_id, temp.ptr())) {
1901 0 : return false;
1902 : }
1903 : }
1904 0 : if (!isNull && !temp->isUndefined()) {
1905 : {
1906 0 : bool done = false, failed = false, tryNext;
1907 0 : if (temp.ref().isObject()) {
1908 0 : done = (failed = !mChallenge.TrySetToArrayBufferView(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext ||
1909 0 : (failed = !mChallenge.TrySetToArrayBuffer(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext;
1910 :
1911 : }
1912 0 : if (failed) {
1913 0 : return false;
1914 : }
1915 0 : if (!done) {
1916 0 : ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'challenge' member of MakeCredentialOptions", "ArrayBufferView, ArrayBuffer");
1917 0 : return false;
1918 : }
1919 : }
1920 0 : mIsAnyMemberPresent = true;
1921 0 : } else if (cx) {
1922 : // Don't error out if we have no cx. In that
1923 : // situation the caller is default-constructing us and we'll
1924 : // just assume they know what they're doing.
1925 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
1926 0 : "'challenge' member of MakeCredentialOptions");
1927 : }
1928 :
1929 0 : if (!isNull) {
1930 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->excludeList_id, temp.ptr())) {
1931 0 : return false;
1932 : }
1933 : }
1934 0 : if (!isNull && !temp->isUndefined()) {
1935 0 : mExcludeList.Construct();
1936 0 : if (temp.ref().isObject()) {
1937 0 : JS::ForOfIterator iter(cx);
1938 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
1939 0 : return false;
1940 : }
1941 0 : if (!iter.valueIsIterable()) {
1942 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'excludeList' member of MakeCredentialOptions");
1943 0 : return false;
1944 : }
1945 0 : Sequence<PublicKeyCredentialDescriptor> &arr = (mExcludeList.Value());
1946 0 : JS::Rooted<JS::Value> temp(cx);
1947 : while (true) {
1948 : bool done;
1949 0 : if (!iter.next(&temp, &done)) {
1950 0 : return false;
1951 : }
1952 0 : if (done) {
1953 0 : break;
1954 : }
1955 0 : PublicKeyCredentialDescriptor* slotPtr = arr.AppendElement(mozilla::fallible);
1956 0 : if (!slotPtr) {
1957 0 : JS_ReportOutOfMemory(cx);
1958 0 : return false;
1959 : }
1960 0 : PublicKeyCredentialDescriptor& slot = *slotPtr;
1961 0 : if (!slot.Init(cx, temp, "Element of 'excludeList' member of MakeCredentialOptions", passedToJSImpl)) {
1962 0 : return false;
1963 : }
1964 0 : }
1965 : } else {
1966 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'excludeList' member of MakeCredentialOptions");
1967 0 : return false;
1968 : }
1969 0 : mIsAnyMemberPresent = true;
1970 : }
1971 :
1972 0 : if (!isNull) {
1973 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->parameters_id, temp.ptr())) {
1974 0 : return false;
1975 : }
1976 : }
1977 0 : if (!isNull && !temp->isUndefined()) {
1978 0 : if (temp.ref().isObject()) {
1979 0 : JS::ForOfIterator iter(cx);
1980 0 : if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
1981 0 : return false;
1982 : }
1983 0 : if (!iter.valueIsIterable()) {
1984 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'parameters' member of MakeCredentialOptions");
1985 0 : return false;
1986 : }
1987 0 : Sequence<PublicKeyCredentialParameters> &arr = mParameters;
1988 0 : JS::Rooted<JS::Value> temp(cx);
1989 : while (true) {
1990 : bool done;
1991 0 : if (!iter.next(&temp, &done)) {
1992 0 : return false;
1993 : }
1994 0 : if (done) {
1995 0 : break;
1996 : }
1997 0 : PublicKeyCredentialParameters* slotPtr = arr.AppendElement(mozilla::fallible);
1998 0 : if (!slotPtr) {
1999 0 : JS_ReportOutOfMemory(cx);
2000 0 : return false;
2001 : }
2002 0 : PublicKeyCredentialParameters& slot = *slotPtr;
2003 0 : if (!slot.Init(cx, temp, "Element of 'parameters' member of MakeCredentialOptions", passedToJSImpl)) {
2004 0 : return false;
2005 : }
2006 0 : }
2007 : } else {
2008 0 : ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'parameters' member of MakeCredentialOptions");
2009 0 : return false;
2010 : }
2011 0 : mIsAnyMemberPresent = true;
2012 0 : } else if (cx) {
2013 : // Don't error out if we have no cx. In that
2014 : // situation the caller is default-constructing us and we'll
2015 : // just assume they know what they're doing.
2016 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
2017 0 : "'parameters' member of MakeCredentialOptions");
2018 : }
2019 :
2020 0 : if (!isNull) {
2021 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->rp_id, temp.ptr())) {
2022 0 : return false;
2023 : }
2024 : }
2025 0 : if (!isNull && !temp->isUndefined()) {
2026 0 : if (!mRp.Init(cx, temp.ref(), "'rp' member of MakeCredentialOptions", passedToJSImpl)) {
2027 0 : return false;
2028 : }
2029 0 : mIsAnyMemberPresent = true;
2030 0 : } else if (cx) {
2031 : // Don't error out if we have no cx. In that
2032 : // situation the caller is default-constructing us and we'll
2033 : // just assume they know what they're doing.
2034 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
2035 0 : "'rp' member of MakeCredentialOptions");
2036 : }
2037 :
2038 0 : if (!isNull) {
2039 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->timeout_id, temp.ptr())) {
2040 0 : return false;
2041 : }
2042 : }
2043 0 : if (!isNull && !temp->isUndefined()) {
2044 0 : mTimeout.Construct();
2045 0 : if (!ValueToPrimitive<uint32_t, eDefault>(cx, temp.ref(), &(mTimeout.Value()))) {
2046 0 : return false;
2047 : }
2048 0 : mIsAnyMemberPresent = true;
2049 : }
2050 :
2051 0 : if (!isNull) {
2052 0 : if (!JS_GetPropertyById(cx, *object, atomsCache->user_id, temp.ptr())) {
2053 0 : return false;
2054 : }
2055 : }
2056 0 : if (!isNull && !temp->isUndefined()) {
2057 0 : if (!mUser.Init(cx, temp.ref(), "'user' member of MakeCredentialOptions", passedToJSImpl)) {
2058 0 : return false;
2059 : }
2060 0 : mIsAnyMemberPresent = true;
2061 0 : } else if (cx) {
2062 : // Don't error out if we have no cx. In that
2063 : // situation the caller is default-constructing us and we'll
2064 : // just assume they know what they're doing.
2065 0 : return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
2066 0 : "'user' member of MakeCredentialOptions");
2067 : }
2068 0 : return true;
2069 : }
2070 :
2071 : bool
2072 0 : MakeCredentialOptions::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
2073 : {
2074 0 : MakeCredentialOptionsAtoms* atomsCache = GetAtomCache<MakeCredentialOptionsAtoms>(cx);
2075 0 : if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2076 0 : return false;
2077 : }
2078 :
2079 0 : JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
2080 0 : if (!obj) {
2081 0 : return false;
2082 : }
2083 0 : rval.set(JS::ObjectValue(*obj));
2084 :
2085 : do {
2086 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2087 0 : JS::Rooted<JS::Value> temp(cx);
2088 0 : AuthenticatorSelectionCriteria const & currentValue = mAuthenticatorSelection;
2089 0 : if (!currentValue.ToObjectInternal(cx, &temp)) {
2090 0 : return false;
2091 : }
2092 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->authenticatorSelection_id, temp, JSPROP_ENUMERATE)) {
2093 0 : return false;
2094 : }
2095 0 : break;
2096 : } while(0);
2097 :
2098 : do {
2099 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2100 0 : JS::Rooted<JS::Value> temp(cx);
2101 0 : OwningArrayBufferViewOrArrayBuffer const & currentValue = mChallenge;
2102 0 : if (!currentValue.ToJSVal(cx, obj, &temp)) {
2103 0 : return false;
2104 : }
2105 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->challenge_id, temp, JSPROP_ENUMERATE)) {
2106 0 : return false;
2107 : }
2108 0 : break;
2109 : } while(0);
2110 :
2111 0 : if (mExcludeList.WasPassed()) {
2112 : do {
2113 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2114 0 : JS::Rooted<JS::Value> temp(cx);
2115 0 : Sequence<PublicKeyCredentialDescriptor> const & currentValue = mExcludeList.InternalValue();
2116 :
2117 0 : uint32_t length = currentValue.Length();
2118 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
2119 0 : if (!returnArray) {
2120 0 : return false;
2121 : }
2122 : // Scope for 'tmp'
2123 : {
2124 0 : JS::Rooted<JS::Value> tmp(cx);
2125 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
2126 : // Control block to let us common up the JS_DefineElement calls when there
2127 : // are different ways to succeed at wrapping the object.
2128 : do {
2129 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
2130 0 : return false;
2131 : }
2132 0 : break;
2133 : } while (0);
2134 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
2135 : JSPROP_ENUMERATE)) {
2136 0 : return false;
2137 : }
2138 : }
2139 : }
2140 0 : temp.setObject(*returnArray);
2141 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->excludeList_id, temp, JSPROP_ENUMERATE)) {
2142 0 : return false;
2143 : }
2144 0 : break;
2145 : } while(0);
2146 : }
2147 :
2148 : do {
2149 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2150 0 : JS::Rooted<JS::Value> temp(cx);
2151 0 : Sequence<PublicKeyCredentialParameters> const & currentValue = mParameters;
2152 :
2153 0 : uint32_t length = currentValue.Length();
2154 0 : JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
2155 0 : if (!returnArray) {
2156 0 : return false;
2157 : }
2158 : // Scope for 'tmp'
2159 : {
2160 0 : JS::Rooted<JS::Value> tmp(cx);
2161 0 : for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
2162 : // Control block to let us common up the JS_DefineElement calls when there
2163 : // are different ways to succeed at wrapping the object.
2164 : do {
2165 0 : if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
2166 0 : return false;
2167 : }
2168 0 : break;
2169 : } while (0);
2170 0 : if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
2171 : JSPROP_ENUMERATE)) {
2172 0 : return false;
2173 : }
2174 : }
2175 : }
2176 0 : temp.setObject(*returnArray);
2177 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->parameters_id, temp, JSPROP_ENUMERATE)) {
2178 0 : return false;
2179 : }
2180 0 : break;
2181 : } while(0);
2182 :
2183 : do {
2184 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2185 0 : JS::Rooted<JS::Value> temp(cx);
2186 0 : PublicKeyCredentialEntity const & currentValue = mRp;
2187 0 : if (!currentValue.ToObjectInternal(cx, &temp)) {
2188 0 : return false;
2189 : }
2190 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->rp_id, temp, JSPROP_ENUMERATE)) {
2191 0 : return false;
2192 : }
2193 0 : break;
2194 : } while(0);
2195 :
2196 0 : if (mTimeout.WasPassed()) {
2197 : do {
2198 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2199 0 : JS::Rooted<JS::Value> temp(cx);
2200 0 : uint32_t const & currentValue = mTimeout.InternalValue();
2201 0 : temp.setNumber(currentValue);
2202 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->timeout_id, temp, JSPROP_ENUMERATE)) {
2203 0 : return false;
2204 : }
2205 0 : break;
2206 : } while(0);
2207 : }
2208 :
2209 : do {
2210 : // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2211 0 : JS::Rooted<JS::Value> temp(cx);
2212 0 : PublicKeyCredentialUserEntity const & currentValue = mUser;
2213 0 : if (!currentValue.ToObjectInternal(cx, &temp)) {
2214 0 : return false;
2215 : }
2216 0 : if (!JS_DefinePropertyById(cx, obj, atomsCache->user_id, temp, JSPROP_ENUMERATE)) {
2217 0 : return false;
2218 : }
2219 0 : break;
2220 : } while(0);
2221 :
2222 0 : return true;
2223 : }
2224 :
2225 : void
2226 0 : MakeCredentialOptions::TraceDictionary(JSTracer* trc)
2227 : {
2228 0 : mChallenge.TraceUnion(trc);
2229 :
2230 0 : if (mExcludeList.WasPassed()) {
2231 0 : DoTraceSequence(trc, mExcludeList.Value());
2232 : }
2233 0 : }
2234 :
2235 : namespace binding_detail {
2236 : } // namespace binding_detail
2237 :
2238 :
2239 : namespace AuthenticatorAssertionResponseBinding {
2240 :
2241 : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<AuthenticatorResponseBinding::NativeType>::value,
2242 : "Can't inherit from an interface with a different ownership model.");
2243 :
2244 : static bool
2245 0 : get_authenticatorData(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AuthenticatorAssertionResponse* self, JSJitGetterCallArgs args)
2246 : {
2247 0 : JS::Rooted<JSObject*> result(cx);
2248 0 : self->GetAuthenticatorData(cx, &result);
2249 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2250 0 : JS::ExposeObjectToActiveJS(result);
2251 0 : args.rval().setObject(*result);
2252 0 : if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
2253 0 : return false;
2254 : }
2255 0 : return true;
2256 : }
2257 :
2258 : static const JSJitInfo authenticatorData_getterinfo = {
2259 : { (JSJitGetterOp)get_authenticatorData },
2260 : { prototypes::id::AuthenticatorAssertionResponse },
2261 : { PrototypeTraits<prototypes::id::AuthenticatorAssertionResponse>::Depth },
2262 : JSJitInfo::Getter,
2263 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2264 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
2265 : false, /* isInfallible. False in setters. */
2266 : false, /* isMovable. Not relevant for setters. */
2267 : false, /* isEliminatable. Not relevant for setters. */
2268 : false, /* isAlwaysInSlot. Only relevant for getters. */
2269 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2270 : false, /* isTypedMethod. Only relevant for methods. */
2271 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2272 : };
2273 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2274 : static_assert(0 < 1, "There is no slot for us");
2275 :
2276 : static bool
2277 0 : get_signature(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AuthenticatorAssertionResponse* self, JSJitGetterCallArgs args)
2278 : {
2279 0 : JS::Rooted<JSObject*> result(cx);
2280 0 : self->GetSignature(cx, &result);
2281 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2282 0 : JS::ExposeObjectToActiveJS(result);
2283 0 : args.rval().setObject(*result);
2284 0 : if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
2285 0 : return false;
2286 : }
2287 0 : return true;
2288 : }
2289 :
2290 : static const JSJitInfo signature_getterinfo = {
2291 : { (JSJitGetterOp)get_signature },
2292 : { prototypes::id::AuthenticatorAssertionResponse },
2293 : { PrototypeTraits<prototypes::id::AuthenticatorAssertionResponse>::Depth },
2294 : JSJitInfo::Getter,
2295 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2296 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
2297 : false, /* isInfallible. False in setters. */
2298 : false, /* isMovable. Not relevant for setters. */
2299 : false, /* isEliminatable. Not relevant for setters. */
2300 : false, /* isAlwaysInSlot. Only relevant for getters. */
2301 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2302 : false, /* isTypedMethod. Only relevant for methods. */
2303 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2304 : };
2305 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2306 : static_assert(0 < 1, "There is no slot for us");
2307 :
2308 : static bool
2309 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
2310 : {
2311 0 : mozilla::dom::AuthenticatorAssertionResponse* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AuthenticatorAssertionResponse>(obj);
2312 : // We don't want to preserve if we don't have a wrapper, and we
2313 : // obviously can't preserve if we're not initialized.
2314 0 : if (self && self->GetWrapperPreserveColor()) {
2315 0 : PreserveWrapper(self);
2316 : }
2317 0 : return true;
2318 : }
2319 :
2320 : static void
2321 0 : _finalize(js::FreeOp* fop, JSObject* obj)
2322 : {
2323 0 : mozilla::dom::AuthenticatorAssertionResponse* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AuthenticatorAssertionResponse>(obj);
2324 0 : if (self) {
2325 0 : ClearWrapper(self, self, obj);
2326 0 : AddForDeferredFinalization<mozilla::dom::AuthenticatorAssertionResponse>(self);
2327 : }
2328 0 : }
2329 :
2330 : static void
2331 0 : _objectMoved(JSObject* obj, const JSObject* old)
2332 : {
2333 0 : mozilla::dom::AuthenticatorAssertionResponse* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AuthenticatorAssertionResponse>(obj);
2334 0 : if (self) {
2335 0 : UpdateWrapper(self, self, obj, old);
2336 : }
2337 0 : }
2338 :
2339 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
2340 : #if defined(__clang__)
2341 : #pragma clang diagnostic push
2342 : #pragma clang diagnostic ignored "-Wmissing-braces"
2343 : #endif
2344 : static const JSPropertySpec sAttributes_specs[] = {
2345 : { "authenticatorData", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &authenticatorData_getterinfo, nullptr, nullptr },
2346 : { "signature", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &signature_getterinfo, nullptr, nullptr },
2347 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
2348 : };
2349 : #if defined(__clang__)
2350 : #pragma clang diagnostic pop
2351 : #endif
2352 :
2353 : static PrefableDisablers sAttributes_disablers0 = {
2354 : true, true, 0, nullptr
2355 : };
2356 :
2357 : // Can't be const because the pref-enabled boolean needs to be writable
2358 : static Prefable<const JSPropertySpec> sAttributes[] = {
2359 : { &sAttributes_disablers0, &sAttributes_specs[0] },
2360 : { nullptr, nullptr }
2361 : };
2362 :
2363 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
2364 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
2365 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
2366 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
2367 :
2368 :
2369 : static uint16_t sNativeProperties_sortedPropertyIndices[2];
2370 : static PropertyInfo sNativeProperties_propertyInfos[2];
2371 :
2372 : static const NativePropertiesN<1> sNativeProperties = {
2373 : false, 0,
2374 : false, 0,
2375 : false, 0,
2376 : true, 0 /* sAttributes */,
2377 : false, 0,
2378 : false, 0,
2379 : false, 0,
2380 : -1,
2381 : 2,
2382 : sNativeProperties_sortedPropertyIndices,
2383 : {
2384 : { sAttributes, &sNativeProperties_propertyInfos[0] }
2385 : }
2386 : };
2387 : static_assert(2 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
2388 : "We have a property info count that is oversized");
2389 :
2390 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
2391 : {
2392 : "Function",
2393 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
2394 : &sBoringInterfaceObjectClassClassOps,
2395 : JS_NULL_CLASS_SPEC,
2396 : JS_NULL_CLASS_EXT,
2397 : &sInterfaceObjectClassObjectOps
2398 : },
2399 : eInterface,
2400 : true,
2401 : prototypes::id::AuthenticatorAssertionResponse,
2402 : PrototypeTraits<prototypes::id::AuthenticatorAssertionResponse>::Depth,
2403 : sNativePropertyHooks,
2404 : "function AuthenticatorAssertionResponse() {\n [native code]\n}",
2405 : AuthenticatorResponseBinding::GetConstructorObject
2406 : };
2407 :
2408 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
2409 : {
2410 : "AuthenticatorAssertionResponsePrototype",
2411 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
2412 : JS_NULL_CLASS_OPS,
2413 : JS_NULL_CLASS_SPEC,
2414 : JS_NULL_CLASS_EXT,
2415 : JS_NULL_OBJECT_OPS
2416 : },
2417 : eInterfacePrototype,
2418 : false,
2419 : prototypes::id::AuthenticatorAssertionResponse,
2420 : PrototypeTraits<prototypes::id::AuthenticatorAssertionResponse>::Depth,
2421 : sNativePropertyHooks,
2422 : "[object AuthenticatorAssertionResponsePrototype]",
2423 : AuthenticatorResponseBinding::GetProtoObject
2424 : };
2425 :
2426 : bool
2427 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
2428 : {
2429 : static bool sPrefValue;
2430 : static bool sPrefCacheSetUp = false;
2431 0 : if (!sPrefCacheSetUp) {
2432 0 : sPrefCacheSetUp = true;
2433 0 : Preferences::AddBoolVarCache(&sPrefValue, "security.webauth.webauthn");
2434 : }
2435 :
2436 0 : return sPrefValue &&
2437 0 : mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
2438 : }
2439 :
2440 : JSObject*
2441 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
2442 : {
2443 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
2444 : }
2445 :
2446 : static const js::ClassOps sClassOps = {
2447 : _addProperty, /* addProperty */
2448 : nullptr, /* delProperty */
2449 : nullptr, /* getProperty */
2450 : nullptr, /* setProperty */
2451 : nullptr, /* enumerate */
2452 : nullptr, /* newEnumerate */
2453 : nullptr, /* resolve */
2454 : nullptr, /* mayResolve */
2455 : _finalize, /* finalize */
2456 : nullptr, /* call */
2457 : nullptr, /* hasInstance */
2458 : nullptr, /* construct */
2459 : nullptr, /* trace */
2460 : };
2461 :
2462 : static const js::ClassExtension sClassExtension = {
2463 : nullptr, /* weakmapKeyDelegateOp */
2464 : _objectMoved /* objectMovedOp */
2465 : };
2466 :
2467 : static const DOMJSClass sClass = {
2468 : { "AuthenticatorAssertionResponse",
2469 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
2470 : &sClassOps,
2471 : JS_NULL_CLASS_SPEC,
2472 : &sClassExtension,
2473 : JS_NULL_OBJECT_OPS
2474 : },
2475 : { prototypes::id::AuthenticatorResponse, prototypes::id::AuthenticatorAssertionResponse, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
2476 : IsBaseOf<nsISupports, mozilla::dom::AuthenticatorAssertionResponse >::value,
2477 : sNativePropertyHooks,
2478 : FindAssociatedGlobalForNative<mozilla::dom::AuthenticatorAssertionResponse>::Get,
2479 : GetProtoObjectHandle,
2480 : GetCCParticipant<mozilla::dom::AuthenticatorAssertionResponse>::Get()
2481 : };
2482 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
2483 : "Must have the right minimal number of reserved slots.");
2484 : static_assert(1 >= 1,
2485 : "Must have enough reserved slots.");
2486 :
2487 : const JSClass*
2488 0 : GetJSClass()
2489 : {
2490 0 : return sClass.ToJSClass();
2491 : }
2492 :
2493 : bool
2494 0 : Wrap(JSContext* aCx, mozilla::dom::AuthenticatorAssertionResponse* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
2495 : {
2496 : MOZ_ASSERT(static_cast<mozilla::dom::AuthenticatorAssertionResponse*>(aObject) ==
2497 : reinterpret_cast<mozilla::dom::AuthenticatorAssertionResponse*>(aObject),
2498 : "Multiple inheritance for mozilla::dom::AuthenticatorAssertionResponse is broken.");
2499 : MOZ_ASSERT(static_cast<mozilla::dom::AuthenticatorResponse*>(aObject) ==
2500 : reinterpret_cast<mozilla::dom::AuthenticatorResponse*>(aObject),
2501 : "Multiple inheritance for mozilla::dom::AuthenticatorResponse is broken.");
2502 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
2503 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
2504 0 : MOZ_ASSERT(!aCache->GetWrapper(),
2505 : "You should probably not be using Wrap() directly; use "
2506 : "GetOrCreateDOMReflector instead");
2507 :
2508 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
2509 : "nsISupports must be on our primary inheritance chain");
2510 :
2511 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
2512 0 : if (!global) {
2513 0 : return false;
2514 : }
2515 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
2516 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
2517 :
2518 : // That might have ended up wrapping us already, due to the wonders
2519 : // of XBL. Check for that, and bail out as needed.
2520 0 : aReflector.set(aCache->GetWrapper());
2521 0 : if (aReflector) {
2522 : #ifdef DEBUG
2523 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
2524 : #endif // DEBUG
2525 0 : return true;
2526 : }
2527 :
2528 0 : JSAutoCompartment ac(aCx, global);
2529 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
2530 0 : if (!canonicalProto) {
2531 0 : return false;
2532 : }
2533 0 : JS::Rooted<JSObject*> proto(aCx);
2534 0 : if (aGivenProto) {
2535 0 : proto = aGivenProto;
2536 : // Unfortunately, while aGivenProto was in the compartment of aCx
2537 : // coming in, we changed compartments to that of "parent" so may need
2538 : // to wrap the proto here.
2539 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
2540 0 : if (!JS_WrapObject(aCx, &proto)) {
2541 0 : return false;
2542 : }
2543 : }
2544 : } else {
2545 0 : proto = canonicalProto;
2546 : }
2547 :
2548 0 : BindingJSObjectCreator<mozilla::dom::AuthenticatorAssertionResponse> creator(aCx);
2549 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
2550 0 : if (!aReflector) {
2551 0 : return false;
2552 : }
2553 :
2554 0 : aCache->SetWrapper(aReflector);
2555 0 : creator.InitializationSucceeded();
2556 :
2557 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
2558 : aCache->GetWrapperPreserveColor() == aReflector);
2559 : // If proto != canonicalProto, we have to preserve our wrapper;
2560 : // otherwise we won't be able to properly recreate it later, since
2561 : // we won't know what proto to use. Note that we don't check
2562 : // aGivenProto here, since it's entirely possible (and even
2563 : // somewhat common) to have a non-null aGivenProto which is the
2564 : // same as canonicalProto.
2565 0 : if (proto != canonicalProto) {
2566 0 : PreserveWrapper(aObject);
2567 : }
2568 :
2569 0 : return true;
2570 : }
2571 :
2572 : const NativePropertyHooks sNativePropertyHooks[] = { {
2573 : nullptr,
2574 : nullptr,
2575 : nullptr,
2576 : { sNativeProperties.Upcast(), nullptr },
2577 : prototypes::id::AuthenticatorAssertionResponse,
2578 : constructors::id::AuthenticatorAssertionResponse,
2579 : AuthenticatorResponseBinding::sNativePropertyHooks,
2580 : &DefaultXrayExpandoObjectClass
2581 : } };
2582 :
2583 : void
2584 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
2585 : {
2586 0 : JS::Handle<JSObject*> parentProto(AuthenticatorResponseBinding::GetProtoObjectHandle(aCx));
2587 0 : if (!parentProto) {
2588 0 : return;
2589 : }
2590 :
2591 0 : JS::Handle<JSObject*> constructorProto(AuthenticatorResponseBinding::GetConstructorObjectHandle(aCx));
2592 0 : if (!constructorProto) {
2593 0 : return;
2594 : }
2595 :
2596 : static bool sIdsInited = false;
2597 0 : if (!sIdsInited && NS_IsMainThread()) {
2598 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
2599 0 : return;
2600 : }
2601 0 : sIdsInited = true;
2602 : }
2603 :
2604 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::AuthenticatorAssertionResponse);
2605 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::AuthenticatorAssertionResponse);
2606 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
2607 : &sPrototypeClass.mBase, protoCache,
2608 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
2609 : interfaceCache,
2610 : sNativeProperties.Upcast(),
2611 : nullptr,
2612 : "AuthenticatorAssertionResponse", aDefineOnGlobal,
2613 : nullptr,
2614 0 : false);
2615 : }
2616 :
2617 : JS::Handle<JSObject*>
2618 0 : GetProtoObjectHandle(JSContext* aCx)
2619 : {
2620 : /* Get the interface prototype object for this class. This will create the
2621 : object as needed. */
2622 0 : bool aDefineOnGlobal = true;
2623 :
2624 : /* Make sure our global is sane. Hopefully we can remove this sometime */
2625 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
2626 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
2627 0 : return nullptr;
2628 : }
2629 :
2630 : /* Check to see whether the interface objects are already installed */
2631 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
2632 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::AuthenticatorAssertionResponse)) {
2633 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
2634 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
2635 : }
2636 :
2637 : /*
2638 : * The object might _still_ be null, but that's OK.
2639 : *
2640 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
2641 : * traced by TraceProtoAndIfaceCache() and its contents are never
2642 : * changed after they have been set.
2643 : *
2644 : * Calling address() avoids the read read barrier that does gray
2645 : * unmarking, but it's not possible for the object to be gray here.
2646 : */
2647 :
2648 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::AuthenticatorAssertionResponse);
2649 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
2650 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
2651 : }
2652 :
2653 : JS::Handle<JSObject*>
2654 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
2655 : {
2656 : /* Get the interface object for this class. This will create the object as
2657 : needed. */
2658 :
2659 : /* Make sure our global is sane. Hopefully we can remove this sometime */
2660 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
2661 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
2662 0 : return nullptr;
2663 : }
2664 :
2665 : /* Check to see whether the interface objects are already installed */
2666 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
2667 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::AuthenticatorAssertionResponse)) {
2668 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
2669 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
2670 : }
2671 :
2672 : /*
2673 : * The object might _still_ be null, but that's OK.
2674 : *
2675 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
2676 : * traced by TraceProtoAndIfaceCache() and its contents are never
2677 : * changed after they have been set.
2678 : *
2679 : * Calling address() avoids the read read barrier that does gray
2680 : * unmarking, but it's not possible for the object to be gray here.
2681 : */
2682 :
2683 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::AuthenticatorAssertionResponse);
2684 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
2685 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
2686 : }
2687 :
2688 : JSObject*
2689 0 : GetConstructorObject(JSContext* aCx)
2690 : {
2691 0 : return GetConstructorObjectHandle(aCx);
2692 : }
2693 :
2694 : } // namespace AuthenticatorAssertionResponseBinding
2695 :
2696 :
2697 :
2698 : namespace AuthenticatorAttestationResponseBinding {
2699 :
2700 : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<AuthenticatorResponseBinding::NativeType>::value,
2701 : "Can't inherit from an interface with a different ownership model.");
2702 :
2703 : static bool
2704 0 : get_attestationObject(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AuthenticatorAttestationResponse* self, JSJitGetterCallArgs args)
2705 : {
2706 0 : JS::Rooted<JSObject*> result(cx);
2707 0 : self->GetAttestationObject(cx, &result);
2708 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
2709 0 : JS::ExposeObjectToActiveJS(result);
2710 0 : args.rval().setObject(*result);
2711 0 : if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
2712 0 : return false;
2713 : }
2714 0 : return true;
2715 : }
2716 :
2717 : static const JSJitInfo attestationObject_getterinfo = {
2718 : { (JSJitGetterOp)get_attestationObject },
2719 : { prototypes::id::AuthenticatorAttestationResponse },
2720 : { PrototypeTraits<prototypes::id::AuthenticatorAttestationResponse>::Depth },
2721 : JSJitInfo::Getter,
2722 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
2723 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
2724 : false, /* isInfallible. False in setters. */
2725 : false, /* isMovable. Not relevant for setters. */
2726 : false, /* isEliminatable. Not relevant for setters. */
2727 : false, /* isAlwaysInSlot. Only relevant for getters. */
2728 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
2729 : false, /* isTypedMethod. Only relevant for methods. */
2730 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
2731 : };
2732 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
2733 : static_assert(0 < 1, "There is no slot for us");
2734 :
2735 : static bool
2736 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
2737 : {
2738 0 : mozilla::dom::AuthenticatorAttestationResponse* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AuthenticatorAttestationResponse>(obj);
2739 : // We don't want to preserve if we don't have a wrapper, and we
2740 : // obviously can't preserve if we're not initialized.
2741 0 : if (self && self->GetWrapperPreserveColor()) {
2742 0 : PreserveWrapper(self);
2743 : }
2744 0 : return true;
2745 : }
2746 :
2747 : static void
2748 0 : _finalize(js::FreeOp* fop, JSObject* obj)
2749 : {
2750 0 : mozilla::dom::AuthenticatorAttestationResponse* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AuthenticatorAttestationResponse>(obj);
2751 0 : if (self) {
2752 0 : ClearWrapper(self, self, obj);
2753 0 : AddForDeferredFinalization<mozilla::dom::AuthenticatorAttestationResponse>(self);
2754 : }
2755 0 : }
2756 :
2757 : static void
2758 0 : _objectMoved(JSObject* obj, const JSObject* old)
2759 : {
2760 0 : mozilla::dom::AuthenticatorAttestationResponse* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AuthenticatorAttestationResponse>(obj);
2761 0 : if (self) {
2762 0 : UpdateWrapper(self, self, obj, old);
2763 : }
2764 0 : }
2765 :
2766 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
2767 : #if defined(__clang__)
2768 : #pragma clang diagnostic push
2769 : #pragma clang diagnostic ignored "-Wmissing-braces"
2770 : #endif
2771 : static const JSPropertySpec sAttributes_specs[] = {
2772 : { "attestationObject", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &attestationObject_getterinfo, nullptr, nullptr },
2773 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
2774 : };
2775 : #if defined(__clang__)
2776 : #pragma clang diagnostic pop
2777 : #endif
2778 :
2779 : static PrefableDisablers sAttributes_disablers0 = {
2780 : true, true, 0, nullptr
2781 : };
2782 :
2783 : // Can't be const because the pref-enabled boolean needs to be writable
2784 : static Prefable<const JSPropertySpec> sAttributes[] = {
2785 : { &sAttributes_disablers0, &sAttributes_specs[0] },
2786 : { nullptr, nullptr }
2787 : };
2788 :
2789 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
2790 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
2791 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
2792 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
2793 :
2794 :
2795 : static uint16_t sNativeProperties_sortedPropertyIndices[1];
2796 : static PropertyInfo sNativeProperties_propertyInfos[1];
2797 :
2798 : static const NativePropertiesN<1> sNativeProperties = {
2799 : false, 0,
2800 : false, 0,
2801 : false, 0,
2802 : true, 0 /* sAttributes */,
2803 : false, 0,
2804 : false, 0,
2805 : false, 0,
2806 : -1,
2807 : 1,
2808 : sNativeProperties_sortedPropertyIndices,
2809 : {
2810 : { sAttributes, &sNativeProperties_propertyInfos[0] }
2811 : }
2812 : };
2813 : static_assert(1 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
2814 : "We have a property info count that is oversized");
2815 :
2816 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
2817 : {
2818 : "Function",
2819 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
2820 : &sBoringInterfaceObjectClassClassOps,
2821 : JS_NULL_CLASS_SPEC,
2822 : JS_NULL_CLASS_EXT,
2823 : &sInterfaceObjectClassObjectOps
2824 : },
2825 : eInterface,
2826 : true,
2827 : prototypes::id::AuthenticatorAttestationResponse,
2828 : PrototypeTraits<prototypes::id::AuthenticatorAttestationResponse>::Depth,
2829 : sNativePropertyHooks,
2830 : "function AuthenticatorAttestationResponse() {\n [native code]\n}",
2831 : AuthenticatorResponseBinding::GetConstructorObject
2832 : };
2833 :
2834 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
2835 : {
2836 : "AuthenticatorAttestationResponsePrototype",
2837 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
2838 : JS_NULL_CLASS_OPS,
2839 : JS_NULL_CLASS_SPEC,
2840 : JS_NULL_CLASS_EXT,
2841 : JS_NULL_OBJECT_OPS
2842 : },
2843 : eInterfacePrototype,
2844 : false,
2845 : prototypes::id::AuthenticatorAttestationResponse,
2846 : PrototypeTraits<prototypes::id::AuthenticatorAttestationResponse>::Depth,
2847 : sNativePropertyHooks,
2848 : "[object AuthenticatorAttestationResponsePrototype]",
2849 : AuthenticatorResponseBinding::GetProtoObject
2850 : };
2851 :
2852 : bool
2853 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
2854 : {
2855 : static bool sPrefValue;
2856 : static bool sPrefCacheSetUp = false;
2857 0 : if (!sPrefCacheSetUp) {
2858 0 : sPrefCacheSetUp = true;
2859 0 : Preferences::AddBoolVarCache(&sPrefValue, "security.webauth.webauthn");
2860 : }
2861 :
2862 0 : return sPrefValue &&
2863 0 : mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
2864 : }
2865 :
2866 : JSObject*
2867 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
2868 : {
2869 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
2870 : }
2871 :
2872 : static const js::ClassOps sClassOps = {
2873 : _addProperty, /* addProperty */
2874 : nullptr, /* delProperty */
2875 : nullptr, /* getProperty */
2876 : nullptr, /* setProperty */
2877 : nullptr, /* enumerate */
2878 : nullptr, /* newEnumerate */
2879 : nullptr, /* resolve */
2880 : nullptr, /* mayResolve */
2881 : _finalize, /* finalize */
2882 : nullptr, /* call */
2883 : nullptr, /* hasInstance */
2884 : nullptr, /* construct */
2885 : nullptr, /* trace */
2886 : };
2887 :
2888 : static const js::ClassExtension sClassExtension = {
2889 : nullptr, /* weakmapKeyDelegateOp */
2890 : _objectMoved /* objectMovedOp */
2891 : };
2892 :
2893 : static const DOMJSClass sClass = {
2894 : { "AuthenticatorAttestationResponse",
2895 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
2896 : &sClassOps,
2897 : JS_NULL_CLASS_SPEC,
2898 : &sClassExtension,
2899 : JS_NULL_OBJECT_OPS
2900 : },
2901 : { prototypes::id::AuthenticatorResponse, prototypes::id::AuthenticatorAttestationResponse, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
2902 : IsBaseOf<nsISupports, mozilla::dom::AuthenticatorAttestationResponse >::value,
2903 : sNativePropertyHooks,
2904 : FindAssociatedGlobalForNative<mozilla::dom::AuthenticatorAttestationResponse>::Get,
2905 : GetProtoObjectHandle,
2906 : GetCCParticipant<mozilla::dom::AuthenticatorAttestationResponse>::Get()
2907 : };
2908 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
2909 : "Must have the right minimal number of reserved slots.");
2910 : static_assert(1 >= 1,
2911 : "Must have enough reserved slots.");
2912 :
2913 : const JSClass*
2914 0 : GetJSClass()
2915 : {
2916 0 : return sClass.ToJSClass();
2917 : }
2918 :
2919 : bool
2920 0 : Wrap(JSContext* aCx, mozilla::dom::AuthenticatorAttestationResponse* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
2921 : {
2922 : MOZ_ASSERT(static_cast<mozilla::dom::AuthenticatorAttestationResponse*>(aObject) ==
2923 : reinterpret_cast<mozilla::dom::AuthenticatorAttestationResponse*>(aObject),
2924 : "Multiple inheritance for mozilla::dom::AuthenticatorAttestationResponse is broken.");
2925 : MOZ_ASSERT(static_cast<mozilla::dom::AuthenticatorResponse*>(aObject) ==
2926 : reinterpret_cast<mozilla::dom::AuthenticatorResponse*>(aObject),
2927 : "Multiple inheritance for mozilla::dom::AuthenticatorResponse is broken.");
2928 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
2929 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
2930 0 : MOZ_ASSERT(!aCache->GetWrapper(),
2931 : "You should probably not be using Wrap() directly; use "
2932 : "GetOrCreateDOMReflector instead");
2933 :
2934 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
2935 : "nsISupports must be on our primary inheritance chain");
2936 :
2937 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
2938 0 : if (!global) {
2939 0 : return false;
2940 : }
2941 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
2942 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
2943 :
2944 : // That might have ended up wrapping us already, due to the wonders
2945 : // of XBL. Check for that, and bail out as needed.
2946 0 : aReflector.set(aCache->GetWrapper());
2947 0 : if (aReflector) {
2948 : #ifdef DEBUG
2949 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
2950 : #endif // DEBUG
2951 0 : return true;
2952 : }
2953 :
2954 0 : JSAutoCompartment ac(aCx, global);
2955 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
2956 0 : if (!canonicalProto) {
2957 0 : return false;
2958 : }
2959 0 : JS::Rooted<JSObject*> proto(aCx);
2960 0 : if (aGivenProto) {
2961 0 : proto = aGivenProto;
2962 : // Unfortunately, while aGivenProto was in the compartment of aCx
2963 : // coming in, we changed compartments to that of "parent" so may need
2964 : // to wrap the proto here.
2965 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
2966 0 : if (!JS_WrapObject(aCx, &proto)) {
2967 0 : return false;
2968 : }
2969 : }
2970 : } else {
2971 0 : proto = canonicalProto;
2972 : }
2973 :
2974 0 : BindingJSObjectCreator<mozilla::dom::AuthenticatorAttestationResponse> creator(aCx);
2975 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
2976 0 : if (!aReflector) {
2977 0 : return false;
2978 : }
2979 :
2980 0 : aCache->SetWrapper(aReflector);
2981 0 : creator.InitializationSucceeded();
2982 :
2983 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
2984 : aCache->GetWrapperPreserveColor() == aReflector);
2985 : // If proto != canonicalProto, we have to preserve our wrapper;
2986 : // otherwise we won't be able to properly recreate it later, since
2987 : // we won't know what proto to use. Note that we don't check
2988 : // aGivenProto here, since it's entirely possible (and even
2989 : // somewhat common) to have a non-null aGivenProto which is the
2990 : // same as canonicalProto.
2991 0 : if (proto != canonicalProto) {
2992 0 : PreserveWrapper(aObject);
2993 : }
2994 :
2995 0 : return true;
2996 : }
2997 :
2998 : const NativePropertyHooks sNativePropertyHooks[] = { {
2999 : nullptr,
3000 : nullptr,
3001 : nullptr,
3002 : { sNativeProperties.Upcast(), nullptr },
3003 : prototypes::id::AuthenticatorAttestationResponse,
3004 : constructors::id::AuthenticatorAttestationResponse,
3005 : AuthenticatorResponseBinding::sNativePropertyHooks,
3006 : &DefaultXrayExpandoObjectClass
3007 : } };
3008 :
3009 : void
3010 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
3011 : {
3012 0 : JS::Handle<JSObject*> parentProto(AuthenticatorResponseBinding::GetProtoObjectHandle(aCx));
3013 0 : if (!parentProto) {
3014 0 : return;
3015 : }
3016 :
3017 0 : JS::Handle<JSObject*> constructorProto(AuthenticatorResponseBinding::GetConstructorObjectHandle(aCx));
3018 0 : if (!constructorProto) {
3019 0 : return;
3020 : }
3021 :
3022 : static bool sIdsInited = false;
3023 0 : if (!sIdsInited && NS_IsMainThread()) {
3024 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
3025 0 : return;
3026 : }
3027 0 : sIdsInited = true;
3028 : }
3029 :
3030 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::AuthenticatorAttestationResponse);
3031 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::AuthenticatorAttestationResponse);
3032 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
3033 : &sPrototypeClass.mBase, protoCache,
3034 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
3035 : interfaceCache,
3036 : sNativeProperties.Upcast(),
3037 : nullptr,
3038 : "AuthenticatorAttestationResponse", aDefineOnGlobal,
3039 : nullptr,
3040 0 : false);
3041 : }
3042 :
3043 : JS::Handle<JSObject*>
3044 0 : GetProtoObjectHandle(JSContext* aCx)
3045 : {
3046 : /* Get the interface prototype object for this class. This will create the
3047 : object as needed. */
3048 0 : bool aDefineOnGlobal = true;
3049 :
3050 : /* Make sure our global is sane. Hopefully we can remove this sometime */
3051 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
3052 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
3053 0 : return nullptr;
3054 : }
3055 :
3056 : /* Check to see whether the interface objects are already installed */
3057 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
3058 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::AuthenticatorAttestationResponse)) {
3059 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
3060 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
3061 : }
3062 :
3063 : /*
3064 : * The object might _still_ be null, but that's OK.
3065 : *
3066 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
3067 : * traced by TraceProtoAndIfaceCache() and its contents are never
3068 : * changed after they have been set.
3069 : *
3070 : * Calling address() avoids the read read barrier that does gray
3071 : * unmarking, but it's not possible for the object to be gray here.
3072 : */
3073 :
3074 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::AuthenticatorAttestationResponse);
3075 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
3076 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
3077 : }
3078 :
3079 : JS::Handle<JSObject*>
3080 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
3081 : {
3082 : /* Get the interface object for this class. This will create the object as
3083 : needed. */
3084 :
3085 : /* Make sure our global is sane. Hopefully we can remove this sometime */
3086 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
3087 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
3088 0 : return nullptr;
3089 : }
3090 :
3091 : /* Check to see whether the interface objects are already installed */
3092 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
3093 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::AuthenticatorAttestationResponse)) {
3094 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
3095 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
3096 : }
3097 :
3098 : /*
3099 : * The object might _still_ be null, but that's OK.
3100 : *
3101 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
3102 : * traced by TraceProtoAndIfaceCache() and its contents are never
3103 : * changed after they have been set.
3104 : *
3105 : * Calling address() avoids the read read barrier that does gray
3106 : * unmarking, but it's not possible for the object to be gray here.
3107 : */
3108 :
3109 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::AuthenticatorAttestationResponse);
3110 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
3111 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
3112 : }
3113 :
3114 : JSObject*
3115 0 : GetConstructorObject(JSContext* aCx)
3116 : {
3117 0 : return GetConstructorObjectHandle(aCx);
3118 : }
3119 :
3120 : } // namespace AuthenticatorAttestationResponseBinding
3121 :
3122 :
3123 :
3124 : namespace AuthenticatorResponseBinding {
3125 :
3126 : static bool
3127 0 : get_clientDataJSON(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::AuthenticatorResponse* self, JSJitGetterCallArgs args)
3128 : {
3129 0 : JS::Rooted<JSObject*> result(cx);
3130 0 : self->GetClientDataJSON(cx, &result);
3131 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
3132 0 : JS::ExposeObjectToActiveJS(result);
3133 0 : args.rval().setObject(*result);
3134 0 : if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
3135 0 : return false;
3136 : }
3137 0 : return true;
3138 : }
3139 :
3140 : static const JSJitInfo clientDataJSON_getterinfo = {
3141 : { (JSJitGetterOp)get_clientDataJSON },
3142 : { prototypes::id::AuthenticatorResponse },
3143 : { PrototypeTraits<prototypes::id::AuthenticatorResponse>::Depth },
3144 : JSJitInfo::Getter,
3145 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
3146 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
3147 : false, /* isInfallible. False in setters. */
3148 : false, /* isMovable. Not relevant for setters. */
3149 : false, /* isEliminatable. Not relevant for setters. */
3150 : false, /* isAlwaysInSlot. Only relevant for getters. */
3151 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
3152 : false, /* isTypedMethod. Only relevant for methods. */
3153 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
3154 : };
3155 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
3156 : static_assert(0 < 1, "There is no slot for us");
3157 :
3158 : static bool
3159 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
3160 : {
3161 0 : mozilla::dom::AuthenticatorResponse* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AuthenticatorResponse>(obj);
3162 : // We don't want to preserve if we don't have a wrapper, and we
3163 : // obviously can't preserve if we're not initialized.
3164 0 : if (self && self->GetWrapperPreserveColor()) {
3165 0 : PreserveWrapper(self);
3166 : }
3167 0 : return true;
3168 : }
3169 :
3170 : static void
3171 0 : _finalize(js::FreeOp* fop, JSObject* obj)
3172 : {
3173 0 : mozilla::dom::AuthenticatorResponse* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AuthenticatorResponse>(obj);
3174 0 : if (self) {
3175 0 : ClearWrapper(self, self, obj);
3176 0 : AddForDeferredFinalization<mozilla::dom::AuthenticatorResponse>(self);
3177 : }
3178 0 : }
3179 :
3180 : static void
3181 0 : _objectMoved(JSObject* obj, const JSObject* old)
3182 : {
3183 0 : mozilla::dom::AuthenticatorResponse* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::AuthenticatorResponse>(obj);
3184 0 : if (self) {
3185 0 : UpdateWrapper(self, self, obj, old);
3186 : }
3187 0 : }
3188 :
3189 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
3190 : #if defined(__clang__)
3191 : #pragma clang diagnostic push
3192 : #pragma clang diagnostic ignored "-Wmissing-braces"
3193 : #endif
3194 : static const JSPropertySpec sAttributes_specs[] = {
3195 : { "clientDataJSON", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &clientDataJSON_getterinfo, nullptr, nullptr },
3196 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
3197 : };
3198 : #if defined(__clang__)
3199 : #pragma clang diagnostic pop
3200 : #endif
3201 :
3202 : static PrefableDisablers sAttributes_disablers0 = {
3203 : true, true, 0, nullptr
3204 : };
3205 :
3206 : // Can't be const because the pref-enabled boolean needs to be writable
3207 : static Prefable<const JSPropertySpec> sAttributes[] = {
3208 : { &sAttributes_disablers0, &sAttributes_specs[0] },
3209 : { nullptr, nullptr }
3210 : };
3211 :
3212 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
3213 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
3214 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
3215 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
3216 :
3217 :
3218 : static uint16_t sNativeProperties_sortedPropertyIndices[1];
3219 : static PropertyInfo sNativeProperties_propertyInfos[1];
3220 :
3221 : static const NativePropertiesN<1> sNativeProperties = {
3222 : false, 0,
3223 : false, 0,
3224 : false, 0,
3225 : true, 0 /* sAttributes */,
3226 : false, 0,
3227 : false, 0,
3228 : false, 0,
3229 : -1,
3230 : 1,
3231 : sNativeProperties_sortedPropertyIndices,
3232 : {
3233 : { sAttributes, &sNativeProperties_propertyInfos[0] }
3234 : }
3235 : };
3236 : static_assert(1 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
3237 : "We have a property info count that is oversized");
3238 :
3239 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
3240 : {
3241 : "Function",
3242 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
3243 : &sBoringInterfaceObjectClassClassOps,
3244 : JS_NULL_CLASS_SPEC,
3245 : JS_NULL_CLASS_EXT,
3246 : &sInterfaceObjectClassObjectOps
3247 : },
3248 : eInterface,
3249 : true,
3250 : prototypes::id::AuthenticatorResponse,
3251 : PrototypeTraits<prototypes::id::AuthenticatorResponse>::Depth,
3252 : sNativePropertyHooks,
3253 : "function AuthenticatorResponse() {\n [native code]\n}",
3254 : JS::GetRealmFunctionPrototype
3255 : };
3256 :
3257 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
3258 : {
3259 : "AuthenticatorResponsePrototype",
3260 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
3261 : JS_NULL_CLASS_OPS,
3262 : JS_NULL_CLASS_SPEC,
3263 : JS_NULL_CLASS_EXT,
3264 : JS_NULL_OBJECT_OPS
3265 : },
3266 : eInterfacePrototype,
3267 : false,
3268 : prototypes::id::AuthenticatorResponse,
3269 : PrototypeTraits<prototypes::id::AuthenticatorResponse>::Depth,
3270 : sNativePropertyHooks,
3271 : "[object AuthenticatorResponsePrototype]",
3272 : JS::GetRealmObjectPrototype
3273 : };
3274 :
3275 : bool
3276 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
3277 : {
3278 : static bool sPrefValue;
3279 : static bool sPrefCacheSetUp = false;
3280 0 : if (!sPrefCacheSetUp) {
3281 0 : sPrefCacheSetUp = true;
3282 0 : Preferences::AddBoolVarCache(&sPrefValue, "security.webauth.webauthn");
3283 : }
3284 :
3285 0 : return sPrefValue &&
3286 0 : mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
3287 : }
3288 :
3289 : JSObject*
3290 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
3291 : {
3292 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
3293 : }
3294 :
3295 : static const js::ClassOps sClassOps = {
3296 : _addProperty, /* addProperty */
3297 : nullptr, /* delProperty */
3298 : nullptr, /* getProperty */
3299 : nullptr, /* setProperty */
3300 : nullptr, /* enumerate */
3301 : nullptr, /* newEnumerate */
3302 : nullptr, /* resolve */
3303 : nullptr, /* mayResolve */
3304 : _finalize, /* finalize */
3305 : nullptr, /* call */
3306 : nullptr, /* hasInstance */
3307 : nullptr, /* construct */
3308 : nullptr, /* trace */
3309 : };
3310 :
3311 : static const js::ClassExtension sClassExtension = {
3312 : nullptr, /* weakmapKeyDelegateOp */
3313 : _objectMoved /* objectMovedOp */
3314 : };
3315 :
3316 : static const DOMJSClass sClass = {
3317 : { "AuthenticatorResponse",
3318 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
3319 : &sClassOps,
3320 : JS_NULL_CLASS_SPEC,
3321 : &sClassExtension,
3322 : JS_NULL_OBJECT_OPS
3323 : },
3324 : { prototypes::id::AuthenticatorResponse, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
3325 : IsBaseOf<nsISupports, mozilla::dom::AuthenticatorResponse >::value,
3326 : sNativePropertyHooks,
3327 : FindAssociatedGlobalForNative<mozilla::dom::AuthenticatorResponse>::Get,
3328 : GetProtoObjectHandle,
3329 : GetCCParticipant<mozilla::dom::AuthenticatorResponse>::Get()
3330 : };
3331 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
3332 : "Must have the right minimal number of reserved slots.");
3333 : static_assert(1 >= 1,
3334 : "Must have enough reserved slots.");
3335 :
3336 : const JSClass*
3337 0 : GetJSClass()
3338 : {
3339 0 : return sClass.ToJSClass();
3340 : }
3341 :
3342 : bool
3343 0 : Wrap(JSContext* aCx, mozilla::dom::AuthenticatorResponse* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
3344 : {
3345 : MOZ_ASSERT(static_cast<mozilla::dom::AuthenticatorResponse*>(aObject) ==
3346 : reinterpret_cast<mozilla::dom::AuthenticatorResponse*>(aObject),
3347 : "Multiple inheritance for mozilla::dom::AuthenticatorResponse is broken.");
3348 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
3349 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
3350 0 : MOZ_ASSERT(!aCache->GetWrapper(),
3351 : "You should probably not be using Wrap() directly; use "
3352 : "GetOrCreateDOMReflector instead");
3353 :
3354 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
3355 : "nsISupports must be on our primary inheritance chain");
3356 :
3357 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
3358 0 : if (!global) {
3359 0 : return false;
3360 : }
3361 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
3362 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
3363 :
3364 : // That might have ended up wrapping us already, due to the wonders
3365 : // of XBL. Check for that, and bail out as needed.
3366 0 : aReflector.set(aCache->GetWrapper());
3367 0 : if (aReflector) {
3368 : #ifdef DEBUG
3369 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
3370 : #endif // DEBUG
3371 0 : return true;
3372 : }
3373 :
3374 0 : JSAutoCompartment ac(aCx, global);
3375 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
3376 0 : if (!canonicalProto) {
3377 0 : return false;
3378 : }
3379 0 : JS::Rooted<JSObject*> proto(aCx);
3380 0 : if (aGivenProto) {
3381 0 : proto = aGivenProto;
3382 : // Unfortunately, while aGivenProto was in the compartment of aCx
3383 : // coming in, we changed compartments to that of "parent" so may need
3384 : // to wrap the proto here.
3385 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
3386 0 : if (!JS_WrapObject(aCx, &proto)) {
3387 0 : return false;
3388 : }
3389 : }
3390 : } else {
3391 0 : proto = canonicalProto;
3392 : }
3393 :
3394 0 : BindingJSObjectCreator<mozilla::dom::AuthenticatorResponse> creator(aCx);
3395 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
3396 0 : if (!aReflector) {
3397 0 : return false;
3398 : }
3399 :
3400 0 : aCache->SetWrapper(aReflector);
3401 0 : creator.InitializationSucceeded();
3402 :
3403 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
3404 : aCache->GetWrapperPreserveColor() == aReflector);
3405 : // If proto != canonicalProto, we have to preserve our wrapper;
3406 : // otherwise we won't be able to properly recreate it later, since
3407 : // we won't know what proto to use. Note that we don't check
3408 : // aGivenProto here, since it's entirely possible (and even
3409 : // somewhat common) to have a non-null aGivenProto which is the
3410 : // same as canonicalProto.
3411 0 : if (proto != canonicalProto) {
3412 0 : PreserveWrapper(aObject);
3413 : }
3414 :
3415 0 : return true;
3416 : }
3417 :
3418 : const NativePropertyHooks sNativePropertyHooks[] = { {
3419 : nullptr,
3420 : nullptr,
3421 : nullptr,
3422 : { sNativeProperties.Upcast(), nullptr },
3423 : prototypes::id::AuthenticatorResponse,
3424 : constructors::id::AuthenticatorResponse,
3425 : nullptr,
3426 : &DefaultXrayExpandoObjectClass
3427 : } };
3428 :
3429 : void
3430 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
3431 : {
3432 0 : JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
3433 0 : if (!parentProto) {
3434 0 : return;
3435 : }
3436 :
3437 0 : JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
3438 0 : if (!constructorProto) {
3439 0 : return;
3440 : }
3441 :
3442 : static bool sIdsInited = false;
3443 0 : if (!sIdsInited && NS_IsMainThread()) {
3444 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
3445 0 : return;
3446 : }
3447 0 : sIdsInited = true;
3448 : }
3449 :
3450 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::AuthenticatorResponse);
3451 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::AuthenticatorResponse);
3452 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
3453 : &sPrototypeClass.mBase, protoCache,
3454 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
3455 : interfaceCache,
3456 : sNativeProperties.Upcast(),
3457 : nullptr,
3458 : "AuthenticatorResponse", aDefineOnGlobal,
3459 : nullptr,
3460 0 : false);
3461 : }
3462 :
3463 : JS::Handle<JSObject*>
3464 0 : GetProtoObjectHandle(JSContext* aCx)
3465 : {
3466 : /* Get the interface prototype object for this class. This will create the
3467 : object as needed. */
3468 0 : bool aDefineOnGlobal = true;
3469 :
3470 : /* Make sure our global is sane. Hopefully we can remove this sometime */
3471 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
3472 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
3473 0 : return nullptr;
3474 : }
3475 :
3476 : /* Check to see whether the interface objects are already installed */
3477 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
3478 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::AuthenticatorResponse)) {
3479 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
3480 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
3481 : }
3482 :
3483 : /*
3484 : * The object might _still_ be null, but that's OK.
3485 : *
3486 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
3487 : * traced by TraceProtoAndIfaceCache() and its contents are never
3488 : * changed after they have been set.
3489 : *
3490 : * Calling address() avoids the read read barrier that does gray
3491 : * unmarking, but it's not possible for the object to be gray here.
3492 : */
3493 :
3494 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::AuthenticatorResponse);
3495 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
3496 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
3497 : }
3498 :
3499 : JSObject*
3500 0 : GetProtoObject(JSContext* aCx)
3501 : {
3502 0 : return GetProtoObjectHandle(aCx);
3503 : }
3504 :
3505 : JS::Handle<JSObject*>
3506 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
3507 : {
3508 : /* Get the interface object for this class. This will create the object as
3509 : needed. */
3510 :
3511 : /* Make sure our global is sane. Hopefully we can remove this sometime */
3512 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
3513 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
3514 0 : return nullptr;
3515 : }
3516 :
3517 : /* Check to see whether the interface objects are already installed */
3518 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
3519 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::AuthenticatorResponse)) {
3520 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
3521 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
3522 : }
3523 :
3524 : /*
3525 : * The object might _still_ be null, but that's OK.
3526 : *
3527 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
3528 : * traced by TraceProtoAndIfaceCache() and its contents are never
3529 : * changed after they have been set.
3530 : *
3531 : * Calling address() avoids the read read barrier that does gray
3532 : * unmarking, but it's not possible for the object to be gray here.
3533 : */
3534 :
3535 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::AuthenticatorResponse);
3536 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
3537 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
3538 : }
3539 :
3540 : JSObject*
3541 0 : GetConstructorObject(JSContext* aCx)
3542 : {
3543 0 : return GetConstructorObjectHandle(aCx);
3544 : }
3545 :
3546 : } // namespace AuthenticatorResponseBinding
3547 :
3548 :
3549 :
3550 : namespace PublicKeyCredentialBinding {
3551 :
3552 : static_assert(IsRefcounted<NativeType>::value == IsRefcounted<CredentialBinding::NativeType>::value,
3553 : "Can't inherit from an interface with a different ownership model.");
3554 :
3555 : static bool
3556 0 : get_rawId(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PublicKeyCredential* self, JSJitGetterCallArgs args)
3557 : {
3558 0 : JS::Rooted<JSObject*> result(cx);
3559 0 : self->GetRawId(cx, &result);
3560 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
3561 0 : JS::ExposeObjectToActiveJS(result);
3562 0 : args.rval().setObject(*result);
3563 0 : if (!MaybeWrapNonDOMObjectValue(cx, args.rval())) {
3564 0 : return false;
3565 : }
3566 0 : return true;
3567 : }
3568 :
3569 : static const JSJitInfo rawId_getterinfo = {
3570 : { (JSJitGetterOp)get_rawId },
3571 : { prototypes::id::PublicKeyCredential },
3572 : { PrototypeTraits<prototypes::id::PublicKeyCredential>::Depth },
3573 : JSJitInfo::Getter,
3574 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
3575 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
3576 : false, /* isInfallible. False in setters. */
3577 : false, /* isMovable. Not relevant for setters. */
3578 : false, /* isEliminatable. Not relevant for setters. */
3579 : false, /* isAlwaysInSlot. Only relevant for getters. */
3580 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
3581 : false, /* isTypedMethod. Only relevant for methods. */
3582 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
3583 : };
3584 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
3585 : static_assert(0 < 1, "There is no slot for us");
3586 :
3587 : static bool
3588 0 : get_response(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::PublicKeyCredential* self, JSJitGetterCallArgs args)
3589 : {
3590 0 : auto result(StrongOrRawPtr<mozilla::dom::AuthenticatorResponse>(self->Response()));
3591 0 : MOZ_ASSERT(!JS_IsExceptionPending(cx));
3592 0 : if (!GetOrCreateDOMReflector(cx, result, args.rval())) {
3593 0 : MOZ_ASSERT(true || JS_IsExceptionPending(cx));
3594 0 : return false;
3595 : }
3596 0 : return true;
3597 : }
3598 :
3599 : static const JSJitInfo response_getterinfo = {
3600 : { (JSJitGetterOp)get_response },
3601 : { prototypes::id::PublicKeyCredential },
3602 : { PrototypeTraits<prototypes::id::PublicKeyCredential>::Depth },
3603 : JSJitInfo::Getter,
3604 : JSJitInfo::AliasEverything, /* aliasSet. Not relevant for setters. */
3605 : JSVAL_TYPE_OBJECT, /* returnType. Not relevant for setters. */
3606 : false, /* isInfallible. False in setters. */
3607 : false, /* isMovable. Not relevant for setters. */
3608 : false, /* isEliminatable. Not relevant for setters. */
3609 : false, /* isAlwaysInSlot. Only relevant for getters. */
3610 : false, /* isLazilyCachedInSlot. Only relevant for getters. */
3611 : false, /* isTypedMethod. Only relevant for methods. */
3612 : 0 /* Reserved slot index, if we're stored in a slot, else 0. */
3613 : };
3614 : static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
3615 : static_assert(0 < 1, "There is no slot for us");
3616 :
3617 : static bool
3618 0 : _addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
3619 : {
3620 0 : mozilla::dom::PublicKeyCredential* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::PublicKeyCredential>(obj);
3621 : // We don't want to preserve if we don't have a wrapper, and we
3622 : // obviously can't preserve if we're not initialized.
3623 0 : if (self && self->GetWrapperPreserveColor()) {
3624 0 : PreserveWrapper(self);
3625 : }
3626 0 : return true;
3627 : }
3628 :
3629 : static void
3630 0 : _finalize(js::FreeOp* fop, JSObject* obj)
3631 : {
3632 0 : mozilla::dom::PublicKeyCredential* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::PublicKeyCredential>(obj);
3633 0 : if (self) {
3634 0 : ClearWrapper(self, self, obj);
3635 0 : AddForDeferredFinalization<mozilla::dom::PublicKeyCredential>(self);
3636 : }
3637 0 : }
3638 :
3639 : static void
3640 0 : _objectMoved(JSObject* obj, const JSObject* old)
3641 : {
3642 0 : mozilla::dom::PublicKeyCredential* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::PublicKeyCredential>(obj);
3643 0 : if (self) {
3644 0 : UpdateWrapper(self, self, obj, old);
3645 : }
3646 0 : }
3647 :
3648 : // We deliberately use brace-elision to make Visual Studio produce better initalization code.
3649 : #if defined(__clang__)
3650 : #pragma clang diagnostic push
3651 : #pragma clang diagnostic ignored "-Wmissing-braces"
3652 : #endif
3653 : static const JSPropertySpec sAttributes_specs[] = {
3654 : { "rawId", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &rawId_getterinfo, nullptr, nullptr },
3655 : { "response", JSPROP_SHARED | JSPROP_ENUMERATE, GenericBindingGetter, &response_getterinfo, nullptr, nullptr },
3656 : { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
3657 : };
3658 : #if defined(__clang__)
3659 : #pragma clang diagnostic pop
3660 : #endif
3661 :
3662 : static PrefableDisablers sAttributes_disablers0 = {
3663 : true, true, 0, nullptr
3664 : };
3665 :
3666 : // Can't be const because the pref-enabled boolean needs to be writable
3667 : static Prefable<const JSPropertySpec> sAttributes[] = {
3668 : { &sAttributes_disablers0, &sAttributes_specs[0] },
3669 : { nullptr, nullptr }
3670 : };
3671 :
3672 : static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
3673 : "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
3674 : static_assert(2 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
3675 : "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
3676 :
3677 :
3678 : static uint16_t sNativeProperties_sortedPropertyIndices[2];
3679 : static PropertyInfo sNativeProperties_propertyInfos[2];
3680 :
3681 : static const NativePropertiesN<1> sNativeProperties = {
3682 : false, 0,
3683 : false, 0,
3684 : false, 0,
3685 : true, 0 /* sAttributes */,
3686 : false, 0,
3687 : false, 0,
3688 : false, 0,
3689 : -1,
3690 : 2,
3691 : sNativeProperties_sortedPropertyIndices,
3692 : {
3693 : { sAttributes, &sNativeProperties_propertyInfos[0] }
3694 : }
3695 : };
3696 : static_assert(2 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
3697 : "We have a property info count that is oversized");
3698 :
3699 : static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
3700 : {
3701 : "Function",
3702 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
3703 : &sBoringInterfaceObjectClassClassOps,
3704 : JS_NULL_CLASS_SPEC,
3705 : JS_NULL_CLASS_EXT,
3706 : &sInterfaceObjectClassObjectOps
3707 : },
3708 : eInterface,
3709 : true,
3710 : prototypes::id::PublicKeyCredential,
3711 : PrototypeTraits<prototypes::id::PublicKeyCredential>::Depth,
3712 : sNativePropertyHooks,
3713 : "function PublicKeyCredential() {\n [native code]\n}",
3714 : CredentialBinding::GetConstructorObject
3715 : };
3716 :
3717 : static const DOMIfaceAndProtoJSClass sPrototypeClass = {
3718 : {
3719 : "PublicKeyCredentialPrototype",
3720 : JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
3721 : JS_NULL_CLASS_OPS,
3722 : JS_NULL_CLASS_SPEC,
3723 : JS_NULL_CLASS_EXT,
3724 : JS_NULL_OBJECT_OPS
3725 : },
3726 : eInterfacePrototype,
3727 : false,
3728 : prototypes::id::PublicKeyCredential,
3729 : PrototypeTraits<prototypes::id::PublicKeyCredential>::Depth,
3730 : sNativePropertyHooks,
3731 : "[object PublicKeyCredentialPrototype]",
3732 : CredentialBinding::GetProtoObject
3733 : };
3734 :
3735 : bool
3736 0 : ConstructorEnabled(JSContext* aCx, JS::Handle<JSObject*> aObj)
3737 : {
3738 : static bool sPrefValue;
3739 : static bool sPrefCacheSetUp = false;
3740 0 : if (!sPrefCacheSetUp) {
3741 0 : sPrefCacheSetUp = true;
3742 0 : Preferences::AddBoolVarCache(&sPrefValue, "security.webauth.webauthn");
3743 : }
3744 :
3745 0 : return sPrefValue &&
3746 0 : mozilla::dom::IsSecureContextOrObjectIsFromSecureContext(aCx, aObj);
3747 : }
3748 :
3749 : JSObject*
3750 0 : DefineDOMInterface(JSContext* aCx, JS::Handle<JSObject*> aGlobal, JS::Handle<jsid> id, bool aDefineOnGlobal)
3751 : {
3752 0 : return GetConstructorObjectHandle(aCx, aDefineOnGlobal);
3753 : }
3754 :
3755 : static const js::ClassOps sClassOps = {
3756 : _addProperty, /* addProperty */
3757 : nullptr, /* delProperty */
3758 : nullptr, /* getProperty */
3759 : nullptr, /* setProperty */
3760 : nullptr, /* enumerate */
3761 : nullptr, /* newEnumerate */
3762 : nullptr, /* resolve */
3763 : nullptr, /* mayResolve */
3764 : _finalize, /* finalize */
3765 : nullptr, /* call */
3766 : nullptr, /* hasInstance */
3767 : nullptr, /* construct */
3768 : nullptr, /* trace */
3769 : };
3770 :
3771 : static const js::ClassExtension sClassExtension = {
3772 : nullptr, /* weakmapKeyDelegateOp */
3773 : _objectMoved /* objectMovedOp */
3774 : };
3775 :
3776 : static const DOMJSClass sClass = {
3777 : { "PublicKeyCredential",
3778 : JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
3779 : &sClassOps,
3780 : JS_NULL_CLASS_SPEC,
3781 : &sClassExtension,
3782 : JS_NULL_OBJECT_OPS
3783 : },
3784 : { prototypes::id::Credential, prototypes::id::PublicKeyCredential, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count, prototypes::id::_ID_Count },
3785 : IsBaseOf<nsISupports, mozilla::dom::PublicKeyCredential >::value,
3786 : sNativePropertyHooks,
3787 : FindAssociatedGlobalForNative<mozilla::dom::PublicKeyCredential>::Get,
3788 : GetProtoObjectHandle,
3789 : GetCCParticipant<mozilla::dom::PublicKeyCredential>::Get()
3790 : };
3791 : static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
3792 : "Must have the right minimal number of reserved slots.");
3793 : static_assert(1 >= 1,
3794 : "Must have enough reserved slots.");
3795 :
3796 : const JSClass*
3797 0 : GetJSClass()
3798 : {
3799 0 : return sClass.ToJSClass();
3800 : }
3801 :
3802 : bool
3803 0 : Wrap(JSContext* aCx, mozilla::dom::PublicKeyCredential* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
3804 : {
3805 : MOZ_ASSERT(static_cast<mozilla::dom::PublicKeyCredential*>(aObject) ==
3806 : reinterpret_cast<mozilla::dom::PublicKeyCredential*>(aObject),
3807 : "Multiple inheritance for mozilla::dom::PublicKeyCredential is broken.");
3808 : MOZ_ASSERT(static_cast<mozilla::dom::Credential*>(aObject) ==
3809 : reinterpret_cast<mozilla::dom::Credential*>(aObject),
3810 : "Multiple inheritance for mozilla::dom::Credential is broken.");
3811 0 : MOZ_ASSERT(ToSupportsIsCorrect(aObject));
3812 0 : MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
3813 0 : MOZ_ASSERT(!aCache->GetWrapper(),
3814 : "You should probably not be using Wrap() directly; use "
3815 : "GetOrCreateDOMReflector instead");
3816 :
3817 0 : MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
3818 : "nsISupports must be on our primary inheritance chain");
3819 :
3820 0 : JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
3821 0 : if (!global) {
3822 0 : return false;
3823 : }
3824 0 : MOZ_ASSERT(JS_IsGlobalObject(global));
3825 0 : MOZ_ASSERT(JS::ObjectIsNotGray(global));
3826 :
3827 : // That might have ended up wrapping us already, due to the wonders
3828 : // of XBL. Check for that, and bail out as needed.
3829 0 : aReflector.set(aCache->GetWrapper());
3830 0 : if (aReflector) {
3831 : #ifdef DEBUG
3832 0 : binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
3833 : #endif // DEBUG
3834 0 : return true;
3835 : }
3836 :
3837 0 : JSAutoCompartment ac(aCx, global);
3838 0 : JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
3839 0 : if (!canonicalProto) {
3840 0 : return false;
3841 : }
3842 0 : JS::Rooted<JSObject*> proto(aCx);
3843 0 : if (aGivenProto) {
3844 0 : proto = aGivenProto;
3845 : // Unfortunately, while aGivenProto was in the compartment of aCx
3846 : // coming in, we changed compartments to that of "parent" so may need
3847 : // to wrap the proto here.
3848 0 : if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
3849 0 : if (!JS_WrapObject(aCx, &proto)) {
3850 0 : return false;
3851 : }
3852 : }
3853 : } else {
3854 0 : proto = canonicalProto;
3855 : }
3856 :
3857 0 : BindingJSObjectCreator<mozilla::dom::PublicKeyCredential> creator(aCx);
3858 0 : creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
3859 0 : if (!aReflector) {
3860 0 : return false;
3861 : }
3862 :
3863 0 : aCache->SetWrapper(aReflector);
3864 0 : creator.InitializationSucceeded();
3865 :
3866 0 : MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
3867 : aCache->GetWrapperPreserveColor() == aReflector);
3868 : // If proto != canonicalProto, we have to preserve our wrapper;
3869 : // otherwise we won't be able to properly recreate it later, since
3870 : // we won't know what proto to use. Note that we don't check
3871 : // aGivenProto here, since it's entirely possible (and even
3872 : // somewhat common) to have a non-null aGivenProto which is the
3873 : // same as canonicalProto.
3874 0 : if (proto != canonicalProto) {
3875 0 : PreserveWrapper(aObject);
3876 : }
3877 :
3878 0 : return true;
3879 : }
3880 :
3881 : const NativePropertyHooks sNativePropertyHooks[] = { {
3882 : nullptr,
3883 : nullptr,
3884 : nullptr,
3885 : { sNativeProperties.Upcast(), nullptr },
3886 : prototypes::id::PublicKeyCredential,
3887 : constructors::id::PublicKeyCredential,
3888 : CredentialBinding::sNativePropertyHooks,
3889 : &DefaultXrayExpandoObjectClass
3890 : } };
3891 :
3892 : void
3893 0 : CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
3894 : {
3895 0 : JS::Handle<JSObject*> parentProto(CredentialBinding::GetProtoObjectHandle(aCx));
3896 0 : if (!parentProto) {
3897 0 : return;
3898 : }
3899 :
3900 0 : JS::Handle<JSObject*> constructorProto(CredentialBinding::GetConstructorObjectHandle(aCx));
3901 0 : if (!constructorProto) {
3902 0 : return;
3903 : }
3904 :
3905 : static bool sIdsInited = false;
3906 0 : if (!sIdsInited && NS_IsMainThread()) {
3907 0 : if (!InitIds(aCx, sNativeProperties.Upcast())) {
3908 0 : return;
3909 : }
3910 0 : sIdsInited = true;
3911 : }
3912 :
3913 0 : JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::PublicKeyCredential);
3914 0 : JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::PublicKeyCredential);
3915 0 : dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
3916 : &sPrototypeClass.mBase, protoCache,
3917 : constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
3918 : interfaceCache,
3919 : sNativeProperties.Upcast(),
3920 : nullptr,
3921 : "PublicKeyCredential", aDefineOnGlobal,
3922 : nullptr,
3923 0 : false);
3924 : }
3925 :
3926 : JS::Handle<JSObject*>
3927 0 : GetProtoObjectHandle(JSContext* aCx)
3928 : {
3929 : /* Get the interface prototype object for this class. This will create the
3930 : object as needed. */
3931 0 : bool aDefineOnGlobal = true;
3932 :
3933 : /* Make sure our global is sane. Hopefully we can remove this sometime */
3934 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
3935 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
3936 0 : return nullptr;
3937 : }
3938 :
3939 : /* Check to see whether the interface objects are already installed */
3940 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
3941 0 : if (!protoAndIfaceCache.HasEntryInSlot(prototypes::id::PublicKeyCredential)) {
3942 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
3943 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
3944 : }
3945 :
3946 : /*
3947 : * The object might _still_ be null, but that's OK.
3948 : *
3949 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
3950 : * traced by TraceProtoAndIfaceCache() and its contents are never
3951 : * changed after they have been set.
3952 : *
3953 : * Calling address() avoids the read read barrier that does gray
3954 : * unmarking, but it's not possible for the object to be gray here.
3955 : */
3956 :
3957 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(prototypes::id::PublicKeyCredential);
3958 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
3959 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
3960 : }
3961 :
3962 : JS::Handle<JSObject*>
3963 0 : GetConstructorObjectHandle(JSContext* aCx, bool aDefineOnGlobal)
3964 : {
3965 : /* Get the interface object for this class. This will create the object as
3966 : needed. */
3967 :
3968 : /* Make sure our global is sane. Hopefully we can remove this sometime */
3969 0 : JSObject* global = JS::CurrentGlobalOrNull(aCx);
3970 0 : if (!(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL)) {
3971 0 : return nullptr;
3972 : }
3973 :
3974 : /* Check to see whether the interface objects are already installed */
3975 0 : ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
3976 0 : if (!protoAndIfaceCache.HasEntryInSlot(constructors::id::PublicKeyCredential)) {
3977 0 : JS::Rooted<JSObject*> rootedGlobal(aCx, global);
3978 0 : CreateInterfaceObjects(aCx, rootedGlobal, protoAndIfaceCache, aDefineOnGlobal);
3979 : }
3980 :
3981 : /*
3982 : * The object might _still_ be null, but that's OK.
3983 : *
3984 : * Calling fromMarkedLocation() is safe because protoAndIfaceCache is
3985 : * traced by TraceProtoAndIfaceCache() and its contents are never
3986 : * changed after they have been set.
3987 : *
3988 : * Calling address() avoids the read read barrier that does gray
3989 : * unmarking, but it's not possible for the object to be gray here.
3990 : */
3991 :
3992 0 : const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(constructors::id::PublicKeyCredential);
3993 0 : MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
3994 0 : return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
3995 : }
3996 :
3997 : JSObject*
3998 0 : GetConstructorObject(JSContext* aCx)
3999 : {
4000 0 : return GetConstructorObjectHandle(aCx);
4001 : }
4002 :
4003 : } // namespace PublicKeyCredentialBinding
4004 :
4005 :
4006 :
4007 : } // namespace dom
4008 : } // namespace mozilla
|