LCOV - code coverage report
Current view: top level - obj-x86_64-pc-linux-gnu/dom/bindings - WebAuthenticationBinding.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 1609 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 122 0.0 %
Legend: Lines: hit not hit

          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

Generated by: LCOV version 1.13