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