Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dom/bindings/SubtleCryptoBinding.cpp
Line
Count
Source (jump to first uncovered line)
1
/* THIS FILE IS AUTOGENERATED FROM SubtleCrypto.webidl BY Codegen.py - DO NOT EDIT */
2
3
#include "AtomList.h"
4
#include "SubtleCryptoBinding.h"
5
#include "WrapperFactory.h"
6
#include "XrayWrapper.h"
7
#include "jsfriendapi.h"
8
#include "mozilla/OwningNonNull.h"
9
#include "mozilla/dom/BindingUtils.h"
10
#include "mozilla/dom/CryptoKey.h"
11
#include "mozilla/dom/DOMJSClass.h"
12
#include "mozilla/dom/NonRefcountedDOMObject.h"
13
#include "mozilla/dom/PrimitiveConversions.h"
14
#include "mozilla/dom/Promise.h"
15
#include "mozilla/dom/ScriptSettings.h"
16
#include "mozilla/dom/SimpleGlobalObject.h"
17
#include "mozilla/dom/SubtleCrypto.h"
18
#include "mozilla/dom/ToJSValue.h"
19
#include "mozilla/dom/UnionConversions.h"
20
#include "mozilla/dom/UnionTypes.h"
21
#include "mozilla/dom/XrayExpandoClass.h"
22
23
namespace mozilla {
24
namespace dom {
25
26
namespace binding_detail {}; // Just to make sure it's known as a namespace
27
using namespace mozilla::dom::binding_detail;
28
29
30
31
Algorithm::Algorithm()
32
0
{
33
0
  // Safe to pass a null context if we pass a null value
34
0
  Init(nullptr, JS::NullHandleValue);
35
0
}
36
37
38
39
bool
40
Algorithm::InitIds(JSContext* cx, AlgorithmAtoms* atomsCache)
41
0
{
42
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
43
0
44
0
  // Initialize these in reverse order so that any failure leaves the first one
45
0
  // uninitialized.
46
0
  if (!atomsCache->name_id.init(cx, "name")) {
47
0
    return false;
48
0
  }
49
0
  return true;
50
0
}
51
52
bool
53
Algorithm::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
54
0
{
55
0
  // Passing a null JSContext is OK only if we're initing from null,
56
0
  // Since in that case we will not have to do any property gets
57
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
58
0
  // checkers by static analysis tools
59
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
60
0
  AlgorithmAtoms* atomsCache = nullptr;
61
0
  if (cx) {
62
0
    atomsCache = GetAtomCache<AlgorithmAtoms>(cx);
63
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
64
0
      return false;
65
0
    }
66
0
  }
67
0
68
0
  if (!IsConvertibleToDictionary(val)) {
69
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
70
0
  }
71
0
72
0
  bool isNull = val.isNullOrUndefined();
73
0
  // We only need these if !isNull, in which case we have |cx|.
74
0
  Maybe<JS::Rooted<JSObject *> > object;
75
0
  Maybe<JS::Rooted<JS::Value> > temp;
76
0
  if (!isNull) {
77
0
    MOZ_ASSERT(cx);
78
0
    object.emplace(cx, &val.toObject());
79
0
    temp.emplace(cx);
80
0
  }
81
0
  if (!isNull) {
82
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->name_id, temp.ptr())) {
83
0
      return false;
84
0
    }
85
0
  }
86
0
  if (!isNull && !temp->isUndefined()) {
87
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mName)) {
88
0
      return false;
89
0
    }
90
0
    mIsAnyMemberPresent = true;
91
0
  } else if (cx) {
92
0
    // Don't error out if we have no cx.  In that
93
0
    // situation the caller is default-constructing us and we'll
94
0
    // just assume they know what they're doing.
95
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
96
0
                             "'name' member of Algorithm");
97
0
  }
98
0
  return true;
99
0
}
100
101
bool
102
Algorithm::Init(const nsAString& aJSON)
103
0
{
104
0
  AutoJSAPI jsapi;
105
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
106
0
  if (!cleanGlobal) {
107
0
    return false;
108
0
  }
109
0
  if (!jsapi.Init(cleanGlobal)) {
110
0
    return false;
111
0
  }
112
0
  JSContext* cx = jsapi.cx();
113
0
  JS::Rooted<JS::Value> json(cx);
114
0
  bool ok = ParseJSON(cx, aJSON, &json);
115
0
  NS_ENSURE_TRUE(ok, false);
116
0
  return Init(cx, json);
117
0
}
118
119
bool
120
Algorithm::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
121
0
{
122
0
  AlgorithmAtoms* atomsCache = GetAtomCache<AlgorithmAtoms>(cx);
123
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
124
0
    return false;
125
0
  }
126
0
127
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
128
0
  if (!obj) {
129
0
    return false;
130
0
  }
131
0
  rval.set(JS::ObjectValue(*obj));
132
0
133
0
  do {
134
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
135
0
    JS::Rooted<JS::Value> temp(cx);
136
0
    nsString const & currentValue = mName;
137
0
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
138
0
      return false;
139
0
    }
140
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->name_id, temp, JSPROP_ENUMERATE)) {
141
0
      return false;
142
0
    }
143
0
    break;
144
0
  } while(false);
145
0
146
0
  return true;
147
0
}
148
149
bool
150
Algorithm::ToJSON(nsAString& aJSON) const
151
0
{
152
0
  AutoJSAPI jsapi;
153
0
  jsapi.Init();
154
0
  JSContext *cx = jsapi.cx();
155
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
156
0
  // because we'll only be creating objects, in ways that have no
157
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
158
0
  // which likewise guarantees no side-effects for the sorts of
159
0
  // things we will pass it.
160
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
161
0
  JS::Rooted<JS::Value> val(cx);
162
0
  if (!ToObjectInternal(cx, &val)) {
163
0
    return false;
164
0
  }
165
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
166
0
  return StringifyToJSON(cx, obj, aJSON);
167
0
}
168
169
void
170
Algorithm::TraceDictionary(JSTracer* trc)
171
0
{
172
0
}
173
174
Algorithm&
175
Algorithm::operator=(const Algorithm& aOther)
176
0
{
177
0
  DictionaryBase::operator=(aOther);
178
0
  mName = aOther.mName;
179
0
  return *this;
180
0
}
181
182
namespace binding_detail {
183
} // namespace binding_detail
184
185
186
187
CryptoKeyPair::CryptoKeyPair()
188
0
{
189
0
  // Safe to pass a null context if we pass a null value
190
0
  Init(nullptr, JS::NullHandleValue);
191
0
}
192
193
194
195
bool
196
CryptoKeyPair::InitIds(JSContext* cx, CryptoKeyPairAtoms* atomsCache)
197
0
{
198
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
199
0
200
0
  // Initialize these in reverse order so that any failure leaves the first one
201
0
  // uninitialized.
202
0
  if (!atomsCache->publicKey_id.init(cx, "publicKey") ||
203
0
      !atomsCache->privateKey_id.init(cx, "privateKey")) {
204
0
    return false;
205
0
  }
206
0
  return true;
207
0
}
208
209
bool
210
CryptoKeyPair::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
211
0
{
212
0
  // Passing a null JSContext is OK only if we're initing from null,
213
0
  // Since in that case we will not have to do any property gets
214
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
215
0
  // checkers by static analysis tools
216
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
217
0
  CryptoKeyPairAtoms* atomsCache = nullptr;
218
0
  if (cx) {
219
0
    atomsCache = GetAtomCache<CryptoKeyPairAtoms>(cx);
220
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
221
0
      return false;
222
0
    }
223
0
  }
224
0
225
0
  if (!IsConvertibleToDictionary(val)) {
226
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
227
0
  }
228
0
229
0
  bool isNull = val.isNullOrUndefined();
230
0
  // We only need these if !isNull, in which case we have |cx|.
231
0
  Maybe<JS::Rooted<JSObject *> > object;
232
0
  Maybe<JS::Rooted<JS::Value> > temp;
233
0
  if (!isNull) {
234
0
    MOZ_ASSERT(cx);
235
0
    object.emplace(cx, &val.toObject());
236
0
    temp.emplace(cx);
237
0
  }
238
0
  if (!isNull) {
239
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->privateKey_id, temp.ptr())) {
240
0
      return false;
241
0
    }
242
0
  }
243
0
  if (!isNull && !temp->isUndefined()) {
244
0
    if (temp.ref().isObject()) {
245
0
      static_assert(IsRefcounted<mozilla::dom::CryptoKey>::value, "We can only store refcounted classes.");{
246
0
        nsresult rv = UnwrapObject<prototypes::id::CryptoKey, mozilla::dom::CryptoKey>(temp.ptr(), mPrivateKey);
247
0
        if (NS_FAILED(rv)) {
248
0
          ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "'privateKey' member of CryptoKeyPair", "CryptoKey");
249
0
          return false;
250
0
        }
251
0
      }
252
0
    } else {
253
0
      ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'privateKey' member of CryptoKeyPair");
254
0
      return false;
255
0
    }
256
0
    mIsAnyMemberPresent = true;
257
0
  } else if (cx) {
258
0
    // Don't error out if we have no cx.  In that
259
0
    // situation the caller is default-constructing us and we'll
260
0
    // just assume they know what they're doing.
261
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
262
0
                             "'privateKey' member of CryptoKeyPair");
263
0
  }
264
0
265
0
  if (!isNull) {
266
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->publicKey_id, temp.ptr())) {
267
0
      return false;
268
0
    }
269
0
  }
270
0
  if (!isNull && !temp->isUndefined()) {
271
0
    if (temp.ref().isObject()) {
272
0
      static_assert(IsRefcounted<mozilla::dom::CryptoKey>::value, "We can only store refcounted classes.");{
273
0
        nsresult rv = UnwrapObject<prototypes::id::CryptoKey, mozilla::dom::CryptoKey>(temp.ptr(), mPublicKey);
274
0
        if (NS_FAILED(rv)) {
275
0
          ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "'publicKey' member of CryptoKeyPair", "CryptoKey");
276
0
          return false;
277
0
        }
278
0
      }
279
0
    } else {
280
0
      ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'publicKey' member of CryptoKeyPair");
281
0
      return false;
282
0
    }
283
0
    mIsAnyMemberPresent = true;
284
0
  } else if (cx) {
285
0
    // Don't error out if we have no cx.  In that
286
0
    // situation the caller is default-constructing us and we'll
287
0
    // just assume they know what they're doing.
288
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
289
0
                             "'publicKey' member of CryptoKeyPair");
290
0
  }
291
0
  return true;
292
0
}
293
294
bool
295
CryptoKeyPair::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
296
0
{
297
0
  CryptoKeyPairAtoms* atomsCache = GetAtomCache<CryptoKeyPairAtoms>(cx);
298
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
299
0
    return false;
300
0
  }
301
0
302
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
303
0
  if (!obj) {
304
0
    return false;
305
0
  }
306
0
  rval.set(JS::ObjectValue(*obj));
307
0
308
0
  do {
309
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
310
0
    JS::Rooted<JS::Value> temp(cx);
311
0
    OwningNonNull<mozilla::dom::CryptoKey> const & currentValue = mPrivateKey;
312
0
    if (!GetOrCreateDOMReflector(cx, currentValue, &temp)) {
313
0
      MOZ_ASSERT(JS_IsExceptionPending(cx));
314
0
      return false;
315
0
    }
316
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->privateKey_id, temp, JSPROP_ENUMERATE)) {
317
0
      return false;
318
0
    }
319
0
    break;
320
0
  } while(false);
321
0
322
0
  do {
323
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
324
0
    JS::Rooted<JS::Value> temp(cx);
325
0
    OwningNonNull<mozilla::dom::CryptoKey> const & currentValue = mPublicKey;
326
0
    if (!GetOrCreateDOMReflector(cx, currentValue, &temp)) {
327
0
      MOZ_ASSERT(JS_IsExceptionPending(cx));
328
0
      return false;
329
0
    }
330
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->publicKey_id, temp, JSPROP_ENUMERATE)) {
331
0
      return false;
332
0
    }
333
0
    break;
334
0
  } while(false);
335
0
336
0
  return true;
337
0
}
338
339
void
340
CryptoKeyPair::TraceDictionary(JSTracer* trc)
341
0
{
342
0
}
343
344
345
346
CryptoKeyPair&
347
CryptoKeyPair::operator=(const CryptoKeyPair& aOther)
348
0
{
349
0
  DictionaryBase::operator=(aOther);
350
0
  mPrivateKey = aOther.mPrivateKey;
351
0
  mPublicKey = aOther.mPublicKey;
352
0
  return *this;
353
0
}
354
355
namespace binding_detail {
356
} // namespace binding_detail
357
358
359
bool
360
ObjectOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
361
0
{
362
0
  switch (mType) {
363
0
    case eUninitialized: {
364
0
      return false;
365
0
      break;
366
0
    }
367
0
    case eObject: {
368
0
      JS::ExposeObjectToActiveJS(mValue.mObject.Value());
369
0
      rval.setObject(*mValue.mObject.Value());
370
0
      if (!MaybeWrapObjectValue(cx, rval)) {
371
0
        return false;
372
0
      }
373
0
      return true;
374
0
      break;
375
0
    }
376
0
    case eString: {
377
0
      if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
378
0
        return false;
379
0
      }
380
0
      return true;
381
0
      break;
382
0
    }
383
0
    default: {
384
0
      return false;
385
0
      break;
386
0
    }
387
0
  }
388
0
389
0
  return false;
390
0
}
391
392
393
JSObject*&
394
OwningObjectOrString::RawSetAsObject()
395
0
{
396
0
  if (mType == eObject) {
397
0
    return mValue.mObject.Value();
398
0
  }
399
0
  MOZ_ASSERT(mType == eUninitialized);
400
0
  mType = eObject;
401
0
  return mValue.mObject.SetValue();
402
0
}
403
404
JSObject*&
405
OwningObjectOrString::SetAsObject()
406
0
{
407
0
  if (mType == eObject) {
408
0
    return mValue.mObject.Value();
409
0
  }
410
0
  Uninit();
411
0
  mType = eObject;
412
0
  return mValue.mObject.SetValue();
413
0
}
414
415
416
void
417
OwningObjectOrString::DestroyObject()
418
0
{
419
0
  MOZ_ASSERT(IsObject(), "Wrong type!");
420
0
  mValue.mObject.Destroy();
421
0
  mType = eUninitialized;
422
0
}
423
424
425
426
427
nsString&
428
OwningObjectOrString::RawSetAsString()
429
0
{
430
0
  if (mType == eString) {
431
0
    return mValue.mString.Value();
432
0
  }
433
0
  MOZ_ASSERT(mType == eUninitialized);
434
0
  mType = eString;
435
0
  return mValue.mString.SetValue();
436
0
}
437
438
nsString&
439
OwningObjectOrString::SetAsString()
440
0
{
441
0
  if (mType == eString) {
442
0
    return mValue.mString.Value();
443
0
  }
444
0
  Uninit();
445
0
  mType = eString;
446
0
  return mValue.mString.SetValue();
447
0
}
448
449
bool
450
OwningObjectOrString::TrySetToString(JSContext* cx, JS::Handle<JS::Value> value, bool& tryNext, bool passedToJSImpl)
451
0
{
452
0
  tryNext = false;
453
0
  { // scope for memberSlot
454
0
    nsString& memberSlot = RawSetAsString();
455
0
    if (!ConvertJSValueToString(cx, value, eStringify, eStringify, memberSlot)) {
456
0
      return false;
457
0
    }
458
0
  }
459
0
  return true;
460
0
}
461
462
463
void
464
OwningObjectOrString::DestroyString()
465
0
{
466
0
  MOZ_ASSERT(IsString(), "Wrong type!");
467
0
  mValue.mString.Destroy();
468
0
  mType = eUninitialized;
469
0
}
470
471
472
473
474
void
475
OwningObjectOrString::Uninit()
476
{
477
  switch (mType) {
478
    case eUninitialized: {
479
      break;
480
    }
481
    case eObject: {
482
      DestroyObject();
483
      break;
484
    }
485
    case eString: {
486
      DestroyString();
487
      break;
488
    }
489
  }
490
}
491
492
bool
493
OwningObjectOrString::ToJSVal(JSContext* cx, JS::Handle<JSObject*> scopeObj, JS::MutableHandle<JS::Value> rval) const
494
0
{
495
0
  switch (mType) {
496
0
    case eUninitialized: {
497
0
      return false;
498
0
      break;
499
0
    }
500
0
    case eObject: {
501
0
      JS::ExposeObjectToActiveJS(mValue.mObject.Value());
502
0
      rval.setObject(*mValue.mObject.Value());
503
0
      if (!MaybeWrapObjectValue(cx, rval)) {
504
0
        return false;
505
0
      }
506
0
      return true;
507
0
      break;
508
0
    }
509
0
    case eString: {
510
0
      if (!xpc::NonVoidStringToJsval(cx, mValue.mString.Value(), rval)) {
511
0
        return false;
512
0
      }
513
0
      return true;
514
0
      break;
515
0
    }
516
0
    default: {
517
0
      return false;
518
0
      break;
519
0
    }
520
0
  }
521
0
522
0
  return false;
523
0
}
524
525
void
526
OwningObjectOrString::TraceUnion(JSTracer* trc)
527
{
528
  switch (mType) {
529
    case eObject: {
530
      JS::UnsafeTraceRoot(trc, &mValue.mObject.Value(), "mValue.mObject");
531
      break;
532
    }
533
    default: {
534
      break;
535
    }
536
  }
537
}
538
539
540
541
RsaOtherPrimesInfo::RsaOtherPrimesInfo()
542
0
{
543
0
  // Safe to pass a null context if we pass a null value
544
0
  Init(nullptr, JS::NullHandleValue);
545
0
}
546
547
548
549
bool
550
RsaOtherPrimesInfo::InitIds(JSContext* cx, RsaOtherPrimesInfoAtoms* atomsCache)
551
0
{
552
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
553
0
554
0
  // Initialize these in reverse order so that any failure leaves the first one
555
0
  // uninitialized.
556
0
  if (!atomsCache->t_id.init(cx, "t") ||
557
0
      !atomsCache->r_id.init(cx, "r") ||
558
0
      !atomsCache->d_id.init(cx, "d")) {
559
0
    return false;
560
0
  }
561
0
  return true;
562
0
}
563
564
bool
565
RsaOtherPrimesInfo::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
566
0
{
567
0
  // Passing a null JSContext is OK only if we're initing from null,
568
0
  // Since in that case we will not have to do any property gets
569
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
570
0
  // checkers by static analysis tools
571
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
572
0
  RsaOtherPrimesInfoAtoms* atomsCache = nullptr;
573
0
  if (cx) {
574
0
    atomsCache = GetAtomCache<RsaOtherPrimesInfoAtoms>(cx);
575
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
576
0
      return false;
577
0
    }
578
0
  }
579
0
580
0
  if (!IsConvertibleToDictionary(val)) {
581
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
582
0
  }
583
0
584
0
  bool isNull = val.isNullOrUndefined();
585
0
  // We only need these if !isNull, in which case we have |cx|.
586
0
  Maybe<JS::Rooted<JSObject *> > object;
587
0
  Maybe<JS::Rooted<JS::Value> > temp;
588
0
  if (!isNull) {
589
0
    MOZ_ASSERT(cx);
590
0
    object.emplace(cx, &val.toObject());
591
0
    temp.emplace(cx);
592
0
  }
593
0
  if (!isNull) {
594
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->d_id, temp.ptr())) {
595
0
      return false;
596
0
    }
597
0
  }
598
0
  if (!isNull && !temp->isUndefined()) {
599
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mD)) {
600
0
      return false;
601
0
    }
602
0
    mIsAnyMemberPresent = true;
603
0
  } else if (cx) {
604
0
    // Don't error out if we have no cx.  In that
605
0
    // situation the caller is default-constructing us and we'll
606
0
    // just assume they know what they're doing.
607
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
608
0
                             "'d' member of RsaOtherPrimesInfo");
609
0
  }
610
0
611
0
  if (!isNull) {
612
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->r_id, temp.ptr())) {
613
0
      return false;
614
0
    }
615
0
  }
616
0
  if (!isNull && !temp->isUndefined()) {
617
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mR)) {
618
0
      return false;
619
0
    }
620
0
    mIsAnyMemberPresent = true;
621
0
  } else if (cx) {
622
0
    // Don't error out if we have no cx.  In that
623
0
    // situation the caller is default-constructing us and we'll
624
0
    // just assume they know what they're doing.
625
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
626
0
                             "'r' member of RsaOtherPrimesInfo");
627
0
  }
628
0
629
0
  if (!isNull) {
630
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->t_id, temp.ptr())) {
631
0
      return false;
632
0
    }
633
0
  }
634
0
  if (!isNull && !temp->isUndefined()) {
635
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mT)) {
636
0
      return false;
637
0
    }
638
0
    mIsAnyMemberPresent = true;
639
0
  } else if (cx) {
640
0
    // Don't error out if we have no cx.  In that
641
0
    // situation the caller is default-constructing us and we'll
642
0
    // just assume they know what they're doing.
643
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
644
0
                             "'t' member of RsaOtherPrimesInfo");
645
0
  }
646
0
  return true;
647
0
}
648
649
bool
650
RsaOtherPrimesInfo::Init(const nsAString& aJSON)
651
0
{
652
0
  AutoJSAPI jsapi;
653
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
654
0
  if (!cleanGlobal) {
655
0
    return false;
656
0
  }
657
0
  if (!jsapi.Init(cleanGlobal)) {
658
0
    return false;
659
0
  }
660
0
  JSContext* cx = jsapi.cx();
661
0
  JS::Rooted<JS::Value> json(cx);
662
0
  bool ok = ParseJSON(cx, aJSON, &json);
663
0
  NS_ENSURE_TRUE(ok, false);
664
0
  return Init(cx, json);
665
0
}
666
667
bool
668
RsaOtherPrimesInfo::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
669
0
{
670
0
  RsaOtherPrimesInfoAtoms* atomsCache = GetAtomCache<RsaOtherPrimesInfoAtoms>(cx);
671
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
672
0
    return false;
673
0
  }
674
0
675
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
676
0
  if (!obj) {
677
0
    return false;
678
0
  }
679
0
  rval.set(JS::ObjectValue(*obj));
680
0
681
0
  do {
682
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
683
0
    JS::Rooted<JS::Value> temp(cx);
684
0
    nsString const & currentValue = mD;
685
0
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
686
0
      return false;
687
0
    }
688
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->d_id, temp, JSPROP_ENUMERATE)) {
689
0
      return false;
690
0
    }
691
0
    break;
692
0
  } while(false);
693
0
694
0
  do {
695
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
696
0
    JS::Rooted<JS::Value> temp(cx);
697
0
    nsString const & currentValue = mR;
698
0
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
699
0
      return false;
700
0
    }
701
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->r_id, temp, JSPROP_ENUMERATE)) {
702
0
      return false;
703
0
    }
704
0
    break;
705
0
  } while(false);
706
0
707
0
  do {
708
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
709
0
    JS::Rooted<JS::Value> temp(cx);
710
0
    nsString const & currentValue = mT;
711
0
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
712
0
      return false;
713
0
    }
714
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->t_id, temp, JSPROP_ENUMERATE)) {
715
0
      return false;
716
0
    }
717
0
    break;
718
0
  } while(false);
719
0
720
0
  return true;
721
0
}
722
723
bool
724
RsaOtherPrimesInfo::ToJSON(nsAString& aJSON) const
725
0
{
726
0
  AutoJSAPI jsapi;
727
0
  jsapi.Init();
728
0
  JSContext *cx = jsapi.cx();
729
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
730
0
  // because we'll only be creating objects, in ways that have no
731
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
732
0
  // which likewise guarantees no side-effects for the sorts of
733
0
  // things we will pass it.
734
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
735
0
  JS::Rooted<JS::Value> val(cx);
736
0
  if (!ToObjectInternal(cx, &val)) {
737
0
    return false;
738
0
  }
739
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
740
0
  return StringifyToJSON(cx, obj, aJSON);
741
0
}
742
743
void
744
RsaOtherPrimesInfo::TraceDictionary(JSTracer* trc)
745
0
{
746
0
}
747
748
RsaOtherPrimesInfo&
749
RsaOtherPrimesInfo::operator=(const RsaOtherPrimesInfo& aOther)
750
0
{
751
0
  DictionaryBase::operator=(aOther);
752
0
  mD = aOther.mD;
753
0
  mR = aOther.mR;
754
0
  mT = aOther.mT;
755
0
  return *this;
756
0
}
757
758
namespace binding_detail {
759
} // namespace binding_detail
760
761
762
763
AesCbcParams::AesCbcParams()
764
  : Algorithm(FastDictionaryInitializer())
765
0
{
766
0
  // Safe to pass a null context if we pass a null value
767
0
  Init(nullptr, JS::NullHandleValue);
768
0
}
769
770
771
bool
772
AesCbcParams::InitIds(JSContext* cx, AesCbcParamsAtoms* atomsCache)
773
0
{
774
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
775
0
776
0
  // Initialize these in reverse order so that any failure leaves the first one
777
0
  // uninitialized.
778
0
  if (!atomsCache->iv_id.init(cx, "iv")) {
779
0
    return false;
780
0
  }
781
0
  return true;
782
0
}
783
784
bool
785
AesCbcParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
786
0
{
787
0
  // Passing a null JSContext is OK only if we're initing from null,
788
0
  // Since in that case we will not have to do any property gets
789
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
790
0
  // checkers by static analysis tools
791
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
792
0
  AesCbcParamsAtoms* atomsCache = nullptr;
793
0
  if (cx) {
794
0
    atomsCache = GetAtomCache<AesCbcParamsAtoms>(cx);
795
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
796
0
      return false;
797
0
    }
798
0
  }
799
0
800
0
  // Per spec, we init the parent's members first
801
0
  if (!Algorithm::Init(cx, val)) {
802
0
    return false;
803
0
  }
804
0
805
0
  bool isNull = val.isNullOrUndefined();
806
0
  // We only need these if !isNull, in which case we have |cx|.
807
0
  Maybe<JS::Rooted<JSObject *> > object;
808
0
  Maybe<JS::Rooted<JS::Value> > temp;
809
0
  if (!isNull) {
810
0
    MOZ_ASSERT(cx);
811
0
    object.emplace(cx, &val.toObject());
812
0
    temp.emplace(cx);
813
0
  }
814
0
  if (!isNull) {
815
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->iv_id, temp.ptr())) {
816
0
      return false;
817
0
    }
818
0
  }
819
0
  if (!isNull && !temp->isUndefined()) {
820
0
    {
821
0
      bool done = false, failed = false, tryNext;
822
0
      if (temp.ref().isObject()) {
823
0
        done = (failed = !mIv.TrySetToArrayBufferView(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext ||
824
0
               (failed = !mIv.TrySetToArrayBuffer(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext;
825
0
826
0
      }
827
0
      if (failed) {
828
0
        return false;
829
0
      }
830
0
      if (!done) {
831
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'iv' member of AesCbcParams", "ArrayBufferView, ArrayBuffer");
832
0
        return false;
833
0
      }
834
0
    }
835
0
    mIsAnyMemberPresent = true;
836
0
  } else if (cx) {
837
0
    // Don't error out if we have no cx.  In that
838
0
    // situation the caller is default-constructing us and we'll
839
0
    // just assume they know what they're doing.
840
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
841
0
                             "'iv' member of AesCbcParams");
842
0
  }
843
0
  return true;
844
0
}
845
846
bool
847
AesCbcParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
848
0
{
849
0
  AesCbcParamsAtoms* atomsCache = GetAtomCache<AesCbcParamsAtoms>(cx);
850
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
851
0
    return false;
852
0
  }
853
0
854
0
  // Per spec, we define the parent's members first
855
0
  if (!Algorithm::ToObjectInternal(cx, rval)) {
856
0
    return false;
857
0
  }
858
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
859
0
860
0
  do {
861
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
862
0
    JS::Rooted<JS::Value> temp(cx);
863
0
    OwningArrayBufferViewOrArrayBuffer const & currentValue = mIv;
864
0
    if (!currentValue.ToJSVal(cx, obj, &temp)) {
865
0
      return false;
866
0
    }
867
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->iv_id, temp, JSPROP_ENUMERATE)) {
868
0
      return false;
869
0
    }
870
0
    break;
871
0
  } while(false);
872
0
873
0
  return true;
874
0
}
875
876
void
877
AesCbcParams::TraceDictionary(JSTracer* trc)
878
0
{
879
0
  Algorithm::TraceDictionary(trc);
880
0
  mIv.TraceUnion(trc);
881
0
}
882
883
namespace binding_detail {
884
} // namespace binding_detail
885
886
887
888
AesCtrParams::AesCtrParams()
889
  : Algorithm(FastDictionaryInitializer())
890
0
{
891
0
  // Safe to pass a null context if we pass a null value
892
0
  Init(nullptr, JS::NullHandleValue);
893
0
}
894
895
896
bool
897
AesCtrParams::InitIds(JSContext* cx, AesCtrParamsAtoms* atomsCache)
898
0
{
899
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
900
0
901
0
  // Initialize these in reverse order so that any failure leaves the first one
902
0
  // uninitialized.
903
0
  if (!atomsCache->length_id.init(cx, "length") ||
904
0
      !atomsCache->counter_id.init(cx, "counter")) {
905
0
    return false;
906
0
  }
907
0
  return true;
908
0
}
909
910
bool
911
AesCtrParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
912
0
{
913
0
  // Passing a null JSContext is OK only if we're initing from null,
914
0
  // Since in that case we will not have to do any property gets
915
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
916
0
  // checkers by static analysis tools
917
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
918
0
  AesCtrParamsAtoms* atomsCache = nullptr;
919
0
  if (cx) {
920
0
    atomsCache = GetAtomCache<AesCtrParamsAtoms>(cx);
921
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
922
0
      return false;
923
0
    }
924
0
  }
925
0
926
0
  // Per spec, we init the parent's members first
927
0
  if (!Algorithm::Init(cx, val)) {
928
0
    return false;
929
0
  }
930
0
931
0
  bool isNull = val.isNullOrUndefined();
932
0
  // We only need these if !isNull, in which case we have |cx|.
933
0
  Maybe<JS::Rooted<JSObject *> > object;
934
0
  Maybe<JS::Rooted<JS::Value> > temp;
935
0
  if (!isNull) {
936
0
    MOZ_ASSERT(cx);
937
0
    object.emplace(cx, &val.toObject());
938
0
    temp.emplace(cx);
939
0
  }
940
0
  if (!isNull) {
941
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->counter_id, temp.ptr())) {
942
0
      return false;
943
0
    }
944
0
  }
945
0
  if (!isNull && !temp->isUndefined()) {
946
0
    {
947
0
      bool done = false, failed = false, tryNext;
948
0
      if (temp.ref().isObject()) {
949
0
        done = (failed = !mCounter.TrySetToArrayBufferView(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext ||
950
0
               (failed = !mCounter.TrySetToArrayBuffer(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext;
951
0
952
0
      }
953
0
      if (failed) {
954
0
        return false;
955
0
      }
956
0
      if (!done) {
957
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'counter' member of AesCtrParams", "ArrayBufferView, ArrayBuffer");
958
0
        return false;
959
0
      }
960
0
    }
961
0
    mIsAnyMemberPresent = true;
962
0
  } else if (cx) {
963
0
    // Don't error out if we have no cx.  In that
964
0
    // situation the caller is default-constructing us and we'll
965
0
    // just assume they know what they're doing.
966
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
967
0
                             "'counter' member of AesCtrParams");
968
0
  }
969
0
970
0
  if (!isNull) {
971
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->length_id, temp.ptr())) {
972
0
      return false;
973
0
    }
974
0
  }
975
0
  if (!isNull && !temp->isUndefined()) {
976
0
    if (!ValueToPrimitive<uint8_t, eEnforceRange>(cx, temp.ref(), &mLength)) {
977
0
      return false;
978
0
    }
979
0
    mIsAnyMemberPresent = true;
980
0
  } else if (cx) {
981
0
    // Don't error out if we have no cx.  In that
982
0
    // situation the caller is default-constructing us and we'll
983
0
    // just assume they know what they're doing.
984
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
985
0
                             "'length' member of AesCtrParams");
986
0
  }
987
0
  return true;
988
0
}
989
990
bool
991
AesCtrParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
992
0
{
993
0
  AesCtrParamsAtoms* atomsCache = GetAtomCache<AesCtrParamsAtoms>(cx);
994
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
995
0
    return false;
996
0
  }
997
0
998
0
  // Per spec, we define the parent's members first
999
0
  if (!Algorithm::ToObjectInternal(cx, rval)) {
1000
0
    return false;
1001
0
  }
1002
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
1003
0
1004
0
  do {
1005
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1006
0
    JS::Rooted<JS::Value> temp(cx);
1007
0
    OwningArrayBufferViewOrArrayBuffer const & currentValue = mCounter;
1008
0
    if (!currentValue.ToJSVal(cx, obj, &temp)) {
1009
0
      return false;
1010
0
    }
1011
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->counter_id, temp, JSPROP_ENUMERATE)) {
1012
0
      return false;
1013
0
    }
1014
0
    break;
1015
0
  } while(false);
1016
0
1017
0
  do {
1018
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1019
0
    JS::Rooted<JS::Value> temp(cx);
1020
0
    uint8_t const & currentValue = mLength;
1021
0
    temp.setInt32(int32_t(currentValue));
1022
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->length_id, temp, JSPROP_ENUMERATE)) {
1023
0
      return false;
1024
0
    }
1025
0
    break;
1026
0
  } while(false);
1027
0
1028
0
  return true;
1029
0
}
1030
1031
void
1032
AesCtrParams::TraceDictionary(JSTracer* trc)
1033
0
{
1034
0
  Algorithm::TraceDictionary(trc);
1035
0
  mCounter.TraceUnion(trc);
1036
0
}
1037
1038
namespace binding_detail {
1039
} // namespace binding_detail
1040
1041
1042
1043
AesDerivedKeyParams::AesDerivedKeyParams()
1044
  : Algorithm(FastDictionaryInitializer())
1045
0
{
1046
0
  // Safe to pass a null context if we pass a null value
1047
0
  Init(nullptr, JS::NullHandleValue);
1048
0
}
1049
1050
1051
1052
bool
1053
AesDerivedKeyParams::InitIds(JSContext* cx, AesDerivedKeyParamsAtoms* atomsCache)
1054
0
{
1055
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1056
0
1057
0
  // Initialize these in reverse order so that any failure leaves the first one
1058
0
  // uninitialized.
1059
0
  if (!atomsCache->length_id.init(cx, "length")) {
1060
0
    return false;
1061
0
  }
1062
0
  return true;
1063
0
}
1064
1065
bool
1066
AesDerivedKeyParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1067
0
{
1068
0
  // Passing a null JSContext is OK only if we're initing from null,
1069
0
  // Since in that case we will not have to do any property gets
1070
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
1071
0
  // checkers by static analysis tools
1072
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1073
0
  AesDerivedKeyParamsAtoms* atomsCache = nullptr;
1074
0
  if (cx) {
1075
0
    atomsCache = GetAtomCache<AesDerivedKeyParamsAtoms>(cx);
1076
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1077
0
      return false;
1078
0
    }
1079
0
  }
1080
0
1081
0
  // Per spec, we init the parent's members first
1082
0
  if (!Algorithm::Init(cx, val)) {
1083
0
    return false;
1084
0
  }
1085
0
1086
0
  bool isNull = val.isNullOrUndefined();
1087
0
  // We only need these if !isNull, in which case we have |cx|.
1088
0
  Maybe<JS::Rooted<JSObject *> > object;
1089
0
  Maybe<JS::Rooted<JS::Value> > temp;
1090
0
  if (!isNull) {
1091
0
    MOZ_ASSERT(cx);
1092
0
    object.emplace(cx, &val.toObject());
1093
0
    temp.emplace(cx);
1094
0
  }
1095
0
  if (!isNull) {
1096
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->length_id, temp.ptr())) {
1097
0
      return false;
1098
0
    }
1099
0
  }
1100
0
  if (!isNull && !temp->isUndefined()) {
1101
0
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), &mLength)) {
1102
0
      return false;
1103
0
    }
1104
0
    mIsAnyMemberPresent = true;
1105
0
  } else if (cx) {
1106
0
    // Don't error out if we have no cx.  In that
1107
0
    // situation the caller is default-constructing us and we'll
1108
0
    // just assume they know what they're doing.
1109
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
1110
0
                             "'length' member of AesDerivedKeyParams");
1111
0
  }
1112
0
  return true;
1113
0
}
1114
1115
bool
1116
AesDerivedKeyParams::Init(const nsAString& aJSON)
1117
0
{
1118
0
  AutoJSAPI jsapi;
1119
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
1120
0
  if (!cleanGlobal) {
1121
0
    return false;
1122
0
  }
1123
0
  if (!jsapi.Init(cleanGlobal)) {
1124
0
    return false;
1125
0
  }
1126
0
  JSContext* cx = jsapi.cx();
1127
0
  JS::Rooted<JS::Value> json(cx);
1128
0
  bool ok = ParseJSON(cx, aJSON, &json);
1129
0
  NS_ENSURE_TRUE(ok, false);
1130
0
  return Init(cx, json);
1131
0
}
1132
1133
bool
1134
AesDerivedKeyParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1135
0
{
1136
0
  AesDerivedKeyParamsAtoms* atomsCache = GetAtomCache<AesDerivedKeyParamsAtoms>(cx);
1137
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1138
0
    return false;
1139
0
  }
1140
0
1141
0
  // Per spec, we define the parent's members first
1142
0
  if (!Algorithm::ToObjectInternal(cx, rval)) {
1143
0
    return false;
1144
0
  }
1145
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
1146
0
1147
0
  do {
1148
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1149
0
    JS::Rooted<JS::Value> temp(cx);
1150
0
    uint32_t const & currentValue = mLength;
1151
0
    temp.setNumber(currentValue);
1152
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->length_id, temp, JSPROP_ENUMERATE)) {
1153
0
      return false;
1154
0
    }
1155
0
    break;
1156
0
  } while(false);
1157
0
1158
0
  return true;
1159
0
}
1160
1161
bool
1162
AesDerivedKeyParams::ToJSON(nsAString& aJSON) const
1163
0
{
1164
0
  AutoJSAPI jsapi;
1165
0
  jsapi.Init();
1166
0
  JSContext *cx = jsapi.cx();
1167
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
1168
0
  // because we'll only be creating objects, in ways that have no
1169
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
1170
0
  // which likewise guarantees no side-effects for the sorts of
1171
0
  // things we will pass it.
1172
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
1173
0
  JS::Rooted<JS::Value> val(cx);
1174
0
  if (!ToObjectInternal(cx, &val)) {
1175
0
    return false;
1176
0
  }
1177
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
1178
0
  return StringifyToJSON(cx, obj, aJSON);
1179
0
}
1180
1181
void
1182
AesDerivedKeyParams::TraceDictionary(JSTracer* trc)
1183
0
{
1184
0
  Algorithm::TraceDictionary(trc);
1185
0
}
1186
1187
AesDerivedKeyParams&
1188
AesDerivedKeyParams::operator=(const AesDerivedKeyParams& aOther)
1189
0
{
1190
0
  Algorithm::operator=(aOther);
1191
0
  mLength = aOther.mLength;
1192
0
  return *this;
1193
0
}
1194
1195
namespace binding_detail {
1196
} // namespace binding_detail
1197
1198
1199
1200
AesGcmParams::AesGcmParams()
1201
  : Algorithm(FastDictionaryInitializer())
1202
0
{
1203
0
  // Safe to pass a null context if we pass a null value
1204
0
  Init(nullptr, JS::NullHandleValue);
1205
0
}
1206
1207
1208
bool
1209
AesGcmParams::InitIds(JSContext* cx, AesGcmParamsAtoms* atomsCache)
1210
0
{
1211
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1212
0
1213
0
  // Initialize these in reverse order so that any failure leaves the first one
1214
0
  // uninitialized.
1215
0
  if (!atomsCache->tagLength_id.init(cx, "tagLength") ||
1216
0
      !atomsCache->iv_id.init(cx, "iv") ||
1217
0
      !atomsCache->additionalData_id.init(cx, "additionalData")) {
1218
0
    return false;
1219
0
  }
1220
0
  return true;
1221
0
}
1222
1223
bool
1224
AesGcmParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1225
0
{
1226
0
  // Passing a null JSContext is OK only if we're initing from null,
1227
0
  // Since in that case we will not have to do any property gets
1228
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
1229
0
  // checkers by static analysis tools
1230
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1231
0
  AesGcmParamsAtoms* atomsCache = nullptr;
1232
0
  if (cx) {
1233
0
    atomsCache = GetAtomCache<AesGcmParamsAtoms>(cx);
1234
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1235
0
      return false;
1236
0
    }
1237
0
  }
1238
0
1239
0
  // Per spec, we init the parent's members first
1240
0
  if (!Algorithm::Init(cx, val)) {
1241
0
    return false;
1242
0
  }
1243
0
1244
0
  bool isNull = val.isNullOrUndefined();
1245
0
  // We only need these if !isNull, in which case we have |cx|.
1246
0
  Maybe<JS::Rooted<JSObject *> > object;
1247
0
  Maybe<JS::Rooted<JS::Value> > temp;
1248
0
  if (!isNull) {
1249
0
    MOZ_ASSERT(cx);
1250
0
    object.emplace(cx, &val.toObject());
1251
0
    temp.emplace(cx);
1252
0
  }
1253
0
  if (!isNull) {
1254
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->additionalData_id, temp.ptr())) {
1255
0
      return false;
1256
0
    }
1257
0
  }
1258
0
  if (!isNull && !temp->isUndefined()) {
1259
0
    mAdditionalData.Construct();
1260
0
    {
1261
0
      bool done = false, failed = false, tryNext;
1262
0
      if (temp.ref().isObject()) {
1263
0
        done = (failed = !(mAdditionalData.Value()).TrySetToArrayBufferView(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext ||
1264
0
               (failed = !(mAdditionalData.Value()).TrySetToArrayBuffer(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext;
1265
0
1266
0
      }
1267
0
      if (failed) {
1268
0
        return false;
1269
0
      }
1270
0
      if (!done) {
1271
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'additionalData' member of AesGcmParams", "ArrayBufferView, ArrayBuffer");
1272
0
        return false;
1273
0
      }
1274
0
    }
1275
0
    mIsAnyMemberPresent = true;
1276
0
  }
1277
0
1278
0
  if (!isNull) {
1279
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->iv_id, temp.ptr())) {
1280
0
      return false;
1281
0
    }
1282
0
  }
1283
0
  if (!isNull && !temp->isUndefined()) {
1284
0
    {
1285
0
      bool done = false, failed = false, tryNext;
1286
0
      if (temp.ref().isObject()) {
1287
0
        done = (failed = !mIv.TrySetToArrayBufferView(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext ||
1288
0
               (failed = !mIv.TrySetToArrayBuffer(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext;
1289
0
1290
0
      }
1291
0
      if (failed) {
1292
0
        return false;
1293
0
      }
1294
0
      if (!done) {
1295
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'iv' member of AesGcmParams", "ArrayBufferView, ArrayBuffer");
1296
0
        return false;
1297
0
      }
1298
0
    }
1299
0
    mIsAnyMemberPresent = true;
1300
0
  } else if (cx) {
1301
0
    // Don't error out if we have no cx.  In that
1302
0
    // situation the caller is default-constructing us and we'll
1303
0
    // just assume they know what they're doing.
1304
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
1305
0
                             "'iv' member of AesGcmParams");
1306
0
  }
1307
0
1308
0
  if (!isNull) {
1309
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->tagLength_id, temp.ptr())) {
1310
0
      return false;
1311
0
    }
1312
0
  }
1313
0
  if (!isNull && !temp->isUndefined()) {
1314
0
    mTagLength.Construct();
1315
0
    if (!ValueToPrimitive<uint8_t, eEnforceRange>(cx, temp.ref(), &(mTagLength.Value()))) {
1316
0
      return false;
1317
0
    }
1318
0
    mIsAnyMemberPresent = true;
1319
0
  }
1320
0
  return true;
1321
0
}
1322
1323
bool
1324
AesGcmParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1325
0
{
1326
0
  AesGcmParamsAtoms* atomsCache = GetAtomCache<AesGcmParamsAtoms>(cx);
1327
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1328
0
    return false;
1329
0
  }
1330
0
1331
0
  // Per spec, we define the parent's members first
1332
0
  if (!Algorithm::ToObjectInternal(cx, rval)) {
1333
0
    return false;
1334
0
  }
1335
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
1336
0
1337
0
  if (mAdditionalData.WasPassed()) {
1338
0
    do {
1339
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1340
0
      JS::Rooted<JS::Value> temp(cx);
1341
0
      OwningArrayBufferViewOrArrayBuffer const & currentValue = mAdditionalData.InternalValue();
1342
0
      if (!currentValue.ToJSVal(cx, obj, &temp)) {
1343
0
        return false;
1344
0
      }
1345
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->additionalData_id, temp, JSPROP_ENUMERATE)) {
1346
0
        return false;
1347
0
      }
1348
0
      break;
1349
0
    } while(false);
1350
0
  }
1351
0
1352
0
  do {
1353
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1354
0
    JS::Rooted<JS::Value> temp(cx);
1355
0
    OwningArrayBufferViewOrArrayBuffer const & currentValue = mIv;
1356
0
    if (!currentValue.ToJSVal(cx, obj, &temp)) {
1357
0
      return false;
1358
0
    }
1359
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->iv_id, temp, JSPROP_ENUMERATE)) {
1360
0
      return false;
1361
0
    }
1362
0
    break;
1363
0
  } while(false);
1364
0
1365
0
  if (mTagLength.WasPassed()) {
1366
0
    do {
1367
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1368
0
      JS::Rooted<JS::Value> temp(cx);
1369
0
      uint8_t const & currentValue = mTagLength.InternalValue();
1370
0
      temp.setInt32(int32_t(currentValue));
1371
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->tagLength_id, temp, JSPROP_ENUMERATE)) {
1372
0
        return false;
1373
0
      }
1374
0
      break;
1375
0
    } while(false);
1376
0
  }
1377
0
1378
0
  return true;
1379
0
}
1380
1381
void
1382
AesGcmParams::TraceDictionary(JSTracer* trc)
1383
0
{
1384
0
  Algorithm::TraceDictionary(trc);
1385
0
  if (mAdditionalData.WasPassed()) {
1386
0
    mAdditionalData.Value().TraceUnion(trc);
1387
0
  }
1388
0
1389
0
  mIv.TraceUnion(trc);
1390
0
}
1391
1392
namespace binding_detail {
1393
} // namespace binding_detail
1394
1395
1396
1397
AesKeyGenParams::AesKeyGenParams()
1398
  : Algorithm(FastDictionaryInitializer())
1399
0
{
1400
0
  // Safe to pass a null context if we pass a null value
1401
0
  Init(nullptr, JS::NullHandleValue);
1402
0
}
1403
1404
1405
1406
bool
1407
AesKeyGenParams::InitIds(JSContext* cx, AesKeyGenParamsAtoms* atomsCache)
1408
0
{
1409
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1410
0
1411
0
  // Initialize these in reverse order so that any failure leaves the first one
1412
0
  // uninitialized.
1413
0
  if (!atomsCache->length_id.init(cx, "length")) {
1414
0
    return false;
1415
0
  }
1416
0
  return true;
1417
0
}
1418
1419
bool
1420
AesKeyGenParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1421
0
{
1422
0
  // Passing a null JSContext is OK only if we're initing from null,
1423
0
  // Since in that case we will not have to do any property gets
1424
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
1425
0
  // checkers by static analysis tools
1426
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1427
0
  AesKeyGenParamsAtoms* atomsCache = nullptr;
1428
0
  if (cx) {
1429
0
    atomsCache = GetAtomCache<AesKeyGenParamsAtoms>(cx);
1430
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1431
0
      return false;
1432
0
    }
1433
0
  }
1434
0
1435
0
  // Per spec, we init the parent's members first
1436
0
  if (!Algorithm::Init(cx, val)) {
1437
0
    return false;
1438
0
  }
1439
0
1440
0
  bool isNull = val.isNullOrUndefined();
1441
0
  // We only need these if !isNull, in which case we have |cx|.
1442
0
  Maybe<JS::Rooted<JSObject *> > object;
1443
0
  Maybe<JS::Rooted<JS::Value> > temp;
1444
0
  if (!isNull) {
1445
0
    MOZ_ASSERT(cx);
1446
0
    object.emplace(cx, &val.toObject());
1447
0
    temp.emplace(cx);
1448
0
  }
1449
0
  if (!isNull) {
1450
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->length_id, temp.ptr())) {
1451
0
      return false;
1452
0
    }
1453
0
  }
1454
0
  if (!isNull && !temp->isUndefined()) {
1455
0
    if (!ValueToPrimitive<uint16_t, eEnforceRange>(cx, temp.ref(), &mLength)) {
1456
0
      return false;
1457
0
    }
1458
0
    mIsAnyMemberPresent = true;
1459
0
  } else if (cx) {
1460
0
    // Don't error out if we have no cx.  In that
1461
0
    // situation the caller is default-constructing us and we'll
1462
0
    // just assume they know what they're doing.
1463
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
1464
0
                             "'length' member of AesKeyGenParams");
1465
0
  }
1466
0
  return true;
1467
0
}
1468
1469
bool
1470
AesKeyGenParams::Init(const nsAString& aJSON)
1471
0
{
1472
0
  AutoJSAPI jsapi;
1473
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
1474
0
  if (!cleanGlobal) {
1475
0
    return false;
1476
0
  }
1477
0
  if (!jsapi.Init(cleanGlobal)) {
1478
0
    return false;
1479
0
  }
1480
0
  JSContext* cx = jsapi.cx();
1481
0
  JS::Rooted<JS::Value> json(cx);
1482
0
  bool ok = ParseJSON(cx, aJSON, &json);
1483
0
  NS_ENSURE_TRUE(ok, false);
1484
0
  return Init(cx, json);
1485
0
}
1486
1487
bool
1488
AesKeyGenParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1489
0
{
1490
0
  AesKeyGenParamsAtoms* atomsCache = GetAtomCache<AesKeyGenParamsAtoms>(cx);
1491
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1492
0
    return false;
1493
0
  }
1494
0
1495
0
  // Per spec, we define the parent's members first
1496
0
  if (!Algorithm::ToObjectInternal(cx, rval)) {
1497
0
    return false;
1498
0
  }
1499
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
1500
0
1501
0
  do {
1502
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1503
0
    JS::Rooted<JS::Value> temp(cx);
1504
0
    uint16_t const & currentValue = mLength;
1505
0
    temp.setInt32(int32_t(currentValue));
1506
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->length_id, temp, JSPROP_ENUMERATE)) {
1507
0
      return false;
1508
0
    }
1509
0
    break;
1510
0
  } while(false);
1511
0
1512
0
  return true;
1513
0
}
1514
1515
bool
1516
AesKeyGenParams::ToJSON(nsAString& aJSON) const
1517
0
{
1518
0
  AutoJSAPI jsapi;
1519
0
  jsapi.Init();
1520
0
  JSContext *cx = jsapi.cx();
1521
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
1522
0
  // because we'll only be creating objects, in ways that have no
1523
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
1524
0
  // which likewise guarantees no side-effects for the sorts of
1525
0
  // things we will pass it.
1526
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
1527
0
  JS::Rooted<JS::Value> val(cx);
1528
0
  if (!ToObjectInternal(cx, &val)) {
1529
0
    return false;
1530
0
  }
1531
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
1532
0
  return StringifyToJSON(cx, obj, aJSON);
1533
0
}
1534
1535
void
1536
AesKeyGenParams::TraceDictionary(JSTracer* trc)
1537
0
{
1538
0
  Algorithm::TraceDictionary(trc);
1539
0
}
1540
1541
AesKeyGenParams&
1542
AesKeyGenParams::operator=(const AesKeyGenParams& aOther)
1543
0
{
1544
0
  Algorithm::operator=(aOther);
1545
0
  mLength = aOther.mLength;
1546
0
  return *this;
1547
0
}
1548
1549
namespace binding_detail {
1550
} // namespace binding_detail
1551
1552
1553
1554
DhImportKeyParams::DhImportKeyParams()
1555
  : Algorithm(FastDictionaryInitializer())
1556
0
{
1557
0
  // Safe to pass a null context if we pass a null value
1558
0
  Init(nullptr, JS::NullHandleValue);
1559
0
}
1560
1561
1562
bool
1563
DhImportKeyParams::InitIds(JSContext* cx, DhImportKeyParamsAtoms* atomsCache)
1564
0
{
1565
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1566
0
1567
0
  // Initialize these in reverse order so that any failure leaves the first one
1568
0
  // uninitialized.
1569
0
  if (!atomsCache->prime_id.init(cx, "prime") ||
1570
0
      !atomsCache->generator_id.init(cx, "generator")) {
1571
0
    return false;
1572
0
  }
1573
0
  return true;
1574
0
}
1575
1576
bool
1577
DhImportKeyParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1578
0
{
1579
0
  // Passing a null JSContext is OK only if we're initing from null,
1580
0
  // Since in that case we will not have to do any property gets
1581
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
1582
0
  // checkers by static analysis tools
1583
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1584
0
  DhImportKeyParamsAtoms* atomsCache = nullptr;
1585
0
  if (cx) {
1586
0
    atomsCache = GetAtomCache<DhImportKeyParamsAtoms>(cx);
1587
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1588
0
      return false;
1589
0
    }
1590
0
  }
1591
0
1592
0
  // Per spec, we init the parent's members first
1593
0
  if (!Algorithm::Init(cx, val)) {
1594
0
    return false;
1595
0
  }
1596
0
1597
0
  bool isNull = val.isNullOrUndefined();
1598
0
  // We only need these if !isNull, in which case we have |cx|.
1599
0
  Maybe<JS::Rooted<JSObject *> > object;
1600
0
  Maybe<JS::Rooted<JS::Value> > temp;
1601
0
  if (!isNull) {
1602
0
    MOZ_ASSERT(cx);
1603
0
    object.emplace(cx, &val.toObject());
1604
0
    temp.emplace(cx);
1605
0
  }
1606
0
  if (!isNull) {
1607
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->generator_id, temp.ptr())) {
1608
0
      return false;
1609
0
    }
1610
0
  }
1611
0
  if (!isNull && !temp->isUndefined()) {
1612
0
    if (temp.ref().isObject()) {
1613
0
      if (!mGenerator.Init(&temp.ref().toObject())) {
1614
0
        ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "'generator' member of DhImportKeyParams", "Uint8Array");
1615
0
        return false;
1616
0
      }
1617
0
    } else {
1618
0
      ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'generator' member of DhImportKeyParams");
1619
0
      return false;
1620
0
    }
1621
0
    mIsAnyMemberPresent = true;
1622
0
  } else if (cx) {
1623
0
    // Don't error out if we have no cx.  In that
1624
0
    // situation the caller is default-constructing us and we'll
1625
0
    // just assume they know what they're doing.
1626
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
1627
0
                             "'generator' member of DhImportKeyParams");
1628
0
  }
1629
0
1630
0
  if (!isNull) {
1631
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->prime_id, temp.ptr())) {
1632
0
      return false;
1633
0
    }
1634
0
  }
1635
0
  if (!isNull && !temp->isUndefined()) {
1636
0
    if (temp.ref().isObject()) {
1637
0
      if (!mPrime.Init(&temp.ref().toObject())) {
1638
0
        ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "'prime' member of DhImportKeyParams", "Uint8Array");
1639
0
        return false;
1640
0
      }
1641
0
    } else {
1642
0
      ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'prime' member of DhImportKeyParams");
1643
0
      return false;
1644
0
    }
1645
0
    mIsAnyMemberPresent = true;
1646
0
  } else if (cx) {
1647
0
    // Don't error out if we have no cx.  In that
1648
0
    // situation the caller is default-constructing us and we'll
1649
0
    // just assume they know what they're doing.
1650
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
1651
0
                             "'prime' member of DhImportKeyParams");
1652
0
  }
1653
0
  return true;
1654
0
}
1655
1656
bool
1657
DhImportKeyParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1658
0
{
1659
0
  DhImportKeyParamsAtoms* atomsCache = GetAtomCache<DhImportKeyParamsAtoms>(cx);
1660
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1661
0
    return false;
1662
0
  }
1663
0
1664
0
  // Per spec, we define the parent's members first
1665
0
  if (!Algorithm::ToObjectInternal(cx, rval)) {
1666
0
    return false;
1667
0
  }
1668
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
1669
0
1670
0
  do {
1671
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1672
0
    JS::Rooted<JS::Value> temp(cx);
1673
0
    Uint8Array const & currentValue = mGenerator;
1674
0
    temp.setObject(*currentValue.Obj());
1675
0
    if (!MaybeWrapNonDOMObjectValue(cx, &temp)) {
1676
0
      return false;
1677
0
    }
1678
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->generator_id, temp, JSPROP_ENUMERATE)) {
1679
0
      return false;
1680
0
    }
1681
0
    break;
1682
0
  } while(false);
1683
0
1684
0
  do {
1685
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1686
0
    JS::Rooted<JS::Value> temp(cx);
1687
0
    Uint8Array const & currentValue = mPrime;
1688
0
    temp.setObject(*currentValue.Obj());
1689
0
    if (!MaybeWrapNonDOMObjectValue(cx, &temp)) {
1690
0
      return false;
1691
0
    }
1692
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->prime_id, temp, JSPROP_ENUMERATE)) {
1693
0
      return false;
1694
0
    }
1695
0
    break;
1696
0
  } while(false);
1697
0
1698
0
  return true;
1699
0
}
1700
1701
void
1702
DhImportKeyParams::TraceDictionary(JSTracer* trc)
1703
0
{
1704
0
  Algorithm::TraceDictionary(trc);
1705
0
  mGenerator.TraceSelf(trc);
1706
0
1707
0
  mPrime.TraceSelf(trc);
1708
0
}
1709
1710
namespace binding_detail {
1711
} // namespace binding_detail
1712
1713
1714
1715
DhKeyDeriveParams::DhKeyDeriveParams()
1716
  : Algorithm(FastDictionaryInitializer())
1717
0
{
1718
0
  // Safe to pass a null context if we pass a null value
1719
0
  Init(nullptr, JS::NullHandleValue);
1720
0
}
1721
1722
1723
1724
bool
1725
DhKeyDeriveParams::InitIds(JSContext* cx, DhKeyDeriveParamsAtoms* atomsCache)
1726
0
{
1727
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1728
0
1729
0
  // Initialize these in reverse order so that any failure leaves the first one
1730
0
  // uninitialized.
1731
0
  if (!atomsCache->public_id.init(cx, "public")) {
1732
0
    return false;
1733
0
  }
1734
0
  return true;
1735
0
}
1736
1737
bool
1738
DhKeyDeriveParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1739
0
{
1740
0
  // Passing a null JSContext is OK only if we're initing from null,
1741
0
  // Since in that case we will not have to do any property gets
1742
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
1743
0
  // checkers by static analysis tools
1744
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1745
0
  DhKeyDeriveParamsAtoms* atomsCache = nullptr;
1746
0
  if (cx) {
1747
0
    atomsCache = GetAtomCache<DhKeyDeriveParamsAtoms>(cx);
1748
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1749
0
      return false;
1750
0
    }
1751
0
  }
1752
0
1753
0
  // Per spec, we init the parent's members first
1754
0
  if (!Algorithm::Init(cx, val)) {
1755
0
    return false;
1756
0
  }
1757
0
1758
0
  bool isNull = val.isNullOrUndefined();
1759
0
  // We only need these if !isNull, in which case we have |cx|.
1760
0
  Maybe<JS::Rooted<JSObject *> > object;
1761
0
  Maybe<JS::Rooted<JS::Value> > temp;
1762
0
  if (!isNull) {
1763
0
    MOZ_ASSERT(cx);
1764
0
    object.emplace(cx, &val.toObject());
1765
0
    temp.emplace(cx);
1766
0
  }
1767
0
  if (!isNull) {
1768
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->public_id, temp.ptr())) {
1769
0
      return false;
1770
0
    }
1771
0
  }
1772
0
  if (!isNull && !temp->isUndefined()) {
1773
0
    if (temp.ref().isObject()) {
1774
0
      static_assert(IsRefcounted<mozilla::dom::CryptoKey>::value, "We can only store refcounted classes.");{
1775
0
        nsresult rv = UnwrapObject<prototypes::id::CryptoKey, mozilla::dom::CryptoKey>(temp.ptr(), mPublic);
1776
0
        if (NS_FAILED(rv)) {
1777
0
          ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "'public' member of DhKeyDeriveParams", "CryptoKey");
1778
0
          return false;
1779
0
        }
1780
0
      }
1781
0
    } else {
1782
0
      ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'public' member of DhKeyDeriveParams");
1783
0
      return false;
1784
0
    }
1785
0
    mIsAnyMemberPresent = true;
1786
0
  } else if (cx) {
1787
0
    // Don't error out if we have no cx.  In that
1788
0
    // situation the caller is default-constructing us and we'll
1789
0
    // just assume they know what they're doing.
1790
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
1791
0
                             "'public' member of DhKeyDeriveParams");
1792
0
  }
1793
0
  return true;
1794
0
}
1795
1796
bool
1797
DhKeyDeriveParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1798
0
{
1799
0
  DhKeyDeriveParamsAtoms* atomsCache = GetAtomCache<DhKeyDeriveParamsAtoms>(cx);
1800
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1801
0
    return false;
1802
0
  }
1803
0
1804
0
  // Per spec, we define the parent's members first
1805
0
  if (!Algorithm::ToObjectInternal(cx, rval)) {
1806
0
    return false;
1807
0
  }
1808
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
1809
0
1810
0
  do {
1811
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1812
0
    JS::Rooted<JS::Value> temp(cx);
1813
0
    OwningNonNull<mozilla::dom::CryptoKey> const & currentValue = mPublic;
1814
0
    if (!GetOrCreateDOMReflector(cx, currentValue, &temp)) {
1815
0
      MOZ_ASSERT(JS_IsExceptionPending(cx));
1816
0
      return false;
1817
0
    }
1818
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->public_id, temp, JSPROP_ENUMERATE)) {
1819
0
      return false;
1820
0
    }
1821
0
    break;
1822
0
  } while(false);
1823
0
1824
0
  return true;
1825
0
}
1826
1827
void
1828
DhKeyDeriveParams::TraceDictionary(JSTracer* trc)
1829
0
{
1830
0
  Algorithm::TraceDictionary(trc);
1831
0
}
1832
1833
1834
1835
DhKeyDeriveParams&
1836
DhKeyDeriveParams::operator=(const DhKeyDeriveParams& aOther)
1837
0
{
1838
0
  Algorithm::operator=(aOther);
1839
0
  mPublic = aOther.mPublic;
1840
0
  return *this;
1841
0
}
1842
1843
namespace binding_detail {
1844
} // namespace binding_detail
1845
1846
1847
1848
DhKeyGenParams::DhKeyGenParams()
1849
  : Algorithm(FastDictionaryInitializer())
1850
0
{
1851
0
  // Safe to pass a null context if we pass a null value
1852
0
  Init(nullptr, JS::NullHandleValue);
1853
0
}
1854
1855
1856
bool
1857
DhKeyGenParams::InitIds(JSContext* cx, DhKeyGenParamsAtoms* atomsCache)
1858
0
{
1859
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
1860
0
1861
0
  // Initialize these in reverse order so that any failure leaves the first one
1862
0
  // uninitialized.
1863
0
  if (!atomsCache->prime_id.init(cx, "prime") ||
1864
0
      !atomsCache->generator_id.init(cx, "generator")) {
1865
0
    return false;
1866
0
  }
1867
0
  return true;
1868
0
}
1869
1870
bool
1871
DhKeyGenParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
1872
0
{
1873
0
  // Passing a null JSContext is OK only if we're initing from null,
1874
0
  // Since in that case we will not have to do any property gets
1875
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
1876
0
  // checkers by static analysis tools
1877
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
1878
0
  DhKeyGenParamsAtoms* atomsCache = nullptr;
1879
0
  if (cx) {
1880
0
    atomsCache = GetAtomCache<DhKeyGenParamsAtoms>(cx);
1881
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1882
0
      return false;
1883
0
    }
1884
0
  }
1885
0
1886
0
  // Per spec, we init the parent's members first
1887
0
  if (!Algorithm::Init(cx, val)) {
1888
0
    return false;
1889
0
  }
1890
0
1891
0
  bool isNull = val.isNullOrUndefined();
1892
0
  // We only need these if !isNull, in which case we have |cx|.
1893
0
  Maybe<JS::Rooted<JSObject *> > object;
1894
0
  Maybe<JS::Rooted<JS::Value> > temp;
1895
0
  if (!isNull) {
1896
0
    MOZ_ASSERT(cx);
1897
0
    object.emplace(cx, &val.toObject());
1898
0
    temp.emplace(cx);
1899
0
  }
1900
0
  if (!isNull) {
1901
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->generator_id, temp.ptr())) {
1902
0
      return false;
1903
0
    }
1904
0
  }
1905
0
  if (!isNull && !temp->isUndefined()) {
1906
0
    if (temp.ref().isObject()) {
1907
0
      if (!mGenerator.Init(&temp.ref().toObject())) {
1908
0
        ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "'generator' member of DhKeyGenParams", "Uint8Array");
1909
0
        return false;
1910
0
      }
1911
0
    } else {
1912
0
      ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'generator' member of DhKeyGenParams");
1913
0
      return false;
1914
0
    }
1915
0
    mIsAnyMemberPresent = true;
1916
0
  } else if (cx) {
1917
0
    // Don't error out if we have no cx.  In that
1918
0
    // situation the caller is default-constructing us and we'll
1919
0
    // just assume they know what they're doing.
1920
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
1921
0
                             "'generator' member of DhKeyGenParams");
1922
0
  }
1923
0
1924
0
  if (!isNull) {
1925
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->prime_id, temp.ptr())) {
1926
0
      return false;
1927
0
    }
1928
0
  }
1929
0
  if (!isNull && !temp->isUndefined()) {
1930
0
    if (temp.ref().isObject()) {
1931
0
      if (!mPrime.Init(&temp.ref().toObject())) {
1932
0
        ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "'prime' member of DhKeyGenParams", "Uint8Array");
1933
0
        return false;
1934
0
      }
1935
0
    } else {
1936
0
      ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'prime' member of DhKeyGenParams");
1937
0
      return false;
1938
0
    }
1939
0
    mIsAnyMemberPresent = true;
1940
0
  } else if (cx) {
1941
0
    // Don't error out if we have no cx.  In that
1942
0
    // situation the caller is default-constructing us and we'll
1943
0
    // just assume they know what they're doing.
1944
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
1945
0
                             "'prime' member of DhKeyGenParams");
1946
0
  }
1947
0
  return true;
1948
0
}
1949
1950
bool
1951
DhKeyGenParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
1952
0
{
1953
0
  DhKeyGenParamsAtoms* atomsCache = GetAtomCache<DhKeyGenParamsAtoms>(cx);
1954
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
1955
0
    return false;
1956
0
  }
1957
0
1958
0
  // Per spec, we define the parent's members first
1959
0
  if (!Algorithm::ToObjectInternal(cx, rval)) {
1960
0
    return false;
1961
0
  }
1962
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
1963
0
1964
0
  do {
1965
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1966
0
    JS::Rooted<JS::Value> temp(cx);
1967
0
    Uint8Array const & currentValue = mGenerator;
1968
0
    temp.setObject(*currentValue.Obj());
1969
0
    if (!MaybeWrapNonDOMObjectValue(cx, &temp)) {
1970
0
      return false;
1971
0
    }
1972
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->generator_id, temp, JSPROP_ENUMERATE)) {
1973
0
      return false;
1974
0
    }
1975
0
    break;
1976
0
  } while(false);
1977
0
1978
0
  do {
1979
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
1980
0
    JS::Rooted<JS::Value> temp(cx);
1981
0
    Uint8Array const & currentValue = mPrime;
1982
0
    temp.setObject(*currentValue.Obj());
1983
0
    if (!MaybeWrapNonDOMObjectValue(cx, &temp)) {
1984
0
      return false;
1985
0
    }
1986
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->prime_id, temp, JSPROP_ENUMERATE)) {
1987
0
      return false;
1988
0
    }
1989
0
    break;
1990
0
  } while(false);
1991
0
1992
0
  return true;
1993
0
}
1994
1995
void
1996
DhKeyGenParams::TraceDictionary(JSTracer* trc)
1997
0
{
1998
0
  Algorithm::TraceDictionary(trc);
1999
0
  mGenerator.TraceSelf(trc);
2000
0
2001
0
  mPrime.TraceSelf(trc);
2002
0
}
2003
2004
namespace binding_detail {
2005
} // namespace binding_detail
2006
2007
2008
2009
EcKeyGenParams::EcKeyGenParams()
2010
  : Algorithm(FastDictionaryInitializer())
2011
0
{
2012
0
  // Safe to pass a null context if we pass a null value
2013
0
  Init(nullptr, JS::NullHandleValue);
2014
0
}
2015
2016
2017
2018
bool
2019
EcKeyGenParams::InitIds(JSContext* cx, EcKeyGenParamsAtoms* atomsCache)
2020
0
{
2021
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
2022
0
2023
0
  // Initialize these in reverse order so that any failure leaves the first one
2024
0
  // uninitialized.
2025
0
  if (!atomsCache->namedCurve_id.init(cx, "namedCurve")) {
2026
0
    return false;
2027
0
  }
2028
0
  return true;
2029
0
}
2030
2031
bool
2032
EcKeyGenParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
2033
0
{
2034
0
  // Passing a null JSContext is OK only if we're initing from null,
2035
0
  // Since in that case we will not have to do any property gets
2036
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
2037
0
  // checkers by static analysis tools
2038
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
2039
0
  EcKeyGenParamsAtoms* atomsCache = nullptr;
2040
0
  if (cx) {
2041
0
    atomsCache = GetAtomCache<EcKeyGenParamsAtoms>(cx);
2042
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2043
0
      return false;
2044
0
    }
2045
0
  }
2046
0
2047
0
  // Per spec, we init the parent's members first
2048
0
  if (!Algorithm::Init(cx, val)) {
2049
0
    return false;
2050
0
  }
2051
0
2052
0
  bool isNull = val.isNullOrUndefined();
2053
0
  // We only need these if !isNull, in which case we have |cx|.
2054
0
  Maybe<JS::Rooted<JSObject *> > object;
2055
0
  Maybe<JS::Rooted<JS::Value> > temp;
2056
0
  if (!isNull) {
2057
0
    MOZ_ASSERT(cx);
2058
0
    object.emplace(cx, &val.toObject());
2059
0
    temp.emplace(cx);
2060
0
  }
2061
0
  if (!isNull) {
2062
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->namedCurve_id, temp.ptr())) {
2063
0
      return false;
2064
0
    }
2065
0
  }
2066
0
  if (!isNull && !temp->isUndefined()) {
2067
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mNamedCurve)) {
2068
0
      return false;
2069
0
    }
2070
0
    mIsAnyMemberPresent = true;
2071
0
  } else if (cx) {
2072
0
    // Don't error out if we have no cx.  In that
2073
0
    // situation the caller is default-constructing us and we'll
2074
0
    // just assume they know what they're doing.
2075
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
2076
0
                             "'namedCurve' member of EcKeyGenParams");
2077
0
  }
2078
0
  return true;
2079
0
}
2080
2081
bool
2082
EcKeyGenParams::Init(const nsAString& aJSON)
2083
0
{
2084
0
  AutoJSAPI jsapi;
2085
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
2086
0
  if (!cleanGlobal) {
2087
0
    return false;
2088
0
  }
2089
0
  if (!jsapi.Init(cleanGlobal)) {
2090
0
    return false;
2091
0
  }
2092
0
  JSContext* cx = jsapi.cx();
2093
0
  JS::Rooted<JS::Value> json(cx);
2094
0
  bool ok = ParseJSON(cx, aJSON, &json);
2095
0
  NS_ENSURE_TRUE(ok, false);
2096
0
  return Init(cx, json);
2097
0
}
2098
2099
bool
2100
EcKeyGenParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
2101
0
{
2102
0
  EcKeyGenParamsAtoms* atomsCache = GetAtomCache<EcKeyGenParamsAtoms>(cx);
2103
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2104
0
    return false;
2105
0
  }
2106
0
2107
0
  // Per spec, we define the parent's members first
2108
0
  if (!Algorithm::ToObjectInternal(cx, rval)) {
2109
0
    return false;
2110
0
  }
2111
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
2112
0
2113
0
  do {
2114
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2115
0
    JS::Rooted<JS::Value> temp(cx);
2116
0
    nsString const & currentValue = mNamedCurve;
2117
0
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
2118
0
      return false;
2119
0
    }
2120
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->namedCurve_id, temp, JSPROP_ENUMERATE)) {
2121
0
      return false;
2122
0
    }
2123
0
    break;
2124
0
  } while(false);
2125
0
2126
0
  return true;
2127
0
}
2128
2129
bool
2130
EcKeyGenParams::ToJSON(nsAString& aJSON) const
2131
0
{
2132
0
  AutoJSAPI jsapi;
2133
0
  jsapi.Init();
2134
0
  JSContext *cx = jsapi.cx();
2135
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
2136
0
  // because we'll only be creating objects, in ways that have no
2137
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
2138
0
  // which likewise guarantees no side-effects for the sorts of
2139
0
  // things we will pass it.
2140
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
2141
0
  JS::Rooted<JS::Value> val(cx);
2142
0
  if (!ToObjectInternal(cx, &val)) {
2143
0
    return false;
2144
0
  }
2145
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
2146
0
  return StringifyToJSON(cx, obj, aJSON);
2147
0
}
2148
2149
void
2150
EcKeyGenParams::TraceDictionary(JSTracer* trc)
2151
0
{
2152
0
  Algorithm::TraceDictionary(trc);
2153
0
}
2154
2155
EcKeyGenParams&
2156
EcKeyGenParams::operator=(const EcKeyGenParams& aOther)
2157
0
{
2158
0
  Algorithm::operator=(aOther);
2159
0
  mNamedCurve = aOther.mNamedCurve;
2160
0
  return *this;
2161
0
}
2162
2163
namespace binding_detail {
2164
} // namespace binding_detail
2165
2166
2167
2168
EcKeyImportParams::EcKeyImportParams()
2169
  : Algorithm(FastDictionaryInitializer())
2170
0
{
2171
0
  // Safe to pass a null context if we pass a null value
2172
0
  Init(nullptr, JS::NullHandleValue);
2173
0
}
2174
2175
2176
2177
bool
2178
EcKeyImportParams::InitIds(JSContext* cx, EcKeyImportParamsAtoms* atomsCache)
2179
0
{
2180
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
2181
0
2182
0
  // Initialize these in reverse order so that any failure leaves the first one
2183
0
  // uninitialized.
2184
0
  if (!atomsCache->namedCurve_id.init(cx, "namedCurve")) {
2185
0
    return false;
2186
0
  }
2187
0
  return true;
2188
0
}
2189
2190
bool
2191
EcKeyImportParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
2192
0
{
2193
0
  // Passing a null JSContext is OK only if we're initing from null,
2194
0
  // Since in that case we will not have to do any property gets
2195
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
2196
0
  // checkers by static analysis tools
2197
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
2198
0
  EcKeyImportParamsAtoms* atomsCache = nullptr;
2199
0
  if (cx) {
2200
0
    atomsCache = GetAtomCache<EcKeyImportParamsAtoms>(cx);
2201
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2202
0
      return false;
2203
0
    }
2204
0
  }
2205
0
2206
0
  // Per spec, we init the parent's members first
2207
0
  if (!Algorithm::Init(cx, val)) {
2208
0
    return false;
2209
0
  }
2210
0
2211
0
  bool isNull = val.isNullOrUndefined();
2212
0
  // We only need these if !isNull, in which case we have |cx|.
2213
0
  Maybe<JS::Rooted<JSObject *> > object;
2214
0
  Maybe<JS::Rooted<JS::Value> > temp;
2215
0
  if (!isNull) {
2216
0
    MOZ_ASSERT(cx);
2217
0
    object.emplace(cx, &val.toObject());
2218
0
    temp.emplace(cx);
2219
0
  }
2220
0
  if (!isNull) {
2221
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->namedCurve_id, temp.ptr())) {
2222
0
      return false;
2223
0
    }
2224
0
  }
2225
0
  if (!isNull && !temp->isUndefined()) {
2226
0
    mNamedCurve.Construct();
2227
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mNamedCurve.Value()))) {
2228
0
      return false;
2229
0
    }
2230
0
    mIsAnyMemberPresent = true;
2231
0
  }
2232
0
  return true;
2233
0
}
2234
2235
bool
2236
EcKeyImportParams::Init(const nsAString& aJSON)
2237
0
{
2238
0
  AutoJSAPI jsapi;
2239
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
2240
0
  if (!cleanGlobal) {
2241
0
    return false;
2242
0
  }
2243
0
  if (!jsapi.Init(cleanGlobal)) {
2244
0
    return false;
2245
0
  }
2246
0
  JSContext* cx = jsapi.cx();
2247
0
  JS::Rooted<JS::Value> json(cx);
2248
0
  bool ok = ParseJSON(cx, aJSON, &json);
2249
0
  NS_ENSURE_TRUE(ok, false);
2250
0
  return Init(cx, json);
2251
0
}
2252
2253
bool
2254
EcKeyImportParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
2255
0
{
2256
0
  EcKeyImportParamsAtoms* atomsCache = GetAtomCache<EcKeyImportParamsAtoms>(cx);
2257
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2258
0
    return false;
2259
0
  }
2260
0
2261
0
  // Per spec, we define the parent's members first
2262
0
  if (!Algorithm::ToObjectInternal(cx, rval)) {
2263
0
    return false;
2264
0
  }
2265
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
2266
0
2267
0
  if (mNamedCurve.WasPassed()) {
2268
0
    do {
2269
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2270
0
      JS::Rooted<JS::Value> temp(cx);
2271
0
      nsString const & currentValue = mNamedCurve.InternalValue();
2272
0
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
2273
0
        return false;
2274
0
      }
2275
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->namedCurve_id, temp, JSPROP_ENUMERATE)) {
2276
0
        return false;
2277
0
      }
2278
0
      break;
2279
0
    } while(false);
2280
0
  }
2281
0
2282
0
  return true;
2283
0
}
2284
2285
bool
2286
EcKeyImportParams::ToJSON(nsAString& aJSON) const
2287
0
{
2288
0
  AutoJSAPI jsapi;
2289
0
  jsapi.Init();
2290
0
  JSContext *cx = jsapi.cx();
2291
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
2292
0
  // because we'll only be creating objects, in ways that have no
2293
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
2294
0
  // which likewise guarantees no side-effects for the sorts of
2295
0
  // things we will pass it.
2296
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
2297
0
  JS::Rooted<JS::Value> val(cx);
2298
0
  if (!ToObjectInternal(cx, &val)) {
2299
0
    return false;
2300
0
  }
2301
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
2302
0
  return StringifyToJSON(cx, obj, aJSON);
2303
0
}
2304
2305
void
2306
EcKeyImportParams::TraceDictionary(JSTracer* trc)
2307
0
{
2308
0
  Algorithm::TraceDictionary(trc);
2309
0
}
2310
2311
EcKeyImportParams&
2312
EcKeyImportParams::operator=(const EcKeyImportParams& aOther)
2313
0
{
2314
0
  Algorithm::operator=(aOther);
2315
0
  mNamedCurve.Reset();
2316
0
  if (aOther.mNamedCurve.WasPassed()) {
2317
0
    mNamedCurve.Construct(aOther.mNamedCurve.Value());
2318
0
  }
2319
0
  return *this;
2320
0
}
2321
2322
namespace binding_detail {
2323
} // namespace binding_detail
2324
2325
2326
2327
EcdhKeyDeriveParams::EcdhKeyDeriveParams()
2328
  : Algorithm(FastDictionaryInitializer())
2329
0
{
2330
0
  // Safe to pass a null context if we pass a null value
2331
0
  Init(nullptr, JS::NullHandleValue);
2332
0
}
2333
2334
2335
2336
bool
2337
EcdhKeyDeriveParams::InitIds(JSContext* cx, EcdhKeyDeriveParamsAtoms* atomsCache)
2338
0
{
2339
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
2340
0
2341
0
  // Initialize these in reverse order so that any failure leaves the first one
2342
0
  // uninitialized.
2343
0
  if (!atomsCache->public_id.init(cx, "public")) {
2344
0
    return false;
2345
0
  }
2346
0
  return true;
2347
0
}
2348
2349
bool
2350
EcdhKeyDeriveParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
2351
0
{
2352
0
  // Passing a null JSContext is OK only if we're initing from null,
2353
0
  // Since in that case we will not have to do any property gets
2354
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
2355
0
  // checkers by static analysis tools
2356
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
2357
0
  EcdhKeyDeriveParamsAtoms* atomsCache = nullptr;
2358
0
  if (cx) {
2359
0
    atomsCache = GetAtomCache<EcdhKeyDeriveParamsAtoms>(cx);
2360
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2361
0
      return false;
2362
0
    }
2363
0
  }
2364
0
2365
0
  // Per spec, we init the parent's members first
2366
0
  if (!Algorithm::Init(cx, val)) {
2367
0
    return false;
2368
0
  }
2369
0
2370
0
  bool isNull = val.isNullOrUndefined();
2371
0
  // We only need these if !isNull, in which case we have |cx|.
2372
0
  Maybe<JS::Rooted<JSObject *> > object;
2373
0
  Maybe<JS::Rooted<JS::Value> > temp;
2374
0
  if (!isNull) {
2375
0
    MOZ_ASSERT(cx);
2376
0
    object.emplace(cx, &val.toObject());
2377
0
    temp.emplace(cx);
2378
0
  }
2379
0
  if (!isNull) {
2380
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->public_id, temp.ptr())) {
2381
0
      return false;
2382
0
    }
2383
0
  }
2384
0
  if (!isNull && !temp->isUndefined()) {
2385
0
    if (temp.ref().isObject()) {
2386
0
      static_assert(IsRefcounted<mozilla::dom::CryptoKey>::value, "We can only store refcounted classes.");{
2387
0
        nsresult rv = UnwrapObject<prototypes::id::CryptoKey, mozilla::dom::CryptoKey>(temp.ptr(), mPublic);
2388
0
        if (NS_FAILED(rv)) {
2389
0
          ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "'public' member of EcdhKeyDeriveParams", "CryptoKey");
2390
0
          return false;
2391
0
        }
2392
0
      }
2393
0
    } else {
2394
0
      ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'public' member of EcdhKeyDeriveParams");
2395
0
      return false;
2396
0
    }
2397
0
    mIsAnyMemberPresent = true;
2398
0
  } else if (cx) {
2399
0
    // Don't error out if we have no cx.  In that
2400
0
    // situation the caller is default-constructing us and we'll
2401
0
    // just assume they know what they're doing.
2402
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
2403
0
                             "'public' member of EcdhKeyDeriveParams");
2404
0
  }
2405
0
  return true;
2406
0
}
2407
2408
bool
2409
EcdhKeyDeriveParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
2410
0
{
2411
0
  EcdhKeyDeriveParamsAtoms* atomsCache = GetAtomCache<EcdhKeyDeriveParamsAtoms>(cx);
2412
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2413
0
    return false;
2414
0
  }
2415
0
2416
0
  // Per spec, we define the parent's members first
2417
0
  if (!Algorithm::ToObjectInternal(cx, rval)) {
2418
0
    return false;
2419
0
  }
2420
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
2421
0
2422
0
  do {
2423
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2424
0
    JS::Rooted<JS::Value> temp(cx);
2425
0
    OwningNonNull<mozilla::dom::CryptoKey> const & currentValue = mPublic;
2426
0
    if (!GetOrCreateDOMReflector(cx, currentValue, &temp)) {
2427
0
      MOZ_ASSERT(JS_IsExceptionPending(cx));
2428
0
      return false;
2429
0
    }
2430
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->public_id, temp, JSPROP_ENUMERATE)) {
2431
0
      return false;
2432
0
    }
2433
0
    break;
2434
0
  } while(false);
2435
0
2436
0
  return true;
2437
0
}
2438
2439
void
2440
EcdhKeyDeriveParams::TraceDictionary(JSTracer* trc)
2441
0
{
2442
0
  Algorithm::TraceDictionary(trc);
2443
0
}
2444
2445
2446
2447
EcdhKeyDeriveParams&
2448
EcdhKeyDeriveParams::operator=(const EcdhKeyDeriveParams& aOther)
2449
0
{
2450
0
  Algorithm::operator=(aOther);
2451
0
  mPublic = aOther.mPublic;
2452
0
  return *this;
2453
0
}
2454
2455
namespace binding_detail {
2456
} // namespace binding_detail
2457
2458
2459
2460
EcdsaParams::EcdsaParams()
2461
  : Algorithm(FastDictionaryInitializer())
2462
0
{
2463
0
  // Safe to pass a null context if we pass a null value
2464
0
  Init(nullptr, JS::NullHandleValue);
2465
0
}
2466
2467
2468
bool
2469
EcdsaParams::InitIds(JSContext* cx, EcdsaParamsAtoms* atomsCache)
2470
0
{
2471
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
2472
0
2473
0
  // Initialize these in reverse order so that any failure leaves the first one
2474
0
  // uninitialized.
2475
0
  if (!atomsCache->hash_id.init(cx, "hash")) {
2476
0
    return false;
2477
0
  }
2478
0
  return true;
2479
0
}
2480
2481
bool
2482
EcdsaParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
2483
0
{
2484
0
  // Passing a null JSContext is OK only if we're initing from null,
2485
0
  // Since in that case we will not have to do any property gets
2486
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
2487
0
  // checkers by static analysis tools
2488
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
2489
0
  EcdsaParamsAtoms* atomsCache = nullptr;
2490
0
  if (cx) {
2491
0
    atomsCache = GetAtomCache<EcdsaParamsAtoms>(cx);
2492
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2493
0
      return false;
2494
0
    }
2495
0
  }
2496
0
2497
0
  // Per spec, we init the parent's members first
2498
0
  if (!Algorithm::Init(cx, val)) {
2499
0
    return false;
2500
0
  }
2501
0
2502
0
  bool isNull = val.isNullOrUndefined();
2503
0
  // We only need these if !isNull, in which case we have |cx|.
2504
0
  Maybe<JS::Rooted<JSObject *> > object;
2505
0
  Maybe<JS::Rooted<JS::Value> > temp;
2506
0
  if (!isNull) {
2507
0
    MOZ_ASSERT(cx);
2508
0
    object.emplace(cx, &val.toObject());
2509
0
    temp.emplace(cx);
2510
0
  }
2511
0
  if (!isNull) {
2512
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->hash_id, temp.ptr())) {
2513
0
      return false;
2514
0
    }
2515
0
  }
2516
0
  if (!isNull && !temp->isUndefined()) {
2517
0
    {
2518
0
      bool done = false, failed = false, tryNext;
2519
0
      if (temp.ref().isObject()) {
2520
0
        if (!mHash.SetToObject(cx, &temp.ref().toObject(), passedToJSImpl)) {
2521
0
          return false;
2522
0
        }
2523
0
        done = true;
2524
0
      } else {
2525
0
        do {
2526
0
          done = (failed = !mHash.TrySetToString(cx, temp.ref(), tryNext)) || !tryNext;
2527
0
          break;
2528
0
        } while (false);
2529
0
      }
2530
0
      if (failed) {
2531
0
        return false;
2532
0
      }
2533
0
      if (!done) {
2534
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'hash' member of EcdsaParams", "Object");
2535
0
        return false;
2536
0
      }
2537
0
    }
2538
0
    mIsAnyMemberPresent = true;
2539
0
  } else if (cx) {
2540
0
    // Don't error out if we have no cx.  In that
2541
0
    // situation the caller is default-constructing us and we'll
2542
0
    // just assume they know what they're doing.
2543
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
2544
0
                             "'hash' member of EcdsaParams");
2545
0
  }
2546
0
  return true;
2547
0
}
2548
2549
bool
2550
EcdsaParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
2551
0
{
2552
0
  EcdsaParamsAtoms* atomsCache = GetAtomCache<EcdsaParamsAtoms>(cx);
2553
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2554
0
    return false;
2555
0
  }
2556
0
2557
0
  // Per spec, we define the parent's members first
2558
0
  if (!Algorithm::ToObjectInternal(cx, rval)) {
2559
0
    return false;
2560
0
  }
2561
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
2562
0
2563
0
  do {
2564
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2565
0
    JS::Rooted<JS::Value> temp(cx);
2566
0
    OwningObjectOrString const & currentValue = mHash;
2567
0
    if (!currentValue.ToJSVal(cx, obj, &temp)) {
2568
0
      return false;
2569
0
    }
2570
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->hash_id, temp, JSPROP_ENUMERATE)) {
2571
0
      return false;
2572
0
    }
2573
0
    break;
2574
0
  } while(false);
2575
0
2576
0
  return true;
2577
0
}
2578
2579
void
2580
EcdsaParams::TraceDictionary(JSTracer* trc)
2581
0
{
2582
0
  Algorithm::TraceDictionary(trc);
2583
0
  mHash.TraceUnion(trc);
2584
0
}
2585
2586
namespace binding_detail {
2587
} // namespace binding_detail
2588
2589
2590
2591
HkdfParams::HkdfParams()
2592
  : Algorithm(FastDictionaryInitializer())
2593
0
{
2594
0
  // Safe to pass a null context if we pass a null value
2595
0
  Init(nullptr, JS::NullHandleValue);
2596
0
}
2597
2598
2599
bool
2600
HkdfParams::InitIds(JSContext* cx, HkdfParamsAtoms* atomsCache)
2601
0
{
2602
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
2603
0
2604
0
  // Initialize these in reverse order so that any failure leaves the first one
2605
0
  // uninitialized.
2606
0
  if (!atomsCache->salt_id.init(cx, "salt") ||
2607
0
      !atomsCache->info_id.init(cx, "info") ||
2608
0
      !atomsCache->hash_id.init(cx, "hash")) {
2609
0
    return false;
2610
0
  }
2611
0
  return true;
2612
0
}
2613
2614
bool
2615
HkdfParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
2616
0
{
2617
0
  // Passing a null JSContext is OK only if we're initing from null,
2618
0
  // Since in that case we will not have to do any property gets
2619
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
2620
0
  // checkers by static analysis tools
2621
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
2622
0
  HkdfParamsAtoms* atomsCache = nullptr;
2623
0
  if (cx) {
2624
0
    atomsCache = GetAtomCache<HkdfParamsAtoms>(cx);
2625
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2626
0
      return false;
2627
0
    }
2628
0
  }
2629
0
2630
0
  // Per spec, we init the parent's members first
2631
0
  if (!Algorithm::Init(cx, val)) {
2632
0
    return false;
2633
0
  }
2634
0
2635
0
  bool isNull = val.isNullOrUndefined();
2636
0
  // We only need these if !isNull, in which case we have |cx|.
2637
0
  Maybe<JS::Rooted<JSObject *> > object;
2638
0
  Maybe<JS::Rooted<JS::Value> > temp;
2639
0
  if (!isNull) {
2640
0
    MOZ_ASSERT(cx);
2641
0
    object.emplace(cx, &val.toObject());
2642
0
    temp.emplace(cx);
2643
0
  }
2644
0
  if (!isNull) {
2645
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->hash_id, temp.ptr())) {
2646
0
      return false;
2647
0
    }
2648
0
  }
2649
0
  if (!isNull && !temp->isUndefined()) {
2650
0
    {
2651
0
      bool done = false, failed = false, tryNext;
2652
0
      if (temp.ref().isObject()) {
2653
0
        if (!mHash.SetToObject(cx, &temp.ref().toObject(), passedToJSImpl)) {
2654
0
          return false;
2655
0
        }
2656
0
        done = true;
2657
0
      } else {
2658
0
        do {
2659
0
          done = (failed = !mHash.TrySetToString(cx, temp.ref(), tryNext)) || !tryNext;
2660
0
          break;
2661
0
        } while (false);
2662
0
      }
2663
0
      if (failed) {
2664
0
        return false;
2665
0
      }
2666
0
      if (!done) {
2667
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'hash' member of HkdfParams", "Object");
2668
0
        return false;
2669
0
      }
2670
0
    }
2671
0
    mIsAnyMemberPresent = true;
2672
0
  } else if (cx) {
2673
0
    // Don't error out if we have no cx.  In that
2674
0
    // situation the caller is default-constructing us and we'll
2675
0
    // just assume they know what they're doing.
2676
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
2677
0
                             "'hash' member of HkdfParams");
2678
0
  }
2679
0
2680
0
  if (!isNull) {
2681
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->info_id, temp.ptr())) {
2682
0
      return false;
2683
0
    }
2684
0
  }
2685
0
  if (!isNull && !temp->isUndefined()) {
2686
0
    {
2687
0
      bool done = false, failed = false, tryNext;
2688
0
      if (temp.ref().isObject()) {
2689
0
        done = (failed = !mInfo.TrySetToArrayBufferView(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext ||
2690
0
               (failed = !mInfo.TrySetToArrayBuffer(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext;
2691
0
2692
0
      }
2693
0
      if (failed) {
2694
0
        return false;
2695
0
      }
2696
0
      if (!done) {
2697
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'info' member of HkdfParams", "ArrayBufferView, ArrayBuffer");
2698
0
        return false;
2699
0
      }
2700
0
    }
2701
0
    mIsAnyMemberPresent = true;
2702
0
  } else if (cx) {
2703
0
    // Don't error out if we have no cx.  In that
2704
0
    // situation the caller is default-constructing us and we'll
2705
0
    // just assume they know what they're doing.
2706
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
2707
0
                             "'info' member of HkdfParams");
2708
0
  }
2709
0
2710
0
  if (!isNull) {
2711
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->salt_id, temp.ptr())) {
2712
0
      return false;
2713
0
    }
2714
0
  }
2715
0
  if (!isNull && !temp->isUndefined()) {
2716
0
    {
2717
0
      bool done = false, failed = false, tryNext;
2718
0
      if (temp.ref().isObject()) {
2719
0
        done = (failed = !mSalt.TrySetToArrayBufferView(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext ||
2720
0
               (failed = !mSalt.TrySetToArrayBuffer(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext;
2721
0
2722
0
      }
2723
0
      if (failed) {
2724
0
        return false;
2725
0
      }
2726
0
      if (!done) {
2727
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'salt' member of HkdfParams", "ArrayBufferView, ArrayBuffer");
2728
0
        return false;
2729
0
      }
2730
0
    }
2731
0
    mIsAnyMemberPresent = true;
2732
0
  } else if (cx) {
2733
0
    // Don't error out if we have no cx.  In that
2734
0
    // situation the caller is default-constructing us and we'll
2735
0
    // just assume they know what they're doing.
2736
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
2737
0
                             "'salt' member of HkdfParams");
2738
0
  }
2739
0
  return true;
2740
0
}
2741
2742
bool
2743
HkdfParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
2744
0
{
2745
0
  HkdfParamsAtoms* atomsCache = GetAtomCache<HkdfParamsAtoms>(cx);
2746
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2747
0
    return false;
2748
0
  }
2749
0
2750
0
  // Per spec, we define the parent's members first
2751
0
  if (!Algorithm::ToObjectInternal(cx, rval)) {
2752
0
    return false;
2753
0
  }
2754
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
2755
0
2756
0
  do {
2757
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2758
0
    JS::Rooted<JS::Value> temp(cx);
2759
0
    OwningObjectOrString const & currentValue = mHash;
2760
0
    if (!currentValue.ToJSVal(cx, obj, &temp)) {
2761
0
      return false;
2762
0
    }
2763
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->hash_id, temp, JSPROP_ENUMERATE)) {
2764
0
      return false;
2765
0
    }
2766
0
    break;
2767
0
  } while(false);
2768
0
2769
0
  do {
2770
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2771
0
    JS::Rooted<JS::Value> temp(cx);
2772
0
    OwningArrayBufferViewOrArrayBuffer const & currentValue = mInfo;
2773
0
    if (!currentValue.ToJSVal(cx, obj, &temp)) {
2774
0
      return false;
2775
0
    }
2776
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->info_id, temp, JSPROP_ENUMERATE)) {
2777
0
      return false;
2778
0
    }
2779
0
    break;
2780
0
  } while(false);
2781
0
2782
0
  do {
2783
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2784
0
    JS::Rooted<JS::Value> temp(cx);
2785
0
    OwningArrayBufferViewOrArrayBuffer const & currentValue = mSalt;
2786
0
    if (!currentValue.ToJSVal(cx, obj, &temp)) {
2787
0
      return false;
2788
0
    }
2789
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->salt_id, temp, JSPROP_ENUMERATE)) {
2790
0
      return false;
2791
0
    }
2792
0
    break;
2793
0
  } while(false);
2794
0
2795
0
  return true;
2796
0
}
2797
2798
void
2799
HkdfParams::TraceDictionary(JSTracer* trc)
2800
0
{
2801
0
  Algorithm::TraceDictionary(trc);
2802
0
  mHash.TraceUnion(trc);
2803
0
2804
0
  mInfo.TraceUnion(trc);
2805
0
2806
0
  mSalt.TraceUnion(trc);
2807
0
}
2808
2809
namespace binding_detail {
2810
} // namespace binding_detail
2811
2812
2813
2814
HmacImportParams::HmacImportParams()
2815
  : Algorithm(FastDictionaryInitializer())
2816
0
{
2817
0
  // Safe to pass a null context if we pass a null value
2818
0
  Init(nullptr, JS::NullHandleValue);
2819
0
}
2820
2821
2822
bool
2823
HmacImportParams::InitIds(JSContext* cx, HmacImportParamsAtoms* atomsCache)
2824
0
{
2825
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
2826
0
2827
0
  // Initialize these in reverse order so that any failure leaves the first one
2828
0
  // uninitialized.
2829
0
  if (!atomsCache->hash_id.init(cx, "hash")) {
2830
0
    return false;
2831
0
  }
2832
0
  return true;
2833
0
}
2834
2835
bool
2836
HmacImportParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
2837
0
{
2838
0
  // Passing a null JSContext is OK only if we're initing from null,
2839
0
  // Since in that case we will not have to do any property gets
2840
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
2841
0
  // checkers by static analysis tools
2842
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
2843
0
  HmacImportParamsAtoms* atomsCache = nullptr;
2844
0
  if (cx) {
2845
0
    atomsCache = GetAtomCache<HmacImportParamsAtoms>(cx);
2846
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2847
0
      return false;
2848
0
    }
2849
0
  }
2850
0
2851
0
  // Per spec, we init the parent's members first
2852
0
  if (!Algorithm::Init(cx, val)) {
2853
0
    return false;
2854
0
  }
2855
0
2856
0
  bool isNull = val.isNullOrUndefined();
2857
0
  // We only need these if !isNull, in which case we have |cx|.
2858
0
  Maybe<JS::Rooted<JSObject *> > object;
2859
0
  Maybe<JS::Rooted<JS::Value> > temp;
2860
0
  if (!isNull) {
2861
0
    MOZ_ASSERT(cx);
2862
0
    object.emplace(cx, &val.toObject());
2863
0
    temp.emplace(cx);
2864
0
  }
2865
0
  if (!isNull) {
2866
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->hash_id, temp.ptr())) {
2867
0
      return false;
2868
0
    }
2869
0
  }
2870
0
  if (!isNull && !temp->isUndefined()) {
2871
0
    {
2872
0
      bool done = false, failed = false, tryNext;
2873
0
      if (temp.ref().isObject()) {
2874
0
        if (!mHash.SetToObject(cx, &temp.ref().toObject(), passedToJSImpl)) {
2875
0
          return false;
2876
0
        }
2877
0
        done = true;
2878
0
      } else {
2879
0
        do {
2880
0
          done = (failed = !mHash.TrySetToString(cx, temp.ref(), tryNext)) || !tryNext;
2881
0
          break;
2882
0
        } while (false);
2883
0
      }
2884
0
      if (failed) {
2885
0
        return false;
2886
0
      }
2887
0
      if (!done) {
2888
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'hash' member of HmacImportParams", "Object");
2889
0
        return false;
2890
0
      }
2891
0
    }
2892
0
    mIsAnyMemberPresent = true;
2893
0
  } else if (cx) {
2894
0
    // Don't error out if we have no cx.  In that
2895
0
    // situation the caller is default-constructing us and we'll
2896
0
    // just assume they know what they're doing.
2897
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
2898
0
                             "'hash' member of HmacImportParams");
2899
0
  }
2900
0
  return true;
2901
0
}
2902
2903
bool
2904
HmacImportParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
2905
0
{
2906
0
  HmacImportParamsAtoms* atomsCache = GetAtomCache<HmacImportParamsAtoms>(cx);
2907
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2908
0
    return false;
2909
0
  }
2910
0
2911
0
  // Per spec, we define the parent's members first
2912
0
  if (!Algorithm::ToObjectInternal(cx, rval)) {
2913
0
    return false;
2914
0
  }
2915
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
2916
0
2917
0
  do {
2918
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
2919
0
    JS::Rooted<JS::Value> temp(cx);
2920
0
    OwningObjectOrString const & currentValue = mHash;
2921
0
    if (!currentValue.ToJSVal(cx, obj, &temp)) {
2922
0
      return false;
2923
0
    }
2924
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->hash_id, temp, JSPROP_ENUMERATE)) {
2925
0
      return false;
2926
0
    }
2927
0
    break;
2928
0
  } while(false);
2929
0
2930
0
  return true;
2931
0
}
2932
2933
void
2934
HmacImportParams::TraceDictionary(JSTracer* trc)
2935
0
{
2936
0
  Algorithm::TraceDictionary(trc);
2937
0
  mHash.TraceUnion(trc);
2938
0
}
2939
2940
namespace binding_detail {
2941
} // namespace binding_detail
2942
2943
2944
2945
HmacKeyGenParams::HmacKeyGenParams()
2946
  : Algorithm(FastDictionaryInitializer())
2947
0
{
2948
0
  // Safe to pass a null context if we pass a null value
2949
0
  Init(nullptr, JS::NullHandleValue);
2950
0
}
2951
2952
2953
bool
2954
HmacKeyGenParams::InitIds(JSContext* cx, HmacKeyGenParamsAtoms* atomsCache)
2955
0
{
2956
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
2957
0
2958
0
  // Initialize these in reverse order so that any failure leaves the first one
2959
0
  // uninitialized.
2960
0
  if (!atomsCache->length_id.init(cx, "length") ||
2961
0
      !atomsCache->hash_id.init(cx, "hash")) {
2962
0
    return false;
2963
0
  }
2964
0
  return true;
2965
0
}
2966
2967
bool
2968
HmacKeyGenParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
2969
0
{
2970
0
  // Passing a null JSContext is OK only if we're initing from null,
2971
0
  // Since in that case we will not have to do any property gets
2972
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
2973
0
  // checkers by static analysis tools
2974
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
2975
0
  HmacKeyGenParamsAtoms* atomsCache = nullptr;
2976
0
  if (cx) {
2977
0
    atomsCache = GetAtomCache<HmacKeyGenParamsAtoms>(cx);
2978
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
2979
0
      return false;
2980
0
    }
2981
0
  }
2982
0
2983
0
  // Per spec, we init the parent's members first
2984
0
  if (!Algorithm::Init(cx, val)) {
2985
0
    return false;
2986
0
  }
2987
0
2988
0
  bool isNull = val.isNullOrUndefined();
2989
0
  // We only need these if !isNull, in which case we have |cx|.
2990
0
  Maybe<JS::Rooted<JSObject *> > object;
2991
0
  Maybe<JS::Rooted<JS::Value> > temp;
2992
0
  if (!isNull) {
2993
0
    MOZ_ASSERT(cx);
2994
0
    object.emplace(cx, &val.toObject());
2995
0
    temp.emplace(cx);
2996
0
  }
2997
0
  if (!isNull) {
2998
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->hash_id, temp.ptr())) {
2999
0
      return false;
3000
0
    }
3001
0
  }
3002
0
  if (!isNull && !temp->isUndefined()) {
3003
0
    {
3004
0
      bool done = false, failed = false, tryNext;
3005
0
      if (temp.ref().isObject()) {
3006
0
        if (!mHash.SetToObject(cx, &temp.ref().toObject(), passedToJSImpl)) {
3007
0
          return false;
3008
0
        }
3009
0
        done = true;
3010
0
      } else {
3011
0
        do {
3012
0
          done = (failed = !mHash.TrySetToString(cx, temp.ref(), tryNext)) || !tryNext;
3013
0
          break;
3014
0
        } while (false);
3015
0
      }
3016
0
      if (failed) {
3017
0
        return false;
3018
0
      }
3019
0
      if (!done) {
3020
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'hash' member of HmacKeyGenParams", "Object");
3021
0
        return false;
3022
0
      }
3023
0
    }
3024
0
    mIsAnyMemberPresent = true;
3025
0
  } else if (cx) {
3026
0
    // Don't error out if we have no cx.  In that
3027
0
    // situation the caller is default-constructing us and we'll
3028
0
    // just assume they know what they're doing.
3029
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
3030
0
                             "'hash' member of HmacKeyGenParams");
3031
0
  }
3032
0
3033
0
  if (!isNull) {
3034
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->length_id, temp.ptr())) {
3035
0
      return false;
3036
0
    }
3037
0
  }
3038
0
  if (!isNull && !temp->isUndefined()) {
3039
0
    mLength.Construct();
3040
0
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), &(mLength.Value()))) {
3041
0
      return false;
3042
0
    }
3043
0
    mIsAnyMemberPresent = true;
3044
0
  }
3045
0
  return true;
3046
0
}
3047
3048
bool
3049
HmacKeyGenParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
3050
0
{
3051
0
  HmacKeyGenParamsAtoms* atomsCache = GetAtomCache<HmacKeyGenParamsAtoms>(cx);
3052
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
3053
0
    return false;
3054
0
  }
3055
0
3056
0
  // Per spec, we define the parent's members first
3057
0
  if (!Algorithm::ToObjectInternal(cx, rval)) {
3058
0
    return false;
3059
0
  }
3060
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
3061
0
3062
0
  do {
3063
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3064
0
    JS::Rooted<JS::Value> temp(cx);
3065
0
    OwningObjectOrString const & currentValue = mHash;
3066
0
    if (!currentValue.ToJSVal(cx, obj, &temp)) {
3067
0
      return false;
3068
0
    }
3069
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->hash_id, temp, JSPROP_ENUMERATE)) {
3070
0
      return false;
3071
0
    }
3072
0
    break;
3073
0
  } while(false);
3074
0
3075
0
  if (mLength.WasPassed()) {
3076
0
    do {
3077
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3078
0
      JS::Rooted<JS::Value> temp(cx);
3079
0
      uint32_t const & currentValue = mLength.InternalValue();
3080
0
      temp.setNumber(currentValue);
3081
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->length_id, temp, JSPROP_ENUMERATE)) {
3082
0
        return false;
3083
0
      }
3084
0
      break;
3085
0
    } while(false);
3086
0
  }
3087
0
3088
0
  return true;
3089
0
}
3090
3091
void
3092
HmacKeyGenParams::TraceDictionary(JSTracer* trc)
3093
0
{
3094
0
  Algorithm::TraceDictionary(trc);
3095
0
  mHash.TraceUnion(trc);
3096
0
}
3097
3098
namespace binding_detail {
3099
} // namespace binding_detail
3100
3101
3102
3103
JsonWebKey::JsonWebKey()
3104
0
{
3105
0
  // Safe to pass a null context if we pass a null value
3106
0
  Init(nullptr, JS::NullHandleValue);
3107
0
}
3108
3109
3110
3111
bool
3112
JsonWebKey::InitIds(JSContext* cx, JsonWebKeyAtoms* atomsCache)
3113
0
{
3114
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
3115
0
3116
0
  // Initialize these in reverse order so that any failure leaves the first one
3117
0
  // uninitialized.
3118
0
  if (!atomsCache->y_id.init(cx, "y") ||
3119
0
      !atomsCache->x_id.init(cx, "x") ||
3120
0
      !atomsCache->use_id.init(cx, "use") ||
3121
0
      !atomsCache->qi_id.init(cx, "qi") ||
3122
0
      !atomsCache->q_id.init(cx, "q") ||
3123
0
      !atomsCache->p_id.init(cx, "p") ||
3124
0
      !atomsCache->oth_id.init(cx, "oth") ||
3125
0
      !atomsCache->n_id.init(cx, "n") ||
3126
0
      !atomsCache->kty_id.init(cx, "kty") ||
3127
0
      !atomsCache->key_ops_id.init(cx, "key_ops") ||
3128
0
      !atomsCache->k_id.init(cx, "k") ||
3129
0
      !atomsCache->ext_id.init(cx, "ext") ||
3130
0
      !atomsCache->e_id.init(cx, "e") ||
3131
0
      !atomsCache->dq_id.init(cx, "dq") ||
3132
0
      !atomsCache->dp_id.init(cx, "dp") ||
3133
0
      !atomsCache->d_id.init(cx, "d") ||
3134
0
      !atomsCache->crv_id.init(cx, "crv") ||
3135
0
      !atomsCache->alg_id.init(cx, "alg")) {
3136
0
    return false;
3137
0
  }
3138
0
  return true;
3139
0
}
3140
3141
bool
3142
JsonWebKey::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
3143
0
{
3144
0
  // Passing a null JSContext is OK only if we're initing from null,
3145
0
  // Since in that case we will not have to do any property gets
3146
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
3147
0
  // checkers by static analysis tools
3148
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
3149
0
  JsonWebKeyAtoms* atomsCache = nullptr;
3150
0
  if (cx) {
3151
0
    atomsCache = GetAtomCache<JsonWebKeyAtoms>(cx);
3152
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
3153
0
      return false;
3154
0
    }
3155
0
  }
3156
0
3157
0
  if (!IsConvertibleToDictionary(val)) {
3158
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
3159
0
  }
3160
0
3161
0
  bool isNull = val.isNullOrUndefined();
3162
0
  // We only need these if !isNull, in which case we have |cx|.
3163
0
  Maybe<JS::Rooted<JSObject *> > object;
3164
0
  Maybe<JS::Rooted<JS::Value> > temp;
3165
0
  if (!isNull) {
3166
0
    MOZ_ASSERT(cx);
3167
0
    object.emplace(cx, &val.toObject());
3168
0
    temp.emplace(cx);
3169
0
  }
3170
0
  if (!isNull) {
3171
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->alg_id, temp.ptr())) {
3172
0
      return false;
3173
0
    }
3174
0
  }
3175
0
  if (!isNull && !temp->isUndefined()) {
3176
0
    mAlg.Construct();
3177
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mAlg.Value()))) {
3178
0
      return false;
3179
0
    }
3180
0
    mIsAnyMemberPresent = true;
3181
0
  }
3182
0
3183
0
  if (!isNull) {
3184
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->crv_id, temp.ptr())) {
3185
0
      return false;
3186
0
    }
3187
0
  }
3188
0
  if (!isNull && !temp->isUndefined()) {
3189
0
    mCrv.Construct();
3190
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mCrv.Value()))) {
3191
0
      return false;
3192
0
    }
3193
0
    mIsAnyMemberPresent = true;
3194
0
  }
3195
0
3196
0
  if (!isNull) {
3197
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->d_id, temp.ptr())) {
3198
0
      return false;
3199
0
    }
3200
0
  }
3201
0
  if (!isNull && !temp->isUndefined()) {
3202
0
    mD.Construct();
3203
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mD.Value()))) {
3204
0
      return false;
3205
0
    }
3206
0
    mIsAnyMemberPresent = true;
3207
0
  }
3208
0
3209
0
  if (!isNull) {
3210
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->dp_id, temp.ptr())) {
3211
0
      return false;
3212
0
    }
3213
0
  }
3214
0
  if (!isNull && !temp->isUndefined()) {
3215
0
    mDp.Construct();
3216
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mDp.Value()))) {
3217
0
      return false;
3218
0
    }
3219
0
    mIsAnyMemberPresent = true;
3220
0
  }
3221
0
3222
0
  if (!isNull) {
3223
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->dq_id, temp.ptr())) {
3224
0
      return false;
3225
0
    }
3226
0
  }
3227
0
  if (!isNull && !temp->isUndefined()) {
3228
0
    mDq.Construct();
3229
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mDq.Value()))) {
3230
0
      return false;
3231
0
    }
3232
0
    mIsAnyMemberPresent = true;
3233
0
  }
3234
0
3235
0
  if (!isNull) {
3236
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->e_id, temp.ptr())) {
3237
0
      return false;
3238
0
    }
3239
0
  }
3240
0
  if (!isNull && !temp->isUndefined()) {
3241
0
    mE.Construct();
3242
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mE.Value()))) {
3243
0
      return false;
3244
0
    }
3245
0
    mIsAnyMemberPresent = true;
3246
0
  }
3247
0
3248
0
  if (!isNull) {
3249
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->ext_id, temp.ptr())) {
3250
0
      return false;
3251
0
    }
3252
0
  }
3253
0
  if (!isNull && !temp->isUndefined()) {
3254
0
    mExt.Construct();
3255
0
    if (!ValueToPrimitive<bool, eDefault>(cx, temp.ref(), &(mExt.Value()))) {
3256
0
      return false;
3257
0
    }
3258
0
    mIsAnyMemberPresent = true;
3259
0
  }
3260
0
3261
0
  if (!isNull) {
3262
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->k_id, temp.ptr())) {
3263
0
      return false;
3264
0
    }
3265
0
  }
3266
0
  if (!isNull && !temp->isUndefined()) {
3267
0
    mK.Construct();
3268
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mK.Value()))) {
3269
0
      return false;
3270
0
    }
3271
0
    mIsAnyMemberPresent = true;
3272
0
  }
3273
0
3274
0
  if (!isNull) {
3275
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->key_ops_id, temp.ptr())) {
3276
0
      return false;
3277
0
    }
3278
0
  }
3279
0
  if (!isNull && !temp->isUndefined()) {
3280
0
    mKey_ops.Construct();
3281
0
    if (temp.ref().isObject()) {
3282
0
      JS::ForOfIterator iter(cx);
3283
0
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
3284
0
        return false;
3285
0
      }
3286
0
      if (!iter.valueIsIterable()) {
3287
0
        ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'key_ops' member of JsonWebKey");
3288
0
        return false;
3289
0
      }
3290
0
      Sequence<nsString> &arr = (mKey_ops.Value());
3291
0
      JS::Rooted<JS::Value> temp(cx);
3292
0
      while (true) {
3293
0
        bool done;
3294
0
        if (!iter.next(&temp, &done)) {
3295
0
          return false;
3296
0
        }
3297
0
        if (done) {
3298
0
          break;
3299
0
        }
3300
0
        nsString* slotPtr = arr.AppendElement(mozilla::fallible);
3301
0
        if (!slotPtr) {
3302
0
          JS_ReportOutOfMemory(cx);
3303
0
          return false;
3304
0
        }
3305
0
        nsString& slot = *slotPtr;
3306
0
        if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
3307
0
          return false;
3308
0
        }
3309
0
      }
3310
0
    } else {
3311
0
      ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'key_ops' member of JsonWebKey");
3312
0
      return false;
3313
0
    }
3314
0
    mIsAnyMemberPresent = true;
3315
0
  }
3316
0
3317
0
  if (!isNull) {
3318
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->kty_id, temp.ptr())) {
3319
0
      return false;
3320
0
    }
3321
0
  }
3322
0
  if (!isNull && !temp->isUndefined()) {
3323
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, mKty)) {
3324
0
      return false;
3325
0
    }
3326
0
    mIsAnyMemberPresent = true;
3327
0
  } else if (cx) {
3328
0
    // Don't error out if we have no cx.  In that
3329
0
    // situation the caller is default-constructing us and we'll
3330
0
    // just assume they know what they're doing.
3331
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
3332
0
                             "'kty' member of JsonWebKey");
3333
0
  }
3334
0
3335
0
  if (!isNull) {
3336
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->n_id, temp.ptr())) {
3337
0
      return false;
3338
0
    }
3339
0
  }
3340
0
  if (!isNull && !temp->isUndefined()) {
3341
0
    mN.Construct();
3342
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mN.Value()))) {
3343
0
      return false;
3344
0
    }
3345
0
    mIsAnyMemberPresent = true;
3346
0
  }
3347
0
3348
0
  if (!isNull) {
3349
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->oth_id, temp.ptr())) {
3350
0
      return false;
3351
0
    }
3352
0
  }
3353
0
  if (!isNull && !temp->isUndefined()) {
3354
0
    mOth.Construct();
3355
0
    if (temp.ref().isObject()) {
3356
0
      JS::ForOfIterator iter(cx);
3357
0
      if (!iter.init(temp.ref(), JS::ForOfIterator::AllowNonIterable)) {
3358
0
        return false;
3359
0
      }
3360
0
      if (!iter.valueIsIterable()) {
3361
0
        ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'oth' member of JsonWebKey");
3362
0
        return false;
3363
0
      }
3364
0
      Sequence<RsaOtherPrimesInfo> &arr = (mOth.Value());
3365
0
      JS::Rooted<JS::Value> temp(cx);
3366
0
      while (true) {
3367
0
        bool done;
3368
0
        if (!iter.next(&temp, &done)) {
3369
0
          return false;
3370
0
        }
3371
0
        if (done) {
3372
0
          break;
3373
0
        }
3374
0
        RsaOtherPrimesInfo* slotPtr = arr.AppendElement(mozilla::fallible);
3375
0
        if (!slotPtr) {
3376
0
          JS_ReportOutOfMemory(cx);
3377
0
          return false;
3378
0
        }
3379
0
        RsaOtherPrimesInfo& slot = *slotPtr;
3380
0
        if (!slot.Init(cx, temp,  "Element of 'oth' member of JsonWebKey", passedToJSImpl)) {
3381
0
          return false;
3382
0
        }
3383
0
      }
3384
0
    } else {
3385
0
      ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "'oth' member of JsonWebKey");
3386
0
      return false;
3387
0
    }
3388
0
    mIsAnyMemberPresent = true;
3389
0
  }
3390
0
3391
0
  if (!isNull) {
3392
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->p_id, temp.ptr())) {
3393
0
      return false;
3394
0
    }
3395
0
  }
3396
0
  if (!isNull && !temp->isUndefined()) {
3397
0
    mP.Construct();
3398
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mP.Value()))) {
3399
0
      return false;
3400
0
    }
3401
0
    mIsAnyMemberPresent = true;
3402
0
  }
3403
0
3404
0
  if (!isNull) {
3405
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->q_id, temp.ptr())) {
3406
0
      return false;
3407
0
    }
3408
0
  }
3409
0
  if (!isNull && !temp->isUndefined()) {
3410
0
    mQ.Construct();
3411
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mQ.Value()))) {
3412
0
      return false;
3413
0
    }
3414
0
    mIsAnyMemberPresent = true;
3415
0
  }
3416
0
3417
0
  if (!isNull) {
3418
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->qi_id, temp.ptr())) {
3419
0
      return false;
3420
0
    }
3421
0
  }
3422
0
  if (!isNull && !temp->isUndefined()) {
3423
0
    mQi.Construct();
3424
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mQi.Value()))) {
3425
0
      return false;
3426
0
    }
3427
0
    mIsAnyMemberPresent = true;
3428
0
  }
3429
0
3430
0
  if (!isNull) {
3431
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->use_id, temp.ptr())) {
3432
0
      return false;
3433
0
    }
3434
0
  }
3435
0
  if (!isNull && !temp->isUndefined()) {
3436
0
    mUse.Construct();
3437
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mUse.Value()))) {
3438
0
      return false;
3439
0
    }
3440
0
    mIsAnyMemberPresent = true;
3441
0
  }
3442
0
3443
0
  if (!isNull) {
3444
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->x_id, temp.ptr())) {
3445
0
      return false;
3446
0
    }
3447
0
  }
3448
0
  if (!isNull && !temp->isUndefined()) {
3449
0
    mX.Construct();
3450
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mX.Value()))) {
3451
0
      return false;
3452
0
    }
3453
0
    mIsAnyMemberPresent = true;
3454
0
  }
3455
0
3456
0
  if (!isNull) {
3457
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->y_id, temp.ptr())) {
3458
0
      return false;
3459
0
    }
3460
0
  }
3461
0
  if (!isNull && !temp->isUndefined()) {
3462
0
    mY.Construct();
3463
0
    if (!ConvertJSValueToString(cx, temp.ref(), eStringify, eStringify, (mY.Value()))) {
3464
0
      return false;
3465
0
    }
3466
0
    mIsAnyMemberPresent = true;
3467
0
  }
3468
0
  return true;
3469
0
}
3470
3471
bool
3472
JsonWebKey::Init(const nsAString& aJSON)
3473
0
{
3474
0
  AutoJSAPI jsapi;
3475
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
3476
0
  if (!cleanGlobal) {
3477
0
    return false;
3478
0
  }
3479
0
  if (!jsapi.Init(cleanGlobal)) {
3480
0
    return false;
3481
0
  }
3482
0
  JSContext* cx = jsapi.cx();
3483
0
  JS::Rooted<JS::Value> json(cx);
3484
0
  bool ok = ParseJSON(cx, aJSON, &json);
3485
0
  NS_ENSURE_TRUE(ok, false);
3486
0
  return Init(cx, json);
3487
0
}
3488
3489
bool
3490
JsonWebKey::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
3491
0
{
3492
0
  JsonWebKeyAtoms* atomsCache = GetAtomCache<JsonWebKeyAtoms>(cx);
3493
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
3494
0
    return false;
3495
0
  }
3496
0
3497
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
3498
0
  if (!obj) {
3499
0
    return false;
3500
0
  }
3501
0
  rval.set(JS::ObjectValue(*obj));
3502
0
3503
0
  if (mAlg.WasPassed()) {
3504
0
    do {
3505
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3506
0
      JS::Rooted<JS::Value> temp(cx);
3507
0
      nsString const & currentValue = mAlg.InternalValue();
3508
0
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3509
0
        return false;
3510
0
      }
3511
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->alg_id, temp, JSPROP_ENUMERATE)) {
3512
0
        return false;
3513
0
      }
3514
0
      break;
3515
0
    } while(false);
3516
0
  }
3517
0
3518
0
  if (mCrv.WasPassed()) {
3519
0
    do {
3520
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3521
0
      JS::Rooted<JS::Value> temp(cx);
3522
0
      nsString const & currentValue = mCrv.InternalValue();
3523
0
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3524
0
        return false;
3525
0
      }
3526
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->crv_id, temp, JSPROP_ENUMERATE)) {
3527
0
        return false;
3528
0
      }
3529
0
      break;
3530
0
    } while(false);
3531
0
  }
3532
0
3533
0
  if (mD.WasPassed()) {
3534
0
    do {
3535
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3536
0
      JS::Rooted<JS::Value> temp(cx);
3537
0
      nsString const & currentValue = mD.InternalValue();
3538
0
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3539
0
        return false;
3540
0
      }
3541
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->d_id, temp, JSPROP_ENUMERATE)) {
3542
0
        return false;
3543
0
      }
3544
0
      break;
3545
0
    } while(false);
3546
0
  }
3547
0
3548
0
  if (mDp.WasPassed()) {
3549
0
    do {
3550
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3551
0
      JS::Rooted<JS::Value> temp(cx);
3552
0
      nsString const & currentValue = mDp.InternalValue();
3553
0
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3554
0
        return false;
3555
0
      }
3556
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->dp_id, temp, JSPROP_ENUMERATE)) {
3557
0
        return false;
3558
0
      }
3559
0
      break;
3560
0
    } while(false);
3561
0
  }
3562
0
3563
0
  if (mDq.WasPassed()) {
3564
0
    do {
3565
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3566
0
      JS::Rooted<JS::Value> temp(cx);
3567
0
      nsString const & currentValue = mDq.InternalValue();
3568
0
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3569
0
        return false;
3570
0
      }
3571
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->dq_id, temp, JSPROP_ENUMERATE)) {
3572
0
        return false;
3573
0
      }
3574
0
      break;
3575
0
    } while(false);
3576
0
  }
3577
0
3578
0
  if (mE.WasPassed()) {
3579
0
    do {
3580
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3581
0
      JS::Rooted<JS::Value> temp(cx);
3582
0
      nsString const & currentValue = mE.InternalValue();
3583
0
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3584
0
        return false;
3585
0
      }
3586
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->e_id, temp, JSPROP_ENUMERATE)) {
3587
0
        return false;
3588
0
      }
3589
0
      break;
3590
0
    } while(false);
3591
0
  }
3592
0
3593
0
  if (mExt.WasPassed()) {
3594
0
    do {
3595
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3596
0
      JS::Rooted<JS::Value> temp(cx);
3597
0
      bool const & currentValue = mExt.InternalValue();
3598
0
      temp.setBoolean(currentValue);
3599
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->ext_id, temp, JSPROP_ENUMERATE)) {
3600
0
        return false;
3601
0
      }
3602
0
      break;
3603
0
    } while(false);
3604
0
  }
3605
0
3606
0
  if (mK.WasPassed()) {
3607
0
    do {
3608
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3609
0
      JS::Rooted<JS::Value> temp(cx);
3610
0
      nsString const & currentValue = mK.InternalValue();
3611
0
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3612
0
        return false;
3613
0
      }
3614
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->k_id, temp, JSPROP_ENUMERATE)) {
3615
0
        return false;
3616
0
      }
3617
0
      break;
3618
0
    } while(false);
3619
0
  }
3620
0
3621
0
  if (mKey_ops.WasPassed()) {
3622
0
    do {
3623
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3624
0
      JS::Rooted<JS::Value> temp(cx);
3625
0
      Sequence<nsString> const & currentValue = mKey_ops.InternalValue();
3626
0
3627
0
      uint32_t length = currentValue.Length();
3628
0
      JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
3629
0
      if (!returnArray) {
3630
0
        return false;
3631
0
      }
3632
0
      // Scope for 'tmp'
3633
0
      {
3634
0
        JS::Rooted<JS::Value> tmp(cx);
3635
0
        for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
3636
0
          // Control block to let us common up the JS_DefineElement calls when there
3637
0
          // are different ways to succeed at wrapping the object.
3638
0
          do {
3639
0
            if (!xpc::NonVoidStringToJsval(cx, currentValue[sequenceIdx0], &tmp)) {
3640
0
              return false;
3641
0
            }
3642
0
            break;
3643
0
          } while (false);
3644
0
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
3645
0
                                JSPROP_ENUMERATE)) {
3646
0
            return false;
3647
0
          }
3648
0
        }
3649
0
      }
3650
0
      temp.setObject(*returnArray);
3651
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->key_ops_id, temp, JSPROP_ENUMERATE)) {
3652
0
        return false;
3653
0
      }
3654
0
      break;
3655
0
    } while(false);
3656
0
  }
3657
0
3658
0
  do {
3659
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3660
0
    JS::Rooted<JS::Value> temp(cx);
3661
0
    nsString const & currentValue = mKty;
3662
0
    if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3663
0
      return false;
3664
0
    }
3665
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->kty_id, temp, JSPROP_ENUMERATE)) {
3666
0
      return false;
3667
0
    }
3668
0
    break;
3669
0
  } while(false);
3670
0
3671
0
  if (mN.WasPassed()) {
3672
0
    do {
3673
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3674
0
      JS::Rooted<JS::Value> temp(cx);
3675
0
      nsString const & currentValue = mN.InternalValue();
3676
0
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3677
0
        return false;
3678
0
      }
3679
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->n_id, temp, JSPROP_ENUMERATE)) {
3680
0
        return false;
3681
0
      }
3682
0
      break;
3683
0
    } while(false);
3684
0
  }
3685
0
3686
0
  if (mOth.WasPassed()) {
3687
0
    do {
3688
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3689
0
      JS::Rooted<JS::Value> temp(cx);
3690
0
      Sequence<RsaOtherPrimesInfo> const & currentValue = mOth.InternalValue();
3691
0
3692
0
      uint32_t length = currentValue.Length();
3693
0
      JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
3694
0
      if (!returnArray) {
3695
0
        return false;
3696
0
      }
3697
0
      // Scope for 'tmp'
3698
0
      {
3699
0
        JS::Rooted<JS::Value> tmp(cx);
3700
0
        for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
3701
0
          // Control block to let us common up the JS_DefineElement calls when there
3702
0
          // are different ways to succeed at wrapping the object.
3703
0
          do {
3704
0
            if (!currentValue[sequenceIdx0].ToObjectInternal(cx, &tmp)) {
3705
0
              return false;
3706
0
            }
3707
0
            break;
3708
0
          } while (false);
3709
0
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
3710
0
                                JSPROP_ENUMERATE)) {
3711
0
            return false;
3712
0
          }
3713
0
        }
3714
0
      }
3715
0
      temp.setObject(*returnArray);
3716
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->oth_id, temp, JSPROP_ENUMERATE)) {
3717
0
        return false;
3718
0
      }
3719
0
      break;
3720
0
    } while(false);
3721
0
  }
3722
0
3723
0
  if (mP.WasPassed()) {
3724
0
    do {
3725
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3726
0
      JS::Rooted<JS::Value> temp(cx);
3727
0
      nsString const & currentValue = mP.InternalValue();
3728
0
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3729
0
        return false;
3730
0
      }
3731
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->p_id, temp, JSPROP_ENUMERATE)) {
3732
0
        return false;
3733
0
      }
3734
0
      break;
3735
0
    } while(false);
3736
0
  }
3737
0
3738
0
  if (mQ.WasPassed()) {
3739
0
    do {
3740
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3741
0
      JS::Rooted<JS::Value> temp(cx);
3742
0
      nsString const & currentValue = mQ.InternalValue();
3743
0
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3744
0
        return false;
3745
0
      }
3746
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->q_id, temp, JSPROP_ENUMERATE)) {
3747
0
        return false;
3748
0
      }
3749
0
      break;
3750
0
    } while(false);
3751
0
  }
3752
0
3753
0
  if (mQi.WasPassed()) {
3754
0
    do {
3755
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3756
0
      JS::Rooted<JS::Value> temp(cx);
3757
0
      nsString const & currentValue = mQi.InternalValue();
3758
0
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3759
0
        return false;
3760
0
      }
3761
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->qi_id, temp, JSPROP_ENUMERATE)) {
3762
0
        return false;
3763
0
      }
3764
0
      break;
3765
0
    } while(false);
3766
0
  }
3767
0
3768
0
  if (mUse.WasPassed()) {
3769
0
    do {
3770
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3771
0
      JS::Rooted<JS::Value> temp(cx);
3772
0
      nsString const & currentValue = mUse.InternalValue();
3773
0
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3774
0
        return false;
3775
0
      }
3776
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->use_id, temp, JSPROP_ENUMERATE)) {
3777
0
        return false;
3778
0
      }
3779
0
      break;
3780
0
    } while(false);
3781
0
  }
3782
0
3783
0
  if (mX.WasPassed()) {
3784
0
    do {
3785
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3786
0
      JS::Rooted<JS::Value> temp(cx);
3787
0
      nsString const & currentValue = mX.InternalValue();
3788
0
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3789
0
        return false;
3790
0
      }
3791
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->x_id, temp, JSPROP_ENUMERATE)) {
3792
0
        return false;
3793
0
      }
3794
0
      break;
3795
0
    } while(false);
3796
0
  }
3797
0
3798
0
  if (mY.WasPassed()) {
3799
0
    do {
3800
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
3801
0
      JS::Rooted<JS::Value> temp(cx);
3802
0
      nsString const & currentValue = mY.InternalValue();
3803
0
      if (!xpc::NonVoidStringToJsval(cx, currentValue, &temp)) {
3804
0
        return false;
3805
0
      }
3806
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->y_id, temp, JSPROP_ENUMERATE)) {
3807
0
        return false;
3808
0
      }
3809
0
      break;
3810
0
    } while(false);
3811
0
  }
3812
0
3813
0
  return true;
3814
0
}
3815
3816
bool
3817
JsonWebKey::ToJSON(nsAString& aJSON) const
3818
0
{
3819
0
  AutoJSAPI jsapi;
3820
0
  jsapi.Init();
3821
0
  JSContext *cx = jsapi.cx();
3822
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
3823
0
  // because we'll only be creating objects, in ways that have no
3824
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
3825
0
  // which likewise guarantees no side-effects for the sorts of
3826
0
  // things we will pass it.
3827
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
3828
0
  JS::Rooted<JS::Value> val(cx);
3829
0
  if (!ToObjectInternal(cx, &val)) {
3830
0
    return false;
3831
0
  }
3832
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
3833
0
  return StringifyToJSON(cx, obj, aJSON);
3834
0
}
3835
3836
void
3837
JsonWebKey::TraceDictionary(JSTracer* trc)
3838
0
{
3839
0
}
3840
3841
JsonWebKey&
3842
JsonWebKey::operator=(const JsonWebKey& aOther)
3843
0
{
3844
0
  DictionaryBase::operator=(aOther);
3845
0
  mAlg.Reset();
3846
0
  if (aOther.mAlg.WasPassed()) {
3847
0
    mAlg.Construct(aOther.mAlg.Value());
3848
0
  }
3849
0
  mCrv.Reset();
3850
0
  if (aOther.mCrv.WasPassed()) {
3851
0
    mCrv.Construct(aOther.mCrv.Value());
3852
0
  }
3853
0
  mD.Reset();
3854
0
  if (aOther.mD.WasPassed()) {
3855
0
    mD.Construct(aOther.mD.Value());
3856
0
  }
3857
0
  mDp.Reset();
3858
0
  if (aOther.mDp.WasPassed()) {
3859
0
    mDp.Construct(aOther.mDp.Value());
3860
0
  }
3861
0
  mDq.Reset();
3862
0
  if (aOther.mDq.WasPassed()) {
3863
0
    mDq.Construct(aOther.mDq.Value());
3864
0
  }
3865
0
  mE.Reset();
3866
0
  if (aOther.mE.WasPassed()) {
3867
0
    mE.Construct(aOther.mE.Value());
3868
0
  }
3869
0
  mExt.Reset();
3870
0
  if (aOther.mExt.WasPassed()) {
3871
0
    mExt.Construct(aOther.mExt.Value());
3872
0
  }
3873
0
  mK.Reset();
3874
0
  if (aOther.mK.WasPassed()) {
3875
0
    mK.Construct(aOther.mK.Value());
3876
0
  }
3877
0
  mKey_ops.Reset();
3878
0
  if (aOther.mKey_ops.WasPassed()) {
3879
0
    mKey_ops.Construct(aOther.mKey_ops.Value());
3880
0
  }
3881
0
  mKty = aOther.mKty;
3882
0
  mN.Reset();
3883
0
  if (aOther.mN.WasPassed()) {
3884
0
    mN.Construct(aOther.mN.Value());
3885
0
  }
3886
0
  mOth.Reset();
3887
0
  if (aOther.mOth.WasPassed()) {
3888
0
    mOth.Construct(aOther.mOth.Value());
3889
0
  }
3890
0
  mP.Reset();
3891
0
  if (aOther.mP.WasPassed()) {
3892
0
    mP.Construct(aOther.mP.Value());
3893
0
  }
3894
0
  mQ.Reset();
3895
0
  if (aOther.mQ.WasPassed()) {
3896
0
    mQ.Construct(aOther.mQ.Value());
3897
0
  }
3898
0
  mQi.Reset();
3899
0
  if (aOther.mQi.WasPassed()) {
3900
0
    mQi.Construct(aOther.mQi.Value());
3901
0
  }
3902
0
  mUse.Reset();
3903
0
  if (aOther.mUse.WasPassed()) {
3904
0
    mUse.Construct(aOther.mUse.Value());
3905
0
  }
3906
0
  mX.Reset();
3907
0
  if (aOther.mX.WasPassed()) {
3908
0
    mX.Construct(aOther.mX.Value());
3909
0
  }
3910
0
  mY.Reset();
3911
0
  if (aOther.mY.WasPassed()) {
3912
0
    mY.Construct(aOther.mY.Value());
3913
0
  }
3914
0
  return *this;
3915
0
}
3916
3917
namespace binding_detail {
3918
} // namespace binding_detail
3919
3920
3921
3922
Pbkdf2Params::Pbkdf2Params()
3923
  : Algorithm(FastDictionaryInitializer())
3924
0
{
3925
0
  // Safe to pass a null context if we pass a null value
3926
0
  Init(nullptr, JS::NullHandleValue);
3927
0
}
3928
3929
3930
bool
3931
Pbkdf2Params::InitIds(JSContext* cx, Pbkdf2ParamsAtoms* atomsCache)
3932
0
{
3933
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
3934
0
3935
0
  // Initialize these in reverse order so that any failure leaves the first one
3936
0
  // uninitialized.
3937
0
  if (!atomsCache->salt_id.init(cx, "salt") ||
3938
0
      !atomsCache->iterations_id.init(cx, "iterations") ||
3939
0
      !atomsCache->hash_id.init(cx, "hash")) {
3940
0
    return false;
3941
0
  }
3942
0
  return true;
3943
0
}
3944
3945
bool
3946
Pbkdf2Params::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
3947
0
{
3948
0
  // Passing a null JSContext is OK only if we're initing from null,
3949
0
  // Since in that case we will not have to do any property gets
3950
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
3951
0
  // checkers by static analysis tools
3952
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
3953
0
  Pbkdf2ParamsAtoms* atomsCache = nullptr;
3954
0
  if (cx) {
3955
0
    atomsCache = GetAtomCache<Pbkdf2ParamsAtoms>(cx);
3956
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
3957
0
      return false;
3958
0
    }
3959
0
  }
3960
0
3961
0
  // Per spec, we init the parent's members first
3962
0
  if (!Algorithm::Init(cx, val)) {
3963
0
    return false;
3964
0
  }
3965
0
3966
0
  bool isNull = val.isNullOrUndefined();
3967
0
  // We only need these if !isNull, in which case we have |cx|.
3968
0
  Maybe<JS::Rooted<JSObject *> > object;
3969
0
  Maybe<JS::Rooted<JS::Value> > temp;
3970
0
  if (!isNull) {
3971
0
    MOZ_ASSERT(cx);
3972
0
    object.emplace(cx, &val.toObject());
3973
0
    temp.emplace(cx);
3974
0
  }
3975
0
  if (!isNull) {
3976
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->hash_id, temp.ptr())) {
3977
0
      return false;
3978
0
    }
3979
0
  }
3980
0
  if (!isNull && !temp->isUndefined()) {
3981
0
    {
3982
0
      bool done = false, failed = false, tryNext;
3983
0
      if (temp.ref().isObject()) {
3984
0
        if (!mHash.SetToObject(cx, &temp.ref().toObject(), passedToJSImpl)) {
3985
0
          return false;
3986
0
        }
3987
0
        done = true;
3988
0
      } else {
3989
0
        do {
3990
0
          done = (failed = !mHash.TrySetToString(cx, temp.ref(), tryNext)) || !tryNext;
3991
0
          break;
3992
0
        } while (false);
3993
0
      }
3994
0
      if (failed) {
3995
0
        return false;
3996
0
      }
3997
0
      if (!done) {
3998
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'hash' member of Pbkdf2Params", "Object");
3999
0
        return false;
4000
0
      }
4001
0
    }
4002
0
    mIsAnyMemberPresent = true;
4003
0
  } else if (cx) {
4004
0
    // Don't error out if we have no cx.  In that
4005
0
    // situation the caller is default-constructing us and we'll
4006
0
    // just assume they know what they're doing.
4007
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
4008
0
                             "'hash' member of Pbkdf2Params");
4009
0
  }
4010
0
4011
0
  if (!isNull) {
4012
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->iterations_id, temp.ptr())) {
4013
0
      return false;
4014
0
    }
4015
0
  }
4016
0
  if (!isNull && !temp->isUndefined()) {
4017
0
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), &mIterations)) {
4018
0
      return false;
4019
0
    }
4020
0
    mIsAnyMemberPresent = true;
4021
0
  } else if (cx) {
4022
0
    // Don't error out if we have no cx.  In that
4023
0
    // situation the caller is default-constructing us and we'll
4024
0
    // just assume they know what they're doing.
4025
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
4026
0
                             "'iterations' member of Pbkdf2Params");
4027
0
  }
4028
0
4029
0
  if (!isNull) {
4030
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->salt_id, temp.ptr())) {
4031
0
      return false;
4032
0
    }
4033
0
  }
4034
0
  if (!isNull && !temp->isUndefined()) {
4035
0
    {
4036
0
      bool done = false, failed = false, tryNext;
4037
0
      if (temp.ref().isObject()) {
4038
0
        done = (failed = !mSalt.TrySetToArrayBufferView(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext ||
4039
0
               (failed = !mSalt.TrySetToArrayBuffer(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext;
4040
0
4041
0
      }
4042
0
      if (failed) {
4043
0
        return false;
4044
0
      }
4045
0
      if (!done) {
4046
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'salt' member of Pbkdf2Params", "ArrayBufferView, ArrayBuffer");
4047
0
        return false;
4048
0
      }
4049
0
    }
4050
0
    mIsAnyMemberPresent = true;
4051
0
  } else if (cx) {
4052
0
    // Don't error out if we have no cx.  In that
4053
0
    // situation the caller is default-constructing us and we'll
4054
0
    // just assume they know what they're doing.
4055
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
4056
0
                             "'salt' member of Pbkdf2Params");
4057
0
  }
4058
0
  return true;
4059
0
}
4060
4061
bool
4062
Pbkdf2Params::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
4063
0
{
4064
0
  Pbkdf2ParamsAtoms* atomsCache = GetAtomCache<Pbkdf2ParamsAtoms>(cx);
4065
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
4066
0
    return false;
4067
0
  }
4068
0
4069
0
  // Per spec, we define the parent's members first
4070
0
  if (!Algorithm::ToObjectInternal(cx, rval)) {
4071
0
    return false;
4072
0
  }
4073
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
4074
0
4075
0
  do {
4076
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
4077
0
    JS::Rooted<JS::Value> temp(cx);
4078
0
    OwningObjectOrString const & currentValue = mHash;
4079
0
    if (!currentValue.ToJSVal(cx, obj, &temp)) {
4080
0
      return false;
4081
0
    }
4082
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->hash_id, temp, JSPROP_ENUMERATE)) {
4083
0
      return false;
4084
0
    }
4085
0
    break;
4086
0
  } while(false);
4087
0
4088
0
  do {
4089
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
4090
0
    JS::Rooted<JS::Value> temp(cx);
4091
0
    uint32_t const & currentValue = mIterations;
4092
0
    temp.setNumber(currentValue);
4093
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->iterations_id, temp, JSPROP_ENUMERATE)) {
4094
0
      return false;
4095
0
    }
4096
0
    break;
4097
0
  } while(false);
4098
0
4099
0
  do {
4100
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
4101
0
    JS::Rooted<JS::Value> temp(cx);
4102
0
    OwningArrayBufferViewOrArrayBuffer const & currentValue = mSalt;
4103
0
    if (!currentValue.ToJSVal(cx, obj, &temp)) {
4104
0
      return false;
4105
0
    }
4106
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->salt_id, temp, JSPROP_ENUMERATE)) {
4107
0
      return false;
4108
0
    }
4109
0
    break;
4110
0
  } while(false);
4111
0
4112
0
  return true;
4113
0
}
4114
4115
void
4116
Pbkdf2Params::TraceDictionary(JSTracer* trc)
4117
0
{
4118
0
  Algorithm::TraceDictionary(trc);
4119
0
  mHash.TraceUnion(trc);
4120
0
4121
0
  mSalt.TraceUnion(trc);
4122
0
}
4123
4124
namespace binding_detail {
4125
} // namespace binding_detail
4126
4127
4128
4129
RsaHashedImportParams::RsaHashedImportParams()
4130
0
{
4131
0
  // Safe to pass a null context if we pass a null value
4132
0
  Init(nullptr, JS::NullHandleValue);
4133
0
}
4134
4135
4136
bool
4137
RsaHashedImportParams::InitIds(JSContext* cx, RsaHashedImportParamsAtoms* atomsCache)
4138
0
{
4139
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
4140
0
4141
0
  // Initialize these in reverse order so that any failure leaves the first one
4142
0
  // uninitialized.
4143
0
  if (!atomsCache->hash_id.init(cx, "hash")) {
4144
0
    return false;
4145
0
  }
4146
0
  return true;
4147
0
}
4148
4149
bool
4150
RsaHashedImportParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
4151
0
{
4152
0
  // Passing a null JSContext is OK only if we're initing from null,
4153
0
  // Since in that case we will not have to do any property gets
4154
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
4155
0
  // checkers by static analysis tools
4156
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
4157
0
  RsaHashedImportParamsAtoms* atomsCache = nullptr;
4158
0
  if (cx) {
4159
0
    atomsCache = GetAtomCache<RsaHashedImportParamsAtoms>(cx);
4160
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
4161
0
      return false;
4162
0
    }
4163
0
  }
4164
0
4165
0
  if (!IsConvertibleToDictionary(val)) {
4166
0
    return ThrowErrorMessage(cx, MSG_NOT_DICTIONARY, sourceDescription);
4167
0
  }
4168
0
4169
0
  bool isNull = val.isNullOrUndefined();
4170
0
  // We only need these if !isNull, in which case we have |cx|.
4171
0
  Maybe<JS::Rooted<JSObject *> > object;
4172
0
  Maybe<JS::Rooted<JS::Value> > temp;
4173
0
  if (!isNull) {
4174
0
    MOZ_ASSERT(cx);
4175
0
    object.emplace(cx, &val.toObject());
4176
0
    temp.emplace(cx);
4177
0
  }
4178
0
  if (!isNull) {
4179
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->hash_id, temp.ptr())) {
4180
0
      return false;
4181
0
    }
4182
0
  }
4183
0
  if (!isNull && !temp->isUndefined()) {
4184
0
    {
4185
0
      bool done = false, failed = false, tryNext;
4186
0
      if (temp.ref().isObject()) {
4187
0
        if (!mHash.SetToObject(cx, &temp.ref().toObject(), passedToJSImpl)) {
4188
0
          return false;
4189
0
        }
4190
0
        done = true;
4191
0
      } else {
4192
0
        do {
4193
0
          done = (failed = !mHash.TrySetToString(cx, temp.ref(), tryNext)) || !tryNext;
4194
0
          break;
4195
0
        } while (false);
4196
0
      }
4197
0
      if (failed) {
4198
0
        return false;
4199
0
      }
4200
0
      if (!done) {
4201
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'hash' member of RsaHashedImportParams", "Object");
4202
0
        return false;
4203
0
      }
4204
0
    }
4205
0
    mIsAnyMemberPresent = true;
4206
0
  } else if (cx) {
4207
0
    // Don't error out if we have no cx.  In that
4208
0
    // situation the caller is default-constructing us and we'll
4209
0
    // just assume they know what they're doing.
4210
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
4211
0
                             "'hash' member of RsaHashedImportParams");
4212
0
  }
4213
0
  return true;
4214
0
}
4215
4216
bool
4217
RsaHashedImportParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
4218
0
{
4219
0
  RsaHashedImportParamsAtoms* atomsCache = GetAtomCache<RsaHashedImportParamsAtoms>(cx);
4220
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
4221
0
    return false;
4222
0
  }
4223
0
4224
0
  JS::Rooted<JSObject*> obj(cx, JS_NewPlainObject(cx));
4225
0
  if (!obj) {
4226
0
    return false;
4227
0
  }
4228
0
  rval.set(JS::ObjectValue(*obj));
4229
0
4230
0
  do {
4231
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
4232
0
    JS::Rooted<JS::Value> temp(cx);
4233
0
    OwningObjectOrString const & currentValue = mHash;
4234
0
    if (!currentValue.ToJSVal(cx, obj, &temp)) {
4235
0
      return false;
4236
0
    }
4237
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->hash_id, temp, JSPROP_ENUMERATE)) {
4238
0
      return false;
4239
0
    }
4240
0
    break;
4241
0
  } while(false);
4242
0
4243
0
  return true;
4244
0
}
4245
4246
void
4247
RsaHashedImportParams::TraceDictionary(JSTracer* trc)
4248
0
{
4249
0
  mHash.TraceUnion(trc);
4250
0
}
4251
4252
namespace binding_detail {
4253
} // namespace binding_detail
4254
4255
4256
4257
RsaHashedKeyGenParams::RsaHashedKeyGenParams()
4258
  : Algorithm(FastDictionaryInitializer())
4259
0
{
4260
0
  // Safe to pass a null context if we pass a null value
4261
0
  Init(nullptr, JS::NullHandleValue);
4262
0
}
4263
4264
4265
bool
4266
RsaHashedKeyGenParams::InitIds(JSContext* cx, RsaHashedKeyGenParamsAtoms* atomsCache)
4267
0
{
4268
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
4269
0
4270
0
  // Initialize these in reverse order so that any failure leaves the first one
4271
0
  // uninitialized.
4272
0
  if (!atomsCache->publicExponent_id.init(cx, "publicExponent") ||
4273
0
      !atomsCache->modulusLength_id.init(cx, "modulusLength") ||
4274
0
      !atomsCache->hash_id.init(cx, "hash")) {
4275
0
    return false;
4276
0
  }
4277
0
  return true;
4278
0
}
4279
4280
bool
4281
RsaHashedKeyGenParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
4282
0
{
4283
0
  // Passing a null JSContext is OK only if we're initing from null,
4284
0
  // Since in that case we will not have to do any property gets
4285
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
4286
0
  // checkers by static analysis tools
4287
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
4288
0
  RsaHashedKeyGenParamsAtoms* atomsCache = nullptr;
4289
0
  if (cx) {
4290
0
    atomsCache = GetAtomCache<RsaHashedKeyGenParamsAtoms>(cx);
4291
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
4292
0
      return false;
4293
0
    }
4294
0
  }
4295
0
4296
0
  // Per spec, we init the parent's members first
4297
0
  if (!Algorithm::Init(cx, val)) {
4298
0
    return false;
4299
0
  }
4300
0
4301
0
  bool isNull = val.isNullOrUndefined();
4302
0
  // We only need these if !isNull, in which case we have |cx|.
4303
0
  Maybe<JS::Rooted<JSObject *> > object;
4304
0
  Maybe<JS::Rooted<JS::Value> > temp;
4305
0
  if (!isNull) {
4306
0
    MOZ_ASSERT(cx);
4307
0
    object.emplace(cx, &val.toObject());
4308
0
    temp.emplace(cx);
4309
0
  }
4310
0
  if (!isNull) {
4311
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->hash_id, temp.ptr())) {
4312
0
      return false;
4313
0
    }
4314
0
  }
4315
0
  if (!isNull && !temp->isUndefined()) {
4316
0
    {
4317
0
      bool done = false, failed = false, tryNext;
4318
0
      if (temp.ref().isObject()) {
4319
0
        if (!mHash.SetToObject(cx, &temp.ref().toObject(), passedToJSImpl)) {
4320
0
          return false;
4321
0
        }
4322
0
        done = true;
4323
0
      } else {
4324
0
        do {
4325
0
          done = (failed = !mHash.TrySetToString(cx, temp.ref(), tryNext)) || !tryNext;
4326
0
          break;
4327
0
        } while (false);
4328
0
      }
4329
0
      if (failed) {
4330
0
        return false;
4331
0
      }
4332
0
      if (!done) {
4333
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'hash' member of RsaHashedKeyGenParams", "Object");
4334
0
        return false;
4335
0
      }
4336
0
    }
4337
0
    mIsAnyMemberPresent = true;
4338
0
  } else if (cx) {
4339
0
    // Don't error out if we have no cx.  In that
4340
0
    // situation the caller is default-constructing us and we'll
4341
0
    // just assume they know what they're doing.
4342
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
4343
0
                             "'hash' member of RsaHashedKeyGenParams");
4344
0
  }
4345
0
4346
0
  if (!isNull) {
4347
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->modulusLength_id, temp.ptr())) {
4348
0
      return false;
4349
0
    }
4350
0
  }
4351
0
  if (!isNull && !temp->isUndefined()) {
4352
0
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), &mModulusLength)) {
4353
0
      return false;
4354
0
    }
4355
0
    mIsAnyMemberPresent = true;
4356
0
  } else if (cx) {
4357
0
    // Don't error out if we have no cx.  In that
4358
0
    // situation the caller is default-constructing us and we'll
4359
0
    // just assume they know what they're doing.
4360
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
4361
0
                             "'modulusLength' member of RsaHashedKeyGenParams");
4362
0
  }
4363
0
4364
0
  if (!isNull) {
4365
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->publicExponent_id, temp.ptr())) {
4366
0
      return false;
4367
0
    }
4368
0
  }
4369
0
  if (!isNull && !temp->isUndefined()) {
4370
0
    if (temp.ref().isObject()) {
4371
0
      if (!mPublicExponent.Init(&temp.ref().toObject())) {
4372
0
        ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "'publicExponent' member of RsaHashedKeyGenParams", "Uint8Array");
4373
0
        return false;
4374
0
      }
4375
0
    } else {
4376
0
      ThrowErrorMessage(cx, MSG_NOT_OBJECT, "'publicExponent' member of RsaHashedKeyGenParams");
4377
0
      return false;
4378
0
    }
4379
0
    mIsAnyMemberPresent = true;
4380
0
  } else if (cx) {
4381
0
    // Don't error out if we have no cx.  In that
4382
0
    // situation the caller is default-constructing us and we'll
4383
0
    // just assume they know what they're doing.
4384
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
4385
0
                             "'publicExponent' member of RsaHashedKeyGenParams");
4386
0
  }
4387
0
  return true;
4388
0
}
4389
4390
bool
4391
RsaHashedKeyGenParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
4392
0
{
4393
0
  RsaHashedKeyGenParamsAtoms* atomsCache = GetAtomCache<RsaHashedKeyGenParamsAtoms>(cx);
4394
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
4395
0
    return false;
4396
0
  }
4397
0
4398
0
  // Per spec, we define the parent's members first
4399
0
  if (!Algorithm::ToObjectInternal(cx, rval)) {
4400
0
    return false;
4401
0
  }
4402
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
4403
0
4404
0
  do {
4405
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
4406
0
    JS::Rooted<JS::Value> temp(cx);
4407
0
    OwningObjectOrString const & currentValue = mHash;
4408
0
    if (!currentValue.ToJSVal(cx, obj, &temp)) {
4409
0
      return false;
4410
0
    }
4411
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->hash_id, temp, JSPROP_ENUMERATE)) {
4412
0
      return false;
4413
0
    }
4414
0
    break;
4415
0
  } while(false);
4416
0
4417
0
  do {
4418
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
4419
0
    JS::Rooted<JS::Value> temp(cx);
4420
0
    uint32_t const & currentValue = mModulusLength;
4421
0
    temp.setNumber(currentValue);
4422
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->modulusLength_id, temp, JSPROP_ENUMERATE)) {
4423
0
      return false;
4424
0
    }
4425
0
    break;
4426
0
  } while(false);
4427
0
4428
0
  do {
4429
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
4430
0
    JS::Rooted<JS::Value> temp(cx);
4431
0
    Uint8Array const & currentValue = mPublicExponent;
4432
0
    temp.setObject(*currentValue.Obj());
4433
0
    if (!MaybeWrapNonDOMObjectValue(cx, &temp)) {
4434
0
      return false;
4435
0
    }
4436
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->publicExponent_id, temp, JSPROP_ENUMERATE)) {
4437
0
      return false;
4438
0
    }
4439
0
    break;
4440
0
  } while(false);
4441
0
4442
0
  return true;
4443
0
}
4444
4445
void
4446
RsaHashedKeyGenParams::TraceDictionary(JSTracer* trc)
4447
0
{
4448
0
  Algorithm::TraceDictionary(trc);
4449
0
  mHash.TraceUnion(trc);
4450
0
4451
0
  mPublicExponent.TraceSelf(trc);
4452
0
}
4453
4454
namespace binding_detail {
4455
} // namespace binding_detail
4456
4457
4458
4459
RsaOaepParams::RsaOaepParams()
4460
  : Algorithm(FastDictionaryInitializer())
4461
0
{
4462
0
  // Safe to pass a null context if we pass a null value
4463
0
  Init(nullptr, JS::NullHandleValue);
4464
0
}
4465
4466
4467
bool
4468
RsaOaepParams::InitIds(JSContext* cx, RsaOaepParamsAtoms* atomsCache)
4469
0
{
4470
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
4471
0
4472
0
  // Initialize these in reverse order so that any failure leaves the first one
4473
0
  // uninitialized.
4474
0
  if (!atomsCache->label_id.init(cx, "label")) {
4475
0
    return false;
4476
0
  }
4477
0
  return true;
4478
0
}
4479
4480
bool
4481
RsaOaepParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
4482
0
{
4483
0
  // Passing a null JSContext is OK only if we're initing from null,
4484
0
  // Since in that case we will not have to do any property gets
4485
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
4486
0
  // checkers by static analysis tools
4487
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
4488
0
  RsaOaepParamsAtoms* atomsCache = nullptr;
4489
0
  if (cx) {
4490
0
    atomsCache = GetAtomCache<RsaOaepParamsAtoms>(cx);
4491
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
4492
0
      return false;
4493
0
    }
4494
0
  }
4495
0
4496
0
  // Per spec, we init the parent's members first
4497
0
  if (!Algorithm::Init(cx, val)) {
4498
0
    return false;
4499
0
  }
4500
0
4501
0
  bool isNull = val.isNullOrUndefined();
4502
0
  // We only need these if !isNull, in which case we have |cx|.
4503
0
  Maybe<JS::Rooted<JSObject *> > object;
4504
0
  Maybe<JS::Rooted<JS::Value> > temp;
4505
0
  if (!isNull) {
4506
0
    MOZ_ASSERT(cx);
4507
0
    object.emplace(cx, &val.toObject());
4508
0
    temp.emplace(cx);
4509
0
  }
4510
0
  if (!isNull) {
4511
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->label_id, temp.ptr())) {
4512
0
      return false;
4513
0
    }
4514
0
  }
4515
0
  if (!isNull && !temp->isUndefined()) {
4516
0
    mLabel.Construct();
4517
0
    {
4518
0
      bool done = false, failed = false, tryNext;
4519
0
      if (temp.ref().isObject()) {
4520
0
        done = (failed = !(mLabel.Value()).TrySetToArrayBufferView(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext ||
4521
0
               (failed = !(mLabel.Value()).TrySetToArrayBuffer(cx, temp.ref(), tryNext, passedToJSImpl)) || !tryNext;
4522
0
4523
0
      }
4524
0
      if (failed) {
4525
0
        return false;
4526
0
      }
4527
0
      if (!done) {
4528
0
        ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "'label' member of RsaOaepParams", "ArrayBufferView, ArrayBuffer");
4529
0
        return false;
4530
0
      }
4531
0
    }
4532
0
    mIsAnyMemberPresent = true;
4533
0
  }
4534
0
  return true;
4535
0
}
4536
4537
bool
4538
RsaOaepParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
4539
0
{
4540
0
  RsaOaepParamsAtoms* atomsCache = GetAtomCache<RsaOaepParamsAtoms>(cx);
4541
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
4542
0
    return false;
4543
0
  }
4544
0
4545
0
  // Per spec, we define the parent's members first
4546
0
  if (!Algorithm::ToObjectInternal(cx, rval)) {
4547
0
    return false;
4548
0
  }
4549
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
4550
0
4551
0
  if (mLabel.WasPassed()) {
4552
0
    do {
4553
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
4554
0
      JS::Rooted<JS::Value> temp(cx);
4555
0
      OwningArrayBufferViewOrArrayBuffer const & currentValue = mLabel.InternalValue();
4556
0
      if (!currentValue.ToJSVal(cx, obj, &temp)) {
4557
0
        return false;
4558
0
      }
4559
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->label_id, temp, JSPROP_ENUMERATE)) {
4560
0
        return false;
4561
0
      }
4562
0
      break;
4563
0
    } while(false);
4564
0
  }
4565
0
4566
0
  return true;
4567
0
}
4568
4569
void
4570
RsaOaepParams::TraceDictionary(JSTracer* trc)
4571
0
{
4572
0
  Algorithm::TraceDictionary(trc);
4573
0
  if (mLabel.WasPassed()) {
4574
0
    mLabel.Value().TraceUnion(trc);
4575
0
  }
4576
0
}
4577
4578
namespace binding_detail {
4579
} // namespace binding_detail
4580
4581
4582
4583
RsaPssParams::RsaPssParams()
4584
  : Algorithm(FastDictionaryInitializer())
4585
0
{
4586
0
  // Safe to pass a null context if we pass a null value
4587
0
  Init(nullptr, JS::NullHandleValue);
4588
0
}
4589
4590
4591
4592
bool
4593
RsaPssParams::InitIds(JSContext* cx, RsaPssParamsAtoms* atomsCache)
4594
0
{
4595
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
4596
0
4597
0
  // Initialize these in reverse order so that any failure leaves the first one
4598
0
  // uninitialized.
4599
0
  if (!atomsCache->saltLength_id.init(cx, "saltLength")) {
4600
0
    return false;
4601
0
  }
4602
0
  return true;
4603
0
}
4604
4605
bool
4606
RsaPssParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
4607
0
{
4608
0
  // Passing a null JSContext is OK only if we're initing from null,
4609
0
  // Since in that case we will not have to do any property gets
4610
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
4611
0
  // checkers by static analysis tools
4612
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
4613
0
  RsaPssParamsAtoms* atomsCache = nullptr;
4614
0
  if (cx) {
4615
0
    atomsCache = GetAtomCache<RsaPssParamsAtoms>(cx);
4616
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
4617
0
      return false;
4618
0
    }
4619
0
  }
4620
0
4621
0
  // Per spec, we init the parent's members first
4622
0
  if (!Algorithm::Init(cx, val)) {
4623
0
    return false;
4624
0
  }
4625
0
4626
0
  bool isNull = val.isNullOrUndefined();
4627
0
  // We only need these if !isNull, in which case we have |cx|.
4628
0
  Maybe<JS::Rooted<JSObject *> > object;
4629
0
  Maybe<JS::Rooted<JS::Value> > temp;
4630
0
  if (!isNull) {
4631
0
    MOZ_ASSERT(cx);
4632
0
    object.emplace(cx, &val.toObject());
4633
0
    temp.emplace(cx);
4634
0
  }
4635
0
  if (!isNull) {
4636
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->saltLength_id, temp.ptr())) {
4637
0
      return false;
4638
0
    }
4639
0
  }
4640
0
  if (!isNull && !temp->isUndefined()) {
4641
0
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), &mSaltLength)) {
4642
0
      return false;
4643
0
    }
4644
0
    mIsAnyMemberPresent = true;
4645
0
  } else if (cx) {
4646
0
    // Don't error out if we have no cx.  In that
4647
0
    // situation the caller is default-constructing us and we'll
4648
0
    // just assume they know what they're doing.
4649
0
    return ThrowErrorMessage(cx, MSG_MISSING_REQUIRED_DICTIONARY_MEMBER,
4650
0
                             "'saltLength' member of RsaPssParams");
4651
0
  }
4652
0
  return true;
4653
0
}
4654
4655
bool
4656
RsaPssParams::Init(const nsAString& aJSON)
4657
0
{
4658
0
  AutoJSAPI jsapi;
4659
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
4660
0
  if (!cleanGlobal) {
4661
0
    return false;
4662
0
  }
4663
0
  if (!jsapi.Init(cleanGlobal)) {
4664
0
    return false;
4665
0
  }
4666
0
  JSContext* cx = jsapi.cx();
4667
0
  JS::Rooted<JS::Value> json(cx);
4668
0
  bool ok = ParseJSON(cx, aJSON, &json);
4669
0
  NS_ENSURE_TRUE(ok, false);
4670
0
  return Init(cx, json);
4671
0
}
4672
4673
bool
4674
RsaPssParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
4675
0
{
4676
0
  RsaPssParamsAtoms* atomsCache = GetAtomCache<RsaPssParamsAtoms>(cx);
4677
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
4678
0
    return false;
4679
0
  }
4680
0
4681
0
  // Per spec, we define the parent's members first
4682
0
  if (!Algorithm::ToObjectInternal(cx, rval)) {
4683
0
    return false;
4684
0
  }
4685
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
4686
0
4687
0
  do {
4688
0
    // block for our 'break' successCode and scope for 'temp' and 'currentValue'
4689
0
    JS::Rooted<JS::Value> temp(cx);
4690
0
    uint32_t const & currentValue = mSaltLength;
4691
0
    temp.setNumber(currentValue);
4692
0
    if (!JS_DefinePropertyById(cx, obj, atomsCache->saltLength_id, temp, JSPROP_ENUMERATE)) {
4693
0
      return false;
4694
0
    }
4695
0
    break;
4696
0
  } while(false);
4697
0
4698
0
  return true;
4699
0
}
4700
4701
bool
4702
RsaPssParams::ToJSON(nsAString& aJSON) const
4703
0
{
4704
0
  AutoJSAPI jsapi;
4705
0
  jsapi.Init();
4706
0
  JSContext *cx = jsapi.cx();
4707
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
4708
0
  // because we'll only be creating objects, in ways that have no
4709
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
4710
0
  // which likewise guarantees no side-effects for the sorts of
4711
0
  // things we will pass it.
4712
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
4713
0
  JS::Rooted<JS::Value> val(cx);
4714
0
  if (!ToObjectInternal(cx, &val)) {
4715
0
    return false;
4716
0
  }
4717
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
4718
0
  return StringifyToJSON(cx, obj, aJSON);
4719
0
}
4720
4721
void
4722
RsaPssParams::TraceDictionary(JSTracer* trc)
4723
0
{
4724
0
  Algorithm::TraceDictionary(trc);
4725
0
}
4726
4727
RsaPssParams&
4728
RsaPssParams::operator=(const RsaPssParams& aOther)
4729
0
{
4730
0
  Algorithm::operator=(aOther);
4731
0
  mSaltLength = aOther.mSaltLength;
4732
0
  return *this;
4733
0
}
4734
4735
namespace binding_detail {
4736
} // namespace binding_detail
4737
4738
4739
4740
HmacDerivedKeyParams::HmacDerivedKeyParams()
4741
  : HmacImportParams(FastDictionaryInitializer())
4742
0
{
4743
0
  // Safe to pass a null context if we pass a null value
4744
0
  Init(nullptr, JS::NullHandleValue);
4745
0
}
4746
4747
4748
bool
4749
HmacDerivedKeyParams::InitIds(JSContext* cx, HmacDerivedKeyParamsAtoms* atomsCache)
4750
0
{
4751
0
  MOZ_ASSERT(!*reinterpret_cast<jsid**>(atomsCache));
4752
0
4753
0
  // Initialize these in reverse order so that any failure leaves the first one
4754
0
  // uninitialized.
4755
0
  if (!atomsCache->length_id.init(cx, "length")) {
4756
0
    return false;
4757
0
  }
4758
0
  return true;
4759
0
}
4760
4761
bool
4762
HmacDerivedKeyParams::Init(JSContext* cx, JS::Handle<JS::Value> val, const char* sourceDescription, bool passedToJSImpl)
4763
0
{
4764
0
  // Passing a null JSContext is OK only if we're initing from null,
4765
0
  // Since in that case we will not have to do any property gets
4766
0
  // Also evaluate isNullOrUndefined in order to avoid false-positive
4767
0
  // checkers by static analysis tools
4768
0
  MOZ_ASSERT_IF(!cx, val.isNull() && val.isNullOrUndefined());
4769
0
  HmacDerivedKeyParamsAtoms* atomsCache = nullptr;
4770
0
  if (cx) {
4771
0
    atomsCache = GetAtomCache<HmacDerivedKeyParamsAtoms>(cx);
4772
0
    if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
4773
0
      return false;
4774
0
    }
4775
0
  }
4776
0
4777
0
  // Per spec, we init the parent's members first
4778
0
  if (!HmacImportParams::Init(cx, val)) {
4779
0
    return false;
4780
0
  }
4781
0
4782
0
  bool isNull = val.isNullOrUndefined();
4783
0
  // We only need these if !isNull, in which case we have |cx|.
4784
0
  Maybe<JS::Rooted<JSObject *> > object;
4785
0
  Maybe<JS::Rooted<JS::Value> > temp;
4786
0
  if (!isNull) {
4787
0
    MOZ_ASSERT(cx);
4788
0
    object.emplace(cx, &val.toObject());
4789
0
    temp.emplace(cx);
4790
0
  }
4791
0
  if (!isNull) {
4792
0
    if (!JS_GetPropertyById(cx, *object, atomsCache->length_id, temp.ptr())) {
4793
0
      return false;
4794
0
    }
4795
0
  }
4796
0
  if (!isNull && !temp->isUndefined()) {
4797
0
    mLength.Construct();
4798
0
    if (!ValueToPrimitive<uint32_t, eEnforceRange>(cx, temp.ref(), &(mLength.Value()))) {
4799
0
      return false;
4800
0
    }
4801
0
    mIsAnyMemberPresent = true;
4802
0
  }
4803
0
  return true;
4804
0
}
4805
4806
bool
4807
HmacDerivedKeyParams::Init(const nsAString& aJSON)
4808
0
{
4809
0
  AutoJSAPI jsapi;
4810
0
  JSObject* cleanGlobal = SimpleGlobalObject::Create(SimpleGlobalObject::GlobalType::BindingDetail);
4811
0
  if (!cleanGlobal) {
4812
0
    return false;
4813
0
  }
4814
0
  if (!jsapi.Init(cleanGlobal)) {
4815
0
    return false;
4816
0
  }
4817
0
  JSContext* cx = jsapi.cx();
4818
0
  JS::Rooted<JS::Value> json(cx);
4819
0
  bool ok = ParseJSON(cx, aJSON, &json);
4820
0
  NS_ENSURE_TRUE(ok, false);
4821
0
  return Init(cx, json);
4822
0
}
4823
4824
bool
4825
HmacDerivedKeyParams::ToObjectInternal(JSContext* cx, JS::MutableHandle<JS::Value> rval) const
4826
0
{
4827
0
  HmacDerivedKeyParamsAtoms* atomsCache = GetAtomCache<HmacDerivedKeyParamsAtoms>(cx);
4828
0
  if (!*reinterpret_cast<jsid**>(atomsCache) && !InitIds(cx, atomsCache)) {
4829
0
    return false;
4830
0
  }
4831
0
4832
0
  // Per spec, we define the parent's members first
4833
0
  if (!HmacImportParams::ToObjectInternal(cx, rval)) {
4834
0
    return false;
4835
0
  }
4836
0
  JS::Rooted<JSObject*> obj(cx, &rval.toObject());
4837
0
4838
0
  if (mLength.WasPassed()) {
4839
0
    do {
4840
0
      // block for our 'break' successCode and scope for 'temp' and 'currentValue'
4841
0
      JS::Rooted<JS::Value> temp(cx);
4842
0
      uint32_t const & currentValue = mLength.InternalValue();
4843
0
      temp.setNumber(currentValue);
4844
0
      if (!JS_DefinePropertyById(cx, obj, atomsCache->length_id, temp, JSPROP_ENUMERATE)) {
4845
0
        return false;
4846
0
      }
4847
0
      break;
4848
0
    } while(false);
4849
0
  }
4850
0
4851
0
  return true;
4852
0
}
4853
4854
bool
4855
HmacDerivedKeyParams::ToJSON(nsAString& aJSON) const
4856
0
{
4857
0
  AutoJSAPI jsapi;
4858
0
  jsapi.Init();
4859
0
  JSContext *cx = jsapi.cx();
4860
0
  // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
4861
0
  // because we'll only be creating objects, in ways that have no
4862
0
  // side-effects, followed by a call to JS::ToJSONMaybeSafely,
4863
0
  // which likewise guarantees no side-effects for the sorts of
4864
0
  // things we will pass it.
4865
0
  JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
4866
0
  JS::Rooted<JS::Value> val(cx);
4867
0
  if (!ToObjectInternal(cx, &val)) {
4868
0
    return false;
4869
0
  }
4870
0
  JS::Rooted<JSObject*> obj(cx, &val.toObject());
4871
0
  return StringifyToJSON(cx, obj, aJSON);
4872
0
}
4873
4874
void
4875
HmacDerivedKeyParams::TraceDictionary(JSTracer* trc)
4876
0
{
4877
0
  HmacImportParams::TraceDictionary(trc);
4878
0
}
4879
4880
namespace binding_detail {
4881
} // namespace binding_detail
4882
4883
4884
namespace CryptoKey_Binding {
4885
4886
MOZ_CAN_RUN_SCRIPT static bool
4887
get_type(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::CryptoKey* self, JSJitGetterCallArgs args)
4888
0
{
4889
0
  AUTO_PROFILER_LABEL_FAST("get CryptoKey.type", DOM, cx);
4890
0
4891
0
  DOMString result;
4892
0
  self->GetType(result);
4893
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
4894
0
  if (!xpc::NonVoidStringToJsval(cx, result, args.rval())) {
4895
0
    return false;
4896
0
  }
4897
0
  return true;
4898
0
}
4899
4900
static const JSJitInfo type_getterinfo = {
4901
  { (JSJitGetterOp)get_type },
4902
  { prototypes::id::CryptoKey },
4903
  { PrototypeTraits<prototypes::id::CryptoKey>::Depth },
4904
  JSJitInfo::Getter,
4905
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
4906
  JSVAL_TYPE_STRING,  /* returnType.  Not relevant for setters. */
4907
  false,  /* isInfallible. False in setters. */
4908
  false,  /* isMovable.  Not relevant for setters. */
4909
  false, /* isEliminatable.  Not relevant for setters. */
4910
  false, /* isAlwaysInSlot.  Only relevant for getters. */
4911
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
4912
  false,  /* isTypedMethod.  Only relevant for methods. */
4913
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
4914
};
4915
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
4916
static_assert(0 < 3, "There is no slot for us");
4917
4918
MOZ_CAN_RUN_SCRIPT static bool
4919
get_extractable(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::CryptoKey* self, JSJitGetterCallArgs args)
4920
0
{
4921
0
  AUTO_PROFILER_LABEL_FAST("get CryptoKey.extractable", DOM, cx);
4922
0
4923
0
  bool result(self->Extractable());
4924
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
4925
0
  args.rval().setBoolean(result);
4926
0
  return true;
4927
0
}
4928
4929
static const JSJitInfo extractable_getterinfo = {
4930
  { (JSJitGetterOp)get_extractable },
4931
  { prototypes::id::CryptoKey },
4932
  { PrototypeTraits<prototypes::id::CryptoKey>::Depth },
4933
  JSJitInfo::Getter,
4934
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
4935
  JSVAL_TYPE_BOOLEAN,  /* returnType.  Not relevant for setters. */
4936
  true,  /* isInfallible. False in setters. */
4937
  false,  /* isMovable.  Not relevant for setters. */
4938
  false, /* isEliminatable.  Not relevant for setters. */
4939
  false, /* isAlwaysInSlot.  Only relevant for getters. */
4940
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
4941
  false,  /* isTypedMethod.  Only relevant for methods. */
4942
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
4943
};
4944
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
4945
static_assert(0 < 3, "There is no slot for us");
4946
4947
MOZ_CAN_RUN_SCRIPT static bool
4948
get_algorithm(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::CryptoKey* self, JSJitGetterCallArgs args)
4949
0
{
4950
0
  AUTO_PROFILER_LABEL_FAST("get CryptoKey.algorithm", DOM, cx);
4951
0
4952
0
  // Have to either root across the getter call or reget after.
4953
0
  bool isXray;
4954
0
  JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
4955
0
  if (!slotStorage) {
4956
0
    return false;
4957
0
  }
4958
0
  const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 0) : (DOM_INSTANCE_RESERVED_SLOTS + 0);
4959
0
  MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
4960
0
  {
4961
0
    // Scope for cachedVal
4962
0
    JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
4963
0
    if (!cachedVal.isUndefined()) {
4964
0
      args.rval().set(cachedVal);
4965
0
      // The cached value is in the compartment of slotStorage,
4966
0
      // so wrap into the caller compartment as needed.
4967
0
      if (MaybeWrapObjectValue(cx, args.rval())) {
4968
0
        return true;
4969
0
      }
4970
0
      return false;
4971
0
    }
4972
0
  }
4973
0
4974
0
  FastErrorResult rv;
4975
0
  JS::Rooted<JSObject*> result(cx);
4976
0
  self->GetAlgorithm(cx, &result, rv);
4977
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
4978
0
    return false;
4979
0
  }
4980
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
4981
0
  {
4982
0
    JS::Rooted<JSObject*> conversionScope(cx, isXray ? JS::CurrentGlobalOrNull(cx) : slotStorage);
4983
0
    JSAutoRealm ar(cx, conversionScope);
4984
0
    do { // block we break out of when done wrapping
4985
0
      JS::ExposeObjectToActiveJS(result);
4986
0
      args.rval().setObject(*result);
4987
0
      if (!MaybeWrapObjectValue(cx, args.rval())) {
4988
0
        return false;
4989
0
      }
4990
0
      break;
4991
0
    } while (false);
4992
0
  }
4993
0
  { // And now store things in the realm of our slotStorage.
4994
0
    JSAutoRealm ar(cx, slotStorage);
4995
0
    // Make a copy so that we don't do unnecessary wrapping on args.rval().
4996
0
    JS::Rooted<JS::Value> storedVal(cx, args.rval());
4997
0
    if (!MaybeWrapObjectValue(cx, &storedVal)) {
4998
0
      return false;
4999
0
    }
5000
0
    js::SetReservedSlot(slotStorage, slotIndex, storedVal);
5001
0
    if (!isXray) {
5002
0
      // In the Xray case we don't need to do this, because getting the
5003
0
      // expando object already preserved our wrapper.
5004
0
      PreserveWrapper(self);
5005
0
    }
5006
0
  }
5007
0
  // And now make sure args.rval() is in the caller realm.
5008
0
  if (MaybeWrapObjectValue(cx, args.rval())) {
5009
0
    return true;
5010
0
  }
5011
0
  return false;
5012
0
}
5013
5014
static const JSJitInfo algorithm_getterinfo = {
5015
  { (JSJitGetterOp)get_algorithm },
5016
  { prototypes::id::CryptoKey },
5017
  { PrototypeTraits<prototypes::id::CryptoKey>::Depth },
5018
  JSJitInfo::Getter,
5019
  JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
5020
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
5021
  false,  /* isInfallible. False in setters. */
5022
  false,  /* isMovable.  Not relevant for setters. */
5023
  false, /* isEliminatable.  Not relevant for setters. */
5024
  false, /* isAlwaysInSlot.  Only relevant for getters. */
5025
  true, /* isLazilyCachedInSlot.  Only relevant for getters. */
5026
  false,  /* isTypedMethod.  Only relevant for methods. */
5027
  (DOM_INSTANCE_RESERVED_SLOTS + 0)   /* Reserved slot index, if we're stored in a slot, else 0. */
5028
};
5029
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) <= JSJitInfo::maxSlotIndex, "We won't fit");
5030
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 0) < 3, "There is no slot for us");
5031
5032
MOZ_CAN_RUN_SCRIPT static bool
5033
get_usages(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::CryptoKey* self, JSJitGetterCallArgs args)
5034
0
{
5035
0
  AUTO_PROFILER_LABEL_FAST("get CryptoKey.usages", DOM, cx);
5036
0
5037
0
  // Have to either root across the getter call or reget after.
5038
0
  bool isXray;
5039
0
  JS::Rooted<JSObject*> slotStorage(cx, GetCachedSlotStorageObject(cx, obj, &isXray));
5040
0
  if (!slotStorage) {
5041
0
    return false;
5042
0
  }
5043
0
  const size_t slotIndex = isXray ? (xpc::JSSLOT_EXPANDO_COUNT + 1) : (DOM_INSTANCE_RESERVED_SLOTS + 1);
5044
0
  MOZ_ASSERT(JSCLASS_RESERVED_SLOTS(js::GetObjectClass(slotStorage)) > slotIndex);
5045
0
  {
5046
0
    // Scope for cachedVal
5047
0
    JS::Value cachedVal = js::GetReservedSlot(slotStorage, slotIndex);
5048
0
    if (!cachedVal.isUndefined()) {
5049
0
      args.rval().set(cachedVal);
5050
0
      // The cached value is in the compartment of slotStorage,
5051
0
      // so wrap into the caller compartment as needed.
5052
0
      if (MaybeWrapNonDOMObjectValue(cx, args.rval())) {
5053
0
        return true;
5054
0
      }
5055
0
      return false;
5056
0
    }
5057
0
  }
5058
0
5059
0
  nsTArray<nsString> result;
5060
0
  self->GetUsages(result);
5061
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
5062
0
  {
5063
0
    JS::Rooted<JSObject*> conversionScope(cx, isXray ? JS::CurrentGlobalOrNull(cx) : slotStorage);
5064
0
    JSAutoRealm ar(cx, conversionScope);
5065
0
    do { // block we break out of when done wrapping
5066
0
5067
0
      uint32_t length = result.Length();
5068
0
      JS::Rooted<JSObject*> returnArray(cx, JS_NewArrayObject(cx, length));
5069
0
      if (!returnArray) {
5070
0
        return false;
5071
0
      }
5072
0
      // Scope for 'tmp'
5073
0
      {
5074
0
        JS::Rooted<JS::Value> tmp(cx);
5075
0
        for (uint32_t sequenceIdx0 = 0; sequenceIdx0 < length; ++sequenceIdx0) {
5076
0
          // Control block to let us common up the JS_DefineElement calls when there
5077
0
          // are different ways to succeed at wrapping the object.
5078
0
          do {
5079
0
            if (!xpc::NonVoidStringToJsval(cx, result[sequenceIdx0], &tmp)) {
5080
0
              return false;
5081
0
            }
5082
0
            break;
5083
0
          } while (false);
5084
0
          if (!JS_DefineElement(cx, returnArray, sequenceIdx0, tmp,
5085
0
                                JSPROP_ENUMERATE)) {
5086
0
            return false;
5087
0
          }
5088
0
        }
5089
0
      }
5090
0
      args.rval().setObject(*returnArray);
5091
0
      break;
5092
0
    } while (false);
5093
0
    JS::Rooted<JSObject*> rvalObj(cx, &args.rval().toObject());
5094
0
    if (!JS_FreezeObject(cx, rvalObj)) {
5095
0
      return false;
5096
0
    }
5097
0
  }
5098
0
  { // And now store things in the realm of our slotStorage.
5099
0
    JSAutoRealm ar(cx, slotStorage);
5100
0
    // Make a copy so that we don't do unnecessary wrapping on args.rval().
5101
0
    JS::Rooted<JS::Value> storedVal(cx, args.rval());
5102
0
    if (!MaybeWrapNonDOMObjectValue(cx, &storedVal)) {
5103
0
      return false;
5104
0
    }
5105
0
    js::SetReservedSlot(slotStorage, slotIndex, storedVal);
5106
0
    if (!isXray) {
5107
0
      // In the Xray case we don't need to do this, because getting the
5108
0
      // expando object already preserved our wrapper.
5109
0
      PreserveWrapper(self);
5110
0
    }
5111
0
  }
5112
0
  // And now make sure args.rval() is in the caller realm.
5113
0
  if (MaybeWrapNonDOMObjectValue(cx, args.rval())) {
5114
0
    return true;
5115
0
  }
5116
0
  return false;
5117
0
}
5118
5119
static const JSJitInfo usages_getterinfo = {
5120
  { (JSJitGetterOp)get_usages },
5121
  { prototypes::id::CryptoKey },
5122
  { PrototypeTraits<prototypes::id::CryptoKey>::Depth },
5123
  JSJitInfo::Getter,
5124
  JSJitInfo::AliasNone, /* aliasSet.  Not relevant for setters. */
5125
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
5126
  false,  /* isInfallible. False in setters. */
5127
  true,  /* isMovable.  Not relevant for setters. */
5128
  true, /* isEliminatable.  Not relevant for setters. */
5129
  false, /* isAlwaysInSlot.  Only relevant for getters. */
5130
  true, /* isLazilyCachedInSlot.  Only relevant for getters. */
5131
  false,  /* isTypedMethod.  Only relevant for methods. */
5132
  (DOM_INSTANCE_RESERVED_SLOTS + 1)   /* Reserved slot index, if we're stored in a slot, else 0. */
5133
};
5134
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 1) <= JSJitInfo::maxSlotIndex, "We won't fit");
5135
static_assert((DOM_INSTANCE_RESERVED_SLOTS + 1) < 3, "There is no slot for us");
5136
5137
static bool
5138
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
5139
0
{
5140
0
  mozilla::dom::CryptoKey* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::CryptoKey>(obj);
5141
0
  // We don't want to preserve if we don't have a wrapper, and we
5142
0
  // obviously can't preserve if we're not initialized.
5143
0
  if (self && self->GetWrapperPreserveColor()) {
5144
0
    PreserveWrapper(self);
5145
0
  }
5146
0
  return true;
5147
0
}
5148
5149
static void
5150
_finalize(js::FreeOp* fop, JSObject* obj)
5151
0
{
5152
0
  mozilla::dom::CryptoKey* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::CryptoKey>(obj);
5153
0
  if (self) {
5154
0
    ClearWrapper(self, self, obj);
5155
0
    AddForDeferredFinalization<mozilla::dom::CryptoKey>(self);
5156
0
  }
5157
0
}
5158
5159
static size_t
5160
_objectMoved(JSObject* obj, JSObject* old)
5161
0
{
5162
0
  mozilla::dom::CryptoKey* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::CryptoKey>(obj);
5163
0
  if (self) {
5164
0
    UpdateWrapper(self, self, obj, old);
5165
0
  }
5166
0
5167
0
  return 0;
5168
0
}
5169
5170
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
5171
#if defined(__clang__)
5172
#pragma clang diagnostic push
5173
#pragma clang diagnostic ignored "-Wmissing-braces"
5174
#endif
5175
static const JSPropertySpec sAttributes_specs[] = {
5176
  { "type", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &type_getterinfo, nullptr, nullptr },
5177
  { "extractable", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &extractable_getterinfo, nullptr, nullptr },
5178
  { "algorithm", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &algorithm_getterinfo, nullptr, nullptr },
5179
  { "usages", JSPROP_ENUMERATE, GenericGetter<NormalThisPolicy, ThrowExceptions>, &usages_getterinfo, nullptr, nullptr },
5180
  { nullptr, 0, nullptr, nullptr, nullptr, nullptr }
5181
};
5182
#if defined(__clang__)
5183
#pragma clang diagnostic pop
5184
#endif
5185
5186
5187
static const Prefable<const JSPropertySpec> sAttributes[] = {
5188
  { nullptr, &sAttributes_specs[0] },
5189
  { nullptr, nullptr }
5190
};
5191
5192
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
5193
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
5194
static_assert(4 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
5195
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
5196
5197
5198
static uint16_t sNativeProperties_sortedPropertyIndices[4];
5199
static PropertyInfo sNativeProperties_propertyInfos[4];
5200
5201
static const NativePropertiesN<1> sNativeProperties = {
5202
  false, 0,
5203
  false, 0,
5204
  false, 0,
5205
  true,  0 /* sAttributes */,
5206
  false, 0,
5207
  false, 0,
5208
  false, 0,
5209
  -1,
5210
  4,
5211
  sNativeProperties_sortedPropertyIndices,
5212
  {
5213
    { sAttributes, &sNativeProperties_propertyInfos[0] }
5214
  }
5215
};
5216
static_assert(4 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
5217
    "We have a property info count that is oversized");
5218
5219
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
5220
  {
5221
    "Function",
5222
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
5223
    &sBoringInterfaceObjectClassClassOps,
5224
    JS_NULL_CLASS_SPEC,
5225
    JS_NULL_CLASS_EXT,
5226
    &sInterfaceObjectClassObjectOps
5227
  },
5228
  eInterface,
5229
  true,
5230
  prototypes::id::CryptoKey,
5231
  PrototypeTraits<prototypes::id::CryptoKey>::Depth,
5232
  sNativePropertyHooks,
5233
  "function CryptoKey() {\n    [native code]\n}",
5234
  JS::GetRealmFunctionPrototype
5235
};
5236
5237
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
5238
  {
5239
    "CryptoKeyPrototype",
5240
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
5241
    JS_NULL_CLASS_OPS,
5242
    JS_NULL_CLASS_SPEC,
5243
    JS_NULL_CLASS_EXT,
5244
    JS_NULL_OBJECT_OPS
5245
  },
5246
  eInterfacePrototype,
5247
  false,
5248
  prototypes::id::CryptoKey,
5249
  PrototypeTraits<prototypes::id::CryptoKey>::Depth,
5250
  sNativePropertyHooks,
5251
  "[object CryptoKeyPrototype]",
5252
  JS::GetRealmObjectPrototype
5253
};
5254
5255
static const js::ClassOps sClassOps = {
5256
  _addProperty, /* addProperty */
5257
  nullptr,               /* delProperty */
5258
  nullptr,               /* enumerate */
5259
  nullptr, /* newEnumerate */
5260
  nullptr, /* resolve */
5261
  nullptr, /* mayResolve */
5262
  _finalize, /* finalize */
5263
  nullptr, /* call */
5264
  nullptr,               /* hasInstance */
5265
  nullptr,               /* construct */
5266
  nullptr, /* trace */
5267
};
5268
5269
static const js::ClassExtension sClassExtension = {
5270
  nullptr, /* weakmapKeyDelegateOp */
5271
  _objectMoved /* objectMovedOp */
5272
};
5273
5274
static const DOMJSClass sClass = {
5275
  { "CryptoKey",
5276
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(3),
5277
    &sClassOps,
5278
    JS_NULL_CLASS_SPEC,
5279
    &sClassExtension,
5280
    JS_NULL_OBJECT_OPS
5281
  },
5282
  { prototypes::id::CryptoKey, 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 },
5283
  IsBaseOf<nsISupports, mozilla::dom::CryptoKey >::value,
5284
  sNativePropertyHooks,
5285
  FindAssociatedGlobalForNative<mozilla::dom::CryptoKey>::Get,
5286
  GetProtoObjectHandle,
5287
  GetCCParticipant<mozilla::dom::CryptoKey>::Get()
5288
};
5289
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
5290
              "Must have the right minimal number of reserved slots.");
5291
static_assert(3 >= 3,
5292
              "Must have enough reserved slots.");
5293
5294
const JSClass*
5295
GetJSClass()
5296
0
{
5297
0
  return sClass.ToJSClass();
5298
0
}
5299
5300
bool
5301
Wrap(JSContext* aCx, mozilla::dom::CryptoKey* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
5302
0
{
5303
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::CryptoKey>::value,
5304
0
                "Shouldn't have wrappercached things that are not refcounted.");
5305
0
  MOZ_ASSERT(static_cast<mozilla::dom::CryptoKey*>(aObject) ==
5306
0
             reinterpret_cast<mozilla::dom::CryptoKey*>(aObject),
5307
0
             "Multiple inheritance for mozilla::dom::CryptoKey is broken.");
5308
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
5309
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
5310
0
  MOZ_ASSERT(!aCache->GetWrapper(),
5311
0
             "You should probably not be using Wrap() directly; use "
5312
0
             "GetOrCreateDOMReflector instead");
5313
0
5314
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
5315
0
             "nsISupports must be on our primary inheritance chain");
5316
0
5317
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
5318
0
  if (!global) {
5319
0
    return false;
5320
0
  }
5321
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
5322
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
5323
0
5324
0
  // That might have ended up wrapping us already, due to the wonders
5325
0
  // of XBL.  Check for that, and bail out as needed.
5326
0
  aReflector.set(aCache->GetWrapper());
5327
0
  if (aReflector) {
5328
#ifdef DEBUG
5329
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
5330
#endif // DEBUG
5331
    return true;
5332
0
  }
5333
0
5334
0
  JSAutoRealm ar(aCx, global);
5335
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
5336
0
  if (!canonicalProto) {
5337
0
    return false;
5338
0
  }
5339
0
  JS::Rooted<JSObject*> proto(aCx);
5340
0
  if (aGivenProto) {
5341
0
    proto = aGivenProto;
5342
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
5343
0
    // coming in, we changed compartments to that of "parent" so may need
5344
0
    // to wrap the proto here.
5345
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
5346
0
      if (!JS_WrapObject(aCx, &proto)) {
5347
0
        return false;
5348
0
      }
5349
0
    }
5350
0
  } else {
5351
0
    proto = canonicalProto;
5352
0
  }
5353
0
5354
0
  BindingJSObjectCreator<mozilla::dom::CryptoKey> creator(aCx);
5355
0
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
5356
0
  if (!aReflector) {
5357
0
    return false;
5358
0
  }
5359
0
5360
0
  aCache->SetWrapper(aReflector);
5361
0
  creator.InitializationSucceeded();
5362
0
5363
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
5364
0
             aCache->GetWrapperPreserveColor() == aReflector);
5365
0
  // If proto != canonicalProto, we have to preserve our wrapper;
5366
0
  // otherwise we won't be able to properly recreate it later, since
5367
0
  // we won't know what proto to use.  Note that we don't check
5368
0
  // aGivenProto here, since it's entirely possible (and even
5369
0
  // somewhat common) to have a non-null aGivenProto which is the
5370
0
  // same as canonicalProto.
5371
0
  if (proto != canonicalProto) {
5372
0
    PreserveWrapper(aObject);
5373
0
  }
5374
0
5375
0
  return true;
5376
0
}
5377
5378
// This may allocate too many slots, because we only really need
5379
// slots for our non-interface-typed members that we cache.  But
5380
// allocating slots only for those would make the slot index
5381
// computations much more complicated, so let's do this the simple
5382
// way for now.
5383
DEFINE_XRAY_EXPANDO_CLASS(static, sXrayExpandoObjectClass, 2);
5384
5385
const NativePropertyHooks sNativePropertyHooks[] = { {
5386
  nullptr,
5387
  nullptr,
5388
  nullptr,
5389
  { sNativeProperties.Upcast(), nullptr },
5390
  prototypes::id::CryptoKey,
5391
  constructors::id::CryptoKey,
5392
  nullptr,
5393
  &sXrayExpandoObjectClass
5394
} };
5395
5396
void
5397
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
5398
0
{
5399
0
  JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
5400
0
  if (!parentProto) {
5401
0
    return;
5402
0
  }
5403
0
5404
0
  JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
5405
0
  if (!constructorProto) {
5406
0
    return;
5407
0
  }
5408
0
5409
0
  static bool sIdsInited = false;
5410
0
  if (!sIdsInited && NS_IsMainThread()) {
5411
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
5412
0
      return;
5413
0
    }
5414
0
    sIdsInited = true;
5415
0
  }
5416
0
5417
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::CryptoKey);
5418
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::CryptoKey);
5419
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
5420
0
                              &sPrototypeClass.mBase, protoCache,
5421
0
                              nullptr,
5422
0
                              constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
5423
0
                              interfaceCache,
5424
0
                              sNativeProperties.Upcast(),
5425
0
                              nullptr,
5426
0
                              "CryptoKey", aDefineOnGlobal,
5427
0
                              nullptr,
5428
0
                              false);
5429
0
}
5430
5431
JSObject*
5432
GetConstructorObject(JSContext* aCx)
5433
0
{
5434
0
  return GetConstructorObjectHandle(aCx);
5435
0
}
5436
5437
} // namespace CryptoKey_Binding
5438
5439
5440
5441
namespace SubtleCrypto_Binding {
5442
5443
MOZ_CAN_RUN_SCRIPT static bool
5444
encrypt(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
5445
0
{
5446
0
  AUTO_PROFILER_LABEL_FAST("SubtleCrypto.encrypt", DOM, cx);
5447
0
5448
0
  if (MOZ_UNLIKELY(args.length() < 3)) {
5449
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SubtleCrypto.encrypt");
5450
0
  }
5451
0
  ObjectOrString arg0;
5452
0
  ObjectOrStringArgument arg0_holder(arg0);
5453
0
  {
5454
0
    bool done = false, failed = false, tryNext;
5455
0
    if (args[0].isObject()) {
5456
0
      if (!arg0_holder.SetToObject(cx, &args[0].toObject(), false)) {
5457
0
        return false;
5458
0
      }
5459
0
      done = true;
5460
0
    } else {
5461
0
      do {
5462
0
        done = (failed = !arg0_holder.TrySetToString(cx, args[0], tryNext)) || !tryNext;
5463
0
        break;
5464
0
      } while (false);
5465
0
    }
5466
0
    if (failed) {
5467
0
      return false;
5468
0
    }
5469
0
    if (!done) {
5470
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 1 of SubtleCrypto.encrypt", "Object");
5471
0
      return false;
5472
0
    }
5473
0
  }
5474
0
  NonNull<mozilla::dom::CryptoKey> arg1;
5475
0
  if (args[1].isObject()) {
5476
0
    {
5477
0
      nsresult rv = UnwrapObject<prototypes::id::CryptoKey, mozilla::dom::CryptoKey>(args[1], arg1);
5478
0
      if (NS_FAILED(rv)) {
5479
0
        ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 2 of SubtleCrypto.encrypt", "CryptoKey");
5480
0
        return false;
5481
0
      }
5482
0
    }
5483
0
  } else {
5484
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of SubtleCrypto.encrypt");
5485
0
    return false;
5486
0
  }
5487
0
  ArrayBufferViewOrArrayBuffer arg2;
5488
0
  ArrayBufferViewOrArrayBufferArgument arg2_holder(arg2);
5489
0
  {
5490
0
    bool done = false, failed = false, tryNext;
5491
0
    if (args[2].isObject()) {
5492
0
      done = (failed = !arg2_holder.TrySetToArrayBufferView(cx, args[2], tryNext, false)) || !tryNext ||
5493
0
             (failed = !arg2_holder.TrySetToArrayBuffer(cx, args[2], tryNext, false)) || !tryNext;
5494
0
5495
0
    }
5496
0
    if (failed) {
5497
0
      return false;
5498
0
    }
5499
0
    if (!done) {
5500
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 3 of SubtleCrypto.encrypt", "ArrayBufferView, ArrayBuffer");
5501
0
      return false;
5502
0
    }
5503
0
  }
5504
0
  FastErrorResult rv;
5505
0
  auto result(StrongOrRawPtr<Promise>(self->Encrypt(cx, Constify(arg0), MOZ_KnownLive(NonNullHelper(arg1)), Constify(arg2), rv)));
5506
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
5507
0
    return false;
5508
0
  }
5509
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
5510
0
  if (!ToJSValue(cx, result, args.rval())) {
5511
0
    return false;
5512
0
  }
5513
0
  return true;
5514
0
}
5515
5516
MOZ_CAN_RUN_SCRIPT static bool
5517
encrypt_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
5518
0
{
5519
0
  bool ok = encrypt(cx, obj, self, args);
5520
0
  if (ok) {
5521
0
    return true;
5522
0
  }
5523
0
  return ConvertExceptionToPromise(cx, args.rval());
5524
0
}
5525
5526
static const JSJitInfo encrypt_methodinfo = {
5527
  { (JSJitGetterOp)encrypt_promiseWrapper },
5528
  { prototypes::id::SubtleCrypto },
5529
  { PrototypeTraits<prototypes::id::SubtleCrypto>::Depth },
5530
  JSJitInfo::Method,
5531
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
5532
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
5533
  false,  /* isInfallible. False in setters. */
5534
  false,  /* isMovable.  Not relevant for setters. */
5535
  false, /* isEliminatable.  Not relevant for setters. */
5536
  false, /* isAlwaysInSlot.  Only relevant for getters. */
5537
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
5538
  false,  /* isTypedMethod.  Only relevant for methods. */
5539
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
5540
};
5541
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
5542
static_assert(0 < 1, "There is no slot for us");
5543
5544
MOZ_CAN_RUN_SCRIPT static bool
5545
decrypt(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
5546
0
{
5547
0
  AUTO_PROFILER_LABEL_FAST("SubtleCrypto.decrypt", DOM, cx);
5548
0
5549
0
  if (MOZ_UNLIKELY(args.length() < 3)) {
5550
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SubtleCrypto.decrypt");
5551
0
  }
5552
0
  ObjectOrString arg0;
5553
0
  ObjectOrStringArgument arg0_holder(arg0);
5554
0
  {
5555
0
    bool done = false, failed = false, tryNext;
5556
0
    if (args[0].isObject()) {
5557
0
      if (!arg0_holder.SetToObject(cx, &args[0].toObject(), false)) {
5558
0
        return false;
5559
0
      }
5560
0
      done = true;
5561
0
    } else {
5562
0
      do {
5563
0
        done = (failed = !arg0_holder.TrySetToString(cx, args[0], tryNext)) || !tryNext;
5564
0
        break;
5565
0
      } while (false);
5566
0
    }
5567
0
    if (failed) {
5568
0
      return false;
5569
0
    }
5570
0
    if (!done) {
5571
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 1 of SubtleCrypto.decrypt", "Object");
5572
0
      return false;
5573
0
    }
5574
0
  }
5575
0
  NonNull<mozilla::dom::CryptoKey> arg1;
5576
0
  if (args[1].isObject()) {
5577
0
    {
5578
0
      nsresult rv = UnwrapObject<prototypes::id::CryptoKey, mozilla::dom::CryptoKey>(args[1], arg1);
5579
0
      if (NS_FAILED(rv)) {
5580
0
        ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 2 of SubtleCrypto.decrypt", "CryptoKey");
5581
0
        return false;
5582
0
      }
5583
0
    }
5584
0
  } else {
5585
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of SubtleCrypto.decrypt");
5586
0
    return false;
5587
0
  }
5588
0
  ArrayBufferViewOrArrayBuffer arg2;
5589
0
  ArrayBufferViewOrArrayBufferArgument arg2_holder(arg2);
5590
0
  {
5591
0
    bool done = false, failed = false, tryNext;
5592
0
    if (args[2].isObject()) {
5593
0
      done = (failed = !arg2_holder.TrySetToArrayBufferView(cx, args[2], tryNext, false)) || !tryNext ||
5594
0
             (failed = !arg2_holder.TrySetToArrayBuffer(cx, args[2], tryNext, false)) || !tryNext;
5595
0
5596
0
    }
5597
0
    if (failed) {
5598
0
      return false;
5599
0
    }
5600
0
    if (!done) {
5601
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 3 of SubtleCrypto.decrypt", "ArrayBufferView, ArrayBuffer");
5602
0
      return false;
5603
0
    }
5604
0
  }
5605
0
  FastErrorResult rv;
5606
0
  auto result(StrongOrRawPtr<Promise>(self->Decrypt(cx, Constify(arg0), MOZ_KnownLive(NonNullHelper(arg1)), Constify(arg2), rv)));
5607
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
5608
0
    return false;
5609
0
  }
5610
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
5611
0
  if (!ToJSValue(cx, result, args.rval())) {
5612
0
    return false;
5613
0
  }
5614
0
  return true;
5615
0
}
5616
5617
MOZ_CAN_RUN_SCRIPT static bool
5618
decrypt_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
5619
0
{
5620
0
  bool ok = decrypt(cx, obj, self, args);
5621
0
  if (ok) {
5622
0
    return true;
5623
0
  }
5624
0
  return ConvertExceptionToPromise(cx, args.rval());
5625
0
}
5626
5627
static const JSJitInfo decrypt_methodinfo = {
5628
  { (JSJitGetterOp)decrypt_promiseWrapper },
5629
  { prototypes::id::SubtleCrypto },
5630
  { PrototypeTraits<prototypes::id::SubtleCrypto>::Depth },
5631
  JSJitInfo::Method,
5632
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
5633
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
5634
  false,  /* isInfallible. False in setters. */
5635
  false,  /* isMovable.  Not relevant for setters. */
5636
  false, /* isEliminatable.  Not relevant for setters. */
5637
  false, /* isAlwaysInSlot.  Only relevant for getters. */
5638
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
5639
  false,  /* isTypedMethod.  Only relevant for methods. */
5640
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
5641
};
5642
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
5643
static_assert(0 < 1, "There is no slot for us");
5644
5645
MOZ_CAN_RUN_SCRIPT static bool
5646
sign(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
5647
0
{
5648
0
  AUTO_PROFILER_LABEL_FAST("SubtleCrypto.sign", DOM, cx);
5649
0
5650
0
  if (MOZ_UNLIKELY(args.length() < 3)) {
5651
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SubtleCrypto.sign");
5652
0
  }
5653
0
  ObjectOrString arg0;
5654
0
  ObjectOrStringArgument arg0_holder(arg0);
5655
0
  {
5656
0
    bool done = false, failed = false, tryNext;
5657
0
    if (args[0].isObject()) {
5658
0
      if (!arg0_holder.SetToObject(cx, &args[0].toObject(), false)) {
5659
0
        return false;
5660
0
      }
5661
0
      done = true;
5662
0
    } else {
5663
0
      do {
5664
0
        done = (failed = !arg0_holder.TrySetToString(cx, args[0], tryNext)) || !tryNext;
5665
0
        break;
5666
0
      } while (false);
5667
0
    }
5668
0
    if (failed) {
5669
0
      return false;
5670
0
    }
5671
0
    if (!done) {
5672
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 1 of SubtleCrypto.sign", "Object");
5673
0
      return false;
5674
0
    }
5675
0
  }
5676
0
  NonNull<mozilla::dom::CryptoKey> arg1;
5677
0
  if (args[1].isObject()) {
5678
0
    {
5679
0
      nsresult rv = UnwrapObject<prototypes::id::CryptoKey, mozilla::dom::CryptoKey>(args[1], arg1);
5680
0
      if (NS_FAILED(rv)) {
5681
0
        ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 2 of SubtleCrypto.sign", "CryptoKey");
5682
0
        return false;
5683
0
      }
5684
0
    }
5685
0
  } else {
5686
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of SubtleCrypto.sign");
5687
0
    return false;
5688
0
  }
5689
0
  ArrayBufferViewOrArrayBuffer arg2;
5690
0
  ArrayBufferViewOrArrayBufferArgument arg2_holder(arg2);
5691
0
  {
5692
0
    bool done = false, failed = false, tryNext;
5693
0
    if (args[2].isObject()) {
5694
0
      done = (failed = !arg2_holder.TrySetToArrayBufferView(cx, args[2], tryNext, false)) || !tryNext ||
5695
0
             (failed = !arg2_holder.TrySetToArrayBuffer(cx, args[2], tryNext, false)) || !tryNext;
5696
0
5697
0
    }
5698
0
    if (failed) {
5699
0
      return false;
5700
0
    }
5701
0
    if (!done) {
5702
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 3 of SubtleCrypto.sign", "ArrayBufferView, ArrayBuffer");
5703
0
      return false;
5704
0
    }
5705
0
  }
5706
0
  FastErrorResult rv;
5707
0
  auto result(StrongOrRawPtr<Promise>(self->Sign(cx, Constify(arg0), MOZ_KnownLive(NonNullHelper(arg1)), Constify(arg2), rv)));
5708
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
5709
0
    return false;
5710
0
  }
5711
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
5712
0
  if (!ToJSValue(cx, result, args.rval())) {
5713
0
    return false;
5714
0
  }
5715
0
  return true;
5716
0
}
5717
5718
MOZ_CAN_RUN_SCRIPT static bool
5719
sign_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
5720
0
{
5721
0
  bool ok = sign(cx, obj, self, args);
5722
0
  if (ok) {
5723
0
    return true;
5724
0
  }
5725
0
  return ConvertExceptionToPromise(cx, args.rval());
5726
0
}
5727
5728
static const JSJitInfo sign_methodinfo = {
5729
  { (JSJitGetterOp)sign_promiseWrapper },
5730
  { prototypes::id::SubtleCrypto },
5731
  { PrototypeTraits<prototypes::id::SubtleCrypto>::Depth },
5732
  JSJitInfo::Method,
5733
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
5734
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
5735
  false,  /* isInfallible. False in setters. */
5736
  false,  /* isMovable.  Not relevant for setters. */
5737
  false, /* isEliminatable.  Not relevant for setters. */
5738
  false, /* isAlwaysInSlot.  Only relevant for getters. */
5739
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
5740
  false,  /* isTypedMethod.  Only relevant for methods. */
5741
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
5742
};
5743
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
5744
static_assert(0 < 1, "There is no slot for us");
5745
5746
MOZ_CAN_RUN_SCRIPT static bool
5747
verify(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
5748
0
{
5749
0
  AUTO_PROFILER_LABEL_FAST("SubtleCrypto.verify", DOM, cx);
5750
0
5751
0
  if (MOZ_UNLIKELY(args.length() < 4)) {
5752
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SubtleCrypto.verify");
5753
0
  }
5754
0
  ObjectOrString arg0;
5755
0
  ObjectOrStringArgument arg0_holder(arg0);
5756
0
  {
5757
0
    bool done = false, failed = false, tryNext;
5758
0
    if (args[0].isObject()) {
5759
0
      if (!arg0_holder.SetToObject(cx, &args[0].toObject(), false)) {
5760
0
        return false;
5761
0
      }
5762
0
      done = true;
5763
0
    } else {
5764
0
      do {
5765
0
        done = (failed = !arg0_holder.TrySetToString(cx, args[0], tryNext)) || !tryNext;
5766
0
        break;
5767
0
      } while (false);
5768
0
    }
5769
0
    if (failed) {
5770
0
      return false;
5771
0
    }
5772
0
    if (!done) {
5773
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 1 of SubtleCrypto.verify", "Object");
5774
0
      return false;
5775
0
    }
5776
0
  }
5777
0
  NonNull<mozilla::dom::CryptoKey> arg1;
5778
0
  if (args[1].isObject()) {
5779
0
    {
5780
0
      nsresult rv = UnwrapObject<prototypes::id::CryptoKey, mozilla::dom::CryptoKey>(args[1], arg1);
5781
0
      if (NS_FAILED(rv)) {
5782
0
        ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 2 of SubtleCrypto.verify", "CryptoKey");
5783
0
        return false;
5784
0
      }
5785
0
    }
5786
0
  } else {
5787
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of SubtleCrypto.verify");
5788
0
    return false;
5789
0
  }
5790
0
  ArrayBufferViewOrArrayBuffer arg2;
5791
0
  ArrayBufferViewOrArrayBufferArgument arg2_holder(arg2);
5792
0
  {
5793
0
    bool done = false, failed = false, tryNext;
5794
0
    if (args[2].isObject()) {
5795
0
      done = (failed = !arg2_holder.TrySetToArrayBufferView(cx, args[2], tryNext, false)) || !tryNext ||
5796
0
             (failed = !arg2_holder.TrySetToArrayBuffer(cx, args[2], tryNext, false)) || !tryNext;
5797
0
5798
0
    }
5799
0
    if (failed) {
5800
0
      return false;
5801
0
    }
5802
0
    if (!done) {
5803
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 3 of SubtleCrypto.verify", "ArrayBufferView, ArrayBuffer");
5804
0
      return false;
5805
0
    }
5806
0
  }
5807
0
  ArrayBufferViewOrArrayBuffer arg3;
5808
0
  ArrayBufferViewOrArrayBufferArgument arg3_holder(arg3);
5809
0
  {
5810
0
    bool done = false, failed = false, tryNext;
5811
0
    if (args[3].isObject()) {
5812
0
      done = (failed = !arg3_holder.TrySetToArrayBufferView(cx, args[3], tryNext, false)) || !tryNext ||
5813
0
             (failed = !arg3_holder.TrySetToArrayBuffer(cx, args[3], tryNext, false)) || !tryNext;
5814
0
5815
0
    }
5816
0
    if (failed) {
5817
0
      return false;
5818
0
    }
5819
0
    if (!done) {
5820
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 4 of SubtleCrypto.verify", "ArrayBufferView, ArrayBuffer");
5821
0
      return false;
5822
0
    }
5823
0
  }
5824
0
  FastErrorResult rv;
5825
0
  auto result(StrongOrRawPtr<Promise>(self->Verify(cx, Constify(arg0), MOZ_KnownLive(NonNullHelper(arg1)), Constify(arg2), Constify(arg3), rv)));
5826
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
5827
0
    return false;
5828
0
  }
5829
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
5830
0
  if (!ToJSValue(cx, result, args.rval())) {
5831
0
    return false;
5832
0
  }
5833
0
  return true;
5834
0
}
5835
5836
MOZ_CAN_RUN_SCRIPT static bool
5837
verify_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
5838
0
{
5839
0
  bool ok = verify(cx, obj, self, args);
5840
0
  if (ok) {
5841
0
    return true;
5842
0
  }
5843
0
  return ConvertExceptionToPromise(cx, args.rval());
5844
0
}
5845
5846
static const JSJitInfo verify_methodinfo = {
5847
  { (JSJitGetterOp)verify_promiseWrapper },
5848
  { prototypes::id::SubtleCrypto },
5849
  { PrototypeTraits<prototypes::id::SubtleCrypto>::Depth },
5850
  JSJitInfo::Method,
5851
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
5852
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
5853
  false,  /* isInfallible. False in setters. */
5854
  false,  /* isMovable.  Not relevant for setters. */
5855
  false, /* isEliminatable.  Not relevant for setters. */
5856
  false, /* isAlwaysInSlot.  Only relevant for getters. */
5857
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
5858
  false,  /* isTypedMethod.  Only relevant for methods. */
5859
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
5860
};
5861
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
5862
static_assert(0 < 1, "There is no slot for us");
5863
5864
MOZ_CAN_RUN_SCRIPT static bool
5865
digest(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
5866
0
{
5867
0
  AUTO_PROFILER_LABEL_FAST("SubtleCrypto.digest", DOM, cx);
5868
0
5869
0
  if (MOZ_UNLIKELY(args.length() < 2)) {
5870
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SubtleCrypto.digest");
5871
0
  }
5872
0
  ObjectOrString arg0;
5873
0
  ObjectOrStringArgument arg0_holder(arg0);
5874
0
  {
5875
0
    bool done = false, failed = false, tryNext;
5876
0
    if (args[0].isObject()) {
5877
0
      if (!arg0_holder.SetToObject(cx, &args[0].toObject(), false)) {
5878
0
        return false;
5879
0
      }
5880
0
      done = true;
5881
0
    } else {
5882
0
      do {
5883
0
        done = (failed = !arg0_holder.TrySetToString(cx, args[0], tryNext)) || !tryNext;
5884
0
        break;
5885
0
      } while (false);
5886
0
    }
5887
0
    if (failed) {
5888
0
      return false;
5889
0
    }
5890
0
    if (!done) {
5891
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 1 of SubtleCrypto.digest", "Object");
5892
0
      return false;
5893
0
    }
5894
0
  }
5895
0
  ArrayBufferViewOrArrayBuffer arg1;
5896
0
  ArrayBufferViewOrArrayBufferArgument arg1_holder(arg1);
5897
0
  {
5898
0
    bool done = false, failed = false, tryNext;
5899
0
    if (args[1].isObject()) {
5900
0
      done = (failed = !arg1_holder.TrySetToArrayBufferView(cx, args[1], tryNext, false)) || !tryNext ||
5901
0
             (failed = !arg1_holder.TrySetToArrayBuffer(cx, args[1], tryNext, false)) || !tryNext;
5902
0
5903
0
    }
5904
0
    if (failed) {
5905
0
      return false;
5906
0
    }
5907
0
    if (!done) {
5908
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 2 of SubtleCrypto.digest", "ArrayBufferView, ArrayBuffer");
5909
0
      return false;
5910
0
    }
5911
0
  }
5912
0
  FastErrorResult rv;
5913
0
  auto result(StrongOrRawPtr<Promise>(self->Digest(cx, Constify(arg0), Constify(arg1), rv)));
5914
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
5915
0
    return false;
5916
0
  }
5917
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
5918
0
  if (!ToJSValue(cx, result, args.rval())) {
5919
0
    return false;
5920
0
  }
5921
0
  return true;
5922
0
}
5923
5924
MOZ_CAN_RUN_SCRIPT static bool
5925
digest_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
5926
0
{
5927
0
  bool ok = digest(cx, obj, self, args);
5928
0
  if (ok) {
5929
0
    return true;
5930
0
  }
5931
0
  return ConvertExceptionToPromise(cx, args.rval());
5932
0
}
5933
5934
static const JSJitInfo digest_methodinfo = {
5935
  { (JSJitGetterOp)digest_promiseWrapper },
5936
  { prototypes::id::SubtleCrypto },
5937
  { PrototypeTraits<prototypes::id::SubtleCrypto>::Depth },
5938
  JSJitInfo::Method,
5939
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
5940
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
5941
  false,  /* isInfallible. False in setters. */
5942
  false,  /* isMovable.  Not relevant for setters. */
5943
  false, /* isEliminatable.  Not relevant for setters. */
5944
  false, /* isAlwaysInSlot.  Only relevant for getters. */
5945
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
5946
  false,  /* isTypedMethod.  Only relevant for methods. */
5947
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
5948
};
5949
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
5950
static_assert(0 < 1, "There is no slot for us");
5951
5952
MOZ_CAN_RUN_SCRIPT static bool
5953
generateKey(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
5954
0
{
5955
0
  AUTO_PROFILER_LABEL_FAST("SubtleCrypto.generateKey", DOM, cx);
5956
0
5957
0
  if (MOZ_UNLIKELY(args.length() < 3)) {
5958
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SubtleCrypto.generateKey");
5959
0
  }
5960
0
  ObjectOrString arg0;
5961
0
  ObjectOrStringArgument arg0_holder(arg0);
5962
0
  {
5963
0
    bool done = false, failed = false, tryNext;
5964
0
    if (args[0].isObject()) {
5965
0
      if (!arg0_holder.SetToObject(cx, &args[0].toObject(), false)) {
5966
0
        return false;
5967
0
      }
5968
0
      done = true;
5969
0
    } else {
5970
0
      do {
5971
0
        done = (failed = !arg0_holder.TrySetToString(cx, args[0], tryNext)) || !tryNext;
5972
0
        break;
5973
0
      } while (false);
5974
0
    }
5975
0
    if (failed) {
5976
0
      return false;
5977
0
    }
5978
0
    if (!done) {
5979
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 1 of SubtleCrypto.generateKey", "Object");
5980
0
      return false;
5981
0
    }
5982
0
  }
5983
0
  bool arg1;
5984
0
  if (!ValueToPrimitive<bool, eDefault>(cx, args[1], &arg1)) {
5985
0
    return false;
5986
0
  }
5987
0
  binding_detail::AutoSequence<nsString> arg2;
5988
0
  if (args[2].isObject()) {
5989
0
    JS::ForOfIterator iter(cx);
5990
0
    if (!iter.init(args[2], JS::ForOfIterator::AllowNonIterable)) {
5991
0
      return false;
5992
0
    }
5993
0
    if (!iter.valueIsIterable()) {
5994
0
      ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 3 of SubtleCrypto.generateKey");
5995
0
      return false;
5996
0
    }
5997
0
    binding_detail::AutoSequence<nsString> &arr = arg2;
5998
0
    JS::Rooted<JS::Value> temp(cx);
5999
0
    while (true) {
6000
0
      bool done;
6001
0
      if (!iter.next(&temp, &done)) {
6002
0
        return false;
6003
0
      }
6004
0
      if (done) {
6005
0
        break;
6006
0
      }
6007
0
      nsString* slotPtr = arr.AppendElement(mozilla::fallible);
6008
0
      if (!slotPtr) {
6009
0
        JS_ReportOutOfMemory(cx);
6010
0
        return false;
6011
0
      }
6012
0
      nsString& slot = *slotPtr;
6013
0
      if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
6014
0
        return false;
6015
0
      }
6016
0
    }
6017
0
  } else {
6018
0
    ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 3 of SubtleCrypto.generateKey");
6019
0
    return false;
6020
0
  }
6021
0
  FastErrorResult rv;
6022
0
  auto result(StrongOrRawPtr<Promise>(self->GenerateKey(cx, Constify(arg0), arg1, Constify(arg2), rv)));
6023
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
6024
0
    return false;
6025
0
  }
6026
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
6027
0
  if (!ToJSValue(cx, result, args.rval())) {
6028
0
    return false;
6029
0
  }
6030
0
  return true;
6031
0
}
6032
6033
MOZ_CAN_RUN_SCRIPT static bool
6034
generateKey_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
6035
0
{
6036
0
  bool ok = generateKey(cx, obj, self, args);
6037
0
  if (ok) {
6038
0
    return true;
6039
0
  }
6040
0
  return ConvertExceptionToPromise(cx, args.rval());
6041
0
}
6042
6043
static const JSJitInfo generateKey_methodinfo = {
6044
  { (JSJitGetterOp)generateKey_promiseWrapper },
6045
  { prototypes::id::SubtleCrypto },
6046
  { PrototypeTraits<prototypes::id::SubtleCrypto>::Depth },
6047
  JSJitInfo::Method,
6048
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
6049
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
6050
  false,  /* isInfallible. False in setters. */
6051
  false,  /* isMovable.  Not relevant for setters. */
6052
  false, /* isEliminatable.  Not relevant for setters. */
6053
  false, /* isAlwaysInSlot.  Only relevant for getters. */
6054
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
6055
  false,  /* isTypedMethod.  Only relevant for methods. */
6056
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
6057
};
6058
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
6059
static_assert(0 < 1, "There is no slot for us");
6060
6061
MOZ_CAN_RUN_SCRIPT static bool
6062
deriveKey(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
6063
0
{
6064
0
  AUTO_PROFILER_LABEL_FAST("SubtleCrypto.deriveKey", DOM, cx);
6065
0
6066
0
  if (MOZ_UNLIKELY(args.length() < 5)) {
6067
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SubtleCrypto.deriveKey");
6068
0
  }
6069
0
  ObjectOrString arg0;
6070
0
  ObjectOrStringArgument arg0_holder(arg0);
6071
0
  {
6072
0
    bool done = false, failed = false, tryNext;
6073
0
    if (args[0].isObject()) {
6074
0
      if (!arg0_holder.SetToObject(cx, &args[0].toObject(), false)) {
6075
0
        return false;
6076
0
      }
6077
0
      done = true;
6078
0
    } else {
6079
0
      do {
6080
0
        done = (failed = !arg0_holder.TrySetToString(cx, args[0], tryNext)) || !tryNext;
6081
0
        break;
6082
0
      } while (false);
6083
0
    }
6084
0
    if (failed) {
6085
0
      return false;
6086
0
    }
6087
0
    if (!done) {
6088
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 1 of SubtleCrypto.deriveKey", "Object");
6089
0
      return false;
6090
0
    }
6091
0
  }
6092
0
  NonNull<mozilla::dom::CryptoKey> arg1;
6093
0
  if (args[1].isObject()) {
6094
0
    {
6095
0
      nsresult rv = UnwrapObject<prototypes::id::CryptoKey, mozilla::dom::CryptoKey>(args[1], arg1);
6096
0
      if (NS_FAILED(rv)) {
6097
0
        ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 2 of SubtleCrypto.deriveKey", "CryptoKey");
6098
0
        return false;
6099
0
      }
6100
0
    }
6101
0
  } else {
6102
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of SubtleCrypto.deriveKey");
6103
0
    return false;
6104
0
  }
6105
0
  ObjectOrString arg2;
6106
0
  ObjectOrStringArgument arg2_holder(arg2);
6107
0
  {
6108
0
    bool done = false, failed = false, tryNext;
6109
0
    if (args[2].isObject()) {
6110
0
      if (!arg2_holder.SetToObject(cx, &args[2].toObject(), false)) {
6111
0
        return false;
6112
0
      }
6113
0
      done = true;
6114
0
    } else {
6115
0
      do {
6116
0
        done = (failed = !arg2_holder.TrySetToString(cx, args[2], tryNext)) || !tryNext;
6117
0
        break;
6118
0
      } while (false);
6119
0
    }
6120
0
    if (failed) {
6121
0
      return false;
6122
0
    }
6123
0
    if (!done) {
6124
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 3 of SubtleCrypto.deriveKey", "Object");
6125
0
      return false;
6126
0
    }
6127
0
  }
6128
0
  bool arg3;
6129
0
  if (!ValueToPrimitive<bool, eDefault>(cx, args[3], &arg3)) {
6130
0
    return false;
6131
0
  }
6132
0
  binding_detail::AutoSequence<nsString> arg4;
6133
0
  if (args[4].isObject()) {
6134
0
    JS::ForOfIterator iter(cx);
6135
0
    if (!iter.init(args[4], JS::ForOfIterator::AllowNonIterable)) {
6136
0
      return false;
6137
0
    }
6138
0
    if (!iter.valueIsIterable()) {
6139
0
      ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 5 of SubtleCrypto.deriveKey");
6140
0
      return false;
6141
0
    }
6142
0
    binding_detail::AutoSequence<nsString> &arr = arg4;
6143
0
    JS::Rooted<JS::Value> temp(cx);
6144
0
    while (true) {
6145
0
      bool done;
6146
0
      if (!iter.next(&temp, &done)) {
6147
0
        return false;
6148
0
      }
6149
0
      if (done) {
6150
0
        break;
6151
0
      }
6152
0
      nsString* slotPtr = arr.AppendElement(mozilla::fallible);
6153
0
      if (!slotPtr) {
6154
0
        JS_ReportOutOfMemory(cx);
6155
0
        return false;
6156
0
      }
6157
0
      nsString& slot = *slotPtr;
6158
0
      if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
6159
0
        return false;
6160
0
      }
6161
0
    }
6162
0
  } else {
6163
0
    ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 5 of SubtleCrypto.deriveKey");
6164
0
    return false;
6165
0
  }
6166
0
  FastErrorResult rv;
6167
0
  auto result(StrongOrRawPtr<Promise>(self->DeriveKey(cx, Constify(arg0), MOZ_KnownLive(NonNullHelper(arg1)), Constify(arg2), arg3, Constify(arg4), rv)));
6168
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
6169
0
    return false;
6170
0
  }
6171
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
6172
0
  if (!ToJSValue(cx, result, args.rval())) {
6173
0
    return false;
6174
0
  }
6175
0
  return true;
6176
0
}
6177
6178
MOZ_CAN_RUN_SCRIPT static bool
6179
deriveKey_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
6180
0
{
6181
0
  bool ok = deriveKey(cx, obj, self, args);
6182
0
  if (ok) {
6183
0
    return true;
6184
0
  }
6185
0
  return ConvertExceptionToPromise(cx, args.rval());
6186
0
}
6187
6188
static const JSJitInfo deriveKey_methodinfo = {
6189
  { (JSJitGetterOp)deriveKey_promiseWrapper },
6190
  { prototypes::id::SubtleCrypto },
6191
  { PrototypeTraits<prototypes::id::SubtleCrypto>::Depth },
6192
  JSJitInfo::Method,
6193
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
6194
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
6195
  false,  /* isInfallible. False in setters. */
6196
  false,  /* isMovable.  Not relevant for setters. */
6197
  false, /* isEliminatable.  Not relevant for setters. */
6198
  false, /* isAlwaysInSlot.  Only relevant for getters. */
6199
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
6200
  false,  /* isTypedMethod.  Only relevant for methods. */
6201
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
6202
};
6203
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
6204
static_assert(0 < 1, "There is no slot for us");
6205
6206
MOZ_CAN_RUN_SCRIPT static bool
6207
deriveBits(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
6208
0
{
6209
0
  AUTO_PROFILER_LABEL_FAST("SubtleCrypto.deriveBits", DOM, cx);
6210
0
6211
0
  if (MOZ_UNLIKELY(args.length() < 3)) {
6212
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SubtleCrypto.deriveBits");
6213
0
  }
6214
0
  ObjectOrString arg0;
6215
0
  ObjectOrStringArgument arg0_holder(arg0);
6216
0
  {
6217
0
    bool done = false, failed = false, tryNext;
6218
0
    if (args[0].isObject()) {
6219
0
      if (!arg0_holder.SetToObject(cx, &args[0].toObject(), false)) {
6220
0
        return false;
6221
0
      }
6222
0
      done = true;
6223
0
    } else {
6224
0
      do {
6225
0
        done = (failed = !arg0_holder.TrySetToString(cx, args[0], tryNext)) || !tryNext;
6226
0
        break;
6227
0
      } while (false);
6228
0
    }
6229
0
    if (failed) {
6230
0
      return false;
6231
0
    }
6232
0
    if (!done) {
6233
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 1 of SubtleCrypto.deriveBits", "Object");
6234
0
      return false;
6235
0
    }
6236
0
  }
6237
0
  NonNull<mozilla::dom::CryptoKey> arg1;
6238
0
  if (args[1].isObject()) {
6239
0
    {
6240
0
      nsresult rv = UnwrapObject<prototypes::id::CryptoKey, mozilla::dom::CryptoKey>(args[1], arg1);
6241
0
      if (NS_FAILED(rv)) {
6242
0
        ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 2 of SubtleCrypto.deriveBits", "CryptoKey");
6243
0
        return false;
6244
0
      }
6245
0
    }
6246
0
  } else {
6247
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of SubtleCrypto.deriveBits");
6248
0
    return false;
6249
0
  }
6250
0
  uint32_t arg2;
6251
0
  if (!ValueToPrimitive<uint32_t, eDefault>(cx, args[2], &arg2)) {
6252
0
    return false;
6253
0
  }
6254
0
  FastErrorResult rv;
6255
0
  auto result(StrongOrRawPtr<Promise>(self->DeriveBits(cx, Constify(arg0), MOZ_KnownLive(NonNullHelper(arg1)), arg2, rv)));
6256
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
6257
0
    return false;
6258
0
  }
6259
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
6260
0
  if (!ToJSValue(cx, result, args.rval())) {
6261
0
    return false;
6262
0
  }
6263
0
  return true;
6264
0
}
6265
6266
MOZ_CAN_RUN_SCRIPT static bool
6267
deriveBits_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
6268
0
{
6269
0
  bool ok = deriveBits(cx, obj, self, args);
6270
0
  if (ok) {
6271
0
    return true;
6272
0
  }
6273
0
  return ConvertExceptionToPromise(cx, args.rval());
6274
0
}
6275
6276
static const JSJitInfo deriveBits_methodinfo = {
6277
  { (JSJitGetterOp)deriveBits_promiseWrapper },
6278
  { prototypes::id::SubtleCrypto },
6279
  { PrototypeTraits<prototypes::id::SubtleCrypto>::Depth },
6280
  JSJitInfo::Method,
6281
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
6282
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
6283
  false,  /* isInfallible. False in setters. */
6284
  false,  /* isMovable.  Not relevant for setters. */
6285
  false, /* isEliminatable.  Not relevant for setters. */
6286
  false, /* isAlwaysInSlot.  Only relevant for getters. */
6287
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
6288
  false,  /* isTypedMethod.  Only relevant for methods. */
6289
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
6290
};
6291
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
6292
static_assert(0 < 1, "There is no slot for us");
6293
6294
MOZ_CAN_RUN_SCRIPT static bool
6295
importKey(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
6296
0
{
6297
0
  AUTO_PROFILER_LABEL_FAST("SubtleCrypto.importKey", DOM, cx);
6298
0
6299
0
  if (MOZ_UNLIKELY(args.length() < 5)) {
6300
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SubtleCrypto.importKey");
6301
0
  }
6302
0
  binding_detail::FakeString arg0;
6303
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
6304
0
    return false;
6305
0
  }
6306
0
  JS::Rooted<JSObject*> arg1(cx);
6307
0
  if (args[1].isObject()) {
6308
0
    arg1 = &args[1].toObject();
6309
0
  } else {
6310
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of SubtleCrypto.importKey");
6311
0
    return false;
6312
0
  }
6313
0
  ObjectOrString arg2;
6314
0
  ObjectOrStringArgument arg2_holder(arg2);
6315
0
  {
6316
0
    bool done = false, failed = false, tryNext;
6317
0
    if (args[2].isObject()) {
6318
0
      if (!arg2_holder.SetToObject(cx, &args[2].toObject(), false)) {
6319
0
        return false;
6320
0
      }
6321
0
      done = true;
6322
0
    } else {
6323
0
      do {
6324
0
        done = (failed = !arg2_holder.TrySetToString(cx, args[2], tryNext)) || !tryNext;
6325
0
        break;
6326
0
      } while (false);
6327
0
    }
6328
0
    if (failed) {
6329
0
      return false;
6330
0
    }
6331
0
    if (!done) {
6332
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 3 of SubtleCrypto.importKey", "Object");
6333
0
      return false;
6334
0
    }
6335
0
  }
6336
0
  bool arg3;
6337
0
  if (!ValueToPrimitive<bool, eDefault>(cx, args[3], &arg3)) {
6338
0
    return false;
6339
0
  }
6340
0
  binding_detail::AutoSequence<nsString> arg4;
6341
0
  if (args[4].isObject()) {
6342
0
    JS::ForOfIterator iter(cx);
6343
0
    if (!iter.init(args[4], JS::ForOfIterator::AllowNonIterable)) {
6344
0
      return false;
6345
0
    }
6346
0
    if (!iter.valueIsIterable()) {
6347
0
      ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 5 of SubtleCrypto.importKey");
6348
0
      return false;
6349
0
    }
6350
0
    binding_detail::AutoSequence<nsString> &arr = arg4;
6351
0
    JS::Rooted<JS::Value> temp(cx);
6352
0
    while (true) {
6353
0
      bool done;
6354
0
      if (!iter.next(&temp, &done)) {
6355
0
        return false;
6356
0
      }
6357
0
      if (done) {
6358
0
        break;
6359
0
      }
6360
0
      nsString* slotPtr = arr.AppendElement(mozilla::fallible);
6361
0
      if (!slotPtr) {
6362
0
        JS_ReportOutOfMemory(cx);
6363
0
        return false;
6364
0
      }
6365
0
      nsString& slot = *slotPtr;
6366
0
      if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
6367
0
        return false;
6368
0
      }
6369
0
    }
6370
0
  } else {
6371
0
    ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 5 of SubtleCrypto.importKey");
6372
0
    return false;
6373
0
  }
6374
0
  FastErrorResult rv;
6375
0
  auto result(StrongOrRawPtr<Promise>(self->ImportKey(cx, NonNullHelper(Constify(arg0)), arg1, Constify(arg2), arg3, Constify(arg4), rv)));
6376
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
6377
0
    return false;
6378
0
  }
6379
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
6380
0
  if (!ToJSValue(cx, result, args.rval())) {
6381
0
    return false;
6382
0
  }
6383
0
  return true;
6384
0
}
6385
6386
MOZ_CAN_RUN_SCRIPT static bool
6387
importKey_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
6388
0
{
6389
0
  bool ok = importKey(cx, obj, self, args);
6390
0
  if (ok) {
6391
0
    return true;
6392
0
  }
6393
0
  return ConvertExceptionToPromise(cx, args.rval());
6394
0
}
6395
6396
static const JSJitInfo importKey_methodinfo = {
6397
  { (JSJitGetterOp)importKey_promiseWrapper },
6398
  { prototypes::id::SubtleCrypto },
6399
  { PrototypeTraits<prototypes::id::SubtleCrypto>::Depth },
6400
  JSJitInfo::Method,
6401
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
6402
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
6403
  false,  /* isInfallible. False in setters. */
6404
  false,  /* isMovable.  Not relevant for setters. */
6405
  false, /* isEliminatable.  Not relevant for setters. */
6406
  false, /* isAlwaysInSlot.  Only relevant for getters. */
6407
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
6408
  false,  /* isTypedMethod.  Only relevant for methods. */
6409
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
6410
};
6411
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
6412
static_assert(0 < 1, "There is no slot for us");
6413
6414
MOZ_CAN_RUN_SCRIPT static bool
6415
exportKey(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
6416
0
{
6417
0
  AUTO_PROFILER_LABEL_FAST("SubtleCrypto.exportKey", DOM, cx);
6418
0
6419
0
  if (MOZ_UNLIKELY(args.length() < 2)) {
6420
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SubtleCrypto.exportKey");
6421
0
  }
6422
0
  binding_detail::FakeString arg0;
6423
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
6424
0
    return false;
6425
0
  }
6426
0
  NonNull<mozilla::dom::CryptoKey> arg1;
6427
0
  if (args[1].isObject()) {
6428
0
    {
6429
0
      nsresult rv = UnwrapObject<prototypes::id::CryptoKey, mozilla::dom::CryptoKey>(args[1], arg1);
6430
0
      if (NS_FAILED(rv)) {
6431
0
        ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 2 of SubtleCrypto.exportKey", "CryptoKey");
6432
0
        return false;
6433
0
      }
6434
0
    }
6435
0
  } else {
6436
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of SubtleCrypto.exportKey");
6437
0
    return false;
6438
0
  }
6439
0
  FastErrorResult rv;
6440
0
  auto result(StrongOrRawPtr<Promise>(self->ExportKey(NonNullHelper(Constify(arg0)), MOZ_KnownLive(NonNullHelper(arg1)), rv)));
6441
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
6442
0
    return false;
6443
0
  }
6444
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
6445
0
  if (!ToJSValue(cx, result, args.rval())) {
6446
0
    return false;
6447
0
  }
6448
0
  return true;
6449
0
}
6450
6451
MOZ_CAN_RUN_SCRIPT static bool
6452
exportKey_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
6453
0
{
6454
0
  bool ok = exportKey(cx, obj, self, args);
6455
0
  if (ok) {
6456
0
    return true;
6457
0
  }
6458
0
  return ConvertExceptionToPromise(cx, args.rval());
6459
0
}
6460
6461
static const JSJitInfo exportKey_methodinfo = {
6462
  { (JSJitGetterOp)exportKey_promiseWrapper },
6463
  { prototypes::id::SubtleCrypto },
6464
  { PrototypeTraits<prototypes::id::SubtleCrypto>::Depth },
6465
  JSJitInfo::Method,
6466
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
6467
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
6468
  false,  /* isInfallible. False in setters. */
6469
  false,  /* isMovable.  Not relevant for setters. */
6470
  false, /* isEliminatable.  Not relevant for setters. */
6471
  false, /* isAlwaysInSlot.  Only relevant for getters. */
6472
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
6473
  false,  /* isTypedMethod.  Only relevant for methods. */
6474
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
6475
};
6476
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
6477
static_assert(0 < 1, "There is no slot for us");
6478
6479
MOZ_CAN_RUN_SCRIPT static bool
6480
wrapKey(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
6481
0
{
6482
0
  AUTO_PROFILER_LABEL_FAST("SubtleCrypto.wrapKey", DOM, cx);
6483
0
6484
0
  if (MOZ_UNLIKELY(args.length() < 4)) {
6485
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SubtleCrypto.wrapKey");
6486
0
  }
6487
0
  binding_detail::FakeString arg0;
6488
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
6489
0
    return false;
6490
0
  }
6491
0
  NonNull<mozilla::dom::CryptoKey> arg1;
6492
0
  if (args[1].isObject()) {
6493
0
    {
6494
0
      nsresult rv = UnwrapObject<prototypes::id::CryptoKey, mozilla::dom::CryptoKey>(args[1], arg1);
6495
0
      if (NS_FAILED(rv)) {
6496
0
        ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 2 of SubtleCrypto.wrapKey", "CryptoKey");
6497
0
        return false;
6498
0
      }
6499
0
    }
6500
0
  } else {
6501
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 2 of SubtleCrypto.wrapKey");
6502
0
    return false;
6503
0
  }
6504
0
  NonNull<mozilla::dom::CryptoKey> arg2;
6505
0
  if (args[2].isObject()) {
6506
0
    {
6507
0
      nsresult rv = UnwrapObject<prototypes::id::CryptoKey, mozilla::dom::CryptoKey>(args[2], arg2);
6508
0
      if (NS_FAILED(rv)) {
6509
0
        ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 3 of SubtleCrypto.wrapKey", "CryptoKey");
6510
0
        return false;
6511
0
      }
6512
0
    }
6513
0
  } else {
6514
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 3 of SubtleCrypto.wrapKey");
6515
0
    return false;
6516
0
  }
6517
0
  ObjectOrString arg3;
6518
0
  ObjectOrStringArgument arg3_holder(arg3);
6519
0
  {
6520
0
    bool done = false, failed = false, tryNext;
6521
0
    if (args[3].isObject()) {
6522
0
      if (!arg3_holder.SetToObject(cx, &args[3].toObject(), false)) {
6523
0
        return false;
6524
0
      }
6525
0
      done = true;
6526
0
    } else {
6527
0
      do {
6528
0
        done = (failed = !arg3_holder.TrySetToString(cx, args[3], tryNext)) || !tryNext;
6529
0
        break;
6530
0
      } while (false);
6531
0
    }
6532
0
    if (failed) {
6533
0
      return false;
6534
0
    }
6535
0
    if (!done) {
6536
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 4 of SubtleCrypto.wrapKey", "Object");
6537
0
      return false;
6538
0
    }
6539
0
  }
6540
0
  FastErrorResult rv;
6541
0
  auto result(StrongOrRawPtr<Promise>(self->WrapKey(cx, NonNullHelper(Constify(arg0)), MOZ_KnownLive(NonNullHelper(arg1)), MOZ_KnownLive(NonNullHelper(arg2)), Constify(arg3), rv)));
6542
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
6543
0
    return false;
6544
0
  }
6545
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
6546
0
  if (!ToJSValue(cx, result, args.rval())) {
6547
0
    return false;
6548
0
  }
6549
0
  return true;
6550
0
}
6551
6552
MOZ_CAN_RUN_SCRIPT static bool
6553
wrapKey_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
6554
0
{
6555
0
  bool ok = wrapKey(cx, obj, self, args);
6556
0
  if (ok) {
6557
0
    return true;
6558
0
  }
6559
0
  return ConvertExceptionToPromise(cx, args.rval());
6560
0
}
6561
6562
static const JSJitInfo wrapKey_methodinfo = {
6563
  { (JSJitGetterOp)wrapKey_promiseWrapper },
6564
  { prototypes::id::SubtleCrypto },
6565
  { PrototypeTraits<prototypes::id::SubtleCrypto>::Depth },
6566
  JSJitInfo::Method,
6567
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
6568
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
6569
  false,  /* isInfallible. False in setters. */
6570
  false,  /* isMovable.  Not relevant for setters. */
6571
  false, /* isEliminatable.  Not relevant for setters. */
6572
  false, /* isAlwaysInSlot.  Only relevant for getters. */
6573
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
6574
  false,  /* isTypedMethod.  Only relevant for methods. */
6575
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
6576
};
6577
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
6578
static_assert(0 < 1, "There is no slot for us");
6579
6580
MOZ_CAN_RUN_SCRIPT static bool
6581
unwrapKey(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
6582
0
{
6583
0
  AUTO_PROFILER_LABEL_FAST("SubtleCrypto.unwrapKey", DOM, cx);
6584
0
6585
0
  if (MOZ_UNLIKELY(args.length() < 7)) {
6586
0
    return ThrowErrorMessage(cx, MSG_MISSING_ARGUMENTS, "SubtleCrypto.unwrapKey");
6587
0
  }
6588
0
  binding_detail::FakeString arg0;
6589
0
  if (!ConvertJSValueToString(cx, args[0], eStringify, eStringify, arg0)) {
6590
0
    return false;
6591
0
  }
6592
0
  ArrayBufferViewOrArrayBuffer arg1;
6593
0
  ArrayBufferViewOrArrayBufferArgument arg1_holder(arg1);
6594
0
  {
6595
0
    bool done = false, failed = false, tryNext;
6596
0
    if (args[1].isObject()) {
6597
0
      done = (failed = !arg1_holder.TrySetToArrayBufferView(cx, args[1], tryNext, false)) || !tryNext ||
6598
0
             (failed = !arg1_holder.TrySetToArrayBuffer(cx, args[1], tryNext, false)) || !tryNext;
6599
0
6600
0
    }
6601
0
    if (failed) {
6602
0
      return false;
6603
0
    }
6604
0
    if (!done) {
6605
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 2 of SubtleCrypto.unwrapKey", "ArrayBufferView, ArrayBuffer");
6606
0
      return false;
6607
0
    }
6608
0
  }
6609
0
  NonNull<mozilla::dom::CryptoKey> arg2;
6610
0
  if (args[2].isObject()) {
6611
0
    {
6612
0
      nsresult rv = UnwrapObject<prototypes::id::CryptoKey, mozilla::dom::CryptoKey>(args[2], arg2);
6613
0
      if (NS_FAILED(rv)) {
6614
0
        ThrowErrorMessage(cx, MSG_DOES_NOT_IMPLEMENT_INTERFACE, "Argument 3 of SubtleCrypto.unwrapKey", "CryptoKey");
6615
0
        return false;
6616
0
      }
6617
0
    }
6618
0
  } else {
6619
0
    ThrowErrorMessage(cx, MSG_NOT_OBJECT, "Argument 3 of SubtleCrypto.unwrapKey");
6620
0
    return false;
6621
0
  }
6622
0
  ObjectOrString arg3;
6623
0
  ObjectOrStringArgument arg3_holder(arg3);
6624
0
  {
6625
0
    bool done = false, failed = false, tryNext;
6626
0
    if (args[3].isObject()) {
6627
0
      if (!arg3_holder.SetToObject(cx, &args[3].toObject(), false)) {
6628
0
        return false;
6629
0
      }
6630
0
      done = true;
6631
0
    } else {
6632
0
      do {
6633
0
        done = (failed = !arg3_holder.TrySetToString(cx, args[3], tryNext)) || !tryNext;
6634
0
        break;
6635
0
      } while (false);
6636
0
    }
6637
0
    if (failed) {
6638
0
      return false;
6639
0
    }
6640
0
    if (!done) {
6641
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 4 of SubtleCrypto.unwrapKey", "Object");
6642
0
      return false;
6643
0
    }
6644
0
  }
6645
0
  ObjectOrString arg4;
6646
0
  ObjectOrStringArgument arg4_holder(arg4);
6647
0
  {
6648
0
    bool done = false, failed = false, tryNext;
6649
0
    if (args[4].isObject()) {
6650
0
      if (!arg4_holder.SetToObject(cx, &args[4].toObject(), false)) {
6651
0
        return false;
6652
0
      }
6653
0
      done = true;
6654
0
    } else {
6655
0
      do {
6656
0
        done = (failed = !arg4_holder.TrySetToString(cx, args[4], tryNext)) || !tryNext;
6657
0
        break;
6658
0
      } while (false);
6659
0
    }
6660
0
    if (failed) {
6661
0
      return false;
6662
0
    }
6663
0
    if (!done) {
6664
0
      ThrowErrorMessage(cx, MSG_NOT_IN_UNION, "Argument 5 of SubtleCrypto.unwrapKey", "Object");
6665
0
      return false;
6666
0
    }
6667
0
  }
6668
0
  bool arg5;
6669
0
  if (!ValueToPrimitive<bool, eDefault>(cx, args[5], &arg5)) {
6670
0
    return false;
6671
0
  }
6672
0
  binding_detail::AutoSequence<nsString> arg6;
6673
0
  if (args[6].isObject()) {
6674
0
    JS::ForOfIterator iter(cx);
6675
0
    if (!iter.init(args[6], JS::ForOfIterator::AllowNonIterable)) {
6676
0
      return false;
6677
0
    }
6678
0
    if (!iter.valueIsIterable()) {
6679
0
      ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 7 of SubtleCrypto.unwrapKey");
6680
0
      return false;
6681
0
    }
6682
0
    binding_detail::AutoSequence<nsString> &arr = arg6;
6683
0
    JS::Rooted<JS::Value> temp(cx);
6684
0
    while (true) {
6685
0
      bool done;
6686
0
      if (!iter.next(&temp, &done)) {
6687
0
        return false;
6688
0
      }
6689
0
      if (done) {
6690
0
        break;
6691
0
      }
6692
0
      nsString* slotPtr = arr.AppendElement(mozilla::fallible);
6693
0
      if (!slotPtr) {
6694
0
        JS_ReportOutOfMemory(cx);
6695
0
        return false;
6696
0
      }
6697
0
      nsString& slot = *slotPtr;
6698
0
      if (!ConvertJSValueToString(cx, temp, eStringify, eStringify, slot)) {
6699
0
        return false;
6700
0
      }
6701
0
    }
6702
0
  } else {
6703
0
    ThrowErrorMessage(cx, MSG_NOT_SEQUENCE, "Argument 7 of SubtleCrypto.unwrapKey");
6704
0
    return false;
6705
0
  }
6706
0
  FastErrorResult rv;
6707
0
  auto result(StrongOrRawPtr<Promise>(self->UnwrapKey(cx, NonNullHelper(Constify(arg0)), Constify(arg1), MOZ_KnownLive(NonNullHelper(arg2)), Constify(arg3), Constify(arg4), arg5, Constify(arg6), rv)));
6708
0
  if (MOZ_UNLIKELY(rv.MaybeSetPendingException(cx))) {
6709
0
    return false;
6710
0
  }
6711
0
  MOZ_ASSERT(!JS_IsExceptionPending(cx));
6712
0
  if (!ToJSValue(cx, result, args.rval())) {
6713
0
    return false;
6714
0
  }
6715
0
  return true;
6716
0
}
6717
6718
MOZ_CAN_RUN_SCRIPT static bool
6719
unwrapKey_promiseWrapper(JSContext* cx, JS::Handle<JSObject*> obj, mozilla::dom::SubtleCrypto* self, const JSJitMethodCallArgs& args)
6720
0
{
6721
0
  bool ok = unwrapKey(cx, obj, self, args);
6722
0
  if (ok) {
6723
0
    return true;
6724
0
  }
6725
0
  return ConvertExceptionToPromise(cx, args.rval());
6726
0
}
6727
6728
static const JSJitInfo unwrapKey_methodinfo = {
6729
  { (JSJitGetterOp)unwrapKey_promiseWrapper },
6730
  { prototypes::id::SubtleCrypto },
6731
  { PrototypeTraits<prototypes::id::SubtleCrypto>::Depth },
6732
  JSJitInfo::Method,
6733
  JSJitInfo::AliasEverything, /* aliasSet.  Not relevant for setters. */
6734
  JSVAL_TYPE_OBJECT,  /* returnType.  Not relevant for setters. */
6735
  false,  /* isInfallible. False in setters. */
6736
  false,  /* isMovable.  Not relevant for setters. */
6737
  false, /* isEliminatable.  Not relevant for setters. */
6738
  false, /* isAlwaysInSlot.  Only relevant for getters. */
6739
  false, /* isLazilyCachedInSlot.  Only relevant for getters. */
6740
  false,  /* isTypedMethod.  Only relevant for methods. */
6741
  0   /* Reserved slot index, if we're stored in a slot, else 0. */
6742
};
6743
static_assert(0 <= JSJitInfo::maxSlotIndex, "We won't fit");
6744
static_assert(0 < 1, "There is no slot for us");
6745
6746
static bool
6747
_addProperty(JSContext* cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id, JS::Handle<JS::Value> val)
6748
0
{
6749
0
  mozilla::dom::SubtleCrypto* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SubtleCrypto>(obj);
6750
0
  // We don't want to preserve if we don't have a wrapper, and we
6751
0
  // obviously can't preserve if we're not initialized.
6752
0
  if (self && self->GetWrapperPreserveColor()) {
6753
0
    PreserveWrapper(self);
6754
0
  }
6755
0
  return true;
6756
0
}
6757
6758
static void
6759
_finalize(js::FreeOp* fop, JSObject* obj)
6760
0
{
6761
0
  mozilla::dom::SubtleCrypto* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SubtleCrypto>(obj);
6762
0
  if (self) {
6763
0
    ClearWrapper(self, self, obj);
6764
0
    AddForDeferredFinalization<mozilla::dom::SubtleCrypto>(self);
6765
0
  }
6766
0
}
6767
6768
static size_t
6769
_objectMoved(JSObject* obj, JSObject* old)
6770
0
{
6771
0
  mozilla::dom::SubtleCrypto* self = UnwrapPossiblyNotInitializedDOMObject<mozilla::dom::SubtleCrypto>(obj);
6772
0
  if (self) {
6773
0
    UpdateWrapper(self, self, obj, old);
6774
0
  }
6775
0
6776
0
  return 0;
6777
0
}
6778
6779
// We deliberately use brace-elision to make Visual Studio produce better initalization code.
6780
#if defined(__clang__)
6781
#pragma clang diagnostic push
6782
#pragma clang diagnostic ignored "-Wmissing-braces"
6783
#endif
6784
static const JSFunctionSpec sMethods_specs[] = {
6785
  JS_FNSPEC("encrypt", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&encrypt_methodinfo), 3, JSPROP_ENUMERATE, nullptr),
6786
  JS_FNSPEC("decrypt", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&decrypt_methodinfo), 3, JSPROP_ENUMERATE, nullptr),
6787
  JS_FNSPEC("sign", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&sign_methodinfo), 3, JSPROP_ENUMERATE, nullptr),
6788
  JS_FNSPEC("verify", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&verify_methodinfo), 4, JSPROP_ENUMERATE, nullptr),
6789
  JS_FNSPEC("digest", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&digest_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
6790
  JS_FNSPEC("generateKey", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&generateKey_methodinfo), 3, JSPROP_ENUMERATE, nullptr),
6791
  JS_FNSPEC("deriveKey", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&deriveKey_methodinfo), 5, JSPROP_ENUMERATE, nullptr),
6792
  JS_FNSPEC("deriveBits", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&deriveBits_methodinfo), 3, JSPROP_ENUMERATE, nullptr),
6793
  JS_FNSPEC("importKey", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&importKey_methodinfo), 5, JSPROP_ENUMERATE, nullptr),
6794
  JS_FNSPEC("exportKey", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&exportKey_methodinfo), 2, JSPROP_ENUMERATE, nullptr),
6795
  JS_FNSPEC("wrapKey", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&wrapKey_methodinfo), 4, JSPROP_ENUMERATE, nullptr),
6796
  JS_FNSPEC("unwrapKey", (GenericMethod<NormalThisPolicy, ConvertExceptionsToPromises>), reinterpret_cast<const JSJitInfo*>(&unwrapKey_methodinfo), 7, JSPROP_ENUMERATE, nullptr),
6797
  JS_FS_END
6798
};
6799
#if defined(__clang__)
6800
#pragma clang diagnostic pop
6801
#endif
6802
6803
6804
static const Prefable<const JSFunctionSpec> sMethods[] = {
6805
  { nullptr, &sMethods_specs[0] },
6806
  { nullptr, nullptr }
6807
};
6808
6809
static_assert(1 <= 1ull << NUM_BITS_PROPERTY_INFO_PREF_INDEX,
6810
    "We have a prefable index that is >= (1 << NUM_BITS_PROPERTY_INFO_PREF_INDEX)");
6811
static_assert(12 <= 1ull << NUM_BITS_PROPERTY_INFO_SPEC_INDEX,
6812
    "We have a spec index that is >= (1 << NUM_BITS_PROPERTY_INFO_SPEC_INDEX)");
6813
6814
6815
static uint16_t sNativeProperties_sortedPropertyIndices[12];
6816
static PropertyInfo sNativeProperties_propertyInfos[12];
6817
6818
static const NativePropertiesN<1> sNativeProperties = {
6819
  false, 0,
6820
  false, 0,
6821
  true,  0 /* sMethods */,
6822
  false, 0,
6823
  false, 0,
6824
  false, 0,
6825
  false, 0,
6826
  -1,
6827
  12,
6828
  sNativeProperties_sortedPropertyIndices,
6829
  {
6830
    { sMethods, &sNativeProperties_propertyInfos[0] }
6831
  }
6832
};
6833
static_assert(12 < 1ull << CHAR_BIT * sizeof(sNativeProperties.propertyInfoCount),
6834
    "We have a property info count that is oversized");
6835
6836
static const DOMIfaceAndProtoJSClass sInterfaceObjectClass = {
6837
  {
6838
    "Function",
6839
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_SLOTS_BASE),
6840
    &sBoringInterfaceObjectClassClassOps,
6841
    JS_NULL_CLASS_SPEC,
6842
    JS_NULL_CLASS_EXT,
6843
    &sInterfaceObjectClassObjectOps
6844
  },
6845
  eInterface,
6846
  true,
6847
  prototypes::id::SubtleCrypto,
6848
  PrototypeTraits<prototypes::id::SubtleCrypto>::Depth,
6849
  sNativePropertyHooks,
6850
  "function SubtleCrypto() {\n    [native code]\n}",
6851
  JS::GetRealmFunctionPrototype
6852
};
6853
6854
static const DOMIfaceAndProtoJSClass sPrototypeClass = {
6855
  {
6856
    "SubtleCryptoPrototype",
6857
    JSCLASS_IS_DOMIFACEANDPROTOJSCLASS | JSCLASS_HAS_RESERVED_SLOTS(DOM_INTERFACE_PROTO_SLOTS_BASE),
6858
    JS_NULL_CLASS_OPS,
6859
    JS_NULL_CLASS_SPEC,
6860
    JS_NULL_CLASS_EXT,
6861
    JS_NULL_OBJECT_OPS
6862
  },
6863
  eInterfacePrototype,
6864
  false,
6865
  prototypes::id::SubtleCrypto,
6866
  PrototypeTraits<prototypes::id::SubtleCrypto>::Depth,
6867
  sNativePropertyHooks,
6868
  "[object SubtleCryptoPrototype]",
6869
  JS::GetRealmObjectPrototype
6870
};
6871
6872
static const js::ClassOps sClassOps = {
6873
  _addProperty, /* addProperty */
6874
  nullptr,               /* delProperty */
6875
  nullptr,               /* enumerate */
6876
  nullptr, /* newEnumerate */
6877
  nullptr, /* resolve */
6878
  nullptr, /* mayResolve */
6879
  _finalize, /* finalize */
6880
  nullptr, /* call */
6881
  nullptr,               /* hasInstance */
6882
  nullptr,               /* construct */
6883
  nullptr, /* trace */
6884
};
6885
6886
static const js::ClassExtension sClassExtension = {
6887
  nullptr, /* weakmapKeyDelegateOp */
6888
  _objectMoved /* objectMovedOp */
6889
};
6890
6891
static const DOMJSClass sClass = {
6892
  { "SubtleCrypto",
6893
    JSCLASS_IS_DOMJSCLASS | JSCLASS_FOREGROUND_FINALIZE | JSCLASS_HAS_RESERVED_SLOTS(1),
6894
    &sClassOps,
6895
    JS_NULL_CLASS_SPEC,
6896
    &sClassExtension,
6897
    JS_NULL_OBJECT_OPS
6898
  },
6899
  { prototypes::id::SubtleCrypto, 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 },
6900
  IsBaseOf<nsISupports, mozilla::dom::SubtleCrypto >::value,
6901
  sNativePropertyHooks,
6902
  FindAssociatedGlobalForNative<mozilla::dom::SubtleCrypto>::Get,
6903
  GetProtoObjectHandle,
6904
  GetCCParticipant<mozilla::dom::SubtleCrypto>::Get()
6905
};
6906
static_assert(1 == DOM_INSTANCE_RESERVED_SLOTS,
6907
              "Must have the right minimal number of reserved slots.");
6908
static_assert(1 >= 1,
6909
              "Must have enough reserved slots.");
6910
6911
const JSClass*
6912
GetJSClass()
6913
0
{
6914
0
  return sClass.ToJSClass();
6915
0
}
6916
6917
bool
6918
Wrap(JSContext* aCx, mozilla::dom::SubtleCrypto* aObject, nsWrapperCache* aCache, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector)
6919
0
{
6920
0
  static_assert(!IsBaseOf<NonRefcountedDOMObject, mozilla::dom::SubtleCrypto>::value,
6921
0
                "Shouldn't have wrappercached things that are not refcounted.");
6922
0
  MOZ_ASSERT(static_cast<mozilla::dom::SubtleCrypto*>(aObject) ==
6923
0
             reinterpret_cast<mozilla::dom::SubtleCrypto*>(aObject),
6924
0
             "Multiple inheritance for mozilla::dom::SubtleCrypto is broken.");
6925
0
  MOZ_ASSERT(ToSupportsIsCorrect(aObject));
6926
0
  MOZ_ASSERT_IF(aGivenProto, js::IsObjectInContextCompartment(aGivenProto, aCx));
6927
0
  MOZ_ASSERT(!aCache->GetWrapper(),
6928
0
             "You should probably not be using Wrap() directly; use "
6929
0
             "GetOrCreateDOMReflector instead");
6930
0
6931
0
  MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
6932
0
             "nsISupports must be on our primary inheritance chain");
6933
0
6934
0
  JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
6935
0
  if (!global) {
6936
0
    return false;
6937
0
  }
6938
0
  MOZ_ASSERT(JS_IsGlobalObject(global));
6939
0
  MOZ_ASSERT(JS::ObjectIsNotGray(global));
6940
0
6941
0
  // That might have ended up wrapping us already, due to the wonders
6942
0
  // of XBL.  Check for that, and bail out as needed.
6943
0
  aReflector.set(aCache->GetWrapper());
6944
0
  if (aReflector) {
6945
#ifdef DEBUG
6946
    AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
6947
#endif // DEBUG
6948
    return true;
6949
0
  }
6950
0
6951
0
  JSAutoRealm ar(aCx, global);
6952
0
  JS::Handle<JSObject*> canonicalProto = GetProtoObjectHandle(aCx);
6953
0
  if (!canonicalProto) {
6954
0
    return false;
6955
0
  }
6956
0
  JS::Rooted<JSObject*> proto(aCx);
6957
0
  if (aGivenProto) {
6958
0
    proto = aGivenProto;
6959
0
    // Unfortunately, while aGivenProto was in the compartment of aCx
6960
0
    // coming in, we changed compartments to that of "parent" so may need
6961
0
    // to wrap the proto here.
6962
0
    if (js::GetContextCompartment(aCx) != js::GetObjectCompartment(proto)) {
6963
0
      if (!JS_WrapObject(aCx, &proto)) {
6964
0
        return false;
6965
0
      }
6966
0
    }
6967
0
  } else {
6968
0
    proto = canonicalProto;
6969
0
  }
6970
0
6971
0
  BindingJSObjectCreator<mozilla::dom::SubtleCrypto> creator(aCx);
6972
0
  creator.CreateObject(aCx, sClass.ToJSClass(), proto, aObject, aReflector);
6973
0
  if (!aReflector) {
6974
0
    return false;
6975
0
  }
6976
0
6977
0
  aCache->SetWrapper(aReflector);
6978
0
  creator.InitializationSucceeded();
6979
0
6980
0
  MOZ_ASSERT(aCache->GetWrapperPreserveColor() &&
6981
0
             aCache->GetWrapperPreserveColor() == aReflector);
6982
0
  // If proto != canonicalProto, we have to preserve our wrapper;
6983
0
  // otherwise we won't be able to properly recreate it later, since
6984
0
  // we won't know what proto to use.  Note that we don't check
6985
0
  // aGivenProto here, since it's entirely possible (and even
6986
0
  // somewhat common) to have a non-null aGivenProto which is the
6987
0
  // same as canonicalProto.
6988
0
  if (proto != canonicalProto) {
6989
0
    PreserveWrapper(aObject);
6990
0
  }
6991
0
6992
0
  return true;
6993
0
}
6994
6995
const NativePropertyHooks sNativePropertyHooks[] = { {
6996
  nullptr,
6997
  nullptr,
6998
  nullptr,
6999
  { sNativeProperties.Upcast(), nullptr },
7000
  prototypes::id::SubtleCrypto,
7001
  constructors::id::SubtleCrypto,
7002
  nullptr,
7003
  &DefaultXrayExpandoObjectClass
7004
} };
7005
7006
void
7007
CreateInterfaceObjects(JSContext* aCx, JS::Handle<JSObject*> aGlobal, ProtoAndIfaceCache& aProtoAndIfaceCache, bool aDefineOnGlobal)
7008
0
{
7009
0
  JS::Rooted<JSObject*> parentProto(aCx, JS::GetRealmObjectPrototype(aCx));
7010
0
  if (!parentProto) {
7011
0
    return;
7012
0
  }
7013
0
7014
0
  JS::Rooted<JSObject*> constructorProto(aCx, JS::GetRealmFunctionPrototype(aCx));
7015
0
  if (!constructorProto) {
7016
0
    return;
7017
0
  }
7018
0
7019
0
  static bool sIdsInited = false;
7020
0
  if (!sIdsInited && NS_IsMainThread()) {
7021
0
    if (!InitIds(aCx, sNativeProperties.Upcast())) {
7022
0
      return;
7023
0
    }
7024
0
    sIdsInited = true;
7025
0
  }
7026
0
7027
0
  JS::Heap<JSObject*>* protoCache = &aProtoAndIfaceCache.EntrySlotOrCreate(prototypes::id::SubtleCrypto);
7028
0
  JS::Heap<JSObject*>* interfaceCache = &aProtoAndIfaceCache.EntrySlotOrCreate(constructors::id::SubtleCrypto);
7029
0
  dom::CreateInterfaceObjects(aCx, aGlobal, parentProto,
7030
0
                              &sPrototypeClass.mBase, protoCache,
7031
0
                              nullptr,
7032
0
                              constructorProto, &sInterfaceObjectClass.mBase, 0, nullptr,
7033
0
                              interfaceCache,
7034
0
                              sNativeProperties.Upcast(),
7035
0
                              nullptr,
7036
0
                              "SubtleCrypto", aDefineOnGlobal,
7037
0
                              nullptr,
7038
0
                              false);
7039
0
}
7040
7041
JSObject*
7042
GetConstructorObject(JSContext* aCx)
7043
0
{
7044
0
  return GetConstructorObjectHandle(aCx);
7045
0
}
7046
7047
} // namespace SubtleCrypto_Binding
7048
7049
7050
7051
} // namespace dom
7052
} // namespace mozilla